Day 11, 12, 13.

This commit is contained in:
2023-12-07 23:57:09 -05:00
parent 20715bf8d9
commit 54d4614884
7 changed files with 414 additions and 16 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
__pycache__

View File

@@ -10,4 +10,7 @@
- Day 8: 61:00 and 10:00 for leaderboard; I need template code for searching coordinate systems - Day 8: 61:00 and 10:00 for leaderboard; I need template code for searching coordinate systems
- Day 9: 58:00 and 7:32 for leaderboard; I need code for 2D stuff - Day 9: 58:00 and 7:32 for leaderboard; I need code for 2D stuff
- Day 10: 25:20 and 12:17 for leaderboard; okay, okay - Day 10: 25:20 and 12:17 for leaderboard; okay, okay
- Day 11: - Day 11: 45:00 and 18:00 for leaderboard; arg, it was doable man
- Day 12: 39:45 and 9:46 for leaderboard; the people are ready for there searches :D
- Day 13: 44:00 and 12:56 for leaderboard; these people are just good, seriously
- Day 14:

143
d11.py Normal file
View File

@@ -0,0 +1,143 @@
import re
from string import ascii_lowercase, ascii_uppercase
def extract_single_digit(line: str) -> int:
r = re.compile(r"\d+")
for m in r.findall(line):
return int(m)
raise Exception("No single digit sequence in '{line}'")
def extract_digits_list(line: str) -> list[int]:
r = re.compile(r"\d+")
return list(map(int, r.findall(line)))
EXAMPLE = """
Monkey 0:
Starting items: 79, 98
Operation: new = old * 19
Test: divisible by 23
If true: throw to monkey 2
If false: throw to monkey 3
Monkey 1:
Starting items: 54, 65, 75, 74
Operation: new = old + 6
Test: divisible by 19
If true: throw to monkey 2
If false: throw to monkey 0
Monkey 2:
Starting items: 79, 60, 97
Operation: new = old * old
Test: divisible by 13
If true: throw to monkey 1
If false: throw to monkey 3
Monkey 3:
Starting items: 74
Operation: new = old + 3
Test: divisible by 17
If true: throw to monkey 0
If false: throw to monkey 1
"""
def clean(text: str) -> list[str]:
return list(filter(lambda l: l.strip() != "", text.splitlines()))
def get_monkesy(lines):
monkeys = []
for i, line in enumerate(lines):
if line.startswith("Monkey"):
d = extract_single_digit(line)
monkeys.append([d])
elif line.strip().startswith("Starting"):
d = extract_digits_list(line)
monkeys[-1].append(d)
elif line.strip().startswith("Operation"):
if "old * old" in line:
f = lambda y: y * y
monkeys[-1].append(f)
elif "*" in line:
d = extract_single_digit(line)
f = lambda x: (lambda y: x * y)
f = f(d)
monkeys[-1].append(f)
elif "+" in line:
d = extract_single_digit(line)
f = lambda x: (lambda y: x + y)
f = f(d)
monkeys[-1].append(f)
else:
raise Exception(line)
elif line.strip().startswith("Test"):
d = extract_single_digit(line)
monkeys[-1].append(d)
elif line.strip().startswith("If true"):
d = extract_single_digit(line)
monkeys[-1].append(d)
elif line.strip().startswith("If false"):
d = extract_single_digit(line)
monkeys[-1].append(d)
else:
print(line)
raise Exception("Unexpected line.")
for m in monkeys:
m.append(0)
return monkeys
def solve(lines: list[str]):
monkeys = get_monkesy(lines)
for _ in range(20):
for monkey in monkeys:
id, items, op, test, if_true, if_false, count = monkey
while items:
item = items.pop()
monkey[6] += 1
worry = item
worry = op(worry)
worry //= 3
if worry % test == 0:
monkeys[if_true][1].append(worry)
else:
monkeys[if_false][1].append(worry)
monkeys[id][1] = monkeys[id][1][1:]
counts = sorted([m[6] for m in monkeys])[-2:]
return counts[0] * counts[1]
def solve2(lines: list[str]):
monkeys = get_monkesy(lines)
mod = 1
for m in monkeys:
mod *= m[3]
for _ in range(10000):
for monkey in monkeys:
id, items, op, test, if_true, if_false, count = monkey
for item in list(items):
monkey[6] += 1
worry = item
worry = op(worry)
worry %= mod
if worry % test == 0:
monkeys[if_true][1].append(worry)
else:
monkeys[if_false][1].append(worry)
monkeys[id][1] = monkeys[id][1][1:]
counts = sorted([m[6] for m in monkeys])[-2:]
return counts[0] * counts[1]
def main():
example = clean(EXAMPLE)
print("Example 1:", solve(example))
data = clean(open("i11.txt").read())
print("Solution 1:", solve(data))
example = clean(EXAMPLE)
print("Example 2:", solve2(example))
data = clean(open("i11.txt").read())
print("Solution 2:", solve2(data))
if __name__ == "__main__":
main()

