嵌套循环Ruby

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

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

  • 第一轮,你改变每一块鹅卵石(将它们全部涂成白色)。
  • 第二轮,你改变所有其他鹅卵石(你画鹅卵石#2,4,6,8,10黑色)。
  • 第3轮,你改变鹅卵石#3,6,9。
  • 第4轮你改变鹅卵石#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 

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

 element % round == 0 

它应该是:

 (index+1) % round 

你想比较鹅卵石的指数而不是卵石的当前值。 同样,您需要记住索引是从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"] 

因为这是关于嵌套循环的,我只是想补充一点,你不一定要遍历每一轮的所有鹅卵石。 (这是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} 

您的代码中存在一些问题。

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

  • 您修改数组pebble_color而不是pebble_colors

修复这两个问题,程序为pebble_colors留下了值

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

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

你有三个arrays,其中一个将做。 你需要的只是十种颜色的数组,从黑色开始。 我会像这样编码

 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] 

为了简化问题,我认为在更新卵石之前更好地计算所有圆形倍数。

 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}"