汉明数


20

给定一个正整数,按顺序打印许多汉明数

规则:


2
答案应具有哪些目的?高尔夫球?最有效的算法?只是寻找解决方法?
Nakilon 2011年

抱歉,没有具体说明。我自己还没有解决这个问题,所以我不确定我设定的界限是否合理。请告诉我。
grokus


3
1是一个汉明数,因此,打印1,000,000 1s符合您的规格。它也将是有序的,即不是无序序列。:)
威尔·尼斯

Answers:


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内计算百万(如果您确实希望存储输出,则可以更多)

取消高尔夫:

-- 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正整数参数是倒数第二个令牌,其大小在标头中声明为首位。
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 2013年

1
无论如何...简单的优化:h=[1]。另外,直接在源代码中给数字,以保存数字字符<1000000
nitro2k01 2013年

哎呀,很抱歉,没有意识到答案太旧了。
nitro2k01 2013年

@ nitro2k01,我将其设为183个字符。(在第一行的末尾有一些空格,并且缩进应为一个级别的空间和两个级别的制表符)。
彼得·泰勒

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

需要11分钟才能计算出前100,000个数字,我什至不想考虑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.


仅供参考{⍺⍴∧∪,⍵×⍀⍳5}`⍣≡∘1。(反引号需要因错误。)
亚当

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实现进行公平的比较。
彼得·泰勒

@PeterTaylor您认为我应该添加几个字符?
Timtech

0

乌萨拉(Ursala),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^k0 <= i, j, k <= ##是该函数的第一个参数)的所有乘积,然后对Sort它们进行计算,Take仅对第一个进行计算#


1
不知何故,我认为在一分钟内不会执行1e18计算。
乔纳森·艾伦

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.