Last active
September 5, 2019 23:07
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 ) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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