Недислав обнови решението на 19.12.2011 17:21 (преди около 13 години)
+require 'set'
+
+module GameOfLife
+
+ class Board
+ include Enumerable
+ attr_accessor :cells
+
+ def initialize(*args)
+ @cells = args.map do |x|
+ if x.is_a? Cell
+ x
+ else
+ Cell.new(*x)
+ end
+ end
+ end
+
+ def each
+ cells.each do |x|
+ yield [x.x, x.y]
+ end
+ end
+
+ def [](x,y)
+ cells.include? Cell.new(x, y)
+ end
+
+ def next_generation
+ cell_next_gen
+ out = Board.new(*cell_next_gen)
+ end
+
+ def cell_next_gen
+ output = cells.inject([]) do |new_cells, cell|
+ new_cells | cell.next_gen_live(cells) | cell.next_gen_reproduction(cells)
+ end
+ end
+ end
+
+ class Cell
+ attr_accessor :x,:y
+ Displacements = [[0, 1], [0, -1], [1, 0], [-1, 0],
+ [1, 1], [-1, -1], [1, -1], [-1, 1]]
+
+ def initialize(x, y)
+ @x = x
+ @y = y
+ end
+
+ def ==(other)
+ x == other.x && y == other.y
+ end
+
+ def displace(dx, dy)
+ Cell.new(x + dx, y + dy)
+ end
+
+ def adjancent_cells
+ Displacements.map { |x, y| displace x, y }
+ end
+
+ def next_gen_live(cells)
+ if [2,3].include? live_adjancent(cells)
+ [self]
+ else
+ []
+ end
+ end
+
+ def next_gen_reproduction(cells)
+ adjancent_cells.select { |cell| cell.live_adjancent(cells) == 3}
+ end
+
+ def live_adjancent(cells)
+ adjancent_cells.count { |c| cells.include? c }
+ end
+
+ def eql?(other)
+ self == other
+ end
+
+ def hash
+ [x, y].hash
+ end
+
+ def inspect
+ "Cell at: [#{x}, #{y}]"
+ end
+ end
+end