Skip to content

Instantly share code, notes, and snippets.

@dissolved
Created September 30, 2013 01:50
Show Gist options
  • Save dissolved/6758413 to your computer and use it in GitHub Desktop.
Save dissolved/6758413 to your computer and use it in GitHub Desktop.
Our solution to the following challenge: Conway's Game of Life without saving state and without using iteration (or anything provided by Enumerable). Also included is a shorter solution which does use Enumerable.
class NilClass
def [](index) end
end
class Array
def [](index)
(index < 0) ? nil : at(index)
end
end
class World
ADJACENT_OFFSETS = {
:northwest => [-1, 1], :north => [0, 1], :northeast => [1,1],
:west => [-1, 0], :east => [1,0],
:southwest => [-1, -1], :south => [0, -1], :southeast => [1,-1]
}
def self.next_world(current, x = 0, y = 0)
alive_neighbors = count_neighbors(current, x, y)
if x < current.length - 1
next_world(current, x + 1, y)
elsif y < current[x].length - 1
next_world(current, 0, y + 1)
end
current[x][y] = current[x][y] ? [2,3].include?(alive_neighbors) : alive_neighbors == 3
current
end
def self.count_neighbors(world, x, y)
ADJACENT_OFFSETS.values.inject(0) do |sum, offset|
sum + ( world[x + offset[0]][y + offset[1]] ? 1 : 0)
end
end
end
class NilClass
def [](index) end
end
class Array
def [](index)
(index < 0) ? nil : at(index)
end
end
class World
def self.next_world(current, x = 0, y = 0)
alive_neighbors = neighbors(current, x, y)
if x < current.length - 1
next_world(current, x + 1, y)
elsif y < current[x].length - 1
next_world(current, 0, y + 1)
end
current[x][y] = calculate_state(current[x][y], alive_neighbors)
current
end
def self.neighbors(world, x, y)
alive_neighbors = 0
alive_neighbors += 1 if world[x-1][y-1]
alive_neighbors += 1 if world[x-1][y]
alive_neighbors += 1 if world[x-1][y+1]
alive_neighbors += 1 if world[x][y-1]
alive_neighbors += 1 if world[x][y+1]
alive_neighbors += 1 if world[x+1][y-1]
alive_neighbors += 1 if world[x+1][y]
alive_neighbors += 1 if world[x+1][y+1]
alive_neighbors
end
def self.calculate_state(alive, alive_neighbors)
if alive
alive_neighbors == 2 or alive_neighbors == 3
else
alive_neighbors == 3
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment