Skip to content

Instantly share code, notes, and snippets.

@chryss
Last active August 29, 2015 14:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chryss/0ee15360c3fcdad0bc6d to your computer and use it in GitHub Desktop.
Save chryss/0ee15360c3fcdad0bc6d to your computer and use it in GitHub Desktop.
import argparse
import collections
# Let's define a global dispatch table for the 8 different possible neighbors
# clockwise starting top-left: tl, t, tr, r, br, b, bl, l.
# The target index only depends on the number of rows and the start index jj
# As we won't know beforehand which functions to use for a given start index,
# we make them all dependent on both jj and n
neighbordispatch = {
'tl': lambda jj, n: jj - n - 1,
't': lambda jj, n: jj - n,
'tr': lambda jj, n: jj - n + 1,
'r': lambda jj, n: jj + 1,
'br': lambda jj, n: jj + n + 1,
'b': lambda jj, n: jj + n,
'bl': lambda jj, n: jj + n - 1,
'l': lambda jj, n: jj - 1,
}
def getinput(teststr):
"""Cleans up an input line and splits it up"""
idxs, mines = teststr.split(';')
m, n = [int(item) for item in idxs.split(',')]
return m, n, mines
def neighbors(jj, m, n):
"""Generates set of valid neighbors for a given index"""
neighbors = set(neighbordispatch.keys())
if jj < n:
# first row, take out the neighbor candidates above
neighbors.difference_update({'tl', 't', 'tr'})
if jj >= n * (m-1):
# last row, take out the neighbor candidates below
neighbors.difference_update({'bl', 'b', 'br'})
if jj % n == 0:
# first column, take out the neighbor candidates to the left
neighbors.difference_update({'tl', 'l', 'bl'})
if (jj+1) % n == 0:
# last column, take out the neighbor candidates to the right
neighbors.difference_update({'tr', 'r', 'br'})
return neighbors
def selectmines(arg1, arg2):
return arg1 if arg1 == '*' else str(arg2)
def main():
parser = argparse.ArgumentParser()
parser.add_argument("infilepath")
args = parser.parse_args()
with open(args.infilepath, "rU") as source:
for line in source:
teststr = line.strip()
if not teststr:
continue
m, n, mines = getinput(teststr)
neighborcounts = [
countr['*'] for countr in [
collections.Counter([
mines[neighbordispatch[neigh](ii, n)]
for neigh in neighbors(ii, m, n)
]) for ii in range(m*n)
]
]
result = map(selectmines, mines, neighborcounts)
print(''.join(result))
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment