Nomor Hamming


19

Diberi bilangan bulat positif, cetaklah nomor hamming sebanyak itu , secara berurutan.

Aturan:

  • Input akan berupa bilangan bulat positifn1,000,000
  • Keluaran harus menjadi n pertama persyaratan https://oeis.org/A051037
  • Waktu pelaksanaan harus <1 menit
  • Ini adalah ; kode menang paling pendek

2
Tujuan jawaban mana yang seharusnya dimiliki? Golf? Algoritma yang paling efektif? Hanya mencari metode solusi?
Nakilon

Maaf karena tidak spesifik. Saya belum menyelesaikan ini sendiri, jadi saya tidak yakin apakah batasan yang saya masukkan masuk akal. Tolong beritahu saya.
grokus


3
1 adalah nomor Hamming, jadi, mencetak 1.000.000 1sesuai dengan spesifikasi Anda. Itu juga akan dalam urutan, yaitu bukan urutan tidak terurut. :)
Will Ness

Jawaban:


7

Haskell, 101 97 92+ | n | karakter

h=1:m 2h&m 3h&m 5h
m=map.(*)
c@(a:b)&o@(m:n)|a<m=a:b&o|a>m=m:c&n|0<1=a:b&n
main=print$take 1000000h

Menghitung sejuta penuh dalam 3,7 detik pada mesin yang saya uji (lebih bervariasi jika Anda benar-benar ingin output disimpan)

Tidak Disatukan:

-- print out the first million Hamming numbers
main = print $ take 1000000 h

-- h is the entire Hamming sequence.
-- It starts with 1; for each number in the
-- sequence, 2n, 3n and 5n are also in.
h = 1 : (m 2 h) & (m 3 h) & (m 5 h)

-- helper: m scales a list by a constant factor
m f xs = map (f*) xs

-- helper: (&) merges two ordered sequences
a@(ha:ta) & b@(hb:tb)
    |    ha < hb = ha : ta & b
    |    ha > hb = hb :  a & tb
    |  otherwise = ha : ta & tb

Semua Haskell terkenal pandai: mendefinisikan daftar sebagai fungsi malas itu sendiri, dengan cara yang benar-benar berfungsi.


1
Anda tidak mendapatkan parameter bilangan bulat positif, yang menambah ukuran kode Anda
Zhen

@Zhen Parameter bilangan bulat positif adalah token kedua-ke-terakhir, dan ukurannya dinyatakan keluar di header.
JB

3

Python 181 Karakter

h=[]        
h.append(1)
n=input()
i=j=k=0
while n:
    print h[-1]
    while h[i]*2<=h[-1]:
        i+=1
    while h[j]*3<=h[-1]:
        j+=1
    while h[k]*5<=h[-1]:
        k+=1
    h.append(min(h[i]*2,h[j]*3,h[k]*5))
    n-=1

Bagaimana ini 181 karakter? Saya telah menyimpan ini ke file, menghapus spasi setelahnya h=[], menggunakan jarak tab minimum, dan jeda baris karakter tunggal, dan ukuran file akhirnya menjadi 187 byte.
nitro2k01

1
Optimasi Anyway ... Trivial: h=[1]. Juga, berikan nomor langsung dalam kode sumber, untuk menyimpan karakter untuk angka <1000000.
nitro2k01

Dan oops, maaf, tidak menyadari jawabannya sudah sangat tua.
nitro2k01

@ nitro2k01, saya membuatnya 183 karakter. (Ada spasi spasi di akhir baris pertama, dan lekukan harus menjadi ruang untuk satu level dan tab untuk dua level).
Peter Taylor

1

Ruby - 154 231 karakter

def k i,n;(l=Math).log(i,2)*l.log(i,3)*l.log(i,5)/6>n end
def l i,n;k(i,n)?[i]:[i]+l(5*i,n)end
def j i,n;k(i,n)?[i]:[i]+j(3*i,n)+l(5*i,n)end
def h i,n;k(i,n)?[i]:[i]+h(2*i,n)+j(3*i,n)+l(5*i,n)end
puts h(1,n=gets.to_i).sort.first n

Dan sekarang sudah cukup cepat, pasti ada banyak golf yang masih bisa terjadi.

