Skip to content

Instantly share code, notes, and snippets.

@rmela
Last active September 5, 2019 23:07
Show Gist options
  • Save rmela/8de162aed6401dd3aba396d45bb3c146 to your computer and use it in GitHub Desktop.
Save rmela/8de162aed6401dd3aba396d45bb3c146 to your computer and use it in GitHub Desktop.
Game of life. Interview coding challenge. Didn't finish in the hour allotted. Solved it later anyway.
def inrange( maxx, maxy ):
def func( point ):
x,y = point
return x >= 0 and x <= maxx and y >= 0 and y <= maxy
return func
class Game:
def __init__(self):
self.board = [
[0,1,0],
[0,1,0],
[0,1,0]
]
self.inrange = inrange( 2, 2 )
def neighbors(self, i, j ):
cnt = 0
adjacent = (
(i-1, j), # left,
(i+1, j), # right,
(i , j+1), # above
(i , j-1), # below
(i-1, j-1), # above left
(i-1, j+1), # above right
(i+1, j-1), # below left
(i+1, j+1) # below right
)
adjacent = list( filter( self.inrange, adjacent ) )
for cell in adjacent:
x,y = cell
cnt = cnt + self.board[x][y]
return cnt
def tick(self):
for update in self.updates():
self.board[ update[0] ][ update[1]] = update[2]
def updates(self):
rv = []
for i in range(3):
for j in range(3):
alive = self.board[i][j]
neighbors = self.neighbors(i,j)
if not alive and neighbors == 3:
rv.append( (i,j,1) )
elif alive and neighbors > 3 or neighbors < 2:
rv.append( ( i, j, 0 ) )
return rv
def __str__(self):
rv = []
for i in range(3):
for j in range(3):
rv.append( str(self.board[i][j]) )
rv.append("\n")
return "".join( rv )
game = Game()
print(game)
game.tick()
print( game )
game.tick()
print( game )
def inrange( maxx, maxy ):
def func( point ):
x,y = point
return x >= 0 and x <= maxx and y >= 0 and y <= maxy
return func
class Game:
def __init__(self, verbose = 1):
self.board = [
[0,1,0],
[0,1,0],
[0,1,0]
]
# For debug output
self.verbose = verbose
self.ticks = 0
self.inrange = inrange( 2, 2 )
def neighbors(self, i, j ):
cnt = 0
adjacent = (
(i-1, j), # left,
(i+1, j), # right,
(i , j+1), # above
(i , j-1), # below
(i-1, j-1), # above left
(i-1, j+1), # above right
(i+1, j-1), # below left
(i+1, j+1) # below right
)
adjacent = list( filter( self.inrange, adjacent ) )
#print( adjacent )
for cell in adjacent:
x,y = cell
cnt = cnt + self.board[x][y]
return cnt
def tick(self):
self.ticks += 1
for update in self.updates():
self.board[ update[0] ][ update[1]] = update[2]
def updates(self):
"""
This can be reduced to 10 lines
* remove debug statements
* remove conditions which result in no updates
"""
rv = []
for i in range(3):
for j in range(3):
alive = self.board[i][j]
neighbors = self.neighbors(i,j)
self.debug(
"\n",
"I'm", i, j, "and",
alive and "alive" or "dead",
"and have", neighbors, "live neighbors", end=''
)
# Condition 1: Stay alive. Cell is alive, has 2 or 3 live neighbors.
if alive and neighbors in (2,3):
self.debug( ' so I remain alive', neighbors )
# Condition 2: Regenerate. Cell is dead, has three live neighbors
elif not alive and neighbors == 3:
self.debug( " so I regenerate" )
rv.append( (i,j,1) )
# Condition 3: Die. Cell is alive, has <2 or >3 live neighbors
elif alive and neighbors > 3 or neighbors < 2:
self.debug( " so I die")
rv.append( ( i, j, 0 ) )
# Condition 4: no change
else:
self.debug(" so I remain", alive and 'alive' or 'dead')
return rv
def debug( self, *args, **kwargs ):
self.verbose and print( self.ticks, *args, **kwargs )
def __str__(self):
rv = []
for i in range(3):
for j in range(3):
rv.append( str(self.board[i][j]) )
rv.append("\n")
return "".join( rv )
game = Game(verbose=True)
print(game)
game.tick()
print( game )
game.tick()
print( game )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment