Ruby将1d数组转换为2d内联

时间:2017-01-09 00:10:48

标签: arrays ruby

在Eul​​er项目中解决第11个问题,我对输入感到困惑。

“08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65 52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91 22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80 24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50 32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70 67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21 24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72 21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95 78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92 16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57 86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58 19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40 04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66 88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69 04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36 20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16 20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54 01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48“

我需要将这个1d数组转换为2d数组(20×20)。我该如何内联?

3 个答案:

答案 0 :(得分:1)

只需复制Project Euler字符串并在引号,换行符和所有字符串之间移过它:

str = ""

首先我们需要数组中的行。这很简单:

ar = str.lines

现在我们有一个包含20个字符串的数组;一些工作要做。使用以下内容调整上一行:

ar = str.lines.map{|line| line.split}

这导致包含20个数组的数组,所有数组都包含20个字符串。不想要字符串,想要整数。所以再次调整:

ar = str.lines.map{|line| line.split.map{|str| str.to_i }}

答案 1 :(得分:1)

通过拆分空格,将字符串转换为25个元素的数组a,然后将a转换为5个元素的数组b,其元素是5元素数组,例如b[i][j] = a[5*i+j] 1

假设 2

str = 
"08 02 22 97 38 15 00 40 00
75 04 05 07 78 52 12 50 77 91 08
49 49 99 40 17"

然后

arr = str.split
  #=> ["08", "02", "22", "97", "38", "15", "00", "40", "00", "75", "04", "05", "07",
  #    "78", "52", "12", "50", "77", "91", "08", "49", "49", "99", "40", "17"]
arr.size
  #=> 25

arr.each_slice(5).to_a
  #=> [["08", "02", "22", "97", "38"],
  #    ["15", "00", "40", "00", "75"],
  #    ["04", "05", "07", "78", "52"],
  #    ["12", "50", "77", "91", "08"],
  #    ["49", "49", "99", "40", "17"]]

如果你想要整数值,

arr.map(&:to_i).each_slice(5).to_a
  #=> [[ 8,  2, 22, 97, 38],
  #    [15,  0, 40,  0, 75],
  #    [ 4,  5,  7, 78, 52],
  #    [12, 50, 77, 91,  8],
  #    [49, 49, 99, 40, 17]] 

将这些放在一起,我们可以替换变量arr并写:

str.split.map(&:to_i).each_slice(5).to_a

请参阅String#splitString#to_iEnumerable#each_sliceEnumerable#to_a以及whitespace的定义。

1。在Ruby-speak中,"一个由5个元素组成的数组,每个元素都是一个5元素的数组"可能被称为" 5x5阵列"在其他一些语言中。但是,我们可以参考" 5x5矩阵。见Matrix

2。我采用了提问者对字符串的表示,该字符串只有13行不同长度。请参阅我对@ steenslag的回答

的评论

答案 2 :(得分:0)

这是Project Euler#11的解决方案。问题是确定20×20网格中相同方向(上,下,左,右或对角)的四个相邻数字的最大乘积。

我将使用四个辅助方法,说明每个方法的行为

arr = [[ 1,  2,  3, 4,],
       [12, 13, 14, 5,],
       [11, 16, 15, 6,],
       [10,  9,  8, 7,]]

以及产品最大化的元素数量

n = 3

def max_product_in_vector(v, n)
  v.each_cons(n).map { |a| a.reduce(:*) }.max
end

max_product_in_vector(arr[0], n)
  #=> 24 (2x3x4)

def max_product_in_array(a, n)
  a.map { |row| max_product_in_vector(row, n) }.max
end

max_product_in_array(arr, n)           # rows
  #=> 2640 (11*16*15)

max_product_in_array(arr.transpose, n) # columns
  #=> 1872 (13*16*9)

def off_diagonals(arr, n)
  indices = arr.each_index.to_a
  indices.product(indices).
          group_by { |i,j| i+j }.
          values.
          reject { |a| a.size < n }.
          map { |a| a.map { |i,j| arr[i][j] } }
end

off_diagonals(arr, n)
  #=> [[3, 13, 11], [4, 14, 16, 10], [5, 15, 9]]

max_product_in_array(off_diagonals(arr, n), n)
  #=> 2240 (14*16*10)

def rotate_anticlockwise(arr)
  arr.map(&:reverse).transpose
end

r = rotate_anticlockwise(arr)
  #=> [[4, 5, 6, 7],
  #    [3, 14, 15, 8],
  #    [2, 13, 16, 9],
  #    [1, 12, 11, 10]] 

off_diagonals(r, n)
  #=> [[6, 14, 2], [7, 15, 13, 1], [8, 16, 12]] 

max_product_in_array(off_diagonals(r, n), n)
  #=> 1536 (7*15*13)

我们得到了

str = 
"08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
 49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
 81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
 52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
 22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
 24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
 32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
 67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21
 24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
 21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
 78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
 16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
 86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
 19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
 04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
 88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
 04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
 20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
 20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
 01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48"

行,列,对角线和非对角线中四个连续元素的最大乘积如下:

n = 4
arr = str.split.map(&:to_i).each_slice(20).to_a
  #=> [[ 8,  2, 22,..., 91,  8],
  #    [49, 49, 99,..., 62,  0],
  # ...
  #    [ 1, 70, 54,..., 67, 48]]

[max_product_in_array(arr, n),                                       # rows
 max_product_in_array(arr.transpose, n),                             # columns
 max_product_in_array(off_diagonals(rotate_anticlockwise(arr),n),n), # diagonals
 max_product_in_array(off_diagonals(arr,n),n)                        # off-diagonals
].max  
   #=> 70600674 (89*94*97*87, on off-diagonal, arr[12][6] to arr[15][3]

最后没有.max,上面的表达式返回

[48477312, # rows
 51267216, # columns
 40304286, # diagonals
 70600674] # off-diagonals