“grains of wheat on a chessboard” in Ruby
There are 64 squares on a chessboard. Every square has the double that
the one before. Write a program that shows:
- how many grains were on each square, and
- the total number of grains
号
我的代码在第一部分工作,但是我在声明总数时遇到了问题。缺少一些基本类/方法声明。谢谢你的帮助。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class Grains def square(n) array_of_grains = [] (0..63).each {|x| array_of_grains << 2**x} n = n-1 array_of_grains[n] end def total array_of_grains.each {|x| sum += x } end end |
这里有很多问题。
首先,
其次,您的
第三,每次调用方法
您的方法应该如下所示:
1 2 3 4 5 6 7 8 | def square(n) @array_of_grains ||= (0..63).map {|x| 2 ** x } @array_of_grains[n - 1] end def total @array_of_grains.inject(&:+) end |
您可以通过在方法上面简单地添加一个
这里有一个元答案,结合了这里所有的好主意(周围都是赞成票!)使用您的类生成完整的解决方案。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | class Grains attr_accessor :array_of_grains def initialize(n = 1) @array_of_grains = 63.times.with_object([n]) { |i,a| a << 2 * a.last } end def square(n) array_of_grains[n - 1] end def total array_of_grains.reduce(:+) end end |
。
用途:
1 2 3 | board = Grains.new board.square(3) #=> 4 board.total #=> 18446744073709551615 |
。
这是写它的一种方法:
1 2 3 4 5 | square = 63.times.with_object([1]) { |i,a| a << 2 * a.last } #=> [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, # 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, #... # 2305843009213693952, 4611686018427387904, 9223372036854775808] |
。
为了确定总数(我最初在问题中忽略了这一点):
1 2 3 4 5 6 7 | total, square = 63.times.reduce([0,[1]]) do |(t,a),_| v = 2 * a.last [t + v, a << v] end total #=> 18446744073709551614 square #=> (as above) |
1 2 | @square_of_sums = (n * (n + 1) / 2)**2 @number_of_squares = n * (n + 1) * (2 * n + 1) / 6 |
这仍然需要时间,但这是你想要做的事情的数学。
如果希望
您还可以使用Ruby的访问器:
1 2 3 | attr_accessor array_of_grains # getter and setter attr_reader array_of_grains # getter attr_writer array_of_grains # setter |
号
在这种情况下,您可以:
1 2 3 4 5 6 7 8 9 10 11 12 13 | class Grains attr_accessor :array_of_grains def set_grains(array) self.array_of_grains = array end def total return self.array_of_grains.count end end |