120
d12.py Normal file
View File

@@ -0,0 +1,120 @@
import lib
EXAMPLE = """
Sabqponm
abcryxxl
accszExk
acctuvwj
abdefghi
"""
def neighbors_4(row, col, rows, cols):
n = []
for r, c in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
new_row, new_col = row + r, col + c
if new_row >= 0 and new_row < rows and new_col >= 0 and new_col < cols:
n.append((new_row, new_col))
return n
def solve(lines: list[str]):
start = (0, 0)
end = (0, 0)
rows = len(lines)
cols = len(lines[0])
heights = []
dists = []
for (row, line) in enumerate(lines):
heights.append([])
dists.append([])
for (col, c) in enumerate(line):
if c == 'S':
start = (row, col)
heights[row].append(0)
dists[row].append(0)
elif c == 'E':
end = (row, col)
heights[row].append(26)
dists[row].append(2**16)
else:
heights[row].append(ord(lines[row][col]) - ord('a'))
dists[row].append(2**16)
active_fields = [start]
while active_fields:
row, col = active_fields.pop()
current_dist = dists[row][col]
current_height = heights[row][col]
for row, col in neighbors_4(row, col, rows, cols):
pot_height = heights[row][col]
if current_height < pot_height - 1:
continue
if current_dist + 1 < dists[row][col]:
dists[row][col] = current_dist + 1
active_fields.append((row, col))
# for row in dists:
# print(row)
# 34:00
return dists[end[0]][end[1]]
def solve2(lines: list[str]):
starts = []
all_dists =[]
for (row, line) in enumerate(lines):
for (col, c) in enumerate(line):
if c == 'S' or c == 'a':
starts.append((row, col))
for start in starts:
end = (0, 0)
rows = len(lines)
cols = len(lines[0])
heights = []
dists = []
for (row, line) in enumerate(lines):
heights.append([])
dists.append([])
for (col, c) in enumerate(line):
if row == start[0] and col == start[1]:
heights[row].append(0)
dists[row].append(0)
elif c == 'E':
end = (row, col)
heights[row].append(26)
dists[row].append(2**16)
else:
heights[row].append(ord(lines[row][col]) - ord('a'))
dists[row].append(2**16)
active_fields = [start]
while active_fields:
row, col = active_fields.pop()
current_dist = dists[row][col]
current_height = heights[row][col]
for row, col in neighbors_4(row, col, rows, cols):
pot_height = heights[row][col]
if current_height < pot_height - 1:
continue
if current_dist + 1 < dists[row][col]:
dists[row][col] = current_dist + 1
active_fields.append((row, col))
all_dists.append(dists[end[0]][end[1]])
# 39:45
return min(all_dists)
def main():
lines = lib.str_to_lines_no_empty(EXAMPLE)
print("Example 1:", solve(lines))
lines = lib.str_to_lines_no_empty(open("i12.txt").read())
print("Solution 1:", solve(lines))
lines = lib.str_to_lines_no_empty(EXAMPLE)
print("Example 2:", solve2(lines))
lines = lib.str_to_lines_no_empty(open("i12.txt").read())
print("Solution 2:", solve2(lines))
if __name__ == "__main__":
main()

115
d13.py Normal file
View File

