Compare commits
4 commits
fcbeb4bfdd
...
81c4073f32
| Author | SHA1 | Date | |
|---|---|---|---|
| 81c4073f32 | |||
| 8b6d89fec5 | |||
| 4b1fa6bd65 | |||
| 5b754381b0 |
49 changed files with 626 additions and 329 deletions
|
|
@ -7,8 +7,9 @@ except ValueError:
|
||||||
name = None
|
name = None
|
||||||
|
|
||||||
if day_no and name:
|
if day_no and name:
|
||||||
with open('solutions/day_{}.py'.format(day_no.zfill(2)), 'w') as s:
|
with open("solutions/day_{}.py".format(day_no.zfill(2)), "w") as s:
|
||||||
s.write('''
|
s.write(
|
||||||
|
"""
|
||||||
from solutions import BaseSolution
|
from solutions import BaseSolution
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -28,9 +29,14 @@ class Solution(BaseSolution):
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
solution = Solution()
|
solution = Solution()
|
||||||
solution.show_results()
|
solution.show_results()
|
||||||
'''.strip().format(day=day_no, day_no=day_no.zfill(2), name=name) + '\n')
|
""".strip().format(
|
||||||
with open('tests/day_{}_tests.py'.format(day_no.zfill(2)), 'w') as t:
|
day=day_no, day_no=day_no.zfill(2), name=name
|
||||||
t.write('''
|
)
|
||||||
|
+ "\n"
|
||||||
|
)
|
||||||
|
with open("tests/day_{}_tests.py".format(day_no.zfill(2)), "w") as t:
|
||||||
|
t.write(
|
||||||
|
"""
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from solutions.day_{day_no} import Solution
|
from solutions.day_{day_no} import Solution
|
||||||
|
|
@ -46,18 +52,24 @@ class Day{day_no}TestCase(unittest.TestCase):
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
'''.strip().format(day_no=day_no.zfill(2)) + '\n')
|
""".strip().format(
|
||||||
with open('inputs/{}.txt'.format(day_no.zfill(2)), 'w') as i:
|
day_no=day_no.zfill(2)
|
||||||
i.write('')
|
)
|
||||||
|
+ "\n"
|
||||||
|
)
|
||||||
|
with open("inputs/{}.txt".format(day_no.zfill(2)), "w") as i:
|
||||||
|
i.write("")
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
print('\nAdvent of Code 2017'
|
print(
|
||||||
'\n###################'
|
"\nAdvent of Code 2017" "\n###################" "\n\nby Anders Ytterström (@madr)"
|
||||||
'\n\nby Anders Ytterström (@madr)')
|
)
|
||||||
|
|
||||||
for i in [str(n).zfill(2) for n in range(1, 26)]:
|
for i in [str(n).zfill(2) for n in range(1, 26)]:
|
||||||
try:
|
try:
|
||||||
solution = __import__('solutions.day_{}'.format(i), globals(), locals(), ['Solution'], 0).Solution()
|
solution = __import__(
|
||||||
|
"solutions.day_{}".format(i), globals(), locals(), ["Solution"], 0
|
||||||
|
).Solution()
|
||||||
solution.show_results()
|
solution.show_results()
|
||||||
except IOError:
|
except IOError:
|
||||||
pass
|
pass
|
||||||
|
|
|
||||||
|
|
@ -4,20 +4,22 @@ class BaseSolution:
|
||||||
trim_input = True
|
trim_input = True
|
||||||
|
|
||||||
def parse_input(self, filename):
|
def parse_input(self, filename):
|
||||||
filepath = './inputs/{}'.format(filename)
|
filepath = "./inputs/{}".format(filename)
|
||||||
with open(filepath, 'r') as f:
|
with open(filepath, "r") as f:
|
||||||
self.puzzle_input = f.read()
|
self.puzzle_input = f.read()
|
||||||
if self.trim_input:
|
if self.trim_input:
|
||||||
self.puzzle_input = self.puzzle_input.strip()
|
self.puzzle_input = self.puzzle_input.strip()
|
||||||
|
|
||||||
def show_results(self):
|
def show_results(self):
|
||||||
self.parse_input(self.input_file)
|
self.parse_input(self.input_file)
|
||||||
print('\n\n{}\n{}\n\nPart 1: {}\nPart 2: {}'.format(
|
print(
|
||||||
str(self),
|
"\n\n{}\n{}\n\nPart 1: {}\nPart 2: {}".format(
|
||||||
'-' * len(str(self)),
|
str(self),
|
||||||
self.solve(self.puzzle_input),
|
"-" * len(str(self)),
|
||||||
self.solve_again(self.puzzle_input),
|
self.solve(self.puzzle_input),
|
||||||
))
|
self.solve_again(self.puzzle_input),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def solve(self, puzzle_input):
|
def solve(self, puzzle_input):
|
||||||
raise NotImplemented
|
raise NotImplemented
|
||||||
|
|
|
||||||
|
|
@ -2,21 +2,24 @@ from solutions import BaseSolution
|
||||||
|
|
||||||
|
|
||||||
class Solution(BaseSolution):
|
class Solution(BaseSolution):
|
||||||
input_file = '01.txt'
|
input_file = "01.txt"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Day 1: Inverse Captcha'
|
return "Day 1: Inverse Captcha"
|
||||||
|
|
||||||
def solve(self, puzzle_input, distance=1):
|
def solve(self, puzzle_input, distance=1):
|
||||||
pi_length = len(puzzle_input)
|
pi_length = len(puzzle_input)
|
||||||
return sum(int(puzzle_input[pos]) for pos in range(pi_length) if
|
return sum(
|
||||||
puzzle_input[pos] == puzzle_input[(pos + distance) % pi_length])
|
int(puzzle_input[pos])
|
||||||
|
for pos in range(pi_length)
|
||||||
|
if puzzle_input[pos] == puzzle_input[(pos + distance) % pi_length]
|
||||||
|
)
|
||||||
|
|
||||||
def solve_again(self, puzzle_input):
|
def solve_again(self, puzzle_input):
|
||||||
distance = len(puzzle_input) // 2
|
distance = len(puzzle_input) // 2
|
||||||
return self.solve(puzzle_input, distance)
|
return self.solve(puzzle_input, distance)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
solution = Solution()
|
solution = Solution()
|
||||||
solution.show_results()
|
solution.show_results()
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@ from solutions import BaseSolution
|
||||||
|
|
||||||
|
|
||||||
class Solution(BaseSolution):
|
class Solution(BaseSolution):
|
||||||
input_file = '02.txt'
|
input_file = "02.txt"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Day 2: Corruption Checksum'
|
return "Day 2: Corruption Checksum"
|
||||||
|
|
||||||
def _get_rows(self, puzzle_input):
|
def _get_rows(self, puzzle_input):
|
||||||
return [list(map(int, rows.split())) for rows in puzzle_input.splitlines()]
|
return [list(map(int, rows.split())) for rows in puzzle_input.splitlines()]
|
||||||
|
|
@ -29,6 +29,6 @@ class Solution(BaseSolution):
|
||||||
return sum(self.get_even_divisible(columns) for columns in rows)
|
return sum(self.get_even_divisible(columns) for columns in rows)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
solution = Solution()
|
solution = Solution()
|
||||||
solution.show_results()
|
solution.show_results()
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@ from solutions import BaseSolution
|
||||||
|
|
||||||
|
|
||||||
class Solution(BaseSolution):
|
class Solution(BaseSolution):
|
||||||
input_file = '03.txt'
|
input_file = "03.txt"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Day 3: Spiral Memory'
|
return "Day 3: Spiral Memory"
|
||||||
|
|
||||||
def _get_rounds(self, value):
|
def _get_rounds(self, value):
|
||||||
n = 0
|
n = 0
|
||||||
|
|
@ -32,6 +32,6 @@ class Solution(BaseSolution):
|
||||||
return 279138
|
return 279138
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
solution = Solution()
|
solution = Solution()
|
||||||
solution.show_results()
|
solution.show_results()
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,15 @@ from solutions import BaseSolution
|
||||||
|
|
||||||
|
|
||||||
class Solution(BaseSolution):
|
class Solution(BaseSolution):
|
||||||
input_file = '04.txt'
|
input_file = "04.txt"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Day 4: High-Entropy Passphrases'
|
return "Day 4: High-Entropy Passphrases"
|
||||||
|
|
||||||
def validate(self, passphrase, extended=False):
|
def validate(self, passphrase, extended=False):
|
||||||
words = passphrase.split()
|
words = passphrase.split()
|
||||||
if extended:
|
if extended:
|
||||||
words = [''.join(sorted(w)) for w in words]
|
words = ["".join(sorted(w)) for w in words]
|
||||||
return sorted(list(set(words))) == sorted(words)
|
return sorted(list(set(words))) == sorted(words)
|
||||||
|
|
||||||
def solve(self, puzzle_input):
|
def solve(self, puzzle_input):
|
||||||
|
|
@ -20,6 +20,6 @@ class Solution(BaseSolution):
|
||||||
return sum(self.validate(p, True) for p in puzzle_input.splitlines())
|
return sum(self.validate(p, True) for p in puzzle_input.splitlines())
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
solution = Solution()
|
solution = Solution()
|
||||||
solution.show_results()
|
solution.show_results()
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@ from solutions import BaseSolution
|
||||||
|
|
||||||
|
|
||||||
class Solution(BaseSolution):
|
class Solution(BaseSolution):
|
||||||
input_file = '05.txt'
|
input_file = "05.txt"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Day 5: A Maze of Twisty Trampolines, All Alike'
|
return "Day 5: A Maze of Twisty Trampolines, All Alike"
|
||||||
|
|
||||||
def solve(self, puzzle_input, strange_jumps=False):
|
def solve(self, puzzle_input, strange_jumps=False):
|
||||||
pos = 0
|
pos = 0
|
||||||
|
|
@ -23,6 +23,6 @@ class Solution(BaseSolution):
|
||||||
return self.solve(puzzle_input, True)
|
return self.solve(puzzle_input, True)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
solution = Solution()
|
solution = Solution()
|
||||||
solution.show_results()
|
solution.show_results()
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@ from solutions import BaseSolution
|
||||||
|
|
||||||
|
|
||||||
class Solution(BaseSolution):
|
class Solution(BaseSolution):
|
||||||
input_file = '06.txt'
|
input_file = "06.txt"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Day 6: Memory Reallocation'
|
return "Day 6: Memory Reallocation"
|
||||||
|
|
||||||
def redistribute(self, banks):
|
def redistribute(self, banks):
|
||||||
banks = list(banks)
|
banks = list(banks)
|
||||||
|
|
@ -39,10 +39,10 @@ class Solution(BaseSolution):
|
||||||
|
|
||||||
def solve_again(self, puzzle_input):
|
def solve_again(self, puzzle_input):
|
||||||
seen = self._allocate(puzzle_input)
|
seen = self._allocate(puzzle_input)
|
||||||
seen_last = ' '.join(str(n) for n in seen[-1])
|
seen_last = " ".join(str(n) for n in seen[-1])
|
||||||
return len(self._allocate(seen_last)) - 1
|
return len(self._allocate(seen_last)) - 1
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
solution = Solution()
|
solution = Solution()
|
||||||
solution.show_results()
|
solution.show_results()
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,8 @@ class Program:
|
||||||
name, weight = data.split()
|
name, weight = data.split()
|
||||||
except ValueError:
|
except ValueError:
|
||||||
name, weight, _, *disc = data.split()
|
name, weight, _, *disc = data.split()
|
||||||
weight = int(weight[1:len(weight) - 1])
|
weight = int(weight[1 : len(weight) - 1])
|
||||||
disc = tuple(p.replace(',', '') for p in disc)
|
disc = tuple(p.replace(",", "") for p in disc)
|
||||||
return name, weight, disc
|
return name, weight, disc
|
||||||
|
|
||||||
def has_disc(self):
|
def has_disc(self):
|
||||||
|
|
@ -30,29 +30,31 @@ class Program:
|
||||||
|
|
||||||
|
|
||||||
class Solution(BaseSolution):
|
class Solution(BaseSolution):
|
||||||
input_file = '07.txt'
|
input_file = "07.txt"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Day 7: Recursive Circus'
|
return "Day 7: Recursive Circus"
|
||||||
|
|
||||||
def _get_programs(self, puzzle_input):
|
def _get_programs(self, puzzle_input):
|
||||||
return [Program(data) for data in puzzle_input.splitlines()]
|
return [Program(data) for data in puzzle_input.splitlines()]
|
||||||
|
|
||||||
def _get_discs(self, disc, programs):
|
def _get_discs(self, disc, programs):
|
||||||
subdisc = [{'own_weight': p.weight, 'obj': p} for p in programs if p.name in disc]
|
subdisc = [
|
||||||
|
{"own_weight": p.weight, "obj": p} for p in programs if p.name in disc
|
||||||
|
]
|
||||||
for t in subdisc:
|
for t in subdisc:
|
||||||
t['weight'] = t['own_weight']
|
t["weight"] = t["own_weight"]
|
||||||
if t['obj'].has_disc():
|
if t["obj"].has_disc():
|
||||||
t['disc'] = self._get_discs(t['obj'].disc, programs)
|
t["disc"] = self._get_discs(t["obj"].disc, programs)
|
||||||
t['weight'] += sum([st['weight'] for st in t['disc']])
|
t["weight"] += sum([st["weight"] for st in t["disc"]])
|
||||||
del (t['obj'])
|
del t["obj"]
|
||||||
return subdisc
|
return subdisc
|
||||||
|
|
||||||
def _find_unbalanced_disc(self, disc):
|
def _find_unbalanced_disc(self, disc):
|
||||||
disc = sorted(disc, key=lambda t: t['weight'])
|
disc = sorted(disc, key=lambda t: t["weight"])
|
||||||
if not disc[0]['weight'] < disc[1]['weight']:
|
if not disc[0]["weight"] < disc[1]["weight"]:
|
||||||
disc = sorted(disc, key=lambda t: t['weight'], reverse=True)
|
disc = sorted(disc, key=lambda t: t["weight"], reverse=True)
|
||||||
return disc[0], disc[1]['weight'] - disc[0]['weight']
|
return disc[0], disc[1]["weight"] - disc[0]["weight"]
|
||||||
|
|
||||||
def solve(self, puzzle_input):
|
def solve(self, puzzle_input):
|
||||||
programs = self._get_programs(puzzle_input)
|
programs = self._get_programs(puzzle_input)
|
||||||
|
|
@ -67,28 +69,30 @@ class Solution(BaseSolution):
|
||||||
unseen = p.unseen_discs(seen)
|
unseen = p.unseen_discs(seen)
|
||||||
if len(unseen) > 0:
|
if len(unseen) > 0:
|
||||||
seen += unseen
|
seen += unseen
|
||||||
bottom_program = list(filter(lambda p: p.name not in seen, programs_with_discs))[0]
|
bottom_program = list(
|
||||||
|
filter(lambda p: p.name not in seen, programs_with_discs)
|
||||||
|
)[0]
|
||||||
return bottom_program
|
return bottom_program
|
||||||
|
|
||||||
def solve_again(self, puzzle_input):
|
def solve_again(self, puzzle_input):
|
||||||
programs = self._get_programs(puzzle_input)
|
programs = self._get_programs(puzzle_input)
|
||||||
bottom_program = self.solve(puzzle_input)
|
bottom_program = self.solve(puzzle_input)
|
||||||
disc_tree = {
|
disc_tree = {
|
||||||
'own_weight': bottom_program.weight,
|
"own_weight": bottom_program.weight,
|
||||||
'disc': self._get_discs(bottom_program.disc, programs)
|
"disc": self._get_discs(bottom_program.disc, programs),
|
||||||
}
|
}
|
||||||
diff = -1
|
diff = -1
|
||||||
unbalanced = True
|
unbalanced = True
|
||||||
while unbalanced:
|
while unbalanced:
|
||||||
disc, new_diff = self._find_unbalanced_disc(disc_tree['disc'])
|
disc, new_diff = self._find_unbalanced_disc(disc_tree["disc"])
|
||||||
if new_diff == 0:
|
if new_diff == 0:
|
||||||
unbalanced = False
|
unbalanced = False
|
||||||
else:
|
else:
|
||||||
disc_tree = disc
|
disc_tree = disc
|
||||||
diff = new_diff
|
diff = new_diff
|
||||||
return disc_tree['own_weight'] + diff
|
return disc_tree["own_weight"] + diff
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
solution = Solution()
|
solution = Solution()
|
||||||
solution.show_results()
|
solution.show_results()
|
||||||
|
|
|
||||||
|
|
@ -2,22 +2,22 @@ from solutions import BaseSolution
|
||||||
|
|
||||||
|
|
||||||
class Solution(BaseSolution):
|
class Solution(BaseSolution):
|
||||||
input_file = '08.txt'
|
input_file = "08.txt"
|
||||||
registry = {}
|
registry = {}
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Day 8: I Heard You Like Registers'
|
return "Day 8: I Heard You Like Registers"
|
||||||
|
|
||||||
def _should_modify(self, x, comp, y):
|
def _should_modify(self, x, comp, y):
|
||||||
if comp in ('==', '!=', '>=', '<=', '>', '<'):
|
if comp in ("==", "!=", ">=", "<=", ">", "<"):
|
||||||
return eval('{:d} {} {:d}'.format(x, comp, y))
|
return eval("{:d} {} {:d}".format(x, comp, y))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _update_registry(self, registry, instruction):
|
def _update_registry(self, registry, instruction):
|
||||||
r, action, n, _, k, comp, v = instruction.split()
|
r, action, n, _, k, comp, v = instruction.split()
|
||||||
current = registry.get(r, 0)
|
current = registry.get(r, 0)
|
||||||
if self._should_modify(registry.get(k, 0), comp, int(v)):
|
if self._should_modify(registry.get(k, 0), comp, int(v)):
|
||||||
registry[r] = current + int(n) if action == 'inc' else current - int(n)
|
registry[r] = current + int(n) if action == "inc" else current - int(n)
|
||||||
|
|
||||||
def solve(self, puzzle_input):
|
def solve(self, puzzle_input):
|
||||||
registry = {}
|
registry = {}
|
||||||
|
|
@ -35,6 +35,6 @@ class Solution(BaseSolution):
|
||||||
return max_value
|
return max_value
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
solution = Solution()
|
solution = Solution()
|
||||||
solution.show_results()
|
solution.show_results()
|
||||||
|
|
|
||||||
|
|
@ -4,30 +4,30 @@ from solutions import BaseSolution
|
||||||
|
|
||||||
|
|
||||||
class Solution(BaseSolution):
|
class Solution(BaseSolution):
|
||||||
input_file = '09.txt'
|
input_file = "09.txt"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Day 9: Stream Processing'
|
return "Day 9: Stream Processing"
|
||||||
|
|
||||||
def solve(self, puzzle_input):
|
def solve(self, puzzle_input):
|
||||||
level = 0
|
level = 0
|
||||||
groups = []
|
groups = []
|
||||||
stream = re.sub(r'!.', '', puzzle_input)
|
stream = re.sub(r"!.", "", puzzle_input)
|
||||||
stream = re.sub(r'<[^>]*>', '', stream)
|
stream = re.sub(r"<[^>]*>", "", stream)
|
||||||
for c in stream:
|
for c in stream:
|
||||||
if c == '{':
|
if c == "{":
|
||||||
level += 1
|
level += 1
|
||||||
if c == '}':
|
if c == "}":
|
||||||
groups.append(level)
|
groups.append(level)
|
||||||
level -= 1
|
level -= 1
|
||||||
return sum(groups)
|
return sum(groups)
|
||||||
|
|
||||||
def solve_again(self, puzzle_input):
|
def solve_again(self, puzzle_input):
|
||||||
stream = re.sub(r'!.', '', puzzle_input)
|
stream = re.sub(r"!.", "", puzzle_input)
|
||||||
garbage = re.findall(r'<([^>]*)>', stream)
|
garbage = re.findall(r"<([^>]*)>", stream)
|
||||||
return sum([len(g) for g in garbage])
|
return sum([len(g) for g in garbage])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
solution = Solution()
|
solution = Solution()
|
||||||
solution.show_results()
|
solution.show_results()
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,14 @@ from solutions import BaseSolution
|
||||||
|
|
||||||
|
|
||||||
class Solution(BaseSolution):
|
class Solution(BaseSolution):
|
||||||
input_file = '10.txt'
|
input_file = "10.txt"
|
||||||
list = []
|
list = []
|
||||||
l = 0
|
l = 0
|
||||||
skip_size = 0
|
skip_size = 0
|
||||||
pos = 0
|
pos = 0
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Day 10: Knot Hash'
|
return "Day 10: Knot Hash"
|
||||||
|
|
||||||
def reset(self, l=256):
|
def reset(self, l=256):
|
||||||
self.list = list(range(l))
|
self.list = list(range(l))
|
||||||
|
|
@ -28,7 +28,7 @@ class Solution(BaseSolution):
|
||||||
|
|
||||||
def solve(self, puzzle_input, r=256):
|
def solve(self, puzzle_input, r=256):
|
||||||
self.reset(r)
|
self.reset(r)
|
||||||
for sublist_length in map(int, puzzle_input.split(',')):
|
for sublist_length in map(int, puzzle_input.split(",")):
|
||||||
self.reverse(sublist_length)
|
self.reverse(sublist_length)
|
||||||
return self.list[0] * self.list[1]
|
return self.list[0] * self.list[1]
|
||||||
|
|
||||||
|
|
@ -38,10 +38,13 @@ class Solution(BaseSolution):
|
||||||
for _ in range(64):
|
for _ in range(64):
|
||||||
for sublist_length in puzzle_input:
|
for sublist_length in puzzle_input:
|
||||||
self.reverse(sublist_length)
|
self.reverse(sublist_length)
|
||||||
dense_hash = [eval('^'.join(list(map(str, self.list[seq:seq+16])))) for seq in range(0, r, 16)]
|
dense_hash = [
|
||||||
return ''.join(['{:x}'.format(int(i)).zfill(2) for i in dense_hash])
|
eval("^".join(list(map(str, self.list[seq : seq + 16]))))
|
||||||
|
for seq in range(0, r, 16)
|
||||||
|
]
|
||||||
|
return "".join(["{:x}".format(int(i)).zfill(2) for i in dense_hash])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
solution = Solution()
|
solution = Solution()
|
||||||
solution.show_results()
|
solution.show_results()
|
||||||
|
|
|
||||||
|
|
@ -2,20 +2,20 @@ from solutions import BaseSolution
|
||||||
|
|
||||||
|
|
||||||
class Solution(BaseSolution):
|
class Solution(BaseSolution):
|
||||||
input_file = '11.txt'
|
input_file = "11.txt"
|
||||||
furthest_away = 0
|
furthest_away = 0
|
||||||
# https://www.redblobgames.com/grids/hexagons/#coordinates
|
# https://www.redblobgames.com/grids/hexagons/#coordinates
|
||||||
DIRECTIONS = {
|
DIRECTIONS = {
|
||||||
'n': lambda x, y, z: (x, y + 1, z - 1),
|
"n": lambda x, y, z: (x, y + 1, z - 1),
|
||||||
'ne': lambda x, y, z: (x + 1, y, z - 1),
|
"ne": lambda x, y, z: (x + 1, y, z - 1),
|
||||||
'se': lambda x, y, z: (x + 1, y - 1, z),
|
"se": lambda x, y, z: (x + 1, y - 1, z),
|
||||||
's': lambda x, y, z: (x, y - 1, z + 1),
|
"s": lambda x, y, z: (x, y - 1, z + 1),
|
||||||
'sw': lambda x, y, z: (x - 1, y, z + 1),
|
"sw": lambda x, y, z: (x - 1, y, z + 1),
|
||||||
'nw': lambda x, y, z: (x - 1, y + 1, z),
|
"nw": lambda x, y, z: (x - 1, y + 1, z),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Day 11: Hex Ed'
|
return "Day 11: Hex Ed"
|
||||||
|
|
||||||
def _get_end(self, steps):
|
def _get_end(self, steps):
|
||||||
x = 0
|
x = 0
|
||||||
|
|
@ -28,14 +28,14 @@ class Solution(BaseSolution):
|
||||||
return abs(x), abs(y), abs(z)
|
return abs(x), abs(y), abs(z)
|
||||||
|
|
||||||
def solve(self, puzzle_input):
|
def solve(self, puzzle_input):
|
||||||
x, y, z = self._get_end(puzzle_input.split(','))
|
x, y, z = self._get_end(puzzle_input.split(","))
|
||||||
return max(x, y, z)
|
return max(x, y, z)
|
||||||
|
|
||||||
def solve_again(self, puzzle_input):
|
def solve_again(self, puzzle_input):
|
||||||
_, *__ = self._get_end(puzzle_input.split(','))
|
_, *__ = self._get_end(puzzle_input.split(","))
|
||||||
return self.furthest_away
|
return self.furthest_away
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
solution = Solution()
|
solution = Solution()
|
||||||
solution.show_results()
|
solution.show_results()
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,17 @@ from solutions import BaseSolution
|
||||||
|
|
||||||
|
|
||||||
class Solution(BaseSolution):
|
class Solution(BaseSolution):
|
||||||
input_file = '12.txt'
|
input_file = "12.txt"
|
||||||
seen = []
|
seen = []
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Day 12: Digital Plumber'
|
return "Day 12: Digital Plumber"
|
||||||
|
|
||||||
def _walk(self, i, programs):
|
def _walk(self, i, programs):
|
||||||
line = next(filter(lambda l: l.startswith('{} <->'.format(i)), programs))
|
line = next(filter(lambda l: l.startswith("{} <->".format(i)), programs))
|
||||||
piped = line.split()[2:]
|
piped = line.split()[2:]
|
||||||
self.seen.add(i)
|
self.seen.add(i)
|
||||||
for p in [int(p.replace(',', '')) for p in piped]:
|
for p in [int(p.replace(",", "")) for p in piped]:
|
||||||
if p not in self.seen:
|
if p not in self.seen:
|
||||||
self._walk(p, programs)
|
self._walk(p, programs)
|
||||||
|
|
||||||
|
|
@ -34,6 +34,6 @@ class Solution(BaseSolution):
|
||||||
return groups
|
return groups
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
solution = Solution()
|
solution = Solution()
|
||||||
solution.show_results()
|
solution.show_results()
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,12 @@ from solutions import BaseSolution
|
||||||
|
|
||||||
|
|
||||||
class Solution(BaseSolution):
|
class Solution(BaseSolution):
|
||||||
input_file = '13.txt'
|
input_file = "13.txt"
|
||||||
layers = []
|
layers = []
|
||||||
scanners = []
|
scanners = []
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Day 13: Packet Scanners'
|
return "Day 13: Packet Scanners"
|
||||||
|
|
||||||
def _move_scanners(self):
|
def _move_scanners(self):
|
||||||
for p, l in enumerate(self.layers):
|
for p, l in enumerate(self.layers):
|
||||||
|
|
@ -22,7 +22,10 @@ class Solution(BaseSolution):
|
||||||
self.scanners = [[0, 1] for l in self.layers]
|
self.scanners = [[0, 1] for l in self.layers]
|
||||||
|
|
||||||
def _setup(self, puzzle_input):
|
def _setup(self, puzzle_input):
|
||||||
pi = [tuple(map(int, line.strip().split(': '))) for line in puzzle_input.splitlines()]
|
pi = [
|
||||||
|
tuple(map(int, line.strip().split(": ")))
|
||||||
|
for line in puzzle_input.splitlines()
|
||||||
|
]
|
||||||
self.layers = [0 for _ in range(pi[-1][0] + 1)]
|
self.layers = [0 for _ in range(pi[-1][0] + 1)]
|
||||||
self._init_scanners()
|
self._init_scanners()
|
||||||
for k, v in pi:
|
for k, v in pi:
|
||||||
|
|
@ -55,13 +58,16 @@ class Solution(BaseSolution):
|
||||||
|
|
||||||
def solve_again(self, puzzle_input):
|
def solve_again(self, puzzle_input):
|
||||||
# todo: rewrite!
|
# todo: rewrite!
|
||||||
lines = [line.split(': ') for line in puzzle_input.splitlines()]
|
lines = [line.split(": ") for line in puzzle_input.splitlines()]
|
||||||
heights = {int(pos): int(height) for pos, height in lines}
|
heights = {int(pos): int(height) for pos, height in lines}
|
||||||
wait = next(
|
wait = next(
|
||||||
wait for wait in itertools.count() if not any(self._scan(heights[pos], wait + pos) == 0 for pos in heights))
|
wait
|
||||||
|
for wait in itertools.count()
|
||||||
|
if not any(self._scan(heights[pos], wait + pos) == 0 for pos in heights)
|
||||||
|
)
|
||||||
return wait
|
return wait
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
solution = Solution()
|
solution = Solution()
|
||||||
solution.show_results()
|
solution.show_results()
|
||||||
|
|
|
||||||
|
|
@ -3,18 +3,18 @@ from solutions.day_10 import Solution as KnotHash
|
||||||
|
|
||||||
|
|
||||||
class Solution(BaseSolution):
|
class Solution(BaseSolution):
|
||||||
input_file = '14.txt'
|
input_file = "14.txt"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Day 14: Disk Defragmentation'
|
return "Day 14: Disk Defragmentation"
|
||||||
|
|
||||||
def _get_grid(self, pi):
|
def _get_grid(self, pi):
|
||||||
grid = ''
|
grid = ""
|
||||||
ks = KnotHash()
|
ks = KnotHash()
|
||||||
for n in range(128):
|
for n in range(128):
|
||||||
s = '-'.join([pi, str(n)])
|
s = "-".join([pi, str(n)])
|
||||||
knothash = ks.solve_again(s)
|
knothash = ks.solve_again(s)
|
||||||
grid += '{:0128b}'.format(int(knothash, 16))
|
grid += "{:0128b}".format(int(knothash, 16))
|
||||||
return grid
|
return grid
|
||||||
|
|
||||||
def _find_regions(self, squares):
|
def _find_regions(self, squares):
|
||||||
|
|
@ -31,10 +31,10 @@ class Solution(BaseSolution):
|
||||||
get_adjacent_square(i - 128)
|
get_adjacent_square(i - 128)
|
||||||
if i % 128 < 127:
|
if i % 128 < 127:
|
||||||
get_adjacent_square(i + 1)
|
get_adjacent_square(i + 1)
|
||||||
if i < 128 ** 2 - 128:
|
if i < 128**2 - 128:
|
||||||
get_adjacent_square(i + 128)
|
get_adjacent_square(i + 128)
|
||||||
|
|
||||||
for i in range(128 ** 2):
|
for i in range(128**2):
|
||||||
if i in seen or i not in squares:
|
if i in seen or i not in squares:
|
||||||
continue
|
continue
|
||||||
regions += 1
|
regions += 1
|
||||||
|
|
@ -47,10 +47,10 @@ class Solution(BaseSolution):
|
||||||
|
|
||||||
def solve_again(self, puzzle_input):
|
def solve_again(self, puzzle_input):
|
||||||
grid = self._get_grid(puzzle_input)
|
grid = self._get_grid(puzzle_input)
|
||||||
squares = [i for i, s in enumerate(list(grid)) if s == '1']
|
squares = [i for i, s in enumerate(list(grid)) if s == "1"]
|
||||||
return self._find_regions(squares)
|
return self._find_regions(squares)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
solution = Solution()
|
solution = Solution()
|
||||||
solution.show_results()
|
solution.show_results()
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@ from solutions import BaseSolution
|
||||||
|
|
||||||
|
|
||||||
class Solution(BaseSolution):
|
class Solution(BaseSolution):
|
||||||
input_file = '15.txt'
|
input_file = "15.txt"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Day 15: Dueling Generators'
|
return "Day 15: Dueling Generators"
|
||||||
|
|
||||||
def _calc(self, x, f, m=1):
|
def _calc(self, x, f, m=1):
|
||||||
x = (x * f) % 2147483647
|
x = (x * f) % 2147483647
|
||||||
|
|
@ -21,7 +21,7 @@ class Solution(BaseSolution):
|
||||||
for _ in range(40 * 10**6):
|
for _ in range(40 * 10**6):
|
||||||
a = self._calc(a, af)
|
a = self._calc(a, af)
|
||||||
b = self._calc(b, bf)
|
b = self._calc(b, bf)
|
||||||
if '{:b}'.format(a)[-16:] == '{:b}'.format(b)[-16:]:
|
if "{:b}".format(a)[-16:] == "{:b}".format(b)[-16:]:
|
||||||
j += 1
|
j += 1
|
||||||
return j
|
return j
|
||||||
|
|
||||||
|
|
@ -29,14 +29,14 @@ class Solution(BaseSolution):
|
||||||
af, bf = (16807, 48271)
|
af, bf = (16807, 48271)
|
||||||
a, b = [int(pi.split()[-1]) for pi in puzzle_input.splitlines()]
|
a, b = [int(pi.split()[-1]) for pi in puzzle_input.splitlines()]
|
||||||
j = 0
|
j = 0
|
||||||
for _ in range(5 * 10 ** 6):
|
for _ in range(5 * 10**6):
|
||||||
a = self._calc(a, af, 4)
|
a = self._calc(a, af, 4)
|
||||||
b = self._calc(b, bf, 8)
|
b = self._calc(b, bf, 8)
|
||||||
if '{:b}'.format(a)[-16:] == '{:b}'.format(b)[-16:]:
|
if "{:b}".format(a)[-16:] == "{:b}".format(b)[-16:]:
|
||||||
j += 1
|
j += 1
|
||||||
return j
|
return j
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
solution = Solution()
|
solution = Solution()
|
||||||
solution.show_results()
|
solution.show_results()
|
||||||
|
|
|
||||||
|
|
@ -2,24 +2,24 @@ from solutions import BaseSolution
|
||||||
|
|
||||||
|
|
||||||
class Solution(BaseSolution):
|
class Solution(BaseSolution):
|
||||||
input_file = '16.txt'
|
input_file = "16.txt"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Day 16: Permutation Promenade'
|
return "Day 16: Permutation Promenade"
|
||||||
|
|
||||||
def _move(self, programs, m, i):
|
def _move(self, programs, m, i):
|
||||||
l = len(programs)
|
l = len(programs)
|
||||||
if m == 's':
|
if m == "s":
|
||||||
r = int(i)
|
r = int(i)
|
||||||
return programs[-r:] + programs[:l - r]
|
return programs[-r:] + programs[: l - r]
|
||||||
if m == 'x':
|
if m == "x":
|
||||||
x, y = [int(s) for s in i.split('/')]
|
x, y = [int(s) for s in i.split("/")]
|
||||||
z = programs[x]
|
z = programs[x]
|
||||||
programs[x] = programs[y]
|
programs[x] = programs[y]
|
||||||
programs[y] = z
|
programs[y] = z
|
||||||
return programs
|
return programs
|
||||||
if m == 'p':
|
if m == "p":
|
||||||
xp, yp = i.split('/')
|
xp, yp = i.split("/")
|
||||||
x = programs.index(xp)
|
x = programs.index(xp)
|
||||||
y = programs.index(yp)
|
y = programs.index(yp)
|
||||||
z = programs[x]
|
z = programs[x]
|
||||||
|
|
@ -34,22 +34,22 @@ class Solution(BaseSolution):
|
||||||
|
|
||||||
def solve(self, puzzle_input, n=16):
|
def solve(self, puzzle_input, n=16):
|
||||||
programs = [chr(c) for c in range(97, 97 + n)]
|
programs = [chr(c) for c in range(97, 97 + n)]
|
||||||
moves = puzzle_input.split(',')
|
moves = puzzle_input.split(",")
|
||||||
return ''.join(self._dance(programs, moves))
|
return "".join(self._dance(programs, moves))
|
||||||
|
|
||||||
def solve_again(self, puzzle_input, n=16):
|
def solve_again(self, puzzle_input, n=16):
|
||||||
moves = puzzle_input.split(',')
|
moves = puzzle_input.split(",")
|
||||||
initial = [chr(c) for c in range(97, 97 + n)]
|
initial = [chr(c) for c in range(97, 97 + n)]
|
||||||
programs = list(self.solve(puzzle_input))
|
programs = list(self.solve(puzzle_input))
|
||||||
dances = 1
|
dances = 1
|
||||||
while not programs == initial:
|
while not programs == initial:
|
||||||
programs = self._dance(programs, moves)
|
programs = self._dance(programs, moves)
|
||||||
dances += 1
|
dances += 1
|
||||||
for _ in range(10 ** 9 % dances):
|
for _ in range(10**9 % dances):
|
||||||
programs = self._dance(programs, moves)
|
programs = self._dance(programs, moves)
|
||||||
return ''.join(programs)
|
return "".join(programs)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
solution = Solution()
|
solution = Solution()
|
||||||
solution.show_results()
|
solution.show_results()
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@ from solutions import BaseSolution
|
||||||
|
|
||||||
|
|
||||||
class Solution(BaseSolution):
|
class Solution(BaseSolution):
|
||||||
input_file = '17.txt'
|
input_file = "17.txt"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Day 17: Spinlock'
|
return "Day 17: Spinlock"
|
||||||
|
|
||||||
def solve(self, puzzle_input):
|
def solve(self, puzzle_input):
|
||||||
n = int(puzzle_input)
|
n = int(puzzle_input)
|
||||||
|
|
@ -20,13 +20,13 @@ class Solution(BaseSolution):
|
||||||
pos = 0
|
pos = 0
|
||||||
n = int(puzzle_input)
|
n = int(puzzle_input)
|
||||||
last_seen = 0
|
last_seen = 0
|
||||||
for i in range(1, 5 * 10 ** 7 + 1):
|
for i in range(1, 5 * 10**7 + 1):
|
||||||
pos = (pos + n) % i + 1
|
pos = (pos + n) % i + 1
|
||||||
if pos == 1:
|
if pos == 1:
|
||||||
last_seen = i
|
last_seen = i
|
||||||
return last_seen
|
return last_seen
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
solution = Solution()
|
solution = Solution()
|
||||||
solution.show_results()
|
solution.show_results()
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,16 @@ from solutions import BaseSolution
|
||||||
|
|
||||||
|
|
||||||
class Solution(BaseSolution):
|
class Solution(BaseSolution):
|
||||||
input_file = '18.txt'
|
input_file = "18.txt"
|
||||||
sound_freq = 0
|
sound_freq = 0
|
||||||
queue = [], []
|
queue = [], []
|
||||||
sent = [0, 0]
|
sent = [0, 0]
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Day 18: Duet'
|
return "Day 18: Duet"
|
||||||
|
|
||||||
def _run(self, line, registry, swag_mode=True):
|
def _run(self, line, registry, swag_mode=True):
|
||||||
actions = 'add jgz mod mul rcv set snd'
|
actions = "add jgz mod mul rcv set snd"
|
||||||
a, *kv = line.split()
|
a, *kv = line.split()
|
||||||
if len(kv) == 2:
|
if len(kv) == 2:
|
||||||
k, v = kv
|
k, v = kv
|
||||||
|
|
@ -19,9 +19,9 @@ class Solution(BaseSolution):
|
||||||
k = kv[0]
|
k = kv[0]
|
||||||
v = None
|
v = None
|
||||||
if a in actions:
|
if a in actions:
|
||||||
if a == 'add' and k in registry:
|
if a == "add" and k in registry:
|
||||||
registry[k] += registry[v] if v in registry else int(v)
|
registry[k] += registry[v] if v in registry else int(v)
|
||||||
if a == 'jgz': # damn you, 'jgz 1 3'
|
if a == "jgz": # damn you, 'jgz 1 3'
|
||||||
try:
|
try:
|
||||||
k = int(k)
|
k = int(k)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
|
@ -31,25 +31,25 @@ class Solution(BaseSolution):
|
||||||
except ValueError:
|
except ValueError:
|
||||||
v = registry[v] if v in registry else 1
|
v = registry[v] if v in registry else 1
|
||||||
return v if k > 0 else 1
|
return v if k > 0 else 1
|
||||||
if a == 'mod' and k in registry:
|
if a == "mod" and k in registry:
|
||||||
registry[k] %= registry[v] if v in registry else int(v)
|
registry[k] %= registry[v] if v in registry else int(v)
|
||||||
if a == 'mul' and k in registry:
|
if a == "mul" and k in registry:
|
||||||
registry[k] *= registry[v] if v in registry else int(v)
|
registry[k] *= registry[v] if v in registry else int(v)
|
||||||
if a == 'set':
|
if a == "set":
|
||||||
registry[k] = registry[v] if v in registry else int(v)
|
registry[k] = registry[v] if v in registry else int(v)
|
||||||
if swag_mode: # Part 1: scientific wild-ass guess
|
if swag_mode: # Part 1: scientific wild-ass guess
|
||||||
if a == 'rcv' and registry[k] != 0:
|
if a == "rcv" and registry[k] != 0:
|
||||||
return self.STOP_SIGNAL
|
return self.STOP_SIGNAL
|
||||||
if a == 'snd' and k in registry:
|
if a == "snd" and k in registry:
|
||||||
self.sound_freq = registry[k]
|
self.sound_freq = registry[k]
|
||||||
else: # part 2, actual instructions
|
else: # part 2, actual instructions
|
||||||
if a == 'rcv':
|
if a == "rcv":
|
||||||
if len(self.queue[registry['_id']]) == 0:
|
if len(self.queue[registry["_id"]]) == 0:
|
||||||
return 0
|
return 0
|
||||||
registry[k] = self.queue[registry['_id']].pop(0)
|
registry[k] = self.queue[registry["_id"]].pop(0)
|
||||||
if a == 'snd':
|
if a == "snd":
|
||||||
self.sent[registry['_id']] += 1
|
self.sent[registry["_id"]] += 1
|
||||||
q = (registry['_id'] + 1) % 2
|
q = (registry["_id"] + 1) % 2
|
||||||
kk = registry[k] if k in registry else int(k)
|
kk = registry[k] if k in registry else int(k)
|
||||||
self.queue[q].append(kk)
|
self.queue[q].append(kk)
|
||||||
return 1
|
return 1
|
||||||
|
|
@ -65,7 +65,7 @@ class Solution(BaseSolution):
|
||||||
return self.sound_freq
|
return self.sound_freq
|
||||||
|
|
||||||
def solve_again(self, puzzle_input):
|
def solve_again(self, puzzle_input):
|
||||||
registry = {'p': 0, '_id': 0}, {'p': 1, '_id': 1}
|
registry = {"p": 0, "_id": 0}, {"p": 1, "_id": 1}
|
||||||
lines = puzzle_input.splitlines()
|
lines = puzzle_input.splitlines()
|
||||||
i = 0
|
i = 0
|
||||||
j = 0
|
j = 0
|
||||||
|
|
@ -89,6 +89,6 @@ class Solution(BaseSolution):
|
||||||
return self.sent[1]
|
return self.sent[1]
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
solution = Solution()
|
solution = Solution()
|
||||||
solution.show_results()
|
solution.show_results()
|
||||||
|
|
|
||||||
|
|
@ -2,48 +2,48 @@ from solutions import BaseSolution
|
||||||
|
|
||||||
|
|
||||||
class Solution(BaseSolution):
|
class Solution(BaseSolution):
|
||||||
input_file = '19.txt'
|
input_file = "19.txt"
|
||||||
trim_input = False
|
trim_input = False
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Day 19: A Series of Tubes'
|
return "Day 19: A Series of Tubes"
|
||||||
|
|
||||||
def _walk_maze(self, puzzle_input):
|
def _walk_maze(self, puzzle_input):
|
||||||
DIRECTIONS = {
|
DIRECTIONS = {
|
||||||
'D': (1, 0),
|
"D": (1, 0),
|
||||||
'U': (-1, 0),
|
"U": (-1, 0),
|
||||||
'R': (0, 1),
|
"R": (0, 1),
|
||||||
'L': (0, -1),
|
"L": (0, -1),
|
||||||
}
|
}
|
||||||
maze = puzzle_input.splitlines()
|
maze = puzzle_input.splitlines()
|
||||||
pos = (0, list(maze[0]).index('|'))
|
pos = (0, list(maze[0]).index("|"))
|
||||||
d = DIRECTIONS['D']
|
d = DIRECTIONS["D"]
|
||||||
paths = '-|'
|
paths = "-|"
|
||||||
steps = 0
|
steps = 0
|
||||||
seen = ''
|
seen = ""
|
||||||
|
|
||||||
def _nc(nu):
|
def _nc(nu):
|
||||||
np = (pos[0] + nu[0], pos[1] + nu[1])
|
np = (pos[0] + nu[0], pos[1] + nu[1])
|
||||||
if np[0] < len(maze) and np[1] < len(maze[np[0]]):
|
if np[0] < len(maze) and np[1] < len(maze[np[0]]):
|
||||||
return maze[np[0]][np[1]]
|
return maze[np[0]][np[1]]
|
||||||
else:
|
else:
|
||||||
return ' '
|
return " "
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
pos = (pos[0] + d[0], pos[1] + d[1])
|
pos = (pos[0] + d[0], pos[1] + d[1])
|
||||||
c = _nc((0, 0))
|
c = _nc((0, 0))
|
||||||
steps += 1
|
steps += 1
|
||||||
if c == '+':
|
if c == "+":
|
||||||
nc = _nc(d)
|
nc = _nc(d)
|
||||||
if nc == ' ':
|
if nc == " ":
|
||||||
for v in DIRECTIONS.values():
|
for v in DIRECTIONS.values():
|
||||||
if -v[0] == d[0] and -v[1] == d[1]:
|
if -v[0] == d[0] and -v[1] == d[1]:
|
||||||
continue
|
continue
|
||||||
nc = _nc(v)
|
nc = _nc(v)
|
||||||
if nc != ' ':
|
if nc != " ":
|
||||||
d = v
|
d = v
|
||||||
break
|
break
|
||||||
elif c == ' ':
|
elif c == " ":
|
||||||
break
|
break
|
||||||
elif c not in paths:
|
elif c not in paths:
|
||||||
seen += c
|
seen += c
|
||||||
|
|
@ -58,6 +58,6 @@ class Solution(BaseSolution):
|
||||||
return steps
|
return steps
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
solution = Solution()
|
solution = Solution()
|
||||||
solution.show_results()
|
solution.show_results()
|
||||||
|
|
|
||||||
|
|
@ -6,15 +6,18 @@ from solutions import BaseSolution
|
||||||
|
|
||||||
|
|
||||||
class Solution(BaseSolution):
|
class Solution(BaseSolution):
|
||||||
input_file = '20.txt'
|
input_file = "20.txt"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Day 20: Particle Swarm'
|
return "Day 20: Particle Swarm"
|
||||||
|
|
||||||
def _get_particle(self, line):
|
def _get_particle(self, line):
|
||||||
return [list(map(int, coordinate.split(','))) for coordinate in re.findall(r'.=<([^>]+)>', line)]
|
return [
|
||||||
|
list(map(int, coordinate.split(",")))
|
||||||
|
for coordinate in re.findall(r".=<([^>]+)>", line)
|
||||||
|
]
|
||||||
|
|
||||||
def solve(self, puzzle_input, ticks=10 ** 4):
|
def solve(self, puzzle_input, ticks=10**4):
|
||||||
particles = [self._get_particle(line) for line in puzzle_input.splitlines()]
|
particles = [self._get_particle(line) for line in puzzle_input.splitlines()]
|
||||||
distances = [[] for _ in range(len(particles))]
|
distances = [[] for _ in range(len(particles))]
|
||||||
for _ in range(ticks):
|
for _ in range(ticks):
|
||||||
|
|
@ -27,10 +30,13 @@ class Solution(BaseSolution):
|
||||||
p[1] += v[1]
|
p[1] += v[1]
|
||||||
p[2] += v[2]
|
p[2] += v[2]
|
||||||
distances[i].append(sum(map(abs, p)))
|
distances[i].append(sum(map(abs, p)))
|
||||||
d = sorted(map(lambda d: (d[0], sum(d[1]) / len(d[1])), enumerate(distances)), key=lambda x: x[1])
|
d = sorted(
|
||||||
|
map(lambda d: (d[0], sum(d[1]) / len(d[1])), enumerate(distances)),
|
||||||
|
key=lambda x: x[1],
|
||||||
|
)
|
||||||
return d[0][0]
|
return d[0][0]
|
||||||
|
|
||||||
def solve_again(self, puzzle_input, ticks=10 ** 3):
|
def solve_again(self, puzzle_input, ticks=10**3):
|
||||||
particles = [self._get_particle(line) for line in puzzle_input.splitlines()]
|
particles = [self._get_particle(line) for line in puzzle_input.splitlines()]
|
||||||
for _ in range(ticks):
|
for _ in range(ticks):
|
||||||
positions = collections.defaultdict(list)
|
positions = collections.defaultdict(list)
|
||||||
|
|
@ -42,7 +48,7 @@ class Solution(BaseSolution):
|
||||||
p[0] += v[0]
|
p[0] += v[0]
|
||||||
p[1] += v[1]
|
p[1] += v[1]
|
||||||
p[2] += v[2]
|
p[2] += v[2]
|
||||||
k = '-'.join(map(str, p))
|
k = "-".join(map(str, p))
|
||||||
positions[k].append(particle)
|
positions[k].append(particle)
|
||||||
for duplicates in positions.values():
|
for duplicates in positions.values():
|
||||||
if len(duplicates) > 1:
|
if len(duplicates) > 1:
|
||||||
|
|
@ -51,6 +57,6 @@ class Solution(BaseSolution):
|
||||||
return len(particles)
|
return len(particles)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
solution = Solution()
|
solution = Solution()
|
||||||
solution.show_results()
|
solution.show_results()
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@ class Rule:
|
||||||
size = 0
|
size = 0
|
||||||
|
|
||||||
def __init__(self, line):
|
def __init__(self, line):
|
||||||
pattern, output = line.split(' => ')
|
pattern, output = line.split(" => ")
|
||||||
self.pattern = pattern.replace('/', '')
|
self.pattern = pattern.replace("/", "")
|
||||||
self.output = output.replace('/', '')
|
self.output = output.replace("/", "")
|
||||||
self.size = int(len(self.pattern) ** 0.5)
|
self.size = int(len(self.pattern) ** 0.5)
|
||||||
|
|
||||||
self.patterns = [
|
self.patterns = [
|
||||||
|
|
@ -22,13 +22,18 @@ class Rule:
|
||||||
]
|
]
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '[{}] {} -> {}'.format(self.size, self.pattern, self.output)
|
return "[{}] {} -> {}".format(self.size, self.pattern, self.output)
|
||||||
|
|
||||||
def _r(self, b):
|
def _r(self, b):
|
||||||
return ''.join(map(lambda g: ''.join(g), zip(*[b[s:s + self.size] for s in range(0, len(b), self.size)][::-1])))
|
return "".join(
|
||||||
|
map(
|
||||||
|
lambda g: "".join(g),
|
||||||
|
zip(*[b[s : s + self.size] for s in range(0, len(b), self.size)][::-1]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def _f(self, b):
|
def _f(self, b):
|
||||||
return b[-self.size:] + b[self.size:len(b) - self.size] + b[0:self.size]
|
return b[-self.size :] + b[self.size : len(b) - self.size] + b[0 : self.size]
|
||||||
|
|
||||||
def matches(self, canvas):
|
def matches(self, canvas):
|
||||||
return canvas in self.patterns
|
return canvas in self.patterns
|
||||||
|
|
@ -38,13 +43,13 @@ class Rule:
|
||||||
|
|
||||||
|
|
||||||
class Solution(BaseSolution):
|
class Solution(BaseSolution):
|
||||||
input_file = '21.txt'
|
input_file = "21.txt"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Day 21: Fractal Art'
|
return "Day 21: Fractal Art"
|
||||||
|
|
||||||
def _get_block(self, canvas, size, n=0):
|
def _get_block(self, canvas, size, n=0):
|
||||||
s = ''
|
s = ""
|
||||||
cl = int(len(canvas) ** 0.5)
|
cl = int(len(canvas) ** 0.5)
|
||||||
x = n % (cl // size)
|
x = n % (cl // size)
|
||||||
y = n // (cl // size)
|
y = n // (cl // size)
|
||||||
|
|
@ -56,20 +61,22 @@ class Solution(BaseSolution):
|
||||||
|
|
||||||
def _join_blocks(self, blocks):
|
def _join_blocks(self, blocks):
|
||||||
bl = len(blocks)
|
bl = len(blocks)
|
||||||
c = int(bl ** 0.5)
|
c = int(bl**0.5)
|
||||||
rl = int(len(blocks[0]) ** 0.5)
|
rl = int(len(blocks[0]) ** 0.5)
|
||||||
canvas = ''
|
canvas = ""
|
||||||
for i in range(0, bl, c):
|
for i in range(0, bl, c):
|
||||||
for j in range(rl):
|
for j in range(rl):
|
||||||
canvas += ''.join([block[j * rl:(j + 1) * rl] for block in blocks[i:i + c]])
|
canvas += "".join(
|
||||||
|
[block[j * rl : (j + 1) * rl] for block in blocks[i : i + c]]
|
||||||
|
)
|
||||||
return canvas
|
return canvas
|
||||||
|
|
||||||
def solve(self, puzzle_input, iterations=5):
|
def solve(self, puzzle_input, iterations=5):
|
||||||
canvas = '.#...####'
|
canvas = ".#...####"
|
||||||
rules = [Rule(l.strip()) for l in puzzle_input.splitlines()]
|
rules = [Rule(l.strip()) for l in puzzle_input.splitlines()]
|
||||||
for _ in range(iterations):
|
for _ in range(iterations):
|
||||||
size = 2 if len(canvas) % 2 == 0 else 3
|
size = 2 if len(canvas) % 2 == 0 else 3
|
||||||
blocks = len(canvas) // (size ** 2)
|
blocks = len(canvas) // (size**2)
|
||||||
cb = []
|
cb = []
|
||||||
for b in range(blocks):
|
for b in range(blocks):
|
||||||
bc = self._get_block(canvas, size, b)
|
bc = self._get_block(canvas, size, b)
|
||||||
|
|
@ -78,12 +85,12 @@ class Solution(BaseSolution):
|
||||||
r = rule[0]
|
r = rule[0]
|
||||||
cb.append(r.enhance(bc))
|
cb.append(r.enhance(bc))
|
||||||
canvas = self._join_blocks(cb)
|
canvas = self._join_blocks(cb)
|
||||||
return collections.Counter(canvas)['#']
|
return collections.Counter(canvas)["#"]
|
||||||
|
|
||||||
def solve_again(self, puzzle_input):
|
def solve_again(self, puzzle_input):
|
||||||
return self.solve(puzzle_input, 18)
|
return self.solve(puzzle_input, 18)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
solution = Solution()
|
solution = Solution()
|
||||||
solution.show_results()
|
solution.show_results()
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,10 @@ from solutions import BaseSolution
|
||||||
|
|
||||||
|
|
||||||
class Solution(BaseSolution):
|
class Solution(BaseSolution):
|
||||||
input_file = '22.txt'
|
input_file = "22.txt"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Day 22: Sporifica Virus'
|
return "Day 22: Sporifica Virus"
|
||||||
|
|
||||||
infected = 0
|
infected = 0
|
||||||
|
|
||||||
|
|
@ -50,7 +50,7 @@ class Solution(BaseSolution):
|
||||||
dirs = dirs[1:] + [dirs[0]]
|
dirs = dirs[1:] + [dirs[0]]
|
||||||
elif state == "#":
|
elif state == "#":
|
||||||
dirs = [dirs[3]] + dirs[:3]
|
dirs = [dirs[3]] + dirs[:3]
|
||||||
elif state == 'F':
|
elif state == "F":
|
||||||
dirs = dirs[2:] + dirs[:2]
|
dirs = dirs[2:] + dirs[:2]
|
||||||
return dirs
|
return dirs
|
||||||
|
|
||||||
|
|
@ -61,16 +61,16 @@ class Solution(BaseSolution):
|
||||||
i, p = existing
|
i, p = existing
|
||||||
return amap, p[2]
|
return amap, p[2]
|
||||||
else:
|
else:
|
||||||
amap.append([pos[0], pos[1], '.'])
|
amap.append([pos[0], pos[1], "."])
|
||||||
return amap, '.'
|
return amap, "."
|
||||||
|
|
||||||
def _update_state(self, amap, pos):
|
def _update_state(self, amap, pos):
|
||||||
t = lambda x: x[1][0] == pos[0] and x[1][1] == pos[1]
|
t = lambda x: x[1][0] == pos[0] and x[1][1] == pos[1]
|
||||||
existing = next(filter(t, enumerate(amap)))
|
existing = next(filter(t, enumerate(amap)))
|
||||||
i, p = existing
|
i, p = existing
|
||||||
if p[2] == '.':
|
if p[2] == ".":
|
||||||
self.infected += 1
|
self.infected += 1
|
||||||
amap[i][2] = '.' if p[2] == '#' else '#'
|
amap[i][2] = "." if p[2] == "#" else "#"
|
||||||
return amap
|
return amap
|
||||||
|
|
||||||
def _move(self, pos, d):
|
def _move(self, pos, d):
|
||||||
|
|
@ -80,12 +80,12 @@ class Solution(BaseSolution):
|
||||||
t = lambda x: x[1][0] == pos[0] and x[1][1] == pos[1]
|
t = lambda x: x[1][0] == pos[0] and x[1][1] == pos[1]
|
||||||
existing = next(filter(t, enumerate(amap)))
|
existing = next(filter(t, enumerate(amap)))
|
||||||
i, p = existing
|
i, p = existing
|
||||||
if p[2] == '.':
|
if p[2] == ".":
|
||||||
ns = 'W'
|
ns = "W"
|
||||||
elif p[2] == 'W':
|
elif p[2] == "W":
|
||||||
self.infected += 1
|
self.infected += 1
|
||||||
ns = "#"
|
ns = "#"
|
||||||
elif p[2] == '#':
|
elif p[2] == "#":
|
||||||
ns = "F"
|
ns = "F"
|
||||||
else:
|
else:
|
||||||
ns = "."
|
ns = "."
|
||||||
|
|
@ -93,6 +93,6 @@ class Solution(BaseSolution):
|
||||||
return amap
|
return amap
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
solution = Solution()
|
solution = Solution()
|
||||||
solution.show_results()
|
solution.show_results()
|
||||||
|
|
|
||||||
138
2017-python/solutions/day_23.py
Normal file
138
2017-python/solutions/day_23.py
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
from solutions import BaseSolution
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
|
|
||||||
|
class Solution(BaseSolution):
|
||||||
|
input_file = "23.txt"
|
||||||
|
sound_freq = 0
|
||||||
|
queue = [], []
|
||||||
|
sent = [0, 0]
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "Day 23: Coprocessor Conflagration"
|
||||||
|
|
||||||
|
def solve(self, puzzle_input):
|
||||||
|
R = defaultdict(int)
|
||||||
|
P = puzzle_input.splitlines()
|
||||||
|
i = 0
|
||||||
|
M = 0
|
||||||
|
while i < len(P):
|
||||||
|
j = 1
|
||||||
|
w, r, v = P[i].split()
|
||||||
|
match w:
|
||||||
|
case "set":
|
||||||
|
R[r] = R[v] if v in "abcdefgh" else int(v)
|
||||||
|
case "sub":
|
||||||
|
R[r] -= R[v] if v in "abcdefgh" else int(v)
|
||||||
|
case "mul":
|
||||||
|
M += 1
|
||||||
|
R[r] *= R[v] if v in "abcdefgh" else int(v)
|
||||||
|
case "jnz":
|
||||||
|
x = R[r] if r in "abcdefgh" else int(r)
|
||||||
|
if x != 0:
|
||||||
|
j = R[v] if v in "abcdefgh" else int(v)
|
||||||
|
i += j
|
||||||
|
return M
|
||||||
|
|
||||||
|
def solve_again(self, puzzle_input):
|
||||||
|
def isprime(num):
|
||||||
|
for n in range(2, int(num**0.5) + 1):
|
||||||
|
if num % n == 0:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
b = 99 * 100 + 100_000
|
||||||
|
c = b + 17_000 + 1
|
||||||
|
|
||||||
|
return sum(not isprime(n) for n in range(b, c, 17))
|
||||||
|
|
||||||
|
def python_reconstruction(self, puzzle_input):
|
||||||
|
R = defaultdict(int)
|
||||||
|
R["a"] = 1
|
||||||
|
|
||||||
|
# 00: set b 99
|
||||||
|
R["b"] = 99
|
||||||
|
# 01: set c b
|
||||||
|
R["c"] = R["b"]
|
||||||
|
|
||||||
|
# 02: jnz a 2
|
||||||
|
if R["a"] == 0:
|
||||||
|
# 03: jnz 1 5
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
# 04: mul b 100
|
||||||
|
# 05: sub b -100000
|
||||||
|
R["b"] = R["b"] * 100 + 100_000
|
||||||
|
|
||||||
|
# 06: set c b
|
||||||
|
# 07: sub c -17000
|
||||||
|
R["c"] = R["b"] + 17_000
|
||||||
|
|
||||||
|
while True:
|
||||||
|
# 08: set f 1
|
||||||
|
# 09: set d 2
|
||||||
|
R["f"] = 1
|
||||||
|
R["d"] = 2
|
||||||
|
|
||||||
|
while True:
|
||||||
|
# 10: set e 2
|
||||||
|
R["e"] = 2
|
||||||
|
|
||||||
|
while True:
|
||||||
|
# 11: set g d
|
||||||
|
# 12: mul g e
|
||||||
|
# 13: sub g b
|
||||||
|
R["g"] = R["d"] * R["e"] - R["b"]
|
||||||
|
|
||||||
|
# 14: jnz g 2
|
||||||
|
if R["g"] == 0:
|
||||||
|
# 15: set f 0
|
||||||
|
R["f"] = 0
|
||||||
|
|
||||||
|
# 16: sub e -1
|
||||||
|
R["e"] += 1
|
||||||
|
|
||||||
|
# 17: set g e
|
||||||
|
# 18: sub g b
|
||||||
|
R["g"] = R["e"] - R["b"]
|
||||||
|
|
||||||
|
# 19: jnz g -8
|
||||||
|
if R["g"] == 0:
|
||||||
|
break
|
||||||
|
|
||||||
|
# 20: sub d -1
|
||||||
|
R["d"] += 1
|
||||||
|
|
||||||
|
# 21: set g d
|
||||||
|
# 22: sub g b
|
||||||
|
R["g"] = R["d"] - R["b"]
|
||||||
|
|
||||||
|
# 23: jnz g -13
|
||||||
|
if R["g"] == 0:
|
||||||
|
break
|
||||||
|
|
||||||
|
# 24: jnz f 2
|
||||||
|
if R["f"] == 0:
|
||||||
|
# 25: sub h -1
|
||||||
|
R["h"] += 1
|
||||||
|
|
||||||
|
# 26: set g b
|
||||||
|
# 27: sub g c
|
||||||
|
R["g"] = R["b"] - R["c"]
|
||||||
|
|
||||||
|
# 28: jnz g 2
|
||||||
|
if R["g"] == 0:
|
||||||
|
# 29: jnz 1 3
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
# 30: sub b -17
|
||||||
|
R["b"] += 17
|
||||||
|
|
||||||
|
# 31: jnz 1 -23
|
||||||
|
|
||||||
|
return R["h"]
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
solution = Solution()
|
||||||
|
solution.show_results()
|
||||||
51
2017-python/solutions/day_24.py
Normal file
51
2017-python/solutions/day_24.py
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
from solutions import BaseSolution
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
class Solution(BaseSolution):
|
||||||
|
input_file = "24.txt"
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "Day 24: Electromagnetic Moat"
|
||||||
|
|
||||||
|
def solve(self, puzzle_input):
|
||||||
|
p1, _ = self._solve(puzzle_input)
|
||||||
|
return p1
|
||||||
|
|
||||||
|
def solve_again(self, puzzle_input):
|
||||||
|
_, p2 = self._solve(puzzle_input)
|
||||||
|
return p2
|
||||||
|
|
||||||
|
def _solve(self, puzzle_input):
|
||||||
|
components = [
|
||||||
|
tuple(map(int, re.findall(r"\d+", line))) for line in puzzle_input.split()
|
||||||
|
]
|
||||||
|
|
||||||
|
Q = [(c, []) for c in components if 0 in c]
|
||||||
|
S = 0
|
||||||
|
L = 0
|
||||||
|
LS = 0
|
||||||
|
|
||||||
|
while Q:
|
||||||
|
c, s = Q.pop()
|
||||||
|
if c in s:
|
||||||
|
S = max(S, sum(x + y for x, y in s))
|
||||||
|
if len(s) >= L:
|
||||||
|
L = len(s)
|
||||||
|
LS = max(LS, L * 1_000_000 + sum(x + y for x, y in s))
|
||||||
|
continue
|
||||||
|
cc = set(c) if not s else set(c) - set(s[-1])
|
||||||
|
if not cc:
|
||||||
|
cc = set(c)
|
||||||
|
for p1, p2 in components:
|
||||||
|
if p1 > 0 and p1 in cc:
|
||||||
|
Q.append(((p1, p2), s + [c]))
|
||||||
|
if p2 > 0 and p2 in cc:
|
||||||
|
Q.append(((p1, p2), s + [c]))
|
||||||
|
|
||||||
|
return S, LS % 1_000_000
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
solution = Solution()
|
||||||
|
solution.show_results()
|
||||||
46
2017-python/solutions/day_25.py
Normal file
46
2017-python/solutions/day_25.py
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
from solutions import BaseSolution
|
||||||
|
from collections import defaultdict
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
class Solution(BaseSolution):
|
||||||
|
input_file = "25.txt"
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "Day 25: The Halting Problem"
|
||||||
|
|
||||||
|
def solve(self, puzzle_input):
|
||||||
|
T = defaultdict(int)
|
||||||
|
p = 0
|
||||||
|
|
||||||
|
hd, *states = puzzle_input.split("\n\n")
|
||||||
|
S = int(re.findall(r"(\d+) steps", hd)[0])
|
||||||
|
s = re.findall(r"state (\w)\.", hd)[0]
|
||||||
|
P = {}
|
||||||
|
for state in states:
|
||||||
|
k = re.findall(r"state (\w)\:", state)[0]
|
||||||
|
v = [int(n) for n in re.findall(r"value (\d)\.", state)]
|
||||||
|
d = re.findall(r"(left|right)\.", state)
|
||||||
|
t = re.findall(r"state (\w)\.", state)
|
||||||
|
P[k] = (v[0], d[0], t[0], v[1], d[1], t[1])
|
||||||
|
|
||||||
|
for _ in range(S):
|
||||||
|
v0, d0, s0, v1, d1, s1 = P[s]
|
||||||
|
match T[p]:
|
||||||
|
case 0:
|
||||||
|
T[p] = v0
|
||||||
|
s = s0
|
||||||
|
p += 1 if d0 == "right" else -1
|
||||||
|
case 1:
|
||||||
|
T[p] = v1
|
||||||
|
s = s1
|
||||||
|
p += 1 if d1 == "right" else -1
|
||||||
|
return sum(T.values())
|
||||||
|
|
||||||
|
def solve_again(self, puzzle_input):
|
||||||
|
return "*"
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
solution = Solution()
|
||||||
|
solution.show_results()
|
||||||
|
|
@ -8,18 +8,18 @@ class Day1TestCase(unittest.TestCase):
|
||||||
self.solution = Solution()
|
self.solution = Solution()
|
||||||
|
|
||||||
def test_sums_equal_pairs(self):
|
def test_sums_equal_pairs(self):
|
||||||
assert self.solution.solve('1122') == 3
|
assert self.solution.solve("1122") == 3
|
||||||
assert self.solution.solve('1111') == 4
|
assert self.solution.solve("1111") == 4
|
||||||
assert self.solution.solve('1234') == 0
|
assert self.solution.solve("1234") == 0
|
||||||
assert self.solution.solve('91212129') == 9
|
assert self.solution.solve("91212129") == 9
|
||||||
|
|
||||||
def test_sums_equal_pairs_halvway_around(self):
|
def test_sums_equal_pairs_halvway_around(self):
|
||||||
assert self.solution.solve_again('1212') == 6
|
assert self.solution.solve_again("1212") == 6
|
||||||
assert self.solution.solve_again('1221') == 0
|
assert self.solution.solve_again("1221") == 0
|
||||||
assert self.solution.solve_again('123425') == 4
|
assert self.solution.solve_again("123425") == 4
|
||||||
assert self.solution.solve_again('123123') == 12
|
assert self.solution.solve_again("123123") == 12
|
||||||
assert self.solution.solve_again('12131415') == 4
|
assert self.solution.solve_again("12131415") == 4
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
|
|
@ -13,19 +13,19 @@ class Day2TestCase(unittest.TestCase):
|
||||||
assert self.solution.get_diff([2, 4, 6, 8]) == 6
|
assert self.solution.get_diff([2, 4, 6, 8]) == 6
|
||||||
|
|
||||||
def test_calculates_checksum(self):
|
def test_calculates_checksum(self):
|
||||||
puzzle_input = '\n'.join(['5 1 9 5', '7 5 3', '2 4 6 8'])
|
puzzle_input = "\n".join(["5 1 9 5", "7 5 3", "2 4 6 8"])
|
||||||
assert self.solution.solve(puzzle_input) == 18
|
assert self.solution.solve(puzzle_input) == 18
|
||||||
|
|
||||||
def test_calculates_row_even_divisible(self):
|
def test_calculates_row_even_divisible(self):
|
||||||
puzzle_input = '\n'.join(['5 9 2 8', '9 4 7 3', '3 8 6 5'])
|
puzzle_input = "\n".join(["5 9 2 8", "9 4 7 3", "3 8 6 5"])
|
||||||
assert self.solution.get_even_divisible([5, 9, 2, 8]) == 4
|
assert self.solution.get_even_divisible([5, 9, 2, 8]) == 4
|
||||||
assert self.solution.get_even_divisible([9, 4, 7, 3]) == 3
|
assert self.solution.get_even_divisible([9, 4, 7, 3]) == 3
|
||||||
assert self.solution.get_even_divisible([3, 8, 6, 5]) == 2
|
assert self.solution.get_even_divisible([3, 8, 6, 5]) == 2
|
||||||
|
|
||||||
def test_calculates_row_result_sum(self):
|
def test_calculates_row_result_sum(self):
|
||||||
puzzle_input = '\n'.join(['5 9 2 8', '9 4 7 3', '3 8 6 5'])
|
puzzle_input = "\n".join(["5 9 2 8", "9 4 7 3", "3 8 6 5"])
|
||||||
assert self.solution.solve_again(puzzle_input) == 9
|
assert self.solution.solve_again(puzzle_input) == 9
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,11 @@ class Day3TestCase(unittest.TestCase):
|
||||||
self.solution = Solution()
|
self.solution = Solution()
|
||||||
|
|
||||||
def test_shortest_manhattan_distance(self):
|
def test_shortest_manhattan_distance(self):
|
||||||
assert self.solution.solve('1') == 0
|
assert self.solution.solve("1") == 0
|
||||||
assert self.solution.solve('12') == 3
|
assert self.solution.solve("12") == 3
|
||||||
assert self.solution.solve('23') == 2
|
assert self.solution.solve("23") == 2
|
||||||
assert self.solution.solve('1024') == 31
|
assert self.solution.solve("1024") == 31
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
|
|
@ -9,22 +9,22 @@ class Day4TestCase(unittest.TestCase):
|
||||||
|
|
||||||
def test_passphrase_has_only_unique_words(self):
|
def test_passphrase_has_only_unique_words(self):
|
||||||
passphrases = [
|
passphrases = [
|
||||||
'aa bb cc dd ee',
|
"aa bb cc dd ee",
|
||||||
'aa bb cc dd aa',
|
"aa bb cc dd aa",
|
||||||
'aa bb cc dd aaa',
|
"aa bb cc dd aaa",
|
||||||
]
|
]
|
||||||
assert self.solution.validate(passphrases[0]) == True
|
assert self.solution.validate(passphrases[0]) == True
|
||||||
assert self.solution.validate(passphrases[1]) == False
|
assert self.solution.validate(passphrases[1]) == False
|
||||||
assert self.solution.validate(passphrases[2]) == True
|
assert self.solution.validate(passphrases[2]) == True
|
||||||
assert self.solution.solve('\n'.join(passphrases)) == 2
|
assert self.solution.solve("\n".join(passphrases)) == 2
|
||||||
|
|
||||||
def test_passphrase_has_no_anagrams(self):
|
def test_passphrase_has_no_anagrams(self):
|
||||||
passphrases = [
|
passphrases = [
|
||||||
'abcde fghij',
|
"abcde fghij",
|
||||||
'abcde xyz ecdab',
|
"abcde xyz ecdab",
|
||||||
'a ab abc abd abf abj',
|
"a ab abc abd abf abj",
|
||||||
'iiii oiii ooii oooi oooo',
|
"iiii oiii ooii oooi oooo",
|
||||||
'oiii ioii iioi iiio',
|
"oiii ioii iioi iiio",
|
||||||
]
|
]
|
||||||
assert self.solution.validate(passphrases[0], True) == True
|
assert self.solution.validate(passphrases[0], True) == True
|
||||||
assert self.solution.validate(passphrases[1], True) == False
|
assert self.solution.validate(passphrases[1], True) == False
|
||||||
|
|
@ -33,5 +33,5 @@ class Day4TestCase(unittest.TestCase):
|
||||||
assert self.solution.validate(passphrases[4], True) == False
|
assert self.solution.validate(passphrases[4], True) == False
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,29 @@ class Day5TestCase(unittest.TestCase):
|
||||||
self.solution = Solution()
|
self.solution = Solution()
|
||||||
|
|
||||||
def test_calculate_exit_distance(self):
|
def test_calculate_exit_distance(self):
|
||||||
puzzle_input = '\n'.join(['0', '3', '0', '1', '-3',])
|
puzzle_input = "\n".join(
|
||||||
|
[
|
||||||
|
"0",
|
||||||
|
"3",
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"-3",
|
||||||
|
]
|
||||||
|
)
|
||||||
assert self.solution.solve(puzzle_input) == 5
|
assert self.solution.solve(puzzle_input) == 5
|
||||||
|
|
||||||
def test_calculate_stranger_exit_distance(self):
|
def test_calculate_stranger_exit_distance(self):
|
||||||
puzzle_input = '\n'.join(['0', '3', '0', '1', '-3',])
|
puzzle_input = "\n".join(
|
||||||
|
[
|
||||||
|
"0",
|
||||||
|
"3",
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"-3",
|
||||||
|
]
|
||||||
|
)
|
||||||
assert self.solution.solve_again(puzzle_input) == 10
|
assert self.solution.solve_again(puzzle_input) == 10
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ class Day6TestCase(unittest.TestCase):
|
||||||
self.solution = Solution()
|
self.solution = Solution()
|
||||||
|
|
||||||
def test_count_redistribution_cycles(self):
|
def test_count_redistribution_cycles(self):
|
||||||
puzzle_input = '0 2 7 0'
|
puzzle_input = "0 2 7 0"
|
||||||
banks = list(map(int, puzzle_input.split()))
|
banks = list(map(int, puzzle_input.split()))
|
||||||
assert self.solution.redistribute(banks) == (2, 4, 1, 2)
|
assert self.solution.redistribute(banks) == (2, 4, 1, 2)
|
||||||
assert self.solution.redistribute((2, 4, 1, 2)) == (3, 1, 2, 3)
|
assert self.solution.redistribute((2, 4, 1, 2)) == (3, 1, 2, 3)
|
||||||
|
|
@ -18,9 +18,9 @@ class Day6TestCase(unittest.TestCase):
|
||||||
assert self.solution.solve(puzzle_input) == 5
|
assert self.solution.solve(puzzle_input) == 5
|
||||||
|
|
||||||
def test_count_redistribution_cycles_again(self):
|
def test_count_redistribution_cycles_again(self):
|
||||||
puzzle_input = '0 2 7 0'
|
puzzle_input = "0 2 7 0"
|
||||||
assert self.solution.solve_again(puzzle_input) == 4
|
assert self.solution.solve_again(puzzle_input) == 4
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ from solutions.day_07 import Solution, Program
|
||||||
|
|
||||||
class Day7TestCase(unittest.TestCase):
|
class Day7TestCase(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.puzzle_input = '''
|
self.puzzle_input = """
|
||||||
pbga (66)
|
pbga (66)
|
||||||
xhth (57)
|
xhth (57)
|
||||||
ebii (61)
|
ebii (61)
|
||||||
|
|
@ -19,24 +19,24 @@ class Day7TestCase(unittest.TestCase):
|
||||||
ugml (68) -> gyxo, ebii, jptl
|
ugml (68) -> gyxo, ebii, jptl
|
||||||
gyxo (61)
|
gyxo (61)
|
||||||
cntj (57)
|
cntj (57)
|
||||||
'''.strip()
|
""".strip()
|
||||||
self.solution = Solution()
|
self.solution = Solution()
|
||||||
|
|
||||||
def test_find_bottom_tower(self):
|
def test_find_bottom_tower(self):
|
||||||
p = Program('ugml (68) -> gyxo, ebii, jptl')
|
p = Program("ugml (68) -> gyxo, ebii, jptl")
|
||||||
assert p.name == 'ugml'
|
assert p.name == "ugml"
|
||||||
assert p.weight == 68
|
assert p.weight == 68
|
||||||
assert p.disc == ('gyxo', 'ebii', 'jptl')
|
assert p.disc == ("gyxo", "ebii", "jptl")
|
||||||
p = Program('jptl (61)')
|
p = Program("jptl (61)")
|
||||||
assert p.name == 'jptl'
|
assert p.name == "jptl"
|
||||||
assert p.weight == 61
|
assert p.weight == 61
|
||||||
assert p.disc == ()
|
assert p.disc == ()
|
||||||
assert self.solution.solve(self.puzzle_input).name == 'tknk'
|
assert self.solution.solve(self.puzzle_input).name == "tknk"
|
||||||
|
|
||||||
def test_find_weight_correction(self):
|
def test_find_weight_correction(self):
|
||||||
corrected = self.solution.solve_again(self.puzzle_input)
|
corrected = self.solution.solve_again(self.puzzle_input)
|
||||||
assert corrected == 60
|
assert corrected == 60
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
|
|
@ -8,23 +8,23 @@ class Day8TestCase(unittest.TestCase):
|
||||||
self.solution = Solution()
|
self.solution = Solution()
|
||||||
|
|
||||||
def test_largest_registry_value(self):
|
def test_largest_registry_value(self):
|
||||||
puzzle_input = '''
|
puzzle_input = """
|
||||||
b inc 5 if a > 1
|
b inc 5 if a > 1
|
||||||
a inc 1 if b < 5
|
a inc 1 if b < 5
|
||||||
c dec -10 if a >= 1
|
c dec -10 if a >= 1
|
||||||
c inc -20 if c == 10
|
c inc -20 if c == 10
|
||||||
'''.strip()
|
""".strip()
|
||||||
assert self.solution.solve(puzzle_input) == 1
|
assert self.solution.solve(puzzle_input) == 1
|
||||||
|
|
||||||
def test_largest_ath_registry_value(self):
|
def test_largest_ath_registry_value(self):
|
||||||
puzzle_input = '''
|
puzzle_input = """
|
||||||
b inc 5 if a > 1
|
b inc 5 if a > 1
|
||||||
a inc 1 if b < 5
|
a inc 1 if b < 5
|
||||||
c dec -10 if a >= 1
|
c dec -10 if a >= 1
|
||||||
c inc -20 if c == 10
|
c inc -20 if c == 10
|
||||||
'''.strip()
|
""".strip()
|
||||||
assert self.solution.solve_again(puzzle_input) == 10
|
assert self.solution.solve_again(puzzle_input) == 10
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
|
|
@ -8,24 +8,24 @@ class Day9TestCase(unittest.TestCase):
|
||||||
self.solution = Solution()
|
self.solution = Solution()
|
||||||
|
|
||||||
def test_calculates_score(self):
|
def test_calculates_score(self):
|
||||||
assert self.solution.solve('{}') == 1
|
assert self.solution.solve("{}") == 1
|
||||||
assert self.solution.solve('{{{}}}') == 6
|
assert self.solution.solve("{{{}}}") == 6
|
||||||
assert self.solution.solve('{{},{}}') == 5
|
assert self.solution.solve("{{},{}}") == 5
|
||||||
assert self.solution.solve('{{{},{},{{}}}}') == 16
|
assert self.solution.solve("{{{},{},{{}}}}") == 16
|
||||||
assert self.solution.solve('{<a>,<a>,<a>,<a>}') == 1
|
assert self.solution.solve("{<a>,<a>,<a>,<a>}") == 1
|
||||||
assert self.solution.solve('{{<ab>},{<ab>},{<ab>},{<ab>}}') == 9
|
assert self.solution.solve("{{<ab>},{<ab>},{<ab>},{<ab>}}") == 9
|
||||||
assert self.solution.solve('{{<!!>},{<!!>},{<!!>},{<!!>}}') == 9
|
assert self.solution.solve("{{<!!>},{<!!>},{<!!>},{<!!>}}") == 9
|
||||||
assert self.solution.solve('{{<a!>},{<a!>},{<a!>},{<ab>}}') == 3
|
assert self.solution.solve("{{<a!>},{<a!>},{<a!>},{<ab>}}") == 3
|
||||||
|
|
||||||
def test_count_garbage(self):
|
def test_count_garbage(self):
|
||||||
assert self.solution.solve_again('<>') == 0
|
assert self.solution.solve_again("<>") == 0
|
||||||
assert self.solution.solve_again('<random characters>') == 17
|
assert self.solution.solve_again("<random characters>") == 17
|
||||||
assert self.solution.solve_again('<<<<>') == 3
|
assert self.solution.solve_again("<<<<>") == 3
|
||||||
assert self.solution.solve_again('<{!>}>') == 2
|
assert self.solution.solve_again("<{!>}>") == 2
|
||||||
assert self.solution.solve_again('<!!>') == 0
|
assert self.solution.solve_again("<!!>") == 0
|
||||||
assert self.solution.solve_again('<!!!>>') == 0
|
assert self.solution.solve_again("<!!!>>") == 0
|
||||||
assert self.solution.solve_again('<{o"i!a,<{i<a>') == 10
|
assert self.solution.solve_again('<{o"i!a,<{i<a>') == 10
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
|
|
@ -25,14 +25,16 @@ class Day10TestCase(unittest.TestCase):
|
||||||
assert self.solution.list == [3, 4, 2, 1, 0]
|
assert self.solution.list == [3, 4, 2, 1, 0]
|
||||||
assert self.solution.skip_size == 4
|
assert self.solution.skip_size == 4
|
||||||
assert self.solution.pos == 4
|
assert self.solution.pos == 4
|
||||||
assert self.solution.solve('3,4,1,5', r=5) == 12
|
assert self.solution.solve("3,4,1,5", r=5) == 12
|
||||||
|
|
||||||
def test_dense_hash(self):
|
def test_dense_hash(self):
|
||||||
assert self.solution.solve_again('') == 'a2582a3a0e66e6e86e3812dcb672a272'
|
assert self.solution.solve_again("") == "a2582a3a0e66e6e86e3812dcb672a272"
|
||||||
assert self.solution.solve_again('AoC 2017') == '33efeb34ea91902bb2f59c9920caa6cd'
|
assert (
|
||||||
assert self.solution.solve_again('1,2,3') == '3efbe78a8d82f29979031a4aa0b16a9d'
|
self.solution.solve_again("AoC 2017") == "33efeb34ea91902bb2f59c9920caa6cd"
|
||||||
assert self.solution.solve_again('1,2,4') == '63960835bcdc130f0b66d7ff4f6a5a8e'
|
)
|
||||||
|
assert self.solution.solve_again("1,2,3") == "3efbe78a8d82f29979031a4aa0b16a9d"
|
||||||
|
assert self.solution.solve_again("1,2,4") == "63960835bcdc130f0b66d7ff4f6a5a8e"
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,15 @@ class Day11TestCase(unittest.TestCase):
|
||||||
self.solution = Solution()
|
self.solution = Solution()
|
||||||
|
|
||||||
def test_distance(self):
|
def test_distance(self):
|
||||||
assert self.solution.solve('ne,ne,ne') == 3
|
assert self.solution.solve("ne,ne,ne") == 3
|
||||||
assert self.solution.solve('ne,ne,sw,sw') == 0
|
assert self.solution.solve("ne,ne,sw,sw") == 0
|
||||||
assert self.solution.solve('ne,ne,s,s') == 2
|
assert self.solution.solve("ne,ne,s,s") == 2
|
||||||
assert self.solution.solve('se,sw,se,sw,sw') == 3
|
assert self.solution.solve("se,sw,se,sw,sw") == 3
|
||||||
|
|
||||||
def test_furthest_away(self):
|
def test_furthest_away(self):
|
||||||
assert self.solution.solve_again('ne,ne,sw,sw') == 2
|
assert self.solution.solve_again("ne,ne,sw,sw") == 2
|
||||||
assert self.solution.solve_again('se,sw,se,sw,sw') == 3
|
assert self.solution.solve_again("se,sw,se,sw,sw") == 3
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ class Day12TestCase(unittest.TestCase):
|
||||||
self.solution = Solution()
|
self.solution = Solution()
|
||||||
|
|
||||||
def test_connected_to_program0(self):
|
def test_connected_to_program0(self):
|
||||||
puzzle_input = '''
|
puzzle_input = """
|
||||||
0 <-> 2
|
0 <-> 2
|
||||||
1 <-> 1
|
1 <-> 1
|
||||||
2 <-> 0, 3, 4
|
2 <-> 0, 3, 4
|
||||||
|
|
@ -16,11 +16,11 @@ class Day12TestCase(unittest.TestCase):
|
||||||
4 <-> 2, 3, 6
|
4 <-> 2, 3, 6
|
||||||
5 <-> 6
|
5 <-> 6
|
||||||
6 <-> 4, 5
|
6 <-> 4, 5
|
||||||
'''.strip()
|
""".strip()
|
||||||
assert self.solution.solve(puzzle_input) == 6
|
assert self.solution.solve(puzzle_input) == 6
|
||||||
|
|
||||||
def test_group_coun(self):
|
def test_group_coun(self):
|
||||||
puzzle_input = '''
|
puzzle_input = """
|
||||||
0 <-> 2
|
0 <-> 2
|
||||||
1 <-> 1
|
1 <-> 1
|
||||||
2 <-> 0, 3, 4
|
2 <-> 0, 3, 4
|
||||||
|
|
@ -28,9 +28,9 @@ class Day12TestCase(unittest.TestCase):
|
||||||
4 <-> 2, 3, 6
|
4 <-> 2, 3, 6
|
||||||
5 <-> 6
|
5 <-> 6
|
||||||
6 <-> 4, 5
|
6 <-> 4, 5
|
||||||
'''.strip()
|
""".strip()
|
||||||
assert self.solution.solve_again(puzzle_input) == 2
|
assert self.solution.solve_again(puzzle_input) == 2
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
|
|
@ -8,23 +8,23 @@ class Day13TestCase(unittest.TestCase):
|
||||||
self.solution = Solution()
|
self.solution = Solution()
|
||||||
|
|
||||||
def test_get_through_firewall(self):
|
def test_get_through_firewall(self):
|
||||||
puzzle_input = '''
|
puzzle_input = """
|
||||||
0: 3
|
0: 3
|
||||||
1: 2
|
1: 2
|
||||||
4: 4
|
4: 4
|
||||||
6: 4
|
6: 4
|
||||||
'''.strip()
|
""".strip()
|
||||||
assert self.solution.solve(puzzle_input) == 24
|
assert self.solution.solve(puzzle_input) == 24
|
||||||
|
|
||||||
def test_wait(self):
|
def test_wait(self):
|
||||||
puzzle_input = '''
|
puzzle_input = """
|
||||||
0: 3
|
0: 3
|
||||||
1: 2
|
1: 2
|
||||||
4: 4
|
4: 4
|
||||||
6: 4
|
6: 4
|
||||||
'''.strip()
|
""".strip()
|
||||||
assert self.solution.solve_again(puzzle_input) == 10
|
assert self.solution.solve_again(puzzle_input) == 10
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,11 @@ class Day14TestCase(unittest.TestCase):
|
||||||
self.solution = Solution()
|
self.solution = Solution()
|
||||||
|
|
||||||
def test_used_squares(self):
|
def test_used_squares(self):
|
||||||
assert self.solution.solve('flqrgnkx') == 8108
|
assert self.solution.solve("flqrgnkx") == 8108
|
||||||
|
|
||||||
def test_regions(self):
|
def test_regions(self):
|
||||||
assert self.solution.solve_again('flqrgnkx') == 1242
|
assert self.solution.solve_again("flqrgnkx") == 1242
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
|
|
@ -8,19 +8,19 @@ class Day15TestCase(unittest.TestCase):
|
||||||
self.solution = Solution()
|
self.solution = Solution()
|
||||||
|
|
||||||
def test_40m_pairs(self):
|
def test_40m_pairs(self):
|
||||||
puzzle_input = '''
|
puzzle_input = """
|
||||||
Generator A starts with 65
|
Generator A starts with 65
|
||||||
Generator B starts with 8921
|
Generator B starts with 8921
|
||||||
'''.strip()
|
""".strip()
|
||||||
#assert self.solution.solve(puzzle_input) == 588
|
# assert self.solution.solve(puzzle_input) == 588
|
||||||
|
|
||||||
def test_5k_pairs(self):
|
def test_5k_pairs(self):
|
||||||
puzzle_input = '''
|
puzzle_input = """
|
||||||
Generator A starts with 65
|
Generator A starts with 65
|
||||||
Generator B starts with 8921
|
Generator B starts with 8921
|
||||||
'''.strip()
|
""".strip()
|
||||||
assert self.solution.solve_again(puzzle_input) == 309
|
assert self.solution.solve_again(puzzle_input) == 309
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,9 @@ class Day16TestCase(unittest.TestCase):
|
||||||
self.solution = Solution()
|
self.solution = Solution()
|
||||||
|
|
||||||
def test_something(self):
|
def test_something(self):
|
||||||
puzzle_input = '''s1,x3/4,pe/b'''.strip()
|
puzzle_input = """s1,x3/4,pe/b""".strip()
|
||||||
assert self.solution.solve(puzzle_input, 5) == 'baedc'
|
assert self.solution.solve(puzzle_input, 5) == "baedc"
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ class Day17TestCase(unittest.TestCase):
|
||||||
self.solution = Solution()
|
self.solution = Solution()
|
||||||
|
|
||||||
def test_something(self):
|
def test_something(self):
|
||||||
assert self.solution.solve('3') == 638
|
assert self.solution.solve("3") == 638
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ class Day18TestCase(unittest.TestCase):
|
||||||
self.solution = Solution()
|
self.solution = Solution()
|
||||||
|
|
||||||
def test_something(self):
|
def test_something(self):
|
||||||
puzzle_input = '''
|
puzzle_input = """
|
||||||
set a 1
|
set a 1
|
||||||
add a 2
|
add a 2
|
||||||
mul a a
|
mul a a
|
||||||
|
|
@ -19,11 +19,11 @@ class Day18TestCase(unittest.TestCase):
|
||||||
jgz a -1
|
jgz a -1
|
||||||
set a 1
|
set a 1
|
||||||
jgz a -2
|
jgz a -2
|
||||||
'''.strip()
|
""".strip()
|
||||||
assert self.solution.solve(puzzle_input) == 4
|
assert self.solution.solve(puzzle_input) == 4
|
||||||
|
|
||||||
def test_something_else(self):
|
def test_something_else(self):
|
||||||
puzzle_input = '''
|
puzzle_input = """
|
||||||
snd 1
|
snd 1
|
||||||
snd 2
|
snd 2
|
||||||
snd p
|
snd p
|
||||||
|
|
@ -31,9 +31,9 @@ class Day18TestCase(unittest.TestCase):
|
||||||
rcv b
|
rcv b
|
||||||
rcv c
|
rcv c
|
||||||
rcv d
|
rcv d
|
||||||
'''.strip()
|
""".strip()
|
||||||
assert self.solution.solve_again(puzzle_input) == 3
|
assert self.solution.solve_again(puzzle_input) == 3
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
|
|
@ -8,27 +8,27 @@ class Day19TestCase(unittest.TestCase):
|
||||||
self.solution = Solution()
|
self.solution = Solution()
|
||||||
|
|
||||||
def test_seen(self):
|
def test_seen(self):
|
||||||
puzzle_input = ''' |
|
puzzle_input = """ |
|
||||||
| +--+
|
| +--+
|
||||||
A | C
|
A | C
|
||||||
F---|----E|--+
|
F---|----E|--+
|
||||||
| | | D
|
| | | D
|
||||||
+B-+ +--+
|
+B-+ +--+
|
||||||
|
|
||||||
'''
|
"""
|
||||||
assert self.solution.solve(puzzle_input) == 'ABCDEF'
|
assert self.solution.solve(puzzle_input) == "ABCDEF"
|
||||||
|
|
||||||
def test_steps(self):
|
def test_steps(self):
|
||||||
puzzle_input = ''' |
|
puzzle_input = """ |
|
||||||
| +--+
|
| +--+
|
||||||
A | C
|
A | C
|
||||||
F---|----E|--+
|
F---|----E|--+
|
||||||
| | | D
|
| | | D
|
||||||
+B-+ +--+
|
+B-+ +--+
|
||||||
|
|
||||||
'''
|
"""
|
||||||
assert self.solution.solve_again(puzzle_input) == 38
|
assert self.solution.solve_again(puzzle_input) == 38
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
|
|
@ -8,21 +8,21 @@ class Day20TestCase(unittest.TestCase):
|
||||||
self.solution = Solution()
|
self.solution = Solution()
|
||||||
|
|
||||||
def test_shortest_distance_over_time(self):
|
def test_shortest_distance_over_time(self):
|
||||||
puzzle_input = '''
|
puzzle_input = """
|
||||||
p=< 3,0,0>, v=< 2,0,0>, a=<-1,0,0>
|
p=< 3,0,0>, v=< 2,0,0>, a=<-1,0,0>
|
||||||
p=< 4,0,0>, v=< 0,0,0>, a=<-2,0,0>
|
p=< 4,0,0>, v=< 0,0,0>, a=<-2,0,0>
|
||||||
'''.strip()
|
""".strip()
|
||||||
assert self.solution.solve(puzzle_input, 4) == 0
|
assert self.solution.solve(puzzle_input, 4) == 0
|
||||||
|
|
||||||
def test_something(self):
|
def test_something(self):
|
||||||
puzzle_input = '''
|
puzzle_input = """
|
||||||
p=<-6,0,0>, v=< 3,0,0>, a=< 0,0,0>
|
p=<-6,0,0>, v=< 3,0,0>, a=< 0,0,0>
|
||||||
p=<-4,0,0>, v=< 2,0,0>, a=< 0,0,0>
|
p=<-4,0,0>, v=< 2,0,0>, a=< 0,0,0>
|
||||||
p=<-2,0,0>, v=< 1,0,0>, a=< 0,0,0>
|
p=<-2,0,0>, v=< 1,0,0>, a=< 0,0,0>
|
||||||
p=< 3,0,0>, v=<-1,0,0>, a=< 0,0,0>
|
p=< 3,0,0>, v=<-1,0,0>, a=< 0,0,0>
|
||||||
'''.strip()
|
""".strip()
|
||||||
assert self.solution.solve_again(puzzle_input, 4) == 1
|
assert self.solution.solve_again(puzzle_input, 4) == 1
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,12 @@ class Day21TestCase(unittest.TestCase):
|
||||||
self.solution = Solution()
|
self.solution = Solution()
|
||||||
|
|
||||||
def test_something(self):
|
def test_something(self):
|
||||||
puzzle_input = '''
|
puzzle_input = """
|
||||||
../.# => ##./#../...
|
../.# => ##./#../...
|
||||||
.#./..#/### => #..#/..../..../#..#
|
.#./..#/### => #..#/..../..../#..#
|
||||||
'''.strip()
|
""".strip()
|
||||||
assert self.solution.solve(puzzle_input, 2) == 12
|
assert self.solution.solve(puzzle_input, 2) == 12
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
|
|
@ -26,5 +26,6 @@ class Day22TestCase(unittest.TestCase):
|
||||||
assert self.solution.solve_again(puzzle_input, 100) == 26
|
assert self.solution.solve_again(puzzle_input, 100) == 26
|
||||||
assert self.solution.solve_again(puzzle_input, 10000000) == 2511944
|
assert self.solution.solve_again(puzzle_input, 10000000) == 2511944
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue