2020 day 19 and day 20 part 1
This commit is contained in:
62
2020/d19.py
Normal file
62
2020/d19.py
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
from lib import get_data
|
||||||
|
|
||||||
|
data = get_data(__file__)
|
||||||
|
|
||||||
|
rules = {}
|
||||||
|
msgs = []
|
||||||
|
|
||||||
|
for line in data.splitlines():
|
||||||
|
if len(line.strip()) == 0:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if ":" in line:
|
||||||
|
id, rule = line.split(":")
|
||||||
|
id = int(id)
|
||||||
|
|
||||||
|
branches = [[]]
|
||||||
|
for part in rule.split():
|
||||||
|
if part.startswith('"') and part.endswith('"'):
|
||||||
|
branches = part[1]
|
||||||
|
elif part == "|":
|
||||||
|
assert type(branches) is list
|
||||||
|
branches.append([])
|
||||||
|
else:
|
||||||
|
assert type(branches) is list
|
||||||
|
branches[-1].append(int(part))
|
||||||
|
rules[id] = branches
|
||||||
|
else:
|
||||||
|
msgs.append(line.strip())
|
||||||
|
|
||||||
|
|
||||||
|
def matches(xs, rule):
|
||||||
|
if xs == "" and rule == []:
|
||||||
|
return True
|
||||||
|
elif xs == "" or rule == []:
|
||||||
|
return False
|
||||||
|
|
||||||
|
current = rules[rule[0]]
|
||||||
|
if current == xs[0]:
|
||||||
|
return matches(xs[1:], rule[1:])
|
||||||
|
elif type(current) is str:
|
||||||
|
return False
|
||||||
|
elif len(current) >= 1:
|
||||||
|
for ys in current:
|
||||||
|
if matches(xs, ys + rule[1:]):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
t = 0
|
||||||
|
for m in msgs:
|
||||||
|
if matches(m, rules[0][0]):
|
||||||
|
t += 1
|
||||||
|
print(t)
|
||||||
|
|
||||||
|
rules[8] = [[42], [42, 8]]
|
||||||
|
rules[11] = [[42, 31], [42, 11, 31]]
|
||||||
|
|
||||||
|
t = 0
|
||||||
|
for m in msgs:
|
||||||
|
if matches(m, rules[0][0]):
|
||||||
|
t += 1
|
||||||
|
print(t)
|
||||||
238
2020/d20.py
Normal file
238
2020/d20.py
Normal file
@@ -0,0 +1,238 @@
|
|||||||
|
from collections import defaultdict
|
||||||
|
from lib import get_data, ints
|
||||||
|
from math import isqrt
|
||||||
|
|
||||||
|
data = """Tile 2311:
|
||||||
|
..##.#..#.
|
||||||
|
##..#.....
|
||||||
|
#...##..#.
|
||||||
|
####.#...#
|
||||||
|
##.##.###.
|
||||||
|
##...#.###
|
||||||
|
.#.#.#..##
|
||||||
|
..#....#..
|
||||||
|
###...#.#.
|
||||||
|
..###..###
|
||||||
|
|
||||||
|
Tile 1951:
|
||||||
|
#.##...##.
|
||||||
|
#.####...#
|
||||||
|
.....#..##
|
||||||
|
#...######
|
||||||
|
.##.#....#
|
||||||
|
.###.#####
|
||||||
|
###.##.##.
|
||||||
|
.###....#.
|
||||||
|
..#.#..#.#
|
||||||
|
#...##.#..
|
||||||
|
|
||||||
|
Tile 1171:
|
||||||
|
####...##.
|
||||||
|
#..##.#..#
|
||||||
|
##.#..#.#.
|
||||||
|
.###.####.
|
||||||
|
..###.####
|
||||||
|
.##....##.
|
||||||
|
.#...####.
|
||||||
|
#.##.####.
|
||||||
|
####..#...
|
||||||
|
.....##...
|
||||||
|
|
||||||
|
Tile 1427:
|
||||||
|
###.##.#..
|
||||||
|
.#..#.##..
|
||||||
|
.#.##.#..#
|
||||||
|
#.#.#.##.#
|
||||||
|
....#...##
|
||||||
|
...##..##.
|
||||||
|
...#.#####
|
||||||
|
.#.####.#.
|
||||||
|
..#..###.#
|
||||||
|
..##.#..#.
|
||||||
|
|
||||||
|
Tile 1489:
|
||||||
|
##.#.#....
|
||||||
|
..##...#..
|
||||||
|
.##..##...
|
||||||
|
..#...#...
|
||||||
|
#####...#.
|
||||||
|
#..#.#.#.#
|
||||||
|
...#.#.#..
|
||||||
|
##.#...##.
|
||||||
|
..##.##.##
|
||||||
|
###.##.#..
|
||||||
|
|
||||||
|
Tile 2473:
|
||||||
|
#....####.
|
||||||
|
#..#.##...
|
||||||
|
#.##..#...
|
||||||
|
######.#.#
|
||||||
|
.#...#.#.#
|
||||||
|
.#########
|
||||||
|
.###.#..#.
|
||||||
|
########.#
|
||||||
|
##...##.#.
|
||||||
|
..###.#.#.
|
||||||
|
|
||||||
|
Tile 2971:
|
||||||
|
..#.#....#
|
||||||
|
#...###...
|
||||||
|
#.#.###...
|
||||||
|
##.##..#..
|
||||||
|
.#####..##
|
||||||
|
.#..####.#
|
||||||
|
#..#.#..#.
|
||||||
|
..####.###
|
||||||
|
..#.#.###.
|
||||||
|
...#.#.#.#
|
||||||
|
|
||||||
|
Tile 2729:
|
||||||
|
...#.#.#.#
|
||||||
|
####.#....
|
||||||
|
..#.#.....
|
||||||
|
....#..#.#
|
||||||
|
.##..##.#.
|
||||||
|
.#.####...
|
||||||
|
####.#.#..
|
||||||
|
##.####...
|
||||||
|
##..#.##..
|
||||||
|
#.##...##.
|
||||||
|
|
||||||
|
Tile 3079:
|
||||||
|
#.#.#####.
|
||||||
|
.#..######
|
||||||
|
..#.......
|
||||||
|
######....
|
||||||
|
####.#..#.
|
||||||
|
.#...#.##.
|
||||||
|
#.#####.##
|
||||||
|
..#.###...
|
||||||
|
..#.......
|
||||||
|
..#.###..."""
|
||||||
|
|
||||||
|
data = get_data(__file__)
|
||||||
|
|
||||||
|
|
||||||
|
def top(rows):
|
||||||
|
return rows[0]
|
||||||
|
|
||||||
|
|
||||||
|
def bottom(rows):
|
||||||
|
return rows[-1]
|
||||||
|
|
||||||
|
|
||||||
|
def left(rows):
|
||||||
|
return [row[0] for row in rows]
|
||||||
|
|
||||||
|
|
||||||
|
def right(rows):
|
||||||
|
return [row[-1] for row in rows]
|
||||||
|
|
||||||
|
|
||||||
|
def fliph(rows):
|
||||||
|
return [row[::-1] for row in rows]
|
||||||
|
|
||||||
|
|
||||||
|
def flipv(rows):
|
||||||
|
return rows[::-1]
|
||||||
|
|
||||||
|
|
||||||
|
def rot90(rows):
|
||||||
|
return [row for row in zip(*rows[::-1])]
|
||||||
|
|
||||||
|
|
||||||
|
def rot180(rows):
|
||||||
|
return rot90(rot90(rows))
|
||||||
|
|
||||||
|
|
||||||
|
def rot270(rows):
|
||||||
|
return rot90(rot90(rot90(rows)))
|
||||||
|
|
||||||
|
|
||||||
|
def get_borders(rows):
|
||||||
|
return tuple(top(rows)), tuple(right(rows)), tuple(bottom(rows)), tuple(left(rows))
|
||||||
|
|
||||||
|
|
||||||
|
TOP = 0
|
||||||
|
RIGHT = 1
|
||||||
|
BOTTOM = 2
|
||||||
|
LEFT = 3
|
||||||
|
|
||||||
|
|
||||||
|
def all(rows) -> list:
|
||||||
|
orientations = [
|
||||||
|
rows,
|
||||||
|
rot90(rows),
|
||||||
|
rot180(rows),
|
||||||
|
rot270(rows),
|
||||||
|
fliph(rows),
|
||||||
|
flipv(rows),
|
||||||
|
rot90(fliph(rows)),
|
||||||
|
rot90(flipv(rows)),
|
||||||
|
rot180(fliph(rows)),
|
||||||
|
rot180(flipv(rows)),
|
||||||
|
rot270(fliph(rows)),
|
||||||
|
rot270(flipv(rows)),
|
||||||
|
]
|
||||||
|
return [get_borders(orientation) for orientation in orientations]
|
||||||
|
|
||||||
|
|
||||||
|
tiles = []
|
||||||
|
for p in data.strip().split("\n\n"):
|
||||||
|
lines = p.splitlines()
|
||||||
|
(id,) = ints(lines[0])
|
||||||
|
tiles.append((id, all(lines[1:])))
|
||||||
|
|
||||||
|
|
||||||
|
rights = defaultdict(list)
|
||||||
|
bottoms = defaultdict(list)
|
||||||
|
|
||||||
|
for id, variants in tiles:
|
||||||
|
for variant in variants:
|
||||||
|
rights[variant[LEFT]].append((id, variant))
|
||||||
|
bottoms[variant[TOP]].append((id, variant))
|
||||||
|
|
||||||
|
num_tiles = len(tiles)
|
||||||
|
rows = isqrt(len(tiles))
|
||||||
|
|
||||||
|
|
||||||
|
def dfs(id_set, id_list, tiles_used):
|
||||||
|
if len(tiles_used) == num_tiles:
|
||||||
|
return id_list
|
||||||
|
|
||||||
|
i = len(tiles_used)
|
||||||
|
id_variants = None
|
||||||
|
if i < rows: # first row
|
||||||
|
id_variants = rights[tiles_used[i - 1][RIGHT]]
|
||||||
|
elif i % rows == 0: # first tile in row
|
||||||
|
id_variants = bottoms[tiles_used[i - rows][BOTTOM]]
|
||||||
|
else:
|
||||||
|
id_variants = set(bottoms[tiles_used[i - rows][BOTTOM]])
|
||||||
|
id_variants &= set(rights[tiles_used[i - 1][RIGHT]])
|
||||||
|
id_variants = list(id_variants)
|
||||||
|
|
||||||
|
assert id_variants is not None
|
||||||
|
|
||||||
|
for id, variant in id_variants:
|
||||||
|
if id in id_set:
|
||||||
|
continue
|
||||||
|
id_set.add(id)
|
||||||
|
id_list.append(id)
|
||||||
|
tiles_used.append(variant)
|
||||||
|
r = dfs(id_set, id_list, tiles_used)
|
||||||
|
if r is not False:
|
||||||
|
return r
|
||||||
|
tiles_used.pop()
|
||||||
|
id_set.remove(id)
|
||||||
|
id_list.pop()
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
for id, tile_variants in tiles:
|
||||||
|
for tile in tile_variants:
|
||||||
|
r = dfs(set([id]), [id], [tile])
|
||||||
|
if type(r) is list:
|
||||||
|
print(r[0] * r[-1] * r[rows - 1] * r[-rows])
|
||||||
|
exit(0)
|
||||||
|
else:
|
||||||
|
print("no result")
|
||||||
@@ -157,7 +157,8 @@ Solutions and utility script for Advent of Code challenges in Python.
|
|||||||
- Day 16: 33:00 (Not too unhappy really.)
|
- Day 16: 33:00 (Not too unhappy really.)
|
||||||
- Day 17: 10:00 (40th)
|
- Day 17: 10:00 (40th)
|
||||||
- Day 18: 80:00 (I am struggling with stuff where parsing is involved)
|
- Day 18: 80:00 (I am struggling with stuff where parsing is involved)
|
||||||
- Day 19:
|
- Day 19: 78:00 (Should have been faster)
|
||||||
|
- Day 20:
|
||||||
|
|
||||||
## AoC 2022
|
## AoC 2022
|
||||||
|
|
||||||
|
|||||||
3
lib.py
3
lib.py
@@ -202,6 +202,9 @@ def str_to_ints(line: str) -> list[int]:
|
|||||||
return list(map(int, r.findall(line)))
|
return list(map(int, r.findall(line)))
|
||||||
|
|
||||||
|
|
||||||
|
ints = str_to_ints
|
||||||
|
|
||||||
|
|
||||||
def str_to_lines_no_empty(text: str) -> list[str]:
|
def str_to_lines_no_empty(text: str) -> list[str]:
|
||||||
return list(filter(lambda l: l.strip() != "", text.splitlines()))
|
return list(filter(lambda l: l.strip() != "", text.splitlines()))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user