ハミング数


19

正の整数を指定すると、その数のハミング数を順番に出力します。

ルール:

  • 入力は正の整数n1000000
  • 出力はhttps://oeis.org/A051037の最初のn項である必要があります
  • 実行時間は1分未満でなければなりません
  • これはです。最短のコードが勝つ

2
答えに必要な目標はどれですか?ゴルフ?最も効果的なアルゴリズム?ソリューションメソッドを検索するだけですか?
ナキロン

具体的ではないので申し訳ありません。私はこれを自分で解決していないので、私が入れた範囲が妥当かどうかはわかりません。私にお知らせください。
-grokus


3
1はハミング数であるため、1,000,000 1秒の印刷は仕様に準拠しています。また、順序付けされます。つまり、順序付けされていないシーケンスではありません。:)
ウィルネス

回答:


7

Haskell、101 97 92+ | n | キャラクター

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

私がテストしたマシンで3.7秒で100万を計算します(実際に出力を保存したい場合はさらに大きくなります)

ゴルフをしていない:

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

Haskellはすべて、悪名高い:リストをそれ自体の怠zyな関数として、実際に機能する方法で定義することで有名です。


1
正の整数パラメーターを取得しないため、コードにサイズが追加されます
ジェン

@Zhen正の整数パラメーターは、最後から2番目のトークンであり、そのサイズはヘッダーで宣言されています。
JB

3

Python 181文字

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

この181文字はどうですか?これをファイルに保存h=[]し、最小タブ距離と単一文字の改行を使用して、の後の空白を削除しました。ファイルサイズは187バイトになります。
nitro2k01

1
とにかく...簡単な最適化:h=[1]。また、数字の文字を保存するために、ソースコードで直接数字を指定します<1000000
nitro2k01

おっと、申し訳ありませんが、答えが非常に古いことに気付きませんでした。
nitro2k01

@ nitro2k01、183文字にします。(最初の行の末尾には末尾に空白があり、インデントは1レベルのスペースと2レベルのタブである必要があります)。
ピーターテイラー14年

1

ルビー- 154の 231文字

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

そして今、それは十分に速いです、しかし、まだ起こることができる間違いなく多くのゴルフがあります。

→ 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文字(ただし遅すぎる)

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

ゴルフをしていない:

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

最初の100,000個の数値を計算するのに11分かかりますが、1,000,000個も考えたくありません。整然とした3秒間で最初の10,000が完了します。それはO(n ^ 2)に似ているだけです:(


1

APL(Dyalog Classic)34 23バイト

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

オンラインでお試しください!

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.

周りのものをシャッフルして4セーブ:1↓0 1{⍺↑{⍵[⍋⍵]}∪,⍵∘.×⍳5}⍣≡⍨1+⊢
アダム

参考{⍺⍴∧∪,⍵×⍀⍳5}`⍣≡∘1までに。(バッククォートはバグによる必要。)
アダム

0

ハスケル、71

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

出力

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

仕様では印刷する必要があるため、印刷するコードをカウントする必要があります。これにより、他のHaskell実装との公正な比較も可能になります。
ピーターテイラー14年

@PeterTaylor何人のキャラクターを追加すべきだと思いますか?
ティムテック

0

ウルサラ、103

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

出力main = 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バイト

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

非効率的だが短い純粋な関数。フォームのすべての製品を計算2^i * 3^j * 5^kするために0 <= i, j, k <= ##関数の最初の引数である)、そしてSortそれらをSとTakeだけ最初です#


1
どういうわけか、1e18計算の実行が1分以内に行われるとは思わない。
ジョナサンアラン

-1

Japt、15バイト

@_k e§5}a°X}h1ì

それを試してみてください

ÆJ=_k d>5}f°Jª1

それを試してみてください


3バイト

場合はジョー・キングのアプローチが有効であると考えられます。

o!²

それを試してみてください


これは、1分以内に実行するという要件を満たすにはほど遠いようです。(そして、ジョー・キングのアプローチは無効です。)
アンダース・カセオルグ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.