Skip to content

Commit cfa20a0

Browse files
committed
Add days 11,12,13,14, 2016
1 parent e9c2a83 commit cfa20a0

File tree

4 files changed

+171
-0
lines changed

4 files changed

+171
-0
lines changed

2016/day11/solution.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
from itertools import combinations
2+
from collections import deque
3+
4+
5+
def bad_state(chips, generators):
6+
for chip, gen in zip(chips, generators):
7+
for other_gen in generators:
8+
if gen == other_gen:
9+
continue
10+
if chip == other_gen and chip != gen:
11+
return True
12+
return False
13+
14+
15+
def solve(chips, generators):
16+
q = deque([(0, 1, chips, generators)])
17+
seen = set()
18+
while q:
19+
steps, floor, chips, generators = q.popleft()
20+
if (floor, chips, generators) in seen:
21+
continue
22+
seen.add((floor, chips, generators))
23+
if all(chip == 4 for chip in chips) and all(gen == 4 for gen in generators):
24+
return steps
25+
# Purge wrong states: if any chip is at a floor with another generator but not its own generator, then we purge.
26+
if bad_state(chips, generators):
27+
continue
28+
# Need to move one or two items to a floor above or below.
29+
avail_items = [i for i, x in enumerate(chips) if x == floor]
30+
avail_items += [i + len(chips) for i, x in enumerate(generators) if x == floor]
31+
for new_floor in {floor - 1, floor + 1} & {1, 2, 3, 4}:
32+
for items in combinations(avail_items + [None], 2):
33+
new_chips = list(chips)
34+
new_generators = list(generators)
35+
for item in items:
36+
if item is not None:
37+
if item < len(chips):
38+
new_chips[item] = new_floor
39+
else:
40+
new_generators[item - len(chips)] = new_floor
41+
q.append((steps + 1, new_floor, tuple(new_chips), tuple(new_generators)))
42+
43+
# Part 1
44+
print(solve((1, 1, 3, 2, 2), (1, 1, 2, 2, 2)))
45+
46+
# Part 2
47+
print(solve((1, 1, 3, 2, 2, 1, 1), (1, 1, 2, 2, 2, 1, 1)))

2016/day12/solution.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
with open("input") as f:
2+
inp = f.read().strip()
3+
4+
instr = []
5+
for line in inp.split("\n"):
6+
op, *rest = line.split(" ")
7+
instr.append((op, rest))
8+
9+
10+
def solve(c):
11+
register = {x: 0 for x in ("a", "b", "c", "d")}
12+
register["c"] = c
13+
pointer = 0
14+
while pointer < len(instr):
15+
op, rest = instr[pointer]
16+
if op == "cpy":
17+
val, target = rest
18+
register[target] = int(val) if val.isnumeric() else int(register[val])
19+
elif op == "inc":
20+
register[rest[0]] += 1
21+
elif op == "dec":
22+
register[rest[0]] -= 1
23+
elif op == "jnz":
24+
x, y = rest
25+
decider = int(x) if x.isnumeric() else register[x]
26+
if decider != 0:
27+
pointer += int(y)
28+
continue
29+
pointer += 1
30+
return register["a"]
31+
32+
# Part 1
33+
print(solve(0))
34+
35+
# Part 2
36+
print(solve(1))

2016/day13/solution.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from collections import deque
2+
3+
4+
def is_open(x, y):
5+
res = x*x + 3*x + 2*x*y + y + y*y + 1364
6+
return bin(res)[2:].count("1") % 2 == 0
7+
8+
9+
# Part 1
10+
sx, sy = 1, 1
11+
ex, ey = 31, 39
12+
seen = set()
13+
q = deque([(0, sx, sy)])
14+
while q:
15+
steps, x, y = q.popleft()
16+
if (x, y) == (ex, ey):
17+
print(steps)
18+
break
19+
if (x, y) in seen:
20+
continue
21+
seen.add((x, y))
22+
for dx, dy in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
23+
nx = x + dx
24+
ny = y + dy
25+
if nx >= 0 and ny >= 0 and is_open(nx, ny):
26+
q.append((steps + 1, nx, ny))
27+
28+
29+
# Part 2
30+
sx, sy = 1, 1
31+
seen = set()
32+
q = deque([(0, sx, sy)])
33+
while q:
34+
steps, x, y = q.popleft()
35+
if steps > 50:
36+
continue
37+
if (x, y) in seen:
38+
continue
39+
seen.add((x, y))
40+
for dx, dy in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
41+
nx = x + dx
42+
ny = y + dy
43+
if nx >= 0 and ny >= 0 and is_open(nx, ny):
44+
q.append((steps + 1, nx, ny))
45+
46+
print(len(seen))

2016/day14/solution.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import hashlib
2+
import re
3+
from functools import cache
4+
5+
inp = "ngcjuoqr"
6+
7+
@cache
8+
def hash_pt1(i):
9+
return hashlib.md5((inp + str(i)).encode()).hexdigest()
10+
11+
12+
@cache
13+
def hash_pt2(i):
14+
to_hash = inp + str(i)
15+
for _ in range(2017):
16+
res = hashlib.md5(to_hash.encode()).hexdigest()
17+
to_hash = res
18+
return res
19+
20+
21+
def solve(part2 = False):
22+
hash_fct = hash_pt2 if part2 else hash_pt1
23+
i = 0
24+
n_key = 0
25+
while True:
26+
three_peat = re.search(r"(.)\1{2,}",hash_fct(i))
27+
if three_peat:
28+
char = three_peat.group()[0]
29+
for j in range(i + 1, i + 1001):
30+
if re.search(fr"{re.escape(char)}{{5,}}", hash_fct(j)):
31+
n_key += 1
32+
break
33+
if n_key == 64:
34+
return i
35+
i += 1
36+
37+
38+
# Part 1
39+
print(solve())
40+
41+
# Part 2
42+
print(solve(True))

0 commit comments

Comments
 (0)