康威的黄金游戏


18

具体来说,就是Conway的PRIMEGAME

这是John H. Conway设计的一种算法,它使用14个有理数的序列生成素数:

 A   B   C   D   E   F   G   H   I   J   K   L   M   N
17  78  19  23  29  77  95  77   1  11  13  15  15  55
--  --  --  --  --  --  --  --  --  --  --  --  --  --
91  85  51  38  33  29  23  19  17  13  11  14   2   1

例如,F是分数77/29

因此,这是算法查找素数的方式。以数字开头2,找到序列中的第一个条目,相乘后将产生一个整数。这就是M15/2,它产生15。然后,对于该整数15,找到序列中的第一个条目,该条目在相乘时会产生一个整数。那是最后一个N,或55/1,产生825。写下相应的顺序。(机敏的人可能将其视为FRACTRAN程序。)

经过一些迭代,您将获得以下内容:

2, 15, 825, 725, 1925, 2275, 425, 390, 330, 290, 770, 910, 170, 156, 132, 116, 308, 364, 68, 4 ...

请注意,列出的最后一项是42^2。看一下我们2用此算法生成的第一个素数(指数)!最终,该序列将如下所示:

2 ... 2^2 ... 2^3 ... 2^5 ... 2^7 ... etc.

因此,产生质数。这是OEIS A007542

挑战

给定输入数字n(零索引或单索引)(您的选择),输出n此序列的第一个数字,或输出此序列的n第th个数字。

例子

以下示例输出n零索引序列的第th项。

 n   output
 5   2275
19   4
40   408

规则

  • 如果适用,您可以假定输入/输出将适合您语言的本机Integer类型。
  • 输入和输出可以通过任何方便的方法给出。
  • 完整的程序或功能都是可以接受的。如果是函数,则可以返回输出而不是打印输出。
  • 禁止出现标准漏洞
  • 这是因此所有常见的高​​尔夫规则都适用,并且最短的代码(以字节为单位)获胜。

11
也许Conway的主要游戏比“ 让我们玩游戏”更能描述这个挑战。这将使将来更容易发现这一挑战。
林恩

输出可以是浮点数吗?408.0而不是 408举例。
dylnan '18

不幸的是,我们没有(规范的)“解释Fractran”挑战。堆栈溢出中的一个被锁定。
user202729

@dylnan当然可以。
AdmBorkBork '18

Answers:


5

Python 3中173 165 153 145 144 136 135 127 126 125 108 107 104字节

f=lambda n:2>>n*2or[f(n-1)*t//d for t,d in zip(b"NM_M\r7",b"[U3&!\r")if f(n-1)*t%d<1][0]

在线尝试!

  • -30个字节感谢Jonathan Frech!
  • -3个字节,感谢Lynn!

2>>n*22为了n==00否则。

如果可以返回浮点数,则为103个字节


使用Python 2;153个字节
乔纳森·弗雷希

@JonathanFrech很酷,很好的技巧。谢谢!
dylnan '18

1
停留在Python 3中,146个字节
乔纳森·弗雷奇


再次感谢您,您所做的比我现在要多!
dylnan '18

5

FRACTRAN,99个字节

17/2821 78/2635 19/1581 23/1178 29/1023 77/899 95/713 77/589 1/527 11/403 13/341 15/434 15/62 55/31

在线尝试!

该程序2*31^n作为输入,用作初始状态。

原始FRACTRAN程序中的所有小数均已除以31(第一个未使用的素数寄存器),因此该程序在第n次迭代时停止。


厚脸皮的答案。;-)
AdmBorkBork


3

Python 3,107个字节