→ time echo 1000000 | ruby golf-hamming.rb | wc
1000000 1000000 64103205
echo 1000000  0.00s user 0.00s system 0% cpu 0.003 total
ruby golf-hamming.rb  40.39s user 0.81s system 99% cpu 41.229 total
wc  1.58s user 0.05s system 3% cpu 41.228 total

1

Perl, 94 karakter (tapi terlalu lambat)

use List::Util min;
$\=$/;$h{1}=();delete$h{$_=min keys%h},print,@h{$_*2,$_*3,$_*5}=()for 1..<>

Tidak Disatukan:

use List::Util 'min';
my %hamming;
my $up_to = <>;
$hamming{1} = (); # The value is undef, but the key exists!
for (1 .. $up_to) {
    my $next = min( keys %hamming );
    delete $hamming{$next}; # We're done with this one
    print $next, "\n";
    @hamming{ $next * 2, $next * 3, $next * 5 } = (); # Create keys for the multiples
} # Rinse, repeat

Butuh 11 menit untuk menghitung 100.000 angka pertama, dan saya bahkan tidak ingin memikirkan 1.000.000. Ini menyelesaikan 10.000 pertama dalam waktu 3 detik; itu hanya sesuatu yang menyerupai O (n ^ 2) :(


1

APL (Dyalog Classic) , 34 23 byte

{⍺⍴{⍵[⍋⍵]}∪,⍵∘.×⍳5}⍣≡∘1

Cobalah online!

TIO melempar kesalahan WS FULL untuk , tetapi Dyalog pada laptop saya berjalan dalam waktu sekitar 45 detik, tidak termasuk pengguliran untuk menampilkan angka.n=1000000

{⍺⍴{⍵[⍋⍵]}∪,⍵∘.×⍳5}⍣≡∘1     Monadic function:
{⍺⍴{⍵[⍋⍵]}∪,⍵∘.×⍳5}         Define the following helper function g(⍺,⍵):
             ⍵∘.×⍳5             Make a multiplication table between  and (1 2 3 4 5).
                                (Including 4 is unnecessary but saves bytes.)
            ,                   Flatten the table into an array.
                               Keep unique elements.
    {⍵[⍋⍵]}                     Grade up the array and access it at those indices.
                                (This is the APL idiom to sort an array.)
 ⍺⍴                             Keep the first  elements; pad by repeating the array.
{⍺⍴{⍵[⍋⍵]}∪,⍵∘.×⍳5}⍣≡       Repeatedly apply g with some fixed left argument
                             until a fixed point is reached.
                             At this point we have a dyadic function that takes
                             n on the left and the starting value on the right,
                             and returns multiples of the n Hamming numbers.
                      1     Fix 1 as the right argument.


FYI, {⍺⍴∧∪,⍵×⍀⍳5}`⍣≡∘1dalam Perpanjangan. (Backtick diperlukan karena bug.)
Adám

0

Haskell, 71

h n = drop n $ iterate (\(_,(a:t))-> (a,union t [2*a,3*a,5*a])) (0,[1])

Keluaran

*Main> map fst $ take 20 $ h 1
[1,2,3,4,5,6,8,9,10,12,15,16,18,20,24,25,27,30,32,36]

Spec memanggil Anda untuk mencetak, jadi kode yang akan dicetak harus dihitung. Ini juga memungkinkan perbandingan yang adil terhadap implementasi Haskell lainnya.
Peter Taylor

@PeterTaylor Berapa banyak karakter yang menurut saya harus saya tambahkan?
Timtech

0

Ursala, 103

#import std
#import nat
smooth"p" "n" = ~&z take/"n" nleq-< (rep(length "n") ^Ts/~& product*K0/"p") <1>

Output untukmain = smooth<2,3,5>* nrange(1,20)

<1,2,3,4,5,6,8,9,10,12,15,16,18,20,24,25,27,30,32,36>

0

Mathematica, 54 byte

Sort[1##&@@@({2,3,5}^#&/@Tuples[0~Range~#,3])]~Take~#&

Fungsi murni tidak efisien tapi pendek. Hitung semua produk formulir 2^i * 3^j * 5^kuntuk 0 <= i, j, k <= #( #adalah argumen pertama ke fungsi), kemudian Sorts mereka dan Takes hanya yang pertama #.


1
Entah bagaimana saya tidak berpikir melakukan perhitungan 1e18 akan terjadi dalam waktu kurang dari satu menit.
Jonathan Allan

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.