改变迭代的频率

时间:2015-01-13 21:27:07

标签: ruby loops

我正在尝试解决一个挑战,我有100个空盒子,每次你触摸一个空盒子,你应该填充它,每次你触摸一个填充的盒子,你必须清空它。这些盒子都是空的。

你应该首先触摸每个盒子,然后是每隔一个盒子,然后每隔3个盒子,然后每隔4个盒子,直到你每100个盒子都触摸一次。

我正在尝试创建一个象征这个的程序。我这样做是通过创建一个盒子哈希,然后做一个双while循环,一旦我有哈希,我想按照指示迭代。但是我的输出是:

{1=>"1", 2=>"1", 3=>"1", 4=>"1", 5=>"1", 6=>"1", 7=>"1", 8=>"1", 9=>"1", 10=>"1", 11=>"1", 12=>"1", 13=>"1", 14=>"1", 15
=>"1", 16=>"1", 17=>"1", 18=>"1", 19=>"1", 20=>"1", 21=>"1", 22=>"1", 23=>"1", 24=>"1", 25=>"1", 26=>"1", 27=>"1", 28=>"
1", 29=>"1", 30=>"1", 31=>"1", 32=>"1", 33=>"1", 34=>"1", 35=>"1", 36=>"1", 37=>"1", 38=>"1", 39=>"1", 40=>"1", 41=>"1",
 42=>"1", 43=>"1", 44=>"1", 45=>"1", 46=>"1", 47=>"1", 48=>"1", 49=>"1", 50=>"1", 51=>"1", 52=>"1", 53=>"1", 54=>"1", 55
=>"1", 56=>"1", 57=>"1", 58=>"1", 59=>"1", 60=>"1", 61=>"1", 62=>"1", 63=>"1", 64=>"1", 65=>"1", 66=>"1", 67=>"1", 68=>"
1", 69=>"1", 70=>"1", 71=>"1", 72=>"1", 73=>"1", 74=>"1", 75=>"1", 76=>"1", 77=>"1", 78=>"1", 79=>"1", 80=>"1", 81=>"1",
 82=>"1", 83=>"1", 84=>"1", 85=>"1", 86=>"1", 87=>"1", 88=>"1", 89=>"1", 90=>"1", 91=>"1", 92=>"1", 93=>"1", 94=>"1", 95
=>"1", 96=>"1", 97=>"1", 98=>"1", 99=>"1", 100=>"1"}

这似乎不对,因为有些盒子应该是满的(e.i = 1)而有些盒子应该是空的(e.i = 0)但是我的结果显示它们都是满的......我做错了什么?

这是我的代码,提前感谢:

number_setter = 1

boxes = {}

while number_setter <= 100 do
  boxes[number_setter] = '0'
  number_setter += 1
end

iteration_setter = 1
increaser = 1

while increaser <= 100 do   
  while iteration_setter <= 100 do
    if boxes[iteration_setter] == '0'
      boxes[iteration_setter] = '1'
    elsif boxes[iteration_setter] == '1'
      boxes[iteration_setter] = '0'
    else
      puts "something is not right on #{iteration_setter} hash key"
    end 
    iteration_setter += increaser
  end
  increaser += 1
end

puts boxes

2 个答案:

答案 0 :(得分:1)

嗯,首先,你永远不会重新开始iteration_setter,所以它永远只是101 ......

iteration_setter = 1移到while iteration_setter <= 100 do之前的那一行应该可以解决问题。

答案 1 :(得分:0)

我假设你不是在寻找一个数学解决方案(方框i是空的还是最后填充的,可以表示为i的函数)。

Ruby有许多方法可以在这里提供帮助。一个是Array#cycle,它返回一个枚举器:

state = [:empty, :filled]
touch = state.cycle
  #=> #<Enumerator: [:empty, :filled]:cycle>

允许我们写:

touch.next #=> :empty
touch.next #=> :filled
touch.next #=> :empty

而不是笨拙的东西

touch = (touch==:empty) ? :filled : :empty

我们首先要创建一个盒子数组,每个盒子的值都是这个枚举器:

nboxes = 20
boxes = Array.new(nboxes) { [:empty, :filled].cycle }

另一个有用的方法是Range#step,允许我们写:

npasses = 100
(1..npasses).each { |n| (0...nboxes).step(n).each { |i| boxes[i].next } }

然后我们可以检查每个盒子的状态:

boxes.map(&:next)

您可能已经注意到,第一次触摸某个框时,它的状态设置为:empty,这是不正确的。但是,检索最终状态的上一行应用.next,这将获得&#34; next&#34;状态,在开始时纠正错误(因为有两种状态)。

把它们放在一起:

def touch_boxes(nboxes, npasses=100)
  boxes = Array.new(nboxes) { [:empty, :filled].cycle }
  (1..npasses).each { |n| (0...nboxes).step(n).each { |i| boxes[i].next } }
  boxes.map(&:next)
end

touch_boxes(20, npasses=1)
  #=> [:filled, :filled, :filled, :filled, :filled,
  #    :filled, :filled, :filled, :filled, :filled,
  #    :filled, :filled, :filled, :filled, :filled,
  #    :filled, :filled, :filled, :filled, :filled] 
touch_boxes(20, npasses=2)
  #=> [:empty,  :filled, :empty,  :filled, :empty,
  #    :filled, :empty,  :filled, :empty,  :filled, 
  #    :empty,  :filled, :empty,  :filled, :empty,
  #    :filled, :empty,  :filled, :empty,  :filled] 
touch_boxes(20, npasses=3)
  #=> [:filled, :filled, :empty,  :empty,  :empty,
  #    :filled, :filled, :filled, :empty,  :empty,
  #    :empty,  :filled, :filled, :filled, :empty,
  #    :empty,  :empty,  :filled, :filled, :filled] 
touch_boxes(20, npasses=20)
  #=> [:empty,  :filled, :empty,  :empty,  :filled,
  #    :empty,  :empty,  :empty,  :empty,  :filled,
  #    :empty,  :empty,  :empty,  :empty,  :empty,
  #    :empty,  :filled, :empty,  :empty,  :empty]