Ростислав обнови решението на 20.12.2011 18:48 (преди около 13 години)
+require 'matrix'
+
+module GameOfLife
+ class Board
+ include Enumerable
+ attr_accessor :board
+
+ def initialize(*array_of_cells)
+ @board = array_of_cells
+ end
+
+ def each
+ 0.step(@board.size-1, 1) { |iter| yield @board[iter] }
+ end
+
+ def [](i, j)
+ @board.include?([i, j])
+ end
+
+ def count
+ @board.size
+ end
+
+ def to_matrix
+ matrix = Matrix.build(max_rows, max_columns) { |i, j| 0 }
+ @board.each { |array| matrix[array[0], array[1]] = 1 }
+ matrix
+ end
+
+ def next_generation
+ self.to_matrix.next_gen(self.to_matrix.clone).to_board
+ end
+
+ private
+ def max_rows
+ max = 0
+ @board.each { |x| max = x[0] if x[0] > max }
+ max + 2
+ end
+
+ def max_columns
+ max = 0
+ @board.each { |x| max = x[1] if x[1] > max }
+ max + 2
+ end
+ end
+end
+
+class Matrix
+ include GameOfLife
+
+ def []=(i, j, x)
+ @rows[i][j] = x
+ end
+
+ def next_gen(matrix)
+ self.each_with_index do |value, row, col|
+ matrix[row, col] = 0 if value == 1 && (neighbours(row, col) < 2 || neighbours(row, col) > 3)
+ matrix[row, col] = 1 if value == 0 && neighbours(row, col) == 3
+ end
+ matrix
+ end
+
+ def to_board
+ array = []
+ self.each_with_index do |value, row, col|
+ array << [row, col] if value == 1
+ end
+ board = Board.new(*array)
+ end
+
+ private
+ def upper_neighbours(i, j, sum)
+ sum += @rows[i-1][j-1] if i > 0 && j > 0
+ sum += @rows[i-1][j] if i > 0
+ sum += @rows[i-1][j+1] if i > 0 && j < self.column_size-1
+ sum
+ end
+
+ def side_neighbours(i, j, sum)
+ sum += @rows[i][j-1] if j > 0
+ sum += @rows[i][j+1] if j < self.column_size - 1
+ sum
+ end
+
+ def bottom_neighbours(i, j, sum)
+ sum += @rows[i+1][j-1] if i < self.row_size - 1 && j > 0
+ sum += @rows[i+1][j] if i < self.row_size - 1
+ sum += @rows[i+1][j+1] if i < self.row_size - 1 && j < self.column_size - 1
+ sum
+ end
+
+ def neighbours(i, j)
+ upper_neighbours(i, j, 0) + side_neighbours(i, j, 0) + bottom_neighbours(i, j, 0)
+ end
+end