乌兰螺旋之素


17

乌兰(Ulam)的螺旋式是一个真正令人着迷但令人困惑的数学主题。可以在这里找到它的详细工作原理,但简短的摘要可以这样解释:

我先写一个,然后在右边写一个二。在两个上方,我写三个,在左边左侧,我写四个。我继续无限循环(或直到被告知停止)围绕1(以及我与1之间的任何数字)盘旋的这种模式,形成了螺旋模式。(请参见下面的示例)

目标

制作一个程序,该程序接受n(始终为大于零的奇数)作为与行数相关的输入,然后逐行打印Ulam螺旋的素数值。格式可以是任何方式,但必须易于阅读且显而易见。

例如,给定输入3,您的程序应输出5,3,2,7,因为3行会产生以下螺旋:

5 4 3 <-- first row has the primes 5 and 3
6 1 2 <-- second row has the prime 2
7 8 9 <-- third row has the prime 7

由于这是一场代码高尔夫,因此,字节数最少的答案将获胜(无论效率如何)!标准漏洞是不可接受的。


是否可以使用逗号结尾?或更好的是,将空格隔开,例如```5 3 2 7`
Tom Carpenter

5
只要它是人类可读的并且可以告诉我素数,就可以自由使用。
艾迪生·克伦普

Answers:


8

Pyth,20个字节

f}TPTsuC+R=hZ_GtyQ]]

在线试用:演示

此代码生成了完整的Ulam螺旋,连接了所有线条和素数滤波器。

说明:

f}TPTsuC+R=hZ_GtyQ]]   implicit: Z = 0
      u           ]]   reduce, start with G = [[]]
               tyQ     for H in [0, 1, ..., 2*input-2] do:
             _G           reverse the order of the lines
        +R=hZ             append Z + 1 at the end of each line, 
                          updating Z each time with the new value Z + 1
       C                  update G with the transposed of ^
                       this gives the Ulam's spiral
     s                 combine all lines to a big list of numbers
f                      filter for numbers T, which satisfy:
 }TPT                    T appears in the prime-factorization of T
                         (<==> T is prime)

6

MATLAB,48

