Số Hamming


19

Cho một số nguyên dương, in ra nhiều số hamming , theo thứ tự.

Quy tắc:

  • Đầu vào sẽ là số nguyên dương n1,000,000
  • Đầu ra phải là n điều khoản đầu tiên của https://oeis.org/A051037
  • Thời gian thực hiện phải <1 phút
  • Đây là ; mã ngắn nhất sẽ thắng

2
Mà mục tiêu một câu trả lời nên có? Golf? Thuật toán hiệu quả nhất? Chỉ cần tìm kiếm các phương pháp giải pháp?
Nakilon

Xin lỗi vì đã không cụ thể. Tôi đã không tự mình giải quyết vấn đề này, vì vậy tôi không chắc liệu giới hạn mà tôi đưa vào có hợp lý không. Làm ơn cho tôi biết.
Grokus


3
1 là số Hamming, vì vậy, in 1.000.000 1s phù hợp với thông số kỹ thuật của bạn. Nó cũng sẽ theo thứ tự, tức là không phải là một chuỗi không có thứ tự. :)
Will Ness

Câu trả lời:


7

Haskell, 101 97 92+ | n | nhân vật

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

Tính toán cả triệu trong 3.7 giây trên máy mà tôi đã thử nghiệm (nhiều hơn nếu bạn thực sự muốn đầu ra được lưu trữ)

Ung dung:

-- 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ất cả Haskell nổi tiếng là giỏi: định nghĩa một danh sách là một chức năng lười biếng của chính nó, theo cách thực sự hoạt động.


1
Bạn không nhận được tham số nguyên dương, thêm kích thước vào mã của bạn
Zhen

@Zhen Tham số nguyên dương là mã thông báo thứ hai đến cuối cùng và kích thước của nó được khai báo ở phía trước trong tiêu đề.
JB

3

Nhân vật 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

Làm thế nào là 181 ký tự này? Tôi đã lưu tệp này vào một tệp, xóa khoảng trắng sau h=[], sử dụng khoảng cách tab tối thiểu và ngắt dòng ký tự đơn và kích thước tệp kết thúc là 187 byte.
nitro2k01

1
Dù sao ... Tối ưu hóa tầm thường : h=[1]. Ngoài ra, cung cấp một số trực tiếp trong mã nguồn, để lưu các ký tự cho các số <1000000.
nitro2k01

Và xin lỗi, xin lỗi, đã không nhận ra câu trả lời là siêu cũ.
nitro2k01

@ nitro2k01, tôi làm cho nó 183 ký tự. (Có một số khoảng trắng ở cuối dòng đầu tiên và vết lõm phải là khoảng trắng cho một cấp độ và một tab cho hai cấp độ).
Peter Taylor

1

Ruby - 154 231 ký tự

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

Và bây giờ nó đã đủ nhanh, chắc chắn có rất nhiều môn đánh gôn vẫn có thể xảy ra.

→ 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 ký tự (nhưng quá chậm)

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

Ung dung:

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

Mất 11 phút để tính 100.000 số đầu tiên và tôi thậm chí không muốn nghĩ về 1.000.000. Nó nhận được 10.000 đầu tiên được thực hiện trong 3 giây gọn gàng; nó chỉ là một cái gì đó tương tự O (n ^ 2) :(


1

APL (Dyalog Classic) , 34 23 byte

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

Hãy thử trực tuyến!

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.

Xáo trộn mọi thứ xung quanh tiết kiệm bốn:1↓0 1{⍺↑{⍵[⍋⍵]}∪,⍵∘.×⍳5}⍣≡⍨1+⊢
Adám

FYI, {⍺⍴∧∪,⍵×⍀⍳5}`⍣≡∘1trong Mở rộng. (Backtick cần thiết do lỗi.)
Adám

0

Haskell, 71

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

Đầu ra

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

Thông số kỹ thuật gọi cho bạn để in, do đó, mã để in nên được tính. Điều này cũng cho phép so sánh công bằng với việc thực hiện Haskell khác.
Peter Taylor

@PeterTaylor Bạn nghĩ tôi nên thêm bao nhiêu nhân vật?
TimTech

0

Ursala, 103

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

Đầu ra chomain = 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

Toán học, 54 byte

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

Không hiệu quả nhưng chức năng thuần túy ngắn. Tính toán tất cả các sản phẩm có dạng 2^i * 3^j * 5^kcho 0 <= i, j, k <= #( #là đối số đầu tiên của hàm), sau đó Sorts chúng và Takes chỉ là đầu tiên #.


1
Bằng cách nào đó tôi không nghĩ thực hiện các phép tính 1e18 sẽ diễn ra trong vòng một phút.
Jonathan Allan

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.