生成求和网格


15

生成一个7 x 7的网格,其中填充了随机数。但是,在具有奇数行和列编号(从0开始)的单元格中,必须使用周围单元格的总和。这是一个3 x 3网格的小示例(加粗平方和):

2 2  2
2 16 2
2 2  2

这是一个7 x 7网格的示例:

6 5  4 3  7 2  5
6 43 3 50 8 43 8
4 7  8 8  9 3  1
4 36 1 43 6 40 5
3 3  6 1  4 7  5
4 35 3 45 9 42 1
2 6  8 6  8 5  3

规则

  • 不是总和的数字必须始终在1到9之间(含1和9)。

  • 网格必须随机生成。对于每个非总和,无论其位于哪个单元格中,每个数字都必须具有相等的出现机会。

  • 数字必须对齐。这意味着一列中每个数字的第一位或最后一位必须垂直排列。(您可以假定中间数字始终是两位数字。)

  • 周围的单元格包括对角线。因此,每个总和方将包含八个数字,您必须将其相加。

  • 最短的代码获胜,因为这是


3
是否必须是排队的第一个数字?那可以是最后一个吗?
波动率

@波动率我想正确的对齐方式将起作用。编辑
门把手

如果一种语言没有随机数生成器怎么办?
Heimdall

Answers:


14

APL,53 49 43 42 40 39 36

我设法;.在APL中复制J ,并使用Gareth的方法,节省了13个字符。

{×5⌷⍵:5⌷⍵⋄+/⍵}¨3,⌿3,/×∘?∘9¨∘.∨⍨9⍴0 1

样品运行:

      {×5⌷⍵:5⌷⍵⋄+/⍵}¨3,⌿3,/×∘?∘9¨∘.∨⍨9⍴0 1
9  9 6  1 7  5 6
7 55 5 39 9 54 9
9  8 2  1 8  1 9
2 43 8 41 6 42 5
7  3 4  4 8  3 2
2 29 1 26 2 35 8
6  4 2  3 2  3 7

说明:

  • ∘.∨⍨9⍴0 1 生成位掩码。
  • ×∘?∘9¨ 将每个位乘以一个从1到9(含1和9)之间的随机值,生成一个掩码的随机数网格。
  • 3,⌿3,/使用只能被描述为黑客的方法来返回掩码数组中的所有3 x 3重叠框。这些也会在此过程中变平。
  • {×5⌷⍵:5⌷⍵⋄+/⍵}¨遍历数组,将每个元素分配给。对于每次迭代,它取第五个(中间,记住APL索引是基于1的),并返回其符号。在这种情况下,这等效于测试数字是否大于0。如果返回1(为true),则返回该元素。否则,返回展平的3 x 3框中的元素之和。它使用:⋄三元运算符,与?:许多语言等效。

哦哦 看来我将不得不节省更多的角色。:-S
Gareth 2013年

@Gareth好,看看我们这里有什么。我回到领先地位:P
波动性

