···11+import os # NOQA
22+import sys # NOQA
33+import re # NOQA
44+import math # NOQA
55+import fileinput
66+from collections import Counter, deque, namedtuple # NOQA
77+from itertools import count, product, permutations, combinations, combinations_with_replacement # NOQA
88+99+from utils import parse_line, mul, factors, memoize, primes, new_table, Point, DIRS, DIRS_4, DIRS_8 # NOQA
1010+1111+# Itertools Functions:
1212+# product('ABCD', repeat=2) AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD
1313+# permutations('ABCD', 2) AB AC AD BA BC BD CA CB CD DA DB DC
1414+# combinations('ABCD', 2) AB AC AD BC BD CD
1515+# combinations_with_replacement('ABCD', 2) AA AB AC AD BB BC BD CC CD DD
1616+1717+total = 0
1818+result = []
1919+table = new_table(None, width=2, height=4)
2020+2121+for i, line in enumerate(fileinput.input()):
2222+ line = line.strip()
2323+2424+ # data = [x for x in line.split(', ')]
2525+ # data = [x for x in line]
2626+ # data = [int(x) for x in line.split()]
2727+ # data = re.findall(r'(\w+)', line)
2828+ data = parse_line(r'', line)
2929+3030+ if i == 0:
3131+ print(data)
+150
2017/utils.py
···11+import re
22+import math
33+import operator
44+from functools import total_ordering
55+66+77+LETTERS = [x for x in 'abcdefghijklmnopqrstuvwxyz']
88+VOWELS = {'a', 'e', 'i', 'o', 'u'}
99+CONSONANTS = set(x for x in LETTERS if x not in VOWELS)
1010+1111+1212+def parse_line(regex, line):
1313+ ret = []
1414+ for match in re.match(regex, line).groups():
1515+ try:
1616+ ret.append(int(match))
1717+ except ValueError:
1818+ ret.append(match)
1919+2020+ return ret
2121+2222+2323+def new_table(val, width, height):
2424+ return [[val for _ in range(width)] for _ in range(height)]
2525+2626+2727+def mul(lst):
2828+ """Like sum(), but for multiplication."""
2929+ return reduce(operator.mul, lst, 1) # NOQA
3030+3131+3232+def chunks(l, n):
3333+ """Yield successive n-sized chunks from l."""
3434+ for i in range(0, len(l), n):
3535+ yield l[i:i + n]
3636+3737+3838+def factors(n):
3939+ """Returns the factors of n."""
4040+ return sorted(
4141+ x for tup in (
4242+ [i, n // i] for i in range(1, int(n ** 0.5) + 1)
4343+ if n % i == 0)
4444+ for x in tup)
4545+4646+4747+def memoize(f):
4848+ """Simple dictionary-based memoization decorator"""
4949+ cache = {}
5050+5151+ def _mem_fn(*args):
5252+ if args not in cache:
5353+ cache[args] = f(*args)
5454+ return cache[args]
5555+5656+ _mem_fn.cache = cache
5757+ return _mem_fn
5858+5959+6060+def _eratosthenes(n):
6161+ """http://stackoverflow.com/a/3941967/239076"""
6262+ # Initialize list of primes
6363+ _primes = [True] * n
6464+6565+ # Set 0 and 1 to non-prime
6666+ _primes[0] = _primes[1] = False
6767+6868+ for i, is_prime in enumerate(_primes):
6969+ if is_prime:
7070+ yield i
7171+7272+ # Mark factors as non-prime
7373+ for n in xrange(i * i, n, i): # NOQA
7474+ _primes[n] = False
7575+7676+7777+def primes(n):
7878+ """Return a list of primes from [2, n)"""
7979+ return list(_eratosthenes(n))
8080+8181+8282+@total_ordering
8383+class Point:
8484+ """Simple 2-dimensional point."""
8585+ def __init__(self, x, y):
8686+ self.x = x
8787+ self.y = y
8888+8989+ def __add__(self, other):
9090+ return Point(self.x + other.x, self.y + other.y)
9191+9292+ def __sub__(self, other):
9393+ return Point(self.x - other.x, self.y - other.y)
9494+9595+ def __mul__(self, n):
9696+ return Point(self.x * n, self.y * n)
9797+9898+ def __div__(self, n):
9999+ return Point(self.x / n, self.y / n)
100100+101101+ def __neg__(self):
102102+ return Point(-self.x, -self.y)
103103+104104+ def __eq__(self, other):
105105+ return self.x == other.x and self.y == other.y
106106+107107+ def __ne__(self, other):
108108+ return not self == other
109109+110110+ def __lt__(self, other):
111111+ return self.manhattan < other.manhattan
112112+113113+ def __str__(self):
114114+ return "({}, {})".format(self.x, self.y)
115115+116116+ def __hash__(self):
117117+ return hash(tuple((self.x, self.y)))
118118+119119+ @property
120120+ def manhattan(self):
121121+ return abs(self.x) + abs(self.y)
122122+123123+ @property
124124+ def distance(self):
125125+ return math.sqrt(self.x ** 2 + self.y ** 2)
126126+127127+ def neighbours_4(self):
128128+ return [self + p for p in DIRS_4]
129129+130130+ def neighbours_8(self):
131131+ return [self + p for p in DIRS_8]
132132+133133+134134+DIRS_4 = DIRS = [
135135+ Point(0, 1), # north
136136+ Point(1, 0), # east
137137+ Point(0, -1), # south
138138+ Point(-1, 0), # west
139139+]
140140+141141+DIRS_8 = [
142142+ Point(0, 1), # N
143143+ Point(1, 1), # NE
144144+ Point(1, 0), # E
145145+ Point(1, -1), # SE
146146+ Point(0, -1), # S
147147+ Point(-1, -1), # SW
148148+ Point(-1, 0), # W
149149+ Point(-1, 0), # NW
150150+]