a=fliplr(spiral(input(''))');disp(a(isprime(a)))

基本上,这会创建所需大小(用户要求)的螺旋形,然后对其进行排列,以使其以正确的行顺序显示。这存储在一个。接下来,它显示所有素数的值。

正如您所说的任何可读格式,我保存了一个字节,然后去了disp()的默认输出,即(在您的测试用例中,n = 3):

 5
 3
 2
 7

另外,这适用于任何n> 0(包括偶数)的情况。例如,n = 10的输出为:

97
61
59
37
31
89
67
17
13
 5
 3
29
19
 2
11
53
41
 7
71
23
43
47
83
73
79

1
非常好!很spiral
高兴

6

CJam,42 33字节

Xali(2*{_W%zY@,Y+:Y,>a+}*e_{mp},`

在线尝试

最新版本包含@Martin建议的实质性改进。

构造螺旋线的方法是,在每个步骤中,将到目前为止的矩阵旋转90度,然后添加一行并添加其他数字。这是重复的(n / 2) * 4次数。

然后将所得矩阵中的值过滤为素数。

说明:

Xa    Push initial matrix [1].
li    Get input and convert to int.
(2*   Calculate 2*(n-1), which is the number of rotations and row additions needed.
{     Start rotation loop.
  _     Copy current matrix for getting number of rows later.
  W%    Reverse the order of the rows...
  z     ... and transpose the matrix. The combination produces a 90 degree rotation.
  Y     Get next value from variable Y (which is default initialized to 2).
  @,    Rotate previous matrix to top, and get number of rows. This is the number
        of columns after the 90 degree rotation, meaning that it's the length of
        the row to be added.
  Y+    Add first value to row length to get end value.
  :Y    Save it in Y. This will be the first value for next added row.
  ,     Create list of values up to end value.
  >     Slice off values up to start value, leaving only the new values to be added.
  a+    Wrap the new row and add it to matrix.
}*    End of rotation loop.
e_    Flatten matrix into list.
{mp}, Filter list for primes.
`     Convert list to string for output.

可以2/4*被替换2*,或者有你离开它就像是故意?
ETHproductions's October

@ETHproductions这不是等效的,因为它是整数除法。例如,对于输入3,结果需要为4。实际上,考虑到这一点,我相信有一个字节要保存。(2*应该是正确的。
Reto Koradi 2015年

5

Mathematica 223

这适合库巴的 Ulam螺旋代码。这就是为什么我将其提交为社区Wiki。我只是打高尔夫球,并选择了素数,这些素数在它们所在的行中列出。

r=Range;i=Insert;t=Transpose;s@n_:=#~Select~PrimeQ&/@Nest[With[{d=Length@#,l=#[[-1,-1]]},
Composition[i[#,l+3d+2+r[d+2],-1]&,t@i[t@#,l+2d+1+r[d+1],1]&,i[#,l+d+r[d+1,1,-1],1]&,
t@i[t@#,l+r[d,1,-1],-1] &][#,15]]&,{{1}},(n-1)/2]

 s{15]

{{197,193,191},{139,137},{199,101,97,181},{61,59,131},{103,37,31,89,179},{149,67, 17,13},{5、3、29},{151、19、2、11、53、127},{107、41、7},{71、23},{109、43、47、83, 173},{73、79},{113},{157、163、167},{211、223}}

要改善显示效果:

 %// MatrixForm

矩阵


4

Mathematica,118个字节

f=Permute[Range[#*#],Accumulate@Take[Join[{#*#+1}/2,Flatten@Table[(-1)^j i,{j,#},{i,{-1,#}},{j}]],#*#]]~Select~PrimeQ&

通过注意每个后续数字的位置可以累积为

{(n*n + 1)/2, +1, -n, -1, -1, +n, +n, +1, +1, +1, -n, -n, -n, ...}

即从中心开始,然后向右移动1,向上1,向左2,向下2,向右3,向上3,...

输出:

In[515]:= f[5]
Out[515]= {17,13,5,3,19,2,11,7,23}

1

的Javascript,516 363 304 276 243 240个字节

我的解决方案不是使用Spiral创建密集矩阵,而是返回与给定顺序的Ulam矩阵中给定数字相对应的索引。因此,它将遍历2到M * M之间的数字,并使用fn ulamIdx给定的idx创建素数数组

M=15;
$=Math;
_=$.sqrt;
/**
 * Return M*i+j (i.e. lineal or vector idx for the matrix) of the Ulam Matrix for the given integer
 * 
 * Each Segment (there are 4 in each round) contains a line of consecutive integers that wraps the 
 * inner Spiral round. In the foCowing example Segments are: {2,3}, {4,5},
 * {6,7}, {8,9}, {a,b,c,d}, {e,f,g,h}, {i,j,k,l}, {m,n,o,p}  
 *            
 *    h g f e d
 *    i 5 4 3 c
 *    j 6 1 2 b
 *    k 7 8 9 a 
 *    l m n o p
 * 
 * @param n integer The integer which position in the Matrix we want.
 * @param M integer Matrix Order. 
 */
/*
 * m: modulus representing step in segment in current spirtal round
 * v: Step in current spiral round, i.e. n - (inner spirals greatest num.)
 * s: the current Segment one of [1, 2, 3, 4] that represents the current spiral round 
 * L: Segment Length (Current spiral round Order - 1)
 * B: inner Spiral Order, for trib¿vial case 1 it's -1 special case handled differently.
 * C: relative line (row or column) corresponding to n in current spiral Round 
 * R: relative line (column or row) corresponding to n in current spiral Round
 * N: Curren (the one that contains n) Spiral (matrix) round Order
 * D: Difference between M and the current Spiral round order.
 */

/**
 * Runs the loop for every integer between 2 and M*M
 * Does not check sanity for M, that should be odd.
 */
r=[];
for (x = 2; x < M * M; x++) {
    p=1;
    // Is Prime?
    for (k = 2; p&&k <= _(x); k++)
        if (x % k==0) p=0;
    if (p) {
        B = $.floor(_(x - 1));
        B=B&1?B:B-1;
        N = B + 2;
        D = (M - N) / 2;
            v = x - B * B;
            L = B + 1;
            s = $.ceil(v / L);
            m = v % L || L;
            C = D + (s < 3 ? N - m : 1 + m);
            R = s&2 ? D + 1 : D + N;
            w= s&1 ? M * C + R : M * R + C;
        // /*uncomment to debug*/ console.log("X:" + x + ": " + ((s&1) ? [C, R].join() : [R, C].join()));
        r[w] = x;
    }
}
alert(r);

缩小看起来像这样:

for(M=15,$=Math,_=$.sqrt,r=[],x=2;x<M*M;x++){for(p=1,k=2;p&&k<=_(x);k++)x%k==0&&(p=0);p&&(B=$.floor(_(x-1)),B=1&B?B:B-1,N=B+2,D=(M-N)/2,v=x-B*B,L=B+1,s=$.ceil(v/L),m=v%L||L,C=D+(s<3?N-m:1+m),R=2&s?D+1:D+N,w=1&s?M*C+R:M*R+C,r[w]=x)}alert(r);

对于输入15,输出为:

,,,,,,,,,,,,,,,,,、、 ,199,101 ,,,,,,,,,,,,,,,,, 181 ,,,,,,,,,,,,, 61,59 ,,,, 131 ,,,,,,,,,,,,,,,,,,,, 31,89,179,149,67,17 ,,, 13 ,,,,,,,,,,, 5,3,29 ,,,,, 151 ,, ,19,,2,11,53,127 ,,,, 107,,41,,7 ,,,,,,,,,,, 71 ,,,,,,,,,, ,,, 109,,43 ,,,,, 47 ,,,, 83,,173 ,,,,, 73 ,,,,,, 79 ,,,,,,,,,,,,,,,, 、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、


那是很大的压缩。您能说明您的原始代码和更改吗?
Addison Crump

我卸下了一些无用的括号。并意识到uI()具有4个条件,且条件相似。每行有3行为当前段生成行和列(请参见主文档块),因此我用ll&llt行替换了4个块,然后返回行确定llt是行还是列。S&2对于(3,2)中的s是正确的(上段和左段);s <3,对于(1,2)右和上中的s而言。S&1,对于(1,3)中的s将确定ll&llt中的值是row&col还是col&row和M(螺旋顺序)×row + col防止重叠的索引(如校正矩阵,但线性idx错误,则正确性需要ll-1
juanmf

在主循环(运行())中,只有当i为质数(因无需测试<2或%1而减少了fn)时,它才会在螺旋中要求i的索引(ll,llt),而该螺旋已得到纠正。然后只打印结果数组。
juanmf

有3个概念上重要的矩阵。内部,曲线和M。用于计算绝对行和列。减去n的内部将使us拥有一个相对int的螺旋电流(n落入的电流)。M和当前顺序之间的差异充当当前回合中row和col的偏移量以获得绝对值。
juanmf

364-> 240,方法是内联编写fn逻辑并删除未使用的测试。
juanmf 2015年
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.