独特的乘法螺旋


13

这是受Calvin's Hobbies最近乘法表挑战的启发。

编写一个函数或程序,该函数或程序以整数N作为输入,并打印或返回N×N的唯一乘法螺旋。该代码必须(理论上)适用于0到1000之间的N(尽管很难输出)。输出应等于通过以下过程生成的表:

  1. 填写N×N乘法表。例如,N = 3:

    1 2 3
    2 4 6
    3 6 9
    
  2. 从左上角顺时针旋转,记下您访问的数字。当您访问已访问的号码时,将其替换为0。

几个例子可能会更清楚:

n = 0:
0

n = 1:
1

n = 2:       //   Spiral order:
1  2         //   1  2
0  4         //   4  3

n = 3:
1  2  3      //   1  2  3
0  4  6      //   8  9  4
0  0  9      //   7  6  5

n = 4:
1  2  3  4   //   1   2   3   4
0  0  6  8   //  12  13  14   5
0  0  9 12   //  11  16  15   6
0  0  0 16   //  10   9   8   7

n = 5:
1   2   3   4   5
0   0   6   8  10
0   0   9  12  15
0   0   0  16  20
0   0   0   0  25

n = 10:
1   2   3   4   5   6   7   8   9  10
0   0   0   0   0  12  14  16  18  20
0   0   0   0  15   0  21  24  27  30
0   0   0   0   0   0  28  32  36  40
0   0   0   0  25   0  35   0  45  50
0   0   0   0   0   0  42  48  54  60
0   0   0   0   0   0  49  56  63  70
0   0   0   0   0   0   0  64  72  80
0   0   0   0   0   0   0   0  81  90
0   0   0   0   0   0   0   0   0 100

这些数字如下所示:

在此处输入图片说明

可接受任何合理的输出格式,但是它必须是一个N×N矩阵,不能仅仅是列表。可接受以下格式,因为有N个易于区分的1×N列或N×1行:

[[1 2 3][0 4 6][0 0 9]]   <-- OK

[[1 0 0][2 4 0][3 6 9]]   <-- OK

ans =                     <-- OK
    1  2  3
    0  4  6
    0  0  9   

以字节为单位的最短代码获胜。


我用我的小眼睛窥视着一种修改过的橡皮擦筛!我很确定有一种模式可以在这里或其他地方使用。
Addison Crump 2015年

2
为什么n=0在乘法表中没有零的地方会有一个输出。我能理解n=1会输出1,但为什么要包含零?
汤姆·卡彭特

@TomCarpenter,这可能是一个错误的决定,但是我知道会有一个“ N = 0呢?”的问题,所以我制定了N = 0-> 0规则。回想起来,最好说N> 0,但是现在恐怕还为时已晚= /
Stewie Griffin

2
@StewieGriffin您说过,输出必须是一个N×N矩阵,因此for的输出n=0应该是一个0×0矩阵,否则问题将不一致。
alephalpha

Answers:


3

J,22个字节

