不幸的数字!


22

要知道的事情:

首先,幸运数字。

幸运数字生成如下:

取所有自然数:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20...

然后,删除每个第二个数字。

1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39...

现在,3很安全。

删除每第三个数字:

1, 3, 7, 9, 13, 15, 19, 21, 25, 27, 31, 33, 37, 39, 43, 45, 49, 51, 55, 59...

现在,7很安全。

删除每7个数字。

继续,并删除每个n数字,其中n是消除后的第一个安全数字。

安全号码的最后列表是幸运数字。


不幸的数字由单独的数字列表组成,即[U1, U2, U3... Un]

U1 是从幸运“候选人”中删除的第一组数字,因此它们是:

2, 4, 6, 8, 10, 12, 14, 16, 18, 20...

U2 是删除的第二组数字:

5, 11, 17, 23, 29, 35, 41, 47, 53, 59...

依此类推(U3是第三个列表,U4是第四个列表,依此类推)


挑战:

当给定两个输入m和时n,您的任务是m在列表中生成第th个数字Un

输入和输出示例:

(5, 2) -> 29
(10, 1) -> 20

眼镜:

  • 为你的程序必须工作m1e6,和n100
    • 您可以保证mn均为正整数。
    • 如果您好奇,请U(1e6, 100)= 5,333,213,163。(谢谢@pacholik!)
  • 您的程序必须在一台合理的现代计算机上在1天之内进行计算。

这是,因此以字节为单位的最短代码胜出!

PS:如果有人想出了生成这些的通用公式,那就太好了。如果您有公式,请在答案中填写!


在OEIS上:A219178A255543
Arnauld


2
您是否实现了可以实际执行的代码(1e6,1e6)
乔纳森·艾伦

2
如果需要时间,则需要指定计时环境(例如您的计算机,免费提供的在线VM或“合理的现代计算机”)。
Mego

1
该功能不适合这种n=1情况是否可以接受?由于这很特殊-在所有其他情况下,下一个幸运数字的从0开始的索引为n-1
Myridium

Answers:


1

CJam,74个字节