f=lambda n,k=2:n and f(n-1,[k*a//b for a,b in zip(b"NM_M\r7",b"[U3&!\r")if k*a%b<1][0])or k

在线尝试!

通过zip输入两个包含不可打印的低ASCII字符的字节串来编码分数列表。

如果n为零,则返回参数k;否则,我们使用新参数递归。我们的新k值是k*a//b对应(a, b)于列表中某个分数 的第一个值k*a//b,即整数k*a%b<1



2

J116110字节

g=.3 :0
((1047856500267924709512946135x%&(96#.inv])5405040820893044303890643137x)([:({.@I.@(=<.){[)*)])^:y 2
)

在线尝试!

0索引;返回第n个数字

通过使动词默认可以节省一些字节,但是我在^:工作时遇到了问题 。

说明:

J以NrD的形式描述有理数,其中N是分子,D是分母,例如,17r91 78r85 19r51 23r38...我为分子和分母创建了2个单独的列表,并从中得到2个以96为底的数字。

1047856500267924709512946135x%&(96#.inv])5405040820893044303890643137x 将96底数转换为列表,并通过将两个列表相除来构造分数列表。

   1047856500267924709512946135x%&(96#.inv])5405040820893044303890643137x
17r91 78r85 19r51 23r38 29r33 77r29 95r23 77r19 1r17 11r13 13r11 15r14 15r2 55

2 从2开始

^:y重复动词在其左侧的n时间(y是该函数的参数)

] 正确的参数(从2开始,然后使用每次迭代的结果)

* 将分数列表乘以正确的参数

(=<.) 是结果整数(将每个数字与其下限进行比较)

{.@I.@查找I.第一个{.整数的索引

{[ 使用索引来检索数字


1
62个字节:('0m26<l~l *,..V'%&(31x-~3&u:)'ztRE@<620,*-! ')&(0{*#~0=1|*)2:
英里

@miles谢谢,我认为您必须发布解决方案,它比我的方法更好。
Galen Ivanov

2

05AB1E 44  43字节

0索引

2sF•Ë₁ǝßÌ?ƒ¥"h2ÔδD‡béαA5À>,•тв2ä`Š*s‰ʒθ_}нн

在线尝试!

说明

2                                             # initialize stack with 2
 sF                                           # input times do:
   •Ë₁ǝßÌ?ƒ¥"h2ÔδD‡béαA5À>,•                  # push a base-255 compressed large number
                            тв                # convert to a list of base-100 digits
                              2ä`             # split in 2 parts to stack
                                 Š            # move denominators to bottom of stack
                                  *           # multiply the last result by the numerators
                                   s‰         # divmod with denominators
                                     ʒθ_}     # filter, keep only those with mod result 0
                                         нн   # get the div result

被推的大数是 17781923297795770111131515559185513833292319171311140201



1

JavaScript(Node.js)106 95字节

  • 感谢@Arnauld和@Neil减少了11个字节
(n,N=2,I=13,B=Buffer(`[U3&!\rNM_M\r7`))=>n--?f(n,N/B.find(x=>N%x<!!++I)*B[I]):N

在线尝试!


设法挤出了几个字节,但不禁以为我缺少了一些东西:在线尝试!
尼尔,

1
@Neil无需在上使用传播运算符Buffer。另外,我认为将所有数据放在一个缓冲区中是安全的:95 bytes
Arnauld

@Arnauld OP使用了传播运算符(我对Buffer不熟悉,所以我不知道更好),但这对于单个Buffer来说是一个不错的选择!
尼尔

@Arnauld正确,已更新:)
DanielIndie

1

视网膜,213字节

K`17/91¶78/85¶19/51¶23/38¶29/33¶77/29¶95/23¶77/19¶1/17¶11/13¶13/11¶15/2¶1/7¶55/1¶17/91¶78/85¶19/51¶23/38¶29/33¶77/29¶95/23¶77/19¶1/17¶11/13¶13/11¶15/2¶1/7¶55/1¶2
\d+
*
"$+"+`((_+)/(_+)¶(.+¶)*)(\3)+$
$1$#5*$2
r`_\G

在线尝试!说明:

K`17/91¶78/85¶19/51¶23/38¶29/33¶77/29¶95/23¶77/19¶1/17¶11/13¶13/11¶15/2¶1/7¶55/1¶17/91¶78/85¶19/51¶23/38¶29/33¶77/29¶95/23¶77/19¶1/17¶11/13¶13/11¶15/2¶1/7¶55/1¶2

将输入替换为所有分数的列表以及初始整数。

\d+
*

将所有内容都转换为一元。

"$+"+`

重复替换次数为原始输入给出的次数。

((_+)/(_+)¶(.+¶)*)(\3)+$

找到一个将整数均分的分母。

$1$#5*$2

将整数替换为除以分子的结果。

r`_\G

将整数转换为十进制并输出结果。


1

附件,81字节

Nest<~{Find[Integral,_*&`//=>Chop[Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "-31,2]]},2~>

在线尝试!输出1 之上的分数。例如,输入5return 2275/1。可以在前面加上2个字节来解决此问题N@在程序来解决此问题。

说明

这是一个curried函数,它Nest 使用两个预定义的参数进行咖喱:

{Find[Integral,_*&`//=>Chop[Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "-31,2]]}

2。最后一个参数只是初始种子,传递给该函数的参数是嵌套给定函数的迭代次数。

以下用于编码PRIMEGAME:

&`//=>Chop[Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "-31,2]]

评估如下:

A> "0zmt2R6E<@l<~6l2 0*,,*.-.!V "
"0zmt2R6E<@l<~6l2 0*,,*.-.!V "
A> Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "
[48, 122, 109, 116, 50, 82, 54, 69, 60, 64, 108, 60, 126, 54, 108, 50, 32, 48, 42, 44, 44, 42, 46, 45, 46, 33, 86, 32]
A> Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "-31
[17, 91, 78, 85, 19, 51, 23, 38, 29, 33, 77, 29, 95, 23, 77, 19, 1, 17, 11, 13, 13, 11, 15, 14, 15, 2, 55, 1]
A> Chop[Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "-31,2]
 17 91
 78 85
 19 51
 23 38
 29 33
 77 29
 95 23
 77 19
  1 17
 11 13
 13 11
 15 14
 15  2
 55  1
A> &`//=>Chop[Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "-31,2]
[(17/91), (78/85), (19/51), (23/38), (29/33), (77/29), (95/23), (77/19), (1/17), (11/13), (13/11), (15/14), (15/2), (55/1)]

让我们G在解释中替换该表达式。我们的第一个功能变为:

{Find[Integral,_*G]}

_将对函数的输入执行FRACTRAN代码的单次迭代。它是数组Find的一个Integral成员(一个整数)_*G,它是输入_乘以的每个成员GNest只需将此变换应用给定的次数。

附件,42个字节

$langs受此挑战的启发,我实现了库的某些部分,因此我将此部分标记为非竞争性的。

Needs[$langs]2&FRACTRAN_EXAMPLES.prime.run

这只是查询FRACTRAN_EXAMPLES我的清单。每个示例都是一个FractranExample实例,该实例调用内置FRACTRAN函数。该prime示例是Conway的PRIMEGAME。



0

PHP,183个字节(带有“ php”标签的189个字节)

打高尔夫球

$t=2;for(;@$i++<$argv[1];){foreach([17/91,78/85,19/51,23/38,29/33,77/29,95/23,77/19,1/17,11/13,13/11,15/14,15/2,55/1]as$n){$a=$t*$n;if(preg_match('/^\d+$/',$a)){$t=$a;break;}}}echo$t;

取消高尔夫:

<?php 
$t=2;
for(;@$i++<$argv[1];){
    foreach([17/91,78/85,19/51,23/38,29/33,77/29,95/23,77/19,1/17,11/13,13/11,15/14,15/2,55/1] as $n){
        $a=$t*$n;
        if(preg_match('/^\d+$/',$a)){
            $t=$a;break;
        }
    }
}
echo $t;

在线尝试!

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.