NOOOOOOOOOO !!!!!!! :-(
Gareth

13

J,63 61 59 55 52 51 49 47 39 37个字符

3 3(4&{+4{*|+/)@,;._3(**1+?)+./~9$0 9

感谢Volatility节省了10个字符。

说明(每个步骤将具有不同的随机数...):

生成用于生成随机数的掩码(使用$

   9 9$9$0 9
0 9 0 9 0 9 0 9 0
0 9 0 9 0 9 0 9 0
0 9 0 9 0 9 0 9 0
0 9 0 9 0 9 0 9 0
0 9 0 9 0 9 0 9 0
0 9 0 9 0 9 0 9 0
0 9 0 9 0 9 0 9 0
0 9 0 9 0 9 0 9 0
0 9 0 9 0 9 0 9 0

现在我们有了一个钩子。从我开始使用早期版本开始,这实际上是一次不幸的事故。它原本应该是转置的|:,也可以是+.与原版的或。自从我当时使用1和0以来,这很有意义,但是现在我有了9和0。碰巧的是,它与GCD的含义相同+.。对我来说很幸运。:-)

   (+.|:)9 9$9$0 9
0 9 0 9 0 9 0 9 0
9 9 9 9 9 9 9 9 9
0 9 0 9 0 9 0 9 0
9 9 9 9 9 9 9 9 9
0 9 0 9 0 9 0 9 0
9 9 9 9 9 9 9 9 9
0 9 0 9 0 9 0 9 0
9 9 9 9 9 9 9 9 9
0 9 0 9 0 9 0 9 0

所以,既然我们有一个9s和0s的网格,我们想生成一些随机数。?生成一个从0到(但不包括)给定数字的随机数。给定一个列表,它将以这种方式为列表的每个成员生成一个随机数。因此,在这种情况下,它将为表中的每9生成一个0到8的数字,并为每个0生成一个从0到1的浮点数。

   ?(+.|:)9 9$9$0 9
 0.832573 7 0.926379 7 0.775468 6 0.535925 3  0.828123
        7 0        5 5        4 3        4 5         4
0.0944584 2 0.840913 2 0.990768 1 0.853054 3  0.881741
        3 8        7 0        8 3        3 4         8
 0.641563 4 0.699892 7 0.498026 1 0.438401 6  0.417791
        6 8        7 5        2 3        6 6         3
 0.753671 6 0.487016 4 0.886369 7 0.489956 5  0.902991
        3 4        7 8        1 4        8 0         8
0.0833539 4 0.311055 4 0.200411 6 0.247177 5 0.0464731

但是我们希望数字从1到9而不是0到8。所以我们加1。

   (1+?)(+.|:)9 9$9$0 9
 1.4139 4  1.7547 7 1.67065 4 1.52987 1 1.96275
      2 8       2 4       3 9       6 9       9
1.15202 7 1.11341 5  1.0836 1 1.24713 2 1.13858
      9 3       3 2       4 7       3 8       6
1.06383 9 1.67909 4 1.09801 8  1.4805 6  1.0171
      9 5       5 5       9 5       9 4       3
1.22819 1 1.85259 4 1.95632 6 1.33034 3 1.39417
      4 2       5 1       3 7       2 5       6
1.06572 5  1.9942 5 1.78341 5 1.16516 6 1.37087

很好,但是我们丢失了我想要的零,因此在将所有的9都变成1后,我们将其乘以原始蒙版。我通过检查值是否大于1来做到这一点。这使我们:(1&<*1+?)
这里发生了几件事情:

  • 我们创建了一个fork,可以将很多工作打包成很少的字符。
  • 我们&将1 绑定到<动词上。

因此,所有的组合(1&<*1+?)都会生成随机数,并将在原始网格中由零生成的所有数字置零。

   (1&<*1+?)(+.|:)9 9$9$0 9
0 3 0 2 0 7 0 1 0
9 5 2 7 7 1 4 5 7
0 6 0 8 0 3 0 1 0
4 8 7 5 9 7 7 9 4
0 9 0 6 0 9 0 9 0
6 1 2 1 4 6 8 9 4
0 3 0 8 0 6 0 6 0
2 5 2 2 2 2 3 9 3
0 9 0 3 0 5 0 3 0

接下来的一点(无论如何,我认为是:-)很聪明。
cut ;.动词的形式x u;._3 y可将输入切成以下描述的框x,然后将其应用于u它们。在这种情况下,我们有3 3(4&{++/*0=4&{)@,;._3

  • 3 3描述的是我们想要的盒子- 3×3。
  • (4&{++/*0=4&{)@,是动词训练,它描述了我们要对每个框执行的操作。

为了演示;.动词,我将使用它<来显示每个框:

   3 3(<);._3(1&<*1+?)(+.|:)9 9$9$0 9
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│0 8 0│8 0 7│0 7 0│7 0 4│0 4 0│4 0 3│0 3 0│
│9 1 3│1 3 2│3 2 3│2 3 8│3 8 5│8 5 5│5 5 9│
│0 6 0│6 0 1│0 1 0│1 0 2│0 2 0│2 0 4│0 4 0│
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│9 1 3│1 3 2│3 2 3│2 3 8│3 8 5│8 5 5│5 5 9│
│0 6 0│6 0 1│0 1 0│1 0 2│0 2 0│2 0 4│0 4 0│
│7 1 6│1 6 7│6 7 1│7 1 2│1 2 1│2 1 6│1 6 1│
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│0 6 0│6 0 1│0 1 0│1 0 2│0 2 0│2 0 4│0 4 0│
│7 1 6│1 6 7│6 7 1│7 1 2│1 2 1│2 1 6│1 6 1│
│0 7 0│7 0 5│0 5 0│5 0 9│0 9 0│9 0 7│0 7 0│
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│7 1 6│1 6 7│6 7 1│7 1 2│1 2 1│2 1 6│1 6 1│
│0 7 0│7 0 5│0 5 0│5 0 9│0 9 0│9 0 7│0 7 0│
│7 9 9│9 9 7│9 7 1│7 1 9│1 9 4│9 4 9│4 9 5│
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│0 7 0│7 0 5│0 5 0│5 0 9│0 9 0│9 0 7│0 7 0│
│7 9 9│9 9 7│9 7 1│7 1 9│1 9 4│9 4 9│4 9 5│
│0 3 0│3 0 2│0 2 0│2 0 7│0 7 0│7 0 9│0 9 0│
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│7 9 9│9 9 7│9 7 1│7 1 9│1 9 4│9 4 9│4 9 5│
│0 3 0│3 0 2│0 2 0│2 0 7│0 7 0│7 0 9│0 9 0│
│3 1 6│1 6 1│6 1 7│1 7 6│7 6 8│6 8 9│8 9 9│
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│0 3 0│3 0 2│0 2 0│2 0 7│0 7 0│7 0 9│0 9 0│
│3 1 6│1 6 1│6 1 7│1 7 6│7 6 8│6 8 9│8 9 9│
│0 9 0│9 0 3│0 3 0│3 0 4│0 4 0│4 0 3│0 3 0│
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘

注意事项:

  • 框重叠-左上方框的第二和第三列是框右侧的第一和第二列。
  • 有7x7盒子。这就是为什么我们最初有9x9网格的原因。
  • 我们要求总和的每个位置0在框的中心都有一个。

现在,我们只需要将中间的值传递回(如果非零)或将3x3框中的数字加起来(如果中心为零)。
为此,我们需要轻松访问中心号码。,在这里有帮助。它将3x3网格变成9个项目的列表,中心编号为4。
4&{将用于{拉出中心值,然后将其与0:进行比较0=4&{。这将返回一个01为真或假,我们然后乘总和+/。如果在中心为零,则现在需要的总和。如果不是零,那么要结束,我们只添加中心值4&{+
这使动词训练(4&{++/*0=4&{)@,

   3 3(4&{++/*0=4&{)@,;._3(1&<*1+?)(+.|:)9 9$9$0 9
2  6 9  3 7  9 7
3 47 6 51 5 49 5
3  9 9  6 6  2 8
7 48 6 47 1 37 5
5  4 5  7 7  2 6
5 35 3 49 8 51 9
1  6 6  6 7  4 8

您的一行代码是否能完成所有这些工作,包括生成随机数?放心吧 只是很难相信。
DavidC 2013年

是的,很难相信。随机位由来完成?。我将更改说明以反映最新版本。
Gareth 2013年

@DavidCarraher J中的大多数动词都是1个或2个字符,因此47个字符可以完成很多工作。
Gareth 2013年

将9x9盒子切成7x7重叠的正方形绝对是一个聪明的地方。在不到10分钟的时间里,我已经能够应用它,使我目前的GolfScript实现实现7.5%的成功。
彼得·泰勒

哦,好吧,看起来对我来说,它已经回到了画板上。
波动率

5

Ruby(135个字符)

a=(0..48).map{rand(9)+1}
([0,0,j=8]*3).each{|l|a[j]=[0,1,6,7,8].inject{|s,e|s+a[j+e]+a[j-e]};j+=l+2}
a.each_slice(7){|r|puts"%-3s"*7%r}

样品输出

2  1  6  9  4  5  1  
9  34 4  37 2  31 3  
7  2  3  1  8  1  7  
5  42 4  40 2  47 9  
3  9  9  4  9  4  7  
3  44 4  41 2  47 4  
6  9  1  5  7  6  8  

分解

运作方式不太明显,所以这里有一个快速的细分。注意:您可能可以跳过其中一些步骤,更快地跳到较短的版本,但是我认为这足以说明我如何剃除字符,特别是通过在文字中发现模式以将2位数字转换为1位数字的方式来剃除字符。 。

天真的版本

其他依赖于二维数组的Ruby解决方案不同,您可以(最终)通过从一维数组开始并使用偏移值来获得较短的版本,因为模式会重复。

ary=(0..48).map { rand(9) + 1 }

offsets = [-8,-7,-6,-1,1,6,7,8]

3.times do |i|
  [8,10,12].each do |j|
    ary[j + 14*i] = ary.values_at(*offsets.map { |e| j+14*i + e }).inject(:+)
  end
end

ary.each.with_index do |e,i|
  $> << ("%-3s" % e)
  $> << ?\n if i % 7==6
end

这里的关键原理是我们在索引位置8、10、12处工作,只是偏移了14的倍数。位置8、10和12是我们要累加的3x3网格的中心。在样本输出中,位置34是位置8,位置42是位置8 + 14 * 1,依此类推。我们将位置8替换为34,将位置从位置8偏移了[-8,-7,-6,-1,1,6,7,8]—即34 = sum(ary[8-8], ary[8-7], ..., ary[8+8])。相同的原则适用于[8 + 14*i, 10 + 14*i, 12 + 14*i]由于模式重复,因此。

优化它

首先,一些快速优化:

  • 代替3.times { ... }j + 14*i每次计算“内联”头寸[8,10,12,22,24,26,36,38,40]
  • offsets数组仅使用一次,因此请用文字替换变量。
  • 替换为do ... end{...}然后将打印切换到$> << foo。(这里有一个涉及puts nil和的技巧() == nil。)
  • 较短的变量名。

此后的代码是177个字符:

a=(0..48).map{rand(9)+1}
[8,10,12,22,24,26,36,38,40].each{|j|a[j]=a.values_at(*[-8,-7,-6,-1,1,6,7,8].map{|e|j+e}).inject(:+)}
a.map.with_index{|e,i|$><<"%-3s"%e<<(?\nif i%7==6)}

对于下一个减少,请注意,inject不需要按顺序排列offsets数组。[-8,-7,-6,-1,1,6,7,8]因为加法是可交换的,所以我们可以具有或其他某种顺序。

因此,首先要对正负进行配对[1,-1,6,-6,7,-7,8,-8]

现在您可以缩短

[1,-1,6,-6,7,-7,8,-8].map { |e| j+e }.inject(:+)

[1,6,7,8].flat_map { |e| [j+e, j-e] }

这导致

a=(0..48).map{rand(9)+1}
[8,10,12,22,24,26,36,38,40].each{|j|a[j]=a.values_at(*[1,6,7,8].flat_map{|e|[j+e,j-e]}).inject(:+)}
a.map.with_index{|e,i|$><<"%-3s"%e<<(?\nif i%7==6)}

这是176个字符。

移8移至不同点

两个字符的文字值似乎可以缩短,因此请在循环开始[8,10,12,22,24,26,36,38,40]时通过进行8更新并向下移动所有内容j。(请注意,+=8避免更新的偏移值1,6,7,8。)

a=(0..48).map{rand(9)+1}
[0,2,4,14,16,18,28,30,32].each{|j|j+=8;a[j]=a.values_at(*[1,6,7,8].flat_map{|e|[j+e,j-e]}).inject(:+)}
a.map.with_index{|e,i|$><<"%-3s"%e<<(?\nif i%7==6)}

这是179,更大,但j+=8实际上可以将其删除。

第一次改变

[0,2,4,14,16,18,28,30,32]

到一系列差异:

[2,2,10,2,2,10,2,2]

并将这些值累加到initial中j=8。最终将覆盖相同的值。(我们可能直接跳过了这一步,而不是先移8。)

请注意,我们还将9999在差值数组的末尾添加一个虚拟值,并jend而不是循环的开始处添加。理由是2,2,10,2,2,10,2,2看起来非常接近相同的3个数字,重复了3次,并且通过j+difference在循环结束时进行计算,最终的值9999实际上不会影响输出,因为不会a[j]调用j某个值结束10000

a=(0..48).map{rand(9)+1}
j=8
[2,2,10,2,2,10,2,2,9999].each{|l|a[j]=a.values_at(*[1,6,7,8].flat_map{|e|[j+e,j-e]}).inject(:+);j+=l}
a.map.with_index{|e,i|$><<"%-3s"%e<<(?\nif i%7==6)}

使用此差异数组,j+=8现在j=8当然是,因为否则我们将反复添加8太多。我们还将block变量从更改jl

因此,由于9999元素对输出没有影响,因此我们可以将其更改为10并缩短数组。

a=(0..48).map{rand(9)+1}
j=8
([2,2,10]*3).each{|l|a[j]=a.values_at(*[1,6,7,8].flat_map{|e|[j+e,j-e]}).inject(:+);j+=l}
a.map.with_index{|e,i|$><<"%-3s"%e<<(?\nif i%7==6)}

这是170个字符。

但是现在j=8看起来有点笨拙,您可以通过[2,2,10]向下移动2来保存2个字符,以方便地获得8可用于分配的字符。这也需要j+=l成为j+=l+2

a=(0..48).map{rand(9)+1}
([0,0,j=8]*3).each{|l|a[j]=a.values_at(*[1,6,7,8].flat_map{|e|[j+e,j-e]}).inject(:+);j+=l+2}
a.map.with_index{|e,i|$><<"%-3s"%e<<(?\nif i%7==6)}

这是169个字符。压缩7个字符的一种环回方式,但是很简洁。

最终调整

values_at电话实际上是多余的,我们可以内联Array#[]电话。所以

a.values_at(*[1,6,7,8].flat_map{|e|[j+e,j-e]}).inject(:+)

变成

[1,6,7,8].flat_map{|e|[a[j+e],a[j-e]]}.inject(:+)

您还可以发现flat_map+ j+e/j-e+ inject可以用0数组中的首字母简化为更直接的求和。

这使你有152个字符:

a=(0..48).map{rand(9)+1}
([0,0,j=8]*3).each{|l|a[j]=[0,1,6,7,8].inject{|s,e|s+a[j+e]+a[j-e]};j+=l+2}
a.map.with_index{|e,i|$><<"%-3s"%e<<(?\nif i%7==6)}

最后:

  • map.with_index可以成为each_slice
  • 更改打印方式。

135

a=(0..48).map{rand(9)+1}
([0,0,j=8]*3).each{|l|a[j]=[0,1,6,7,8].inject{|s,e|s+a[j+e]+a[j-e]};j+=l+2}
a.each_slice(7){|r|puts"%-3s"*7%r}

您可以替换eachmap一个字节。
乔丹

3

巨蟒,132

从技术上讲,这不符合规则,因为每个数字的最后一位是对齐的,而不是第一位。但是我还是想分享一下:

import numpy
G=numpy.random.randint(1,10,(7,7))
G[1::2,1::2]=sum(G[i:6+i:2,j:6+j:2]for i in[0,1,2]for j in[0,1,2]if i&j!=1)
print G

样本输出:

[[ 8  9  8  3  8  5  8]
 [ 6 53  4 45  8 53  8]
 [ 8  2  8  1  5  3  8]
 [ 2 40  6 34  1 32  7]
 [ 4  1  9  1  3  3  2]
 [ 4 35  7 35  6 31  1]
 [ 1  7  2  5  2  8  6]]

3

Mathematica,108

s=#-1;;#+1&;g=1+8~RandomInteger~{7,7};Column/@
ReplacePart[g,{i_?EvenQ,j_?EvenQ}:>g〚s@i,s@j〛~Total~2-g〚i,j〛]

结果

对于更漂亮的输出,Column/@可以替换TableForm@为2个字符。


非常非常聪明。Grid[ReplacePart[ g, {i_?EvenQ, j_?EvenQ} :> g[[s@i, s@j]]~Total~2 - g[[i, j]]]\[Transpose]]如果将转置算作单个字符(在Mathmatica中),则可以提供更清晰的输出并保存几个字符。顺便说一句,Wolfram的OneLinerSubmission模板计算了106个字符,其中105个带有“转置”字符。
DavidC 2013年

@DavidCarraher谢谢。字符计数是由于不必要的换行符,并且:>是一个符号,尽管它位于unicode的专用区域中。人们甚至可以删除转置,因为有效性求和规则即使在转置后也成立。但是,Grid如果没有其他选项(v8),似乎无法对齐条目
ssch 2013年

Grid将数字居中于列中。从技术上讲,这不能解决挑战,但是看起来确实比在显示的表中显示列表更好。
DavidC

非常好。我只是花了相当多的时间来创建相同的东西,只有我曾经使用PartTuples。即将发布。
威兹德先生2013年

您可以这样保存两个字符:p=2|4|6;Column/@ReplacePart[g,{i:p,j:p}:>g[[s@i,s@j]]~Total~2-g[[i,j]]]
Mr.Wizard

3

GolfScript(79 78 72 70 68 66 65 60个字符)

56,{13%5<,~9rand)}%9/`{>3<zip`{>3<(*(+(\{+}*or' '}+7,%n}+7,/

注意:这包含一个文字选项卡,Markdown可能会破坏该选项卡。

聪明点归功于Gareth:请参阅他的J解决方案。

在线演示


3

R:114个字符

a=array(sample(1:9,49,r=T),c(7,7))
for(i in 2*1:3){for(j in 2*1:3)a[i,j]=sum(a[(i-1):(i+1),(j-1):(j+1)])-a[i,j]}
a

第一行创建一个7 x 7的数组,其中填充有1到9个随机选择的数字(均匀分布,带有替换,因此r=T代表replace=TRUE)。第二行,计算3乘3网格的总和,减去中心并用结果替换。第三行打印结果网格(默认情况下,矩阵和数组列右对齐)。

输出示例:

     [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]    8    5    6    4    3    2    2
[2,]    1   37    6   41    7   38    8
[3,]    5    3    3    3    9    4    3
[4,]    4   31    3   41    3   44    9
[5,]    3    5    5    9    6    7    3
[6,]    3   32    2   40    4   37    5
[7,]    8    2    4    1    9    1    2

2

J,67 65字节

J中的一个幼稚而冗长的解决方案。这是任务的直接实现。

(+/^:_"2((,&.>/@(<:,],>:)"0)&.>m){0 m}a)(m=.{;~1 3 5)}a=.>:?7 7$9

首先,我创建一个7 x 7的1到9之间的整数数组。实际上,J是?动词根据其自变量生成数字,这就是为什么我们需要在J中增加每个元素>

a=.>:?7 7$9 
2 8 7 4 4 5 1
4 5 4 1 6 7 9
3 8 3 6 5 3 3
6 8 6 3 7 7 1
7 7 4 4 5 9 9
2 3 6 5 2 2 9
2 2 6 8 8 1 3

我准备了一个用于将奇数行/列单元归零的掩码,一对奇数行/列索引:

m=.{;~1 3 5
┌───┬───┬───┐
│1 1│1 3│1 5│
├───┼───┼───┤
│3 1│3 3│3 5│
├───┼───┼───┤
│5 1│5 3│5 5│
└───┴───┴───┘

Catalog动词{组合了黑名单列表中原子的项目

┌─────┬─────┐
│1 3 5│1 3 5│
└─────┴─────┘

组成目录,上面两对的3x3表格

然后,我准备一个行/列索引表,用于选择3x3子数组中的每个子数组。

s=.(,&.>/@(<:,],>:)"0)&.>m
┌─────────────┬─────────────┬─────────────┐
│┌─────┬─────┐│┌─────┬─────┐│┌─────┬─────┐│
││0 1 2│0 1 2│││0 1 2│2 3 4│││0 1 2│4 5 6││
│└─────┴─────┘│└─────┴─────┘│└─────┴─────┘│
├─────────────┼─────────────┼─────────────┤
│┌─────┬─────┐│┌─────┬─────┐│┌─────┬─────┐│
││2 3 4│0 1 2│││2 3 4│2 3 4│││2 3 4│4 5 6││
│└─────┴─────┘│└─────┴─────┘│└─────┴─────┘│
├─────────────┼─────────────┼─────────────┤
│┌─────┬─────┐│┌─────┬─────┐│┌─────┬─────┐│
││4 5 6│0 1 2│││4 5 6│2 3 4│││4 5 6│4 5 6││
│└─────┴─────┘│└─────┴─────┘│└─────┴─────┘│
└─────────────┴─────────────┴─────────────┘

对于m数组中的每一对,我制作一对三胞胎,以m对中的每个数字为中心:

        ┌─────┬─────┐
 1 3 -> │0 1 2│2 3 4│
        └─────┴─────┘

这对三元组由J From动词{使用,它可以同时选择多个行和列。0 1 2/2 3 4表示我选择行0、1和2以及列2、3和4,从而选择顶部的第二个3x3子数组。

最后,我可以使用7x7数组和遮罩来完成任务:首先,我使用m作为遮罩将相应的元素设置为0:

0 m}a

然后,我使用s作为选择器来获取所有3x3子数组,并找到它们的总和:

+/^:_"2 s{0 m}a

然后,我将这些数字放回起始数组中。

 (+/^:_"2 s{0 m}a)m}a 
2 8 7 4 4 5 1
4 39 4 39 6 36 9
3 8 3 6 5 3 3
6 44 6 40 7 42 1
7 7 4 4 5 9 9
2 36 6 43 2 46 9
2 2 6 8 8 1 3

在线尝试!



1

红宝石207

我将首先提出我的解决方案(就像往常一样):

a=Array.new(7){Array.new(7){rand(9)+1}}
s=[-1,0,1]
s=s.product s
s.slice!4
r=[1,3,5]
r.product(r).map{|x|u=0
s.map{|y|u+=a[x[0]+y[0]][x[1]+y[1]]}
a[x[0]][x[1]]=u}
puts a.map{|x|x.map{|y|y.to_s.ljust 3}.join

1

Ruby,150个字符

v=(a=0..6).map{a.map{rand(9)+1}}
(o=[1,3,5]).map{|i|o.map{|j|v[i][j]=0
(d=[0,-1,1]).map{|r|d.map{|c|v[i][j]+=v[i+r][j+c]}}}}
puts v.map{|r|"%-3d"*7%r}

如果左对齐要求对齐就是 ljust需要使用好吧,不。我喜欢Ruby的格式化功能。

不要使用Array.new(7){...}(0..6).map{...}既短,更易读您可以免费获得可分配范围。

3号线受到Doorknob解决方案的启发。


1

GolfScript,87个字符

49,{.1&\7/1&!|9rand)*}%.7/{[..1>@0\+]zip{{+}*}%);}:^%zip{^~}%]zip{.0=!=}%{'  '+3<}%7/n*

那里的拉链太多...(请参阅在线

3  9  9  3  3  9  8  
6  46 2  50 3  39 8  
7  3  7  2  4  7  3  
8  33 9  51 8  49 5  
4  3  9  9  3  9  2  
1  45 9  41 6  33 2  
4  3  6  1  6  1  4  

1

J,58/64/67个字符

0j_1":(7$0,:7$0 1){"0 1 |:>v;v-~7 7{.0,.0,3+/\"1]3+/\v=.1+?7 7$9

虽然规范要求数字必须左对齐,但没有要求使用十进制表示法,因此我认为这是有效的输出:

1.0e0 8.0e0 9.0e0 6.0e0 2.0e0 9.0e0 6.0e0
6.0e0 3.9e1 8.0e0 4.0e1 2.0e0 3.8e1 4.0e0
1.0e0 4.0e0 2.0e0 8.0e0 3.0e0 9.0e0 3.0e0
2.0e0 2.4e1 5.0e0 4.1e1 9.0e0 4.7e1 8.0e0
1.0e0 3.0e0 6.0e0 5.0e0 3.0e0 5.0e0 7.0e0
4.0e0 3.0e1 1.0e0 2.3e1 1.0e0 3.1e1 1.0e0
6.0e0 5.0e0 4.0e0 2.0e0 1.0e0 5.0e0 8.0e0

如果可以接受右对齐而不是左对齐,那么我们的字符数58

(7$0,:7$0 1){"0 1 |:>v;v-~7 7{.0,.0,3+/\"1]3+/\v=.1+?7 7$9

J的":(格式)具有三种格式化模式:

  • 右对齐n位数字或收缩包装(默认显示)
  • 左对齐的科学计数法,共有n个数字和m个字符
  • 带有(左/中/右)-(上/中/下)对齐的收缩包装盒装显示器(以下,共69个字符)

根据示例,最冗长但也最通用的也是唯一能够产生输出的是8!:2格式化外部变量,它以格式化字符串作为左参数。另外还有67个字符

'l3.'8!:2(7$0,:7$0 1){"0 1 |:>v;v-~7 7{.0,.0,3+/\"1]3+/\v=.1+?7 7$9

这是盒装格式:

 0 0":<"0(7$0,:7$0 1){"0 1 |:>v;v-~7 7{.0,.0,3+/\"1]3+/\v=.1+?7 7$9

 ┌─┬──┬─┬──┬─┬──┬─┐
 │2│6 │5│7 │5│7 │6│
 ├─┼──┼─┼──┼─┼──┼─┤
 │8│40│4│35│9│49│6│
 ├─┼──┼─┼──┼─┼──┼─┤ 
 │6│7 │2│2 │1│9 │6│
 ├─┼──┼─┼──┼─┼──┼─┤
 │8│41│9│35│3│45│7│
 ├─┼──┼─┼──┼─┼──┼─┤
 │3│1 │5│6 │7│8 │4│
 ├─┼──┼─┼──┼─┼──┼─┤
 │7│37│4│45│6│48│8│
 ├─┼──┼─┼──┼─┼──┼─┤
 │8│4 │5│4 │8│1 │6│
 └─┴──┴─┴──┴─┴──┴─┘

1

Perl,117个字符

print$_,++$j%7?$":$/for map{++$i/7&$i%7&1?
eval join"+",@x[map{$i+$_,$i-$_}1,6,7,8]:" $_"}@x=map{1+int rand 9}$i--..48

这是Perl脚本之一,其中除了一个for循环外,其他所有循环都已折叠到map调用中,以便可以在单个语句中完成所有操作。全局变量在此变量中也有一些重要的外观。我想我想在这里说的是,这个程序有些粗略。

等等,情况变得更糟:脚本中存在一个已知的错误!但是,它被触发的可能性不到一百万分之一,所以我还没有解决它。


不要坚持下去,这是什么错误?

奖励指向第一个发现它的人!
面包盒

1

Mathematica,106/100

在看到之前,我想出了与ssch的代码非常相似的东西。我借用他使用的想法Column。仅使用ASCII,106

s=#-1;;#+1&
a=8~RandomInteger~{7,7}+1
a[[##]]=a[[s@#,s@#2]]~Total~2-a[[##]];&@@@{2,4,6}~Tuples~2
Column/@a

使用Unicode字符(由ssch使用)100

s=#-1;;#+1&
a=8~RandomInteger~{7,7}+1
a〚##〛=a〚s@#,s@#2〛~Total~2-a〚##〛;&@@@{2,4,6}~Tuples~2
Column/@a

1

Excel VBA,74个字节

输出到的VBE立即功能[B2:H9]

[B2:H9]="=IF(ISODD(ROW()*COLUMN()),SUM(A1:C1,A2,C2,A3:C3),INT(RAND()*8)+1)

样本输出

在此处输入图片说明


1

Powershell,149148字节

-1个字节感谢@AdmBorkBork。这个很酷!

$i=-1
($a=(,1*8+0,1*3)*3+,1*7|%{$_*(1+(Random 9))})|?{++$i;!$_}|%{6..8+1|%{$_,-$_}|%{$a[$i]+=$a[$i+$_]}}
-join($a|%{if(!(++$i%7)){"
"};'{0,3}'-f$_})

说明:

$i=-1                       # let $i store -1
($a=                        # let $a is array of random numbers with zero holes
    (,1*8+0,1*3)*3+,1*7|    # the one-dimension array equals
                            # 1 1 1 1 1 1 1
                            # 1 0 1 0 1 0 1
                            # 1 1 1 1 1 1 1
                            # 1 0 1 0 1 0 1
                            # 1 1 1 1 1 1 1
                            # 1 0 1 0 1 0 1
                            # 1 1 1 1 1 1 1
    %{                      # for each element
        $_*(1+(Random 9))   # multiply 0 or 1 element to random digit from 1 to 9
    }                       # now $a stores values like (* is a random digit from 1 to 9)
                            # * * * * * * *
                            # * 0 * 0 * 0 *
                            # * * * * * * *
                            # * 0 * 0 * 0 *
                            # * * * * * * *
                            # * 0 * 0 * 0 *
                            # * * * * * * *
)|?{++$i;!$_                # calc index $i and passthru values == 0 only
}|%{                        # for each zero value cell with index $i
    6..8+1|%{               # offsets for the surrounding cells
                            #  .  .  .
                            #  .  x +1
                            # +6 +7 +8  
        $_,-$_              # add the mirror offsets 
                            # -8 -7 -6
                            # -1  x +1
                            # +6 +7 +8  
    }|%{                    # for each offset 
        $a[$i]+=$a[$i+$_]   # add surrounding values to the cell
    }
}
                            # display the $a
-join(
    $a|%{                   # for each value of $a
        if(!(++$i%7)){"`n"} # line break for each 7 cells
        '{0,3}'-f$_         # formatted value of $a with width = 3 char and align right
    }
)                           # join all values to string

1
您可以通过将您的$a分配封装在括号中并向上移动下一行以($a=(,1*8+0,1*3)*3+,1*7|%{$_*(1+(Random 9))})|?{++$i;!$_}|%{6..8+1|%{$_,-$_}|%{$a[$i]+=$a[$i+$_]}}
换成

不,这不起作用。该数组必须在之前完全填充$a[$i+$_]。所以这是两个步骤。我曾多次尝试将其封装在一个管道中。:)
mazzy

1
如果您未在任务周围放置括号,那将不起作用。使用($a=(,1*8+0,1*3)*3+,1*7|%{$_*(1+(Random 9))})$a在下一个管道实例之前已完全填充。它应该工作(至少对我有用)。
AdmBorkBork

0

数学142 151 172 179

z = (m = RandomInteger[{1, 9}, {7, 7}]; s = SparseArray; o = OddQ; e = EvenQ; i = {1, 1, 1};
(m + ArrayPad[ListCorrelate[{i, i, i}, m] s[{{i_, j_} /; o@i \[And] o@j -> 1}, {5, 5}], 1]
- 2 m s[{{i_, j_} /; e@i \[And] e@j -> 1}, {7, 7}]) // Grid)

用法

z

m8


你有0S; 规则说1-9
门把手

谢谢。我更正了数据和图片。功能保持不变。
DavidC

此外,数字未按问题中指定的对齐。
门把手

Mathematica的冗长(或更准确地说,坚持使用大词)变得显而易见。
DavidC

0

朱莉娅 0.6,127(89)字节

x=rand(1:9,7,7);[x[i,j]=sum(!(0==k==l)*x[i+k,j+l]for k=-1:1,l=-1:1)for i=2:2:7,j=2:2:7]
Base.showarray(STDOUT,x,1<1;header=1<1)

在线尝试!

使用本机显示的89个字节,如果可以打印其他行,则可以接受:

7×7 Array{Int64,2}:
6   6  8   2  3   2  3
7  44  5  33  4  23  5
3   8  1   9  1   3  2
4  41  2  37  5  22  2
7   8  8   8  3   4  2
9  53  6  44  7  36  3
7   7  1   9  2   6  9

0

爪哇10,262个 260 248 239字节

v->{int a[][]=new int[7][7],i=49,j,k;for(;i-->0;)a[i/7][i%7]+=Math.random()*9+1;var r="";for(;++i<7;r+="\n")for(j=0;j<7;r+=(k=a[i][j])>9|j++%2<1?k+" ":k+"  ")if(i*j%2>0)for(a[i][j]=k=0;k<9;k++)a[i][j]+=k!=4?a[i+k/3-1][j+k%3-1]:0;return r;}

-12个字节感谢@ceilingcat

说明:

在这里尝试。

v->{                        // Method with empty unused parameter and String return-type
  int a[][]=new int[7][7],  //  Integer-matrix with 7x7 zeroes
      i=49,j,k;             //  Index integers (`i` starting at 49)
  for(;i-->0;)              //  Loop `i` in the range (49, 0]:
    a[i/7][j%7]+=Math.random()*9+1;
                            //   Fill the current cell with a random 1..9 integer
  var r="";                 //  Result-String, starting empty
  for(;++i<7;               //  Loop `i` in the range [0, 7):
      r+="\n")              //    After every iteration: append a new-line to the result
    for(j=0;j<7;            //   Inner loop `j` in the range [0, 7):
        r+=                 //     After every iteration: append the result-String with:
           (k=a[i][j])>9    //      If the current number has 2 digits,
           |j++%2<1?        //      or it's an even column (indices 0/2/4/6)
            k+" "           //       Append the current number appended with one space
           :                //      Else:
            k+"  ")         //       Append the current number appended with two spaces
      if(i*j%2>1)           //    If both indexes `i` and `j` are odd
        for(a[i][j]=k=0;    //     Reset both the current item and index `k` to 0
            k<9;k++)        //     Inner loop `k` in the range [0, 9):
          a[i][j]+=         //      Sum the item at location `i,j` with:
           k!=4?            //       If `k` is not 4 (the current item itself)
            a[i+k/3-1][j+k%3-1]
                            //        Sum it with the numbers surrounding it
           :                //       Else:
            0;              //        Leave it the same by adding 0
  return r;}                //  Return the result-String

@ceilingcat谢谢!我已经能够节省几个字节,var而不是String+=Math.random()*9+1;代替=(int)(Math.random()*9+1);。访问我所有的旧答案实际上对您很有用,哈哈!:D
凯文·克鲁伊森
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.