หมายเลข Hamming


20

กำหนดจำนวนเต็มบวกให้พิมพ์จำนวนhamming ที่เรียงตามลำดับ

กฎ:

  • อินพุตจะเป็นจำนวนเต็มบวกn1,000,000
  • ผลลัพธ์ควรเป็นคำแรกที่ n ของhttps://oeis.org/A051037
  • เวลาดำเนินการจะต้อง <1 นาที
  • นี่คือ ; รหัสที่สั้นที่สุดชนะ

2
จุดมุ่งหมายคำตอบใดควรมี กอล์ฟ? อัลกอริทึมที่มีประสิทธิภาพมากที่สุด? แค่ค้นหาวิธีการแก้ปัญหา?
Nakilon

ขออภัยที่ไม่เจาะจง ฉันไม่ได้แก้ไขสิ่งนี้ด้วยตัวเองดังนั้นฉันไม่แน่ใจว่าขอบเขตที่ฉันใส่มีความสมเหตุสมผล โปรดแจ้งให้เราทราบ
grokus


3
1 คือหมายเลข Hamming ดังนั้นการพิมพ์ 1,000,000 1s เป็นไปตามข้อกำหนดของคุณ มันจะอยู่ในลำดับเช่นไม่ใช่ลำดับที่ไม่เรียงลำดับ :)
Will Ness

คำตอบ:


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.7s บนเครื่องที่ฉันทดสอบ (แปรปรวนมากขึ้นถ้าคุณต้องการเก็บเอาท์พุทจริง ๆ )

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

Haskell ทั้งหมดมีชื่อเสียงที่ดีที่: กำหนดรายการเป็นฟังก์ชั่นขี้เกียจของตัวเองในวิธีที่ใช้งานได้จริง


1
คุณไม่ได้รับพารามิเตอร์จำนวนเต็มบวกซึ่งเพิ่มขนาดให้กับโค้ดของคุณ
Zhen

@Zhen พารามิเตอร์เลขจำนวนเต็มบวกคือโทเค็นตัวที่สองถึงครั้งสุดท้ายและขนาดจะถูกประกาศไว้ด้านหน้าในส่วนหัว
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 ตัวอักษร (มีช่องว่างต่อท้ายที่ท้ายบรรทัดแรกและการเยื้องควรเป็นช่องว่างสำหรับหนึ่งระดับและแท็บสำหรับสองระดับ)
Peter Taylor

1

Ruby - 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 chars (แต่ช้าเกินไป)

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

ใช้เวลา 11 นาทีในการคำนวณตัวเลข 100,000 ตัวแรกและฉันไม่ต้องการคิดประมาณ 1,000,000 มันทำ 10,000 ครั้งแรกภายใน 3 วินาที มันเป็นเพียงบางสิ่งที่คล้ายกับ O (n ^ 2) :(


1

APL (Dyalog Classic) , 34 23 ไบต์

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

ลองออนไลน์!

TIO พ่นข้อผิดพลาด WS FULL สำหรับ n=1000000แต่ Dyalog บนแล็ปท็อปของฉันทำงานในเวลาประมาณ 45 วินาทีไม่นับการเลื่อนเพื่อแสดงตัวเลข

{⍺⍴{⍵[⍋⍵]}∪,⍵∘.×⍳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.

การสับสิ่งรอบ ๆ ช่วยได้สี่:1↓0 1{⍺↑{⍵[⍋⍵]}∪,⍵∘.×⍳5}⍣≡⍨1+⊢
Adám

FYI {⍺⍴∧∪,⍵×⍀⍳5}`⍣≡∘1ใน Extended (Backtick จำเป็นเนื่องจากข้อผิดพลาด.)
อดัม

0

Haskell, 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 อื่น ๆ
Peter Taylor

@PeterTaylor คุณคิดว่าฉันควรเพิ่มตัวละครกี่ตัว?
Timtech

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ให้นับTakeเฉพาะผลิตภัณฑ์แรก#เท่านั้น


1
อย่างใดฉันไม่คิดว่าการคำนวณ 1e18 จะเกิดขึ้นในไม่กี่นาที
Jonathan Allan

-1

Japt 15 ไบต์

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

ลองมัน

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

ลองมัน


3 ไบต์

หากวิธีการของ Jo Kingนั้นถือว่าใช้ได้

o!²

ลองมัน


สิ่งนี้ดูเหมือนจะไม่ใกล้เคียงกับความต้องการของการดำเนินการใน <1 นาที (และแนวทางของโจคิงไม่ถูกต้อง)
Anders Kaseorg
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.