@@ -0,0 +1,115 @@
import lib
EXAMPLE = """[1,1,3,1,1]
[1,1,5,1,1]
[[1],[2,3,4]]
[[1],4]
[9]
[[8,7,6]]
[[4,4],4,4]
[[4,4],4,4,4]
[7,7,7,7]
[7,7,7]
[]
[3]
[[[]]]
[[]]
[1,[2,[3,[4,[5,6,7]]]],8,9]
[1,[2,[3,[4,[5,6,0]]]],8,9]
"""
def right_order(a, b):
if not a and not b:
return None
elif not a:
return True
elif not b:
return False
l, r = a[0], b[0]
if type(l) is int and type(r) is int:
if l < r:
return True
elif l > r:
return False
else:
return right_order(a[1:], b[1:])
if type(l) is int:
l = [l]
if type(r) is int:
r = [r]
o = right_order(l, r)
if o is not None:
return o
return right_order(a[1:], b[1:])
def solve(lines: list[str]):
res = 0
pairs = [[]]
for (i, line) in enumerate(lines):
if line.strip() == "":
pairs.append([])
else:
pairs[-1].append(eval(line))
for i, p in enumerate(pairs):
if not len(p) == 2:
continue
a, b = p[0], p[1]
o = right_order(a, b)
if o is True:
res += i + 1
if o is None:
raise Exception("NO DECISION")
# 37:00
return res
def solve2(lines: list[str]):
res = 0
packets = list(map(eval, lines))
p1 = [[2]]
packets.append(p1)
p2 = [[6]]
packets.append(p2)
resorted = True
while resorted:
resorted = False
for i in range(len(packets) - 1):
if not right_order(packets[i], packets[i + 1]):
packets[i], packets[i + 1] = packets[i + 1], packets[i]
resorted = True
p1i, p2i = 0, 0
for (i, p) in enumerate(packets):
if p == p1:
p1i = i + 1
elif p == p2:
p2i = i + 1
print(p1i, p2i)
# 44:00
return p1i * p2i
def main():
lines = lib.str_to_lines(EXAMPLE)
print("Example 1:", solve(lines))
lines = lib.str_to_lines(open("i13.txt").read())
print("Solution 1:", solve(lines))
lines = lib.str_to_lines_no_empty(EXAMPLE)
print("Example 2:", solve2(lines))
lines = lib.str_to_lines_no_empty(open("i13.txt").read())
print("Solution 2:", solve2(lines))
if __name__ == "__main__":
main()

28
dx.py
View File

@@ -1,39 +1,37 @@
import re import lib
from string import ascii_lowercase, ascii_uppercase
EXAMPLE = """ EXAMPLE = """
""" """
def clean(text: str) -> list[str]:
return list(filter(lambda l: l.strip() != "", text.splitlines()))
def solve(lines: list[str]): def solve(lines: list[str]):
res = 0 res = 0
for i, line in enumerate(lines): for (i, line) in enumerate(lines):
print(i, line) print(i, line)
# digits = lib.str_to_int_list(line)
# digit = lib.str_to_single_int(line)
return res return res
def solve2(lines: list[str]): def solve2(lines: list[str]):
res = 0 res = 0
for i, line in enumerate(lines): for (i, line) in enumerate(lines):
print(i, line) print(i, line)
return res return res
def main(): def main():
example = clean(EXAMPLE) lines = lib.str_to_lines_no_empty(EXAMPLE)
print("Example 1:", solve(example)) print("Example 1:", solve(lines))
return return
data = clean(open("i6.txt").read()) lines = lib.str_to_lines_no_empty(open("ix.txt").read())
print("Solution 1:", solve(data)) print("Solution 1:", solve(lines))
return return
example = clean(EXAMPLE) lines = lib.str_to_lines_no_empty(EXAMPLE)
print("Example 2:", solve2(example)) print("Example 2:", solve2(lines))
return return
data = clean(open("i6.txt").read()) lines = lib.str_to_lines_no_empty(open("ix.txt").read())
print("Solution 2:", solve2(data)) print("Solution 2:", solve2(lines))
if __name__ == "__main__": if __name__ == "__main__":
main() main()

18
lib.py Normal file
View File

@@ -0,0 +1,18 @@
import re
def str_to_single_int(line: str) -> int:
line = line.replace(" ", "")
r = re.compile(r"\d+")
for m in r.findall(line):
return int(m)
raise Exception("No single digit sequence in '{line}'")
def str_to_int_list(line: str) -> list[int]:
r = re.compile(r"\d+")
return list(map(int, r.findall(line)))
def str_to_lines_no_empty(text: str) -> list[str]:
return list(filter(lambda l: l.strip() != "", text.splitlines()))
def str_to_lines(text: str) -> list[str]:
return list(text.splitlines())