ri0Lri:U{1$W%{1$\(1e>/+}/)+}/2t:A0@{@:B:(_0#):D{D(_A=tD<BD>+}&@)@DU=-}h]1=

在线尝试! 在较大的情况下将超时,更多时间限制如下。


说明:

我们的程序毫不客气地借用了aittsu的代码来生成N个幸运数字的列表,将1替换为2可得到筛子各阶段的增量。其余代码在每个元素上递减直到找到零(通过切片和附加未递减的尾部),并有效地一次计算筛子N个相中每个相的步数。

ri                               e# read M
0Lri:U{1$W%{1$\(1e>/+}/)+}/2t:A  e# list steps (also becomes B)
0@                               e# arrange stack [B I M]
{                                e# while M
   @:B                           e#   get current B
   :(                            e#   decrement every element in B
   _0#):D                        e#   find first 0
   {                             e#   if there is a 0
      D(_A=t                     e#     reset that element in B
      D<BD>+                     e#     replace tail after 0
   }&                            e#   end if
   @)                            e#   increment I
   @DU=-                         e#   decrement M if N-th phase of sieve
}h                               e# end loop
]1=                              e# return I

定时:

如果您绝对必须在浏览器中运行较大数量的程序,则可以使用此解释器,并在出现提示时允许脚本继续运行,但这可能太慢而无法胜任。使用(MN)=(100,100)大约需要247s。就M而言,程序迭代是相对线性的,因此计算(1e6,100)可能需要约29天。

使用PC上的Shell解释器,程序将在约6s内计算(100,100),并在约463s中计算(1e4,100)。该程序应该能够在大约13-17小时内计算(1e6,100)。在这种情况下,我将假定程序合格。

注意所有时间在测量和计算中均被四舍五入。


7

Perl,87 85 82 81字节

包括+4 -pX

将STDIN上的输入作为一行,首先输入n(请注意,这与挑战中建议的顺序相反)。因此计算U(1000000, 100)

unlucky.pl <<< "100 1000000"

基于aditsu的幸运数字的算法回答 时间复杂度很高,O(n^2)因此在所需范围内相当快。的100, 1000000情况下给出了53332131630.7秒。由于perl的do$0基于基础的递归存在的问题,因此会占用大量内存。将其重写为函数会占用内存,O(n)但会增加字节数

unlucky.pl

#!/usr/bin/perl -pX
$_=$a{$_}||=/\d+$/>--$_?2*$&+$^S:($_=$_.A.(do$0,$^S?0|$&+$&/~-$_:$&*$_-1),do$0)

如图所示,该方法有效,但使用文字^S获取要求的分数。

我不知道$^S在perlgolf中有任何较早的使用。


但是这需要多长时间(1e6,100)
Myridium

@Myridium由于do$0它引起的内存爆炸在任何实际的计算机上基本上都是无法达到的。但是,如果这么多内存存在大约2年。我还没有真正写出并测试过基于子例程的普通版本,但是我希望它能在几个月后完成,甚至可以在内存很少的计算机上运行。因此,这些值不在此挑战的要求范围内是一件好事。
Ton Hospel '16

(1e6,100)在一天之内进行计算不是挑​​战吗?您是什么意思这些值不是必需的?
Myridium

@Myridium请注意,在我的程序中,nm以相反的顺序给出。该100 1000000输入计算U(1000000, 100)并给出了5,333,213,1630.7秒。这是目前这些已发布程序中最快的程序
Ton Hospel

好的,我希望(100,1e6)速度比快得多(1e6,100),并认为这是0.7秒快如闪电的解释!
Myridium

7

Python 3、170

from itertools import*
def L(n,k=1):
 if n<2:yield from count(2+k,2)
 t=L(n-1);l=next(t)
 for i in t:
  n+=1
  if(n%l>0)==k:yield i
U=lambda m,n:sum(islice(L(n,0),m-1,m))

函数L生成一行可能的幸运数字(如果k为True)或Un(如果为False)。懒惰地评估(因此,如果我想要Un,则不必生成n-1个无限列表)。

运行功能ü

速度

U(1,000,000; 100)用PyPy在我的机器上运行大约需要1小时45分钟。我怀疑使用CPython大约需要四个小时。(是的,准确地说是4小时20分钟。)

如果我使用列表而不是生成器,则可能会提高速度,但是我需要一个比Python允许的大小更大的列表。如果这样做的话,它将需要数十GB的RAM。


是的,并且U(1,000,000; 100)= 5,333,213,163


现在应该有效。
clismique

3

哈斯克尔

无法计算n = 1:175160字节

编译后,我的计算机花了2h 35m来计算(1000000,100)使用此命令的输入:

n#s=y:(n#p)where y:p=drop(n-1)s
n%s=f n s$[]where f n s=(take(n-1)s++).f n(drop n s) 
l 2=[1,3..]
l m=((l$m-1)!!(m-2))%(l$m-1)
m?n=(((l n)!!(n-1))#(l$n))!!(m-1)

我尝试删除where模块,但是它们似乎会影响速度,我不确定为什么...但是我认为这里还有更多的修剪工作。

使用的方法是m?n查询给定的m和的答案n

不打高尔夫球

everynth n xs = y:(everynth n ys) -- Takes every nth element from a list 'xs'
  where y:ys = drop (n-1) xs

skipeverynth n xs = f' n xs $ []  -- Removes every nth element from a list 'xs'
  where f' n xs = (take (n-1) xs ++) . f' n (drop n xs) 

l 2 = [1,3..] -- The base case of the list of lucky numbers for 'n=2'
l m = skipeverynth ((l$m-1)!!(m-2)) (l$m-1) -- Recursively defining next case as being the last one with every 'ath' element skipped. Here, 'a' is the (m-1)th elemnent of the (l (m-1)) list.
ul m = everynth ((l m)!!(m-1)) (l$m) -- This is not used other than to compute the final, required unlucky number list. It picks out every 'ath' element.

ans m n = (ul n)!!(m-1) -- The function giving the answer.

我认为有可能将“ skipeverynth”和“ everynth”函数组合成一个返回一对的单个函数。

我用这种人的代码跳过了第n个元素。我自己做了几次,但是效率总是低得多,我不知道为什么。

能够计算所有n:170个字节

基本上是一样的,但是max必须抛出几个函数来处理的特殊情况n=1

n#s=y:(n#p)where y:p=drop(n-1)s
n%s=f n s$[]where f n s=(take(n-1)s++).f n(drop n s) 
l 1=[1..]
l m=((l$m-1)!!(max 1$m-2))%(l$m-1)
m?n=(((l n)!!(max 1$n-1))#(l$n))!!(m-1)

2

R 82字节

f<-function(m,n){a=1:2e8
i=1
while(i<n){a=c(0,a)[c(F,rep(T,i))]
i=i+1}
a[(n+1)*m]}

用法

f(5,2)
Returns 29

它必须有一个足够大的向量开始,以便剩下足够的数字来返回该值。创建的向量已经大约为800Mb,并且该函数最多可以处理m = 1e4和n = 100,因此仍远未达到目标。

要创建足够大的向量来计算f(1e6,100),将采用1:2e10的起始向量。由于Rs的数据分配过程,这将创建一个大于70Gb的向量,尽管该代码可以运行,但它不能在我知道的任何计算机上运行。

Error: cannot allocate vector of size 74.5 Gb

作为参考,f(1e4,100)大约在30秒内运行。基于此以及几个较小的测试f(1e6,100)大约需要一个小时。


将您的答案标记为不竞争并不能免除未满足挑战要求的借口。
Mego

@Mego Ive看到了许多不符合要求的答案(此挑战中至少还有1个)。我对它进行了编码,我觉得它符合编码要求的精神,我也清楚指出了它的不足之处。同样,正如您在对该问题的评论中提到的那样,它没有说明需要在哪种计算机上进行测试。我确定那里有可以将7 Gb写入内存并对其进行处理的计算机。我所在的那个无法做到,但我仍然想发表,我认为明确的声明是有效的妥协。
gtwebb

对于不符合挑战规范的答案,我们有明确的政策。话虽这么说,我不确定您为什么将答案标记为不竞争。如果我理解正确,这在给定足够的内存的情况下应该可以工作,但是由于没有足够的RAM而无法测试。那是对的吗?
丹尼斯

1
1.该政策强制执行,而是四个主持人不能测试网站上的所有答案。如果您发现不符合规定的提交内容,请将其标记为主持人注意,以便我们进行查看。2.您不必学习高尔夫球语言即可参加。像R这样的生产语言也受到欢迎。我定期发布Python答案。
丹尼斯

1
3.规范没有提到任何内存限制,但是有24小时的时间限制。在没有配备70 GiB(或者您的意思是giga bits)的计算机上进行测试时,很难确定此答案是否有效。我建议尝试尽可能地推断运行时。如果不到一天,请删除不竞争的标题并将您的推断包括在帖子中。如果需要更长的时间,则应优化或删除您的提交。
丹尼斯,

1

拍框332字节

(λ(N m n)(let loop((l(filter odd?(range 1 N)))(i 1))(define x (list-ref l i))(if(= i (sub1 n))
(begin(set! l(for/list((j(length l))#:when(= 0(modulo(add1 j)x)))(list-ref l j)))(list-ref l(sub1 m)))
(begin(set! l(for/list((j(length l))#:unless(= 0(modulo(add1 j) x)))(list-ref l j)))(if(>= i(sub1 (length l)))l
(loop l(add1 i)))))))

非高尔夫版本:

(define f
  (λ(N m n)
    (let loop ((l (filter odd? (range 1 N))) (i 1))
      (define x (list-ref l i))
      (if (= i (sub1 n))
          (begin (set! l (for/list ((j (length l)) 
                                   #:when (= 0 (modulo (add1 j) x)))
                           (list-ref l j)))
                 (list-ref l (sub1 m)))
          (begin (set! l (for/list ((j (length l)) 
                                   #:unless (= 0 (modulo (add1 j) x)))
                           (list-ref l j)))
                 (if (>= i (sub1 (length l)))
                     l
                     (loop l (add1 i))))))))

测试:

(f 100 5 2)

输出:

29

1

Clojure,221个字节

可能很长,但可以处理案件(f 1)。如果没有这种特殊情况,则为183个字节。不付出太多的努力。

(defn f([n](if(< n 2)(take-nth 2(drop 2(range)))(f n 1(take-nth 2(rest(range))))))([n i c](if (< n 2)c(let[N(first(drop i c))F #((if(= 2 n)= >)(mod(inc %)N)0)](f(dec n)(inc i)(filter some?(map-indexed #(if(F %)%2)c)))))))

样本输出:

(pprint (map #(take 10 (f %)) (range 1 10)))
((2 4 6 8 10 12 14 16 18 20)
 (5 11 17 23 29 35 41 47 53 59)
 (19 39 61 81 103 123 145 165 187 207)
 (27 57 91 121 153 183 217 247 279 309)
 (45 97 147 199 253 301 351 403 453 507)
 (55 117 181 243 315 379 441 505 571 633)
 (85 177 277 369 471 567 663 757 853 949)
 (109 225 345 465 589 705 829 945 1063 1185)
 (139 295 447 603 765 913 1075 1227 1377 1537))

在大约4.7个小时内计算了1000000 100个案例,至少没有崩溃。

java -jar target\stackoverflow-0.0.1-SNAPSHOT-standalone.jar 1000000 100
5333213163
"Elapsed time: 1.7227805535565E7 msecs"
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.