,~$[:(*~:)[:,1*/~@:+i.

输出的0×0矩阵n=0


8

Mathematica 12312211798 92 73字节

多亏了LegionMammal978和alephalpha节省了19个字节,节省了24个字节!


令人惊讶的是,在此表中,任何整数的多个实例n在螺旋中的相对顺序将与在表本身中一样!数字的首次出现n在该数字在表格中首先出现的那个单元格中(当一个人一行又一行地填充表格时)。这意味着该方法可以完全忽略螺旋约束,因为它与结果无关。(请参阅下面的说明。)

ReplacePart[t=1##&~Array~{#,#},Join@@(Rest[t~Position~#]&/@Union@@t)->0]&

ReplacePart[t=1##&~Array~{#,#},Join@@(Rest[t~Position~#]&/@Union@@t)->0]&[10]

{{1,2,3,4,5,6,7,8,9,10},{0,0,0,0,0,12,14,16,16,18,20},{0,0, 0,0,15,0,21,24,27,30},{0,0,0,0,0,0,28,32,36,40},{0,0,0,0,25, 0、35、0、45、50},{0、0、0、0、0、0、42、48、54、60},{0、0、0、0、0、0、49、56 63,70},{0,0,0,0,0,0,0,64,72,80},{0,0,0,0,0,0,0,0,81,90},{ 0,0,0,0,0,0,0,0,0,100}}


Grid[%]

高音


说明

我们利用以下事实:任何数字n的位置的螺旋顺序与函数Positions!返回的行列位置的顺序相同。

每个数字的第一个出现位置(无论是螺旋形式还是表位置的顺序)将是所返回的第一个元素Position。该第一次出现的单元将保留原样。该数字的其余实例将替换为0。

让我们看看它是如何工作的,并检查的情况n==18。这个想法是从乘法表开始的:

(t = Table[k Range@#, {k, #}] &[10]) // Grid

并找到每个数字的行列位置。例如,18位于第2行第9列(第一个实例);第3行,第6列;第6行,第3列;和第9行第2行。它们分别具有螺旋顺序位置{44,58,68,82}。

Position[t, 18]

{{2,9},{3,6},{6,3},{9,2}}

如下表所示。

表2

最后的3个实例18必须替换为0。(我们将使用大号的蓝色粗体零,以便可以轻松发现它们。)

ReplacePart[%, {{3, 6}, {6, 3}, {9, 2}} -> Style[0, {Blue, Bold, 16}]]// Grid

表3


有没有不写作的理由Function吗?
LegionMammal978

1
我在使用嵌套纯函数时遇到了麻烦,但是此迭代不需要这样做。谢谢。
DavidC

我数了117个字节,不包括换行符。
LegionMammal978


一些其他的高尔夫球场:ReplacePart[t=1##&~Array~{#,#},Join@@(Rest[t~Position~#]&/@Union@@t)->0]&
alephalpha

2

Python,99 95 90 89 87 81字节

高尔夫代码:

n=range(1,input()+1);m=[]
for x in n:l=[(x*y,0)[x*y in m]for y in n];m+=l;print l

取消高尔夫:

n=range(1,input()+1);
m=[]
for x in n:
  l=[(x*y,0)[x*y in m]for y in n];
  m+=l;
  print l

输出:

10 
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
[0, 0, 0, 0, 0, 12, 14, 16, 18, 20]
[0, 0, 0, 0, 15, 0, 21, 24, 27, 30] 
[0, 0, 0, 0, 0, 0, 28, 32, 36, 40]
[0, 0, 0, 0, 25, 0, 35, 0, 45, 50] 
[0, 0, 0, 0, 0, 0, 42, 48, 54, 60]
[0, 0, 0, 0, 0, 0, 49, 56, 63, 70] 
[0, 0, 0, 0, 0, 0, 0, 64, 72, 80]
[0, 0, 0, 0, 0, 0, 0, 0, 81, 90] 
[0, 0, 0, 0, 0, 0, 0, 0, 0, 100]

感谢名单@valuah输入字节剃须
CSᵠ

2

MATLAB,96 88 87 86 79字节

这是79字节代码,紧随示例输出之后(特别是对于n = 0)

n=input('');m=+(n>0);for i=1:n;a=i*(1:i);for j=a;m(m==j)=0;end;m(1:i,i)=a;end;m

这是75个字节,除了n = 0以外,具有相同的行为,这将根据问题的含义生成一个空数组(N x N array = 0 x 0 = empty array)。

n=input('');m=[];for i=1:n;a=i*(1:i);for j=a;m(m==j)=0;end;m(1:i,i)=a;end;m

这也适用于Octave。您可以在这里在线尝试。该代码已作为名为“ multspiral.m”的文件添加。因此,在八度提示下,键入multspiral并按Enter。然后,您应该输入表格的大小(例如4)。然后将打印输出。


它是如何工作的?

首先,它根据需要输入一个输入数字(例如6、4等)

n=input('');

然后,我们处理的情况,n=0并且n=1-得到了特殊的对待,因为它们是两个,它们不遵循我用于生成数组的规则-实际上,如果不是晦涩的n=0情况,它可以短5个字节。

m=+(n>0);

然后针对的所有值n>2,进行一些循环,直到矩阵增长到正确的大小为止。

for i=2:n;

两者之间n以及n+1所有人之间实际上只有三个简单的区别n>=2。这些是:

  1. 在包含数字的数组的最右边添加一个新列n(1:n)。这很容易计算:

     a=i*(1:i);
    
  2. 必须将要添加到该新列中的任何元素从现有矩阵中删除(设置为零),因为它们总是比新列晚出现在螺旋中。使用嵌套的for循环将当前矩阵中所有新列中的所有元素设置为零,可以将其删除。

    for j=a;
        m(m==j)=0;
    end;
    
  3. 有一个新的行底部,对于该行,除新列中的元素外,每个元素的零都将为零。添加新列时,由于故意创建的越界索引会自动填充0。MATLAB的强大功能之一是它可以增长数组而无需任何特殊处理,因此我们可以简单地添加新行和列与:

    m(1:i,i)=a;
    

最后,我们有了for循环的结尾-一旦到达,矩阵就m包含了我们的输出。由于您可以灵活地使用输出格式,因此只需用m换行代替分号即可显示矩阵

end;
m

例如,如果运行程序,请输入数字10,我们将获得以下输出:

m =
     1     2     3     4     5     6     7     8     9    10
     0     0     0     0     0    12    14    16    18    20
     0     0     0     0    15     0    21    24    27    30
     0     0     0     0     0     0    28    32    36    40
     0     0     0     0    25     0    35     0    45    50
     0     0     0     0     0     0    42    48    54    60
     0     0     0     0     0     0    49    56    63    70
     0     0     0     0     0     0     0    64    72    80
     0     0     0     0     0     0     0     0    81    90
     0     0     0     0     0     0     0     0     0   100

1

Haskell,103 99字节

import Data.Lists
f 0=[[0]]
f n=chunksOf n$foldr(\c d->c:replace[c][0]d)[][a*b|a<-[1..n],b<-[1..n]]

用法示例:f 4-> [[1,2,3,4],[0,0,6,8],[0,0,9,12],[0,0,0,16]]

我刚刚发现的Data.Lists这对列表(如好的功能模块replace)及再出口Data.ListData.List.SplitData.List.Extras


1

Ruby,67 63 61字节

->n{s,x=1..n,{};s.map{|c|s.map{|r|x[v=c*r]==1?0:(x[v]=1;v)}}}

63个字节

->n{s,x=1..n,{};s.map{|c|s.map{|r|e=x[v=c*r]==1?0:v;x[v]=1;e}}}

67字节

->n{s,x=1..n,[];s.map{|c|s.map{|r|e=x.include?(v=c*r)?0:v;x<<v;e}}}

用法:

->n{s,x=1..n,{};s.map{|c|s.map{|r|x[v=c*r]==1?0:(x[v]=1;v)}}}[10]
=> [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [0, 0, 0, 0, 0, 12, 14, 16, 18, 20], [0, 0, 0, 0, 15, 0, 21, 24, 27, 30], [0, 0, 0, 0, 0, 0, 28, 32, 36, 40], [0, 0, 0, 0, 25, 0, 35, 0, 45, 50], [0, 0, 0, 0, 0, 0, 42, 48, 54, 60], [0, 0, 0, 0, 0, 0, 49, 56, 63, 70], [0, 0, 0, 0, 0, 0, 0, 64, 72, 80], [0, 0, 0, 0, 0, 0, 0, 0, 81, 90], [0, 0, 0, 0, 0, 0, 0, 0, 0, 100]]
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.