Hamming sayıları


20

Pozitif bir tam sayı verildiğinde, birçok çekiçleme sayısını sırayla yazdırın .

Kurallar:

  • Giriş pozitif bir tamsayı olacak n1,000,000
  • Çıktı, https://oeis.org/A051037 adresinin ilk n terimi olmalıdır
  • Yürütme süresi <1 dakika olmalıdır
  • Bu ; en kısa kod kazanır

2
Cevabın hangi amacı olmalı? Golf? En etkili algoritma? Sadece çözüm yöntemlerini mi arıyorsunuz?
Nakilon

Spesifik olmadığım için üzgünüm. Bunu kendim çözmedim, bu yüzden koyduğum sınırların makul olup olmadığından emin değilim. Lütfen bana haber ver.
grokus


3
1 bir Hamming numarasıdır, bu nedenle 1.000.000 1s yazdırma özelliklerinizle uyumludur. Aynı zamanda, yani sıralanmamış bir dizi olmayacaktır. :)
Ness

Yanıtlar:


7

Haskell, 101 97 92+ | n | karakterler

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

Test ettiğim makinede 3,7 saniyede tam milyonu hesaplar (çıktının gerçekten depolanmasını istiyorsanız değişken daha fazla)

Ungolfed:

-- 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

Tüm Haskell herkesin bildiği gibi iyidir: bir listeyi gerçekten işe yarayacak şekilde tembel bir işlev olarak tanımlamak.


1
Kodunuza daha fazla boyut ekleyen pozitif tamsayı parametresini alamıyorsunuz
Zhen

@Zhen Pozitif tamsayı parametresi ikinci-son belirtecidir ve boyutu üstbilgide dışa aktarılır.
JB

3

Python 181 Karakterleri

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

Bu 181 karakter nasıl? Bunu bir dosyaya kaydettim, sonra boşlukları kaldırarak, h=[]minimum sekme mesafesini ve tek karakter satırı sonlarını kullanarak dosya boyutunu 187 bayt olarak bitirdim.
nitro2k01

1
Neyse ... Önemsiz optimizasyonu: h=[1]. Ayrıca, sayıların karakterlerini kaydetmek için doğrudan kaynak kodunda bir sayı verin <1000000.
nitro2k01

Üzgünüz, cevabın çok eski olduğunu fark etmedim.
nitro2k01

@ nitro2k01, 183 karakter yapıyorum. (İlk satırın sonunda bazı boşluklar vardır ve girinti bir seviye için boşluk ve iki seviye için bir sekme olmalıdır).
Peter Taylor

1

Yakut - 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

Ve şimdi yeterince hızlı, yine de yine de olabilecek çok fazla golf var.

→ 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 (ama çok yavaş)

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

Ungolfed:

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

İlk 100.000 sayıyı hesaplamak 11 dakika sürer ve 1.000.000 hakkında düşünmek bile istemiyorum. İlk 10.000'i 3 saniye içinde düzenli hale getirir; sadece O (n ^ 2) 'ye benzeyen bir şey :(


1

APL (Dyalog Klasik) , 34 23 bayt

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

Çevrimiçi deneyin!

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.

Etrafında bir şeyler karıştırmak dört kurtarır:1↓0 1{⍺↑{⍵[⍋⍵]}∪,⍵∘.×⍳5}⍣≡⍨1+⊢
Adám

FYI, {⍺⍴∧∪,⍵×⍀⍳5}`⍣≡∘1Uzatılmış. (Hata nedeniyle backtick gerekli.)
Adám

0

Haskell, 71

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

Çıktı

*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]

Spesifikasyon yazdırmanızı gerektirir, bu nedenle yazdırılacak kod sayılmalıdır. Bu aynı zamanda diğer Haskell uygulamasına karşı adil bir karşılaştırma sağlar.
Peter Taylor

@PeterTaylor Kaç karakter eklemem gerektiğini düşünüyorsun?
Timtech

0

Ursala, 103

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

Çıktı içinmain = 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 bayt

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

Verimsiz ama kısa saf fonksiyon. Formun tüm ürünler hesaplar 2^i * 3^j * 5^kiçin 0 <= i, j, k <= #( #işlevine ilk parametre), daha sonra Sortbunları s ve Takesadece ilk s #.


1
Her nasılsa 1e18 hesaplamaları yapmanın bir dakikadan kısa sürede gerçekleşeceğini sanmıyorum.
Jonathan Allan

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.