0

难以理解这个嵌套循环问题:

你有 10 颗鹅卵石(编号为 1-10)。它们默认为黑色。如果它们是黑色的,您必须通过将它们涂成白色或如果它们是白色的将它们涂成黑色来改变它们。有10轮。每一轮,你必须改变当前轮数倍数的鹅卵石。鹅卵石默认为黑色。

  • 第一轮,你改变每一块鹅卵石(把它们涂成白色)。
  • 第二轮,你改变所有其他的鹅卵石(你把#2、4、6、8、10的鹅卵石涂成黑色)。
  • 第三轮,你改变卵石#3,6,9。
  • 第四轮你改变卵石#4,8。
  • ...
  • ...
  • 第 10 轮,你改变了 10 号卵石。

第 10 轮之后,哪些鹅卵石涂黑,哪些鹅卵石涂白?

下面是我没有运行的解决方案(我尝试通过制作一个数字数组(变成字符串)来做到这一点,如果涂成白色则添加“w”,如果涂成黑色则删除“w”。

(我已经尝试对其进行编辑以使其运行,但是我是嵌套循环的新手,我只是没有掌握这个概念)。如果有人可以向我解释我做错了什么并提供更好的解决方案,我将不胜感激。

pebbles = (1..10).map {|element| element.to_s}
pebble_colors = (1..10).map {|element| element.to_s}

(1..10).each do |round|
  pebbles_to_paint = []
  pebbles.each_with_index {|element, index| pebbles_to_paint << index if element % round == 0}
  pebbles_to_paint.each do |pebble_number|
    if pebble_color[pebble_number].include?("w")
      pebble_color[pebble_number].delete!("w")
    else
      pebble_color[pebble_number] << "w"
    end
  end
end
4

4 回答 4

2

因为这是关于嵌套循环的,所以我只想补充一点,您不必在每一轮中遍历所有鹅卵石。(即 10 个鹅卵石的 100 次迭代!)

相反,您可以使用Range#step迭代每个第 n 个元素,从轮的索引开始:

(1..10).each { |r|
  print "%2d:" % r
  (r..10).step(r) { |i|
    print " #{i}"
  }
  puts
}

产生:

 1: 1 2 3 4 5 6 7 8 9 10
 2: 2 4 6 8 10
 3: 3 6 9
 4: 4 8
 5: 5 10
 6: 6
 7: 7
 8: 8
 9: 9
10: 10

这只是 27 次迭代。一个很好的副作用是您不必再计算余数。

完整示例:

pebbles = Hash[(1..10).map{|i| [i, :black]}]
toggle = {:black => :white, :white => :black}

(1..10).each { |r|
  (r..10).step(r) { |i|
    pebbles[i] = toggle[pebbles[i]]
  }
}
p pebbles
#=> {1=>:white, 2=>:black, 3=>:black, 4=>:white, 5=>:black, 6=>:black, 7=>:black, 8=>:black, 9=>:white, 10=>:black}
于 2013-06-13T19:08:18.967 回答
1

您的主要问题似乎在于决定要绘制哪些鹅卵石。以下是不正确的:

element % round == 0

它应该是:

(index+1) % round

您想要比较 pebble 的索引而不是 pebble 的当前值。同样,您需要记住索引是从 0 开始的(即它们从 0 开始计数)。您需要使索引基于 1(因此添加 1),否则第一个元素将始终更改,而其他元素将关闭 1。

还有一个错字pebble_color,应该是pebble_colors

您绝对可以重新考虑代码以使其更短,但以下似乎可行(仅进行上述最小更改):

pebbles = (1..10).map {|element| element.to_s}
pebble_colors = (1..10).map {|element| element.to_s}

(1..10).each do |round|
  pebbles_to_paint = []
  pebbles.each_with_index {|element, index| pebbles_to_paint << index if (index+1) % round == 0}
  pebbles_to_paint.each do |pebble_number|
    if pebble_colors[pebble_number].include?("w")
      pebble_colors[pebble_number].delete!("w")
    else
      pebble_colors[pebble_number] << "w"
    end
  end
  p pebble_colors
end

输出是:

["1w", "2w", "3w", "4w", "5w", "6w", "7w", "8w", "9w", "10w"]
["1w", "2", "3w", "4", "5w", "6", "7w", "8", "9w", "10"]
["1w", "2", "3", "4", "5w", "6w", "7w", "8", "9", "10"]
["1w", "2", "3", "4w", "5w", "6w", "7w", "8w", "9", "10"]
["1w", "2", "3", "4w", "5", "6w", "7w", "8w", "9", "10w"]
["1w", "2", "3", "4w", "5", "6", "7w", "8w", "9", "10w"]
["1w", "2", "3", "4w", "5", "6", "7", "8w", "9", "10w"]
["1w", "2", "3", "4w", "5", "6", "7", "8", "9", "10w"]
["1w", "2", "3", "4w", "5", "6", "7", "8", "9w", "10w"]
["1w", "2", "3", "4w", "5", "6", "7", "8", "9w", "10"]
于 2013-06-13T17:06:48.907 回答
1

您的代码中有几个问题。

  • 您使用element % round而不是(index + 1) % round

  • 您修改数组pebble_color而不是pebble_colors

解决了这两个问题,程序pebble_colors带着值离开

["1w", "2", "3", "4w", "5", "6", "7", "8", "9w", "10"]

虽然我认为这不是你的想法!

你有三个数组可以做一个。您所需要的只是一组十种颜色,从全黑开始。我会这样编码

pebbles = Array.new(10, :black)

(1..10).each do |round|
  pebbles.each_with_index do |pebble, i|
    if (i + 1).remainder(round) == 0
      pebbles[i] = pebble == :black ? :white : :black
    end
  end
end

p pebbles

输出

[:white, :black, :black, :white, :black, :black, :black, :black, :white, :black]
于 2013-06-13T17:16:08.780 回答
-1

为了使问题简单化,我认为最好在更新卵石之前计算所有整数倍数。

pebbles = Array.new(10)  

10.times do |i|
  # calculate all multiples for each index
  multiples = Array(1..10).select {|j| j % (i + 1) == 0}

  # observer that we must have to sub 1 since Ruby use 0 indexed arrays
  multiples.map! {|j| j - 1}

  # update each pebble
  multiples.each do |j|
    pebbles[j] = pebbles[j] == 'b' ? 'w' : 'b'
  end
end

puts "Black pebbles: #{pebbles.select {|p| p == 'b'}.size}"
于 2013-06-13T16:30:04.413 回答