Brainteaser Locker是打开还是关闭?在Ruby中

时间:2013-04-02 20:27:25

标签: ruby

尝试编写经典的脑力激荡锁定器问题(打开/关闭100个储物柜的问题)。当我运行我编写的代码时,它没有给我10个开放式储物柜的正确答案,而是说所有储物柜都关闭了。我想我的循环中缺少一些东西......有什么建议吗?感谢。

 def lockerproblem
      j = 0
      lockers = []

      while j < 100
       lockers << "open"
       j += 1
      end 

       a = 1
       i = 0

       while a <= 100
       while i < 100
        if ( i + 1 ) % a == 0
          if lockers[i] == "open"
            lockers[i] = "closed"
          else
            lockers[i] = "open"
          end
        end
        i += 1
      end
      a += 1
    end

    lockers[3] = "open"

    lockers.each do |text|
      puts text
    end
  end

  lockerproblem

2 个答案:

答案 0 :(得分:0)

考虑这个用于数组初始化:

lockers = ["open"] * 100

考虑一下你的i变量:何时设置为0?这对内循环意味着什么?如,

a, b = 0, 0
while a < 2
  while b < 2
    puts "a=#{a}, b=#{b}"
    b += 1
  end
  a += 1
end

输出:

a=0, b=0
a=0, b=1

换句话说,你看:

a=0, b=0
a=0, b=1
a=1, b=0
a=1, b=1

为什么呢?因为b递增到2,所以永远不会重置,内循环只执行一次。也许您将i的初始值设置在错误的位置,其中“错误”表示“在外部循环之外”。

最后,打开第四个储物柜(locker[3])会甩掉结果。

有许多小的调整可以使代码更容易理解(我甚至可以在String上为这个小例子定义一个open?方法),但这应该足够了得到你期望的答案。


这种猴子修补并不总是一个好主意,特别是在Ruby内部。但它允许一些简单而漂亮的东西:

> lockers.find_all(&:closed?).size
=> 10

答案 1 :(得分:0)

您可以通过三次更改获得正确的答案:

  • i需要在a的每次迭代开始时重置为0
  • 储物柜应以closed
  • 开头
  • 删除额外的lockers[3] = "open"

更新的代码:

def lockerproblem
    j = 0
    lockers = []

    while j < 100
        lockers << "closed"
        j += 1
    end

    a = 1
    i = 0

    while a <= 100
        i = 0
        while i < 100
            if ( i + 1 ) % a == 0

              if lockers[i] == "open"

                lockers[i] = "closed"
              else

                lockers[i] = "open"
              end
            end
            i += 1
        end
        a += 1
    end

    lockers.each do |text|
        puts text
    end
end

lockerproblem