Solve 10 and 11.

main
felixm 2023-12-15 18:20:31 -05:00
parent 9485fbae1d
commit 437498a745
7 changed files with 396 additions and 2 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
__pycache__
*.txt

View File

@ -7,5 +7,8 @@
- Day 5: 1st 25:00, 2nd 1:55:00; Required patience and accuracy
- Day 6: 13:54; I was slow because I thought it is much harder?
- Day 7: 75:00; leaderboard 16:00... that was just bad; no excuse
- Day 8: 57:00; my input parse function did not consider negative values...
- Day 9:
- Day 8: 25:00; I was doing pretty decent here.
- Day 9: 57:00; my input parse function did not consider negative values...
- Day 10: 180:00; this one was hard for me.
- Day 11: 68:00; okay but not elegant and way too slow ofc.
- Day 12:

218
d10.py Normal file
View File

@ -0,0 +1,218 @@
import lib
EXAMPLE = """
..F7.
.FJ|.
SJ.L7
|F--J
LJ...
"""
EXAMPLE2 = """
...........
.S-------7.
.|F-----7|.
.||.....||.
.||.....||.
.|L-7.F-J|.
.|..|.|..|.
.L--J.L--J.
...........
"""
EXAMPLE3 = """
..........
.S------7.
.|F----7|.
.||OOOO||.
.||OOOO||.
.|L-7F-J|.
.|II||II|.
.L--JL--J.
..........
"""
EXAMPLE4 = """
FF7FSF7F7F7F7F7F---7
L|LJ||||||||||||F--J
FL-7LJLJ||||||LJL-77
F--JF--7||LJLJIF7FJ-
L---JF-JLJIIIIFJLJJ7
|F|F-JF---7IIIL7L|7|
|FFJF7L7F-JF7IIL---7
7-L-JL7||F7|L7F-7F7|
L.L7LFJ|||||FJL7||LJ
L7JLJL-JLJLJL--JLJ.L
"""
# | is a vertical pipe connecting north and south.
# - is a horizontal pipe connecting east and west.
# L is a 90-degree bend connecting north and east.
# J is a 90-degree bend connecting north and west.
# 7 is a 90-degree bend connecting south and west.
# F is a 90-degree bend connecting south and east.
# . is ground; there is no pipe in this tile.
# S is the starting position of the animal; there is a pipe on this tile, but your sketch doesn't show what shape the pipe has.
# Mapping of in-direction to out-direction for each piece.
DIRS = {
'|': {
(1, 0): (1, 0),
(-1, 0): (-1, 0),
},
'-': {
(0, -1): (0, -1),
(0, 1): (0, 1),
},
'L': {
(1, 0): (0, 1),
(0, -1): (-1, 0),
},
'J': {
(0, 1): (-1, 0),
(1, 0): (0, -1),
},
'7': {
(0, 1): (1, 0),
(-1, 0): (0, -1),
},
'F': {
(-1, 0): (0, 1),
(0, -1): (1, 0),
}
}
RIGHTS = {
'|': {
(1, 0): [(0, -1)],
(-1, 0): [(0, 1)],
},
'-': {
(0, -1): [(-1, 0)],
(0, 1): [(1, 0)],
},
'L': {
(1, 0): [(0, -1), (1, 0)],
(0, -1): [(-1, 1)],
},
'J': {
(0, 1): [(1, 0), (0, 1)],
(1, 0): [(-1, -1)],
},
'7': {
(0, 1): [(1, -1)],
(-1, 0): [(0, 1), (-1, 0)],
},
'F': {
(-1, 0): [(1, 1)],
(0, -1): [(-1, 0), (0, -1)],
}
}
def solve(lines: list[str], return_path=False):
res = 0
maze = []
start = ()
max_path, max_right = [], []
maze = list(map(list, lines))
for i, row in enumerate(maze):
for j, col in enumerate(row):
if col == "S":
start = (i , j)
row_max, col_max = len(maze), len(maze[0])
for current_dir in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
current_field = start
steps = 0
path = []
right = []
# print(f"START: {start} {current_dir=}")
while True:
path.append(current_field)
next_field = (current_field[0] + current_dir[0], current_field[1] + current_dir[1])
if next_field == start:
break
if next_field[0] < 0 or next_field[1] < 0 or next_field[0] >= row_max or next_field[1] >= col_max:
# print(f"BREAK: Cannot go to {next_field=}!")
break
prev_dir = current_dir
next_char = maze[next_field[0]][next_field[1]]
try:
current_dir = DIRS[next_char][current_dir]
except KeyError:
# print(f"BREAK: Cannot go from {current_field=} with {current_dir=} to {next_field=} ({next_char})!")
break
for rights in RIGHTS[next_char][prev_dir]:
rf = (next_field[0] + rights[0], next_field[1] + rights[1])
right.append(rf)
current_field = next_field
steps += 1
res = max(res, (steps + 1) // 2)
if len(path) > len(max_path):
max_path = path
max_right = right
if return_path:
return res, max_path, max_right
else:
return res
def solve2(lines: list[str]):
row_max = len(lines)
col_max = len(lines[0])
length, path, right = solve(lines, True)
def clean(fields):
fields = list(set(fields))
cleaned = []
for f in fields:
if f in path:
continue
if f[0] < 0 or f[1] < 0 or f[0] >= row_max or f[1] >= col_max:
continue
cleaned.append(f)
return cleaned
right = clean(right)
visited = set()
to_visit = list(right)
while to_visit:
current = to_visit.pop()
for nb in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
f = (current[0] + nb[0], current[1] + nb[1])
if f[0] < 0 or f[1] < 0 or f[0] >= row_max or f[1] >= col_max:
continue
if f not in visited and f not in path:
right.append(f)
to_visit.append(f)
visited.add(f)
right = clean(right)
n_all = row_max * col_max
n_right = len(right)
n_left = n_all - n_right - len(path)
return min(n_left, n_right)
def main():
lines = lib.str_to_lines_no_empty(EXAMPLE)
print("Example 1:", solve(lines))
lines = lib.str_to_lines_no_empty(open("i10.txt").read())
print("Solution 1:", solve(lines))
lines = lib.str_to_lines_no_empty(EXAMPLE4)
print("Example 2:", solve2(lines))
lines = lib.str_to_lines_no_empty(open("i10.txt").read())
print("Solution 2:", solve2(lines))
if __name__ == "__main__":
main()

111
d11.py Normal file
View File

@ -0,0 +1,111 @@
import lib
EXAMPLE = """
...#......
.......#..
#.........
..........
......#...
.#........
.........#
..........
.......#..
#...#.....
"""
def mdist(a, b):
return abs(a[0] - b[0]) + abs(a[1] - b[1])
def solve(lines: list[str]):
res = 0
g = list(map(list, lines))
er = []
for (i, r) in enumerate(g):
if "#" not in r:
er.append(i)
ec = []
for j in range(len(g[0])):
for row in g:
if "#" == row[j]:
break
else:
ec.append(j)
for r in reversed(er):
g.insert(r, ["." for _ in range(len(g[0]))])
for row in g:
for c in reversed(ec):
row.insert(c, ".")
# for row in g:
# print("".join(row))
gxs = []
for (row, line) in enumerate(g):
for (col, c) in enumerate(line):
if c == '#':
gxs.append((row, col))
for i in range(len(gxs)):
for j in range(i, len(gxs)):
a, b = gxs[i], gxs[j]
d = mdist(a, b)
# print(a, b, d)
res += d
# 16:00
return res
def solve2(lines: list[str], factor):
res = 0
g = list(map(list, lines))
gxs = []
for (row, line) in enumerate(g):
for (col, c) in enumerate(line):
if c == '#':
gxs.append((row, col, row, col))
for (row_i, row) in enumerate(g):
if "#" not in row:
for i in range(len(gxs)):
row, col, orig_row, orig_col = gxs[i]
if orig_row > row_i:
gxs[i] = (row + factor, col, orig_row, orig_col)
for col_j in range(len(g[0])):
for row in g:
if "#" == row[col_j]:
break
else:
for i in range(len(gxs)):
row, col, orig_row, orig_col = gxs[i]
if orig_col > col_j:
gxs[i] = (row, col + factor, orig_row, orig_col)
for i in range(len(gxs)):
for j in range(i, len(gxs)):
a, b = gxs[i], gxs[j]
d = mdist(a, b)
# print(a, b, d)
res += d
# 16:00
return res
def main():
lines = lib.str_to_lines_no_empty(EXAMPLE)
print("Example 1:", solve(lines))
lines = lib.str_to_lines_no_empty(open("i11.txt").read())
print("Solution 1:", solve(lines))
lines = lib.str_to_lines_no_empty(EXAMPLE)
print("Example 2:", solve2(lines, 99))
lines = lib.str_to_lines_no_empty(open("i11.txt").read())
print("Solution 2:", solve2(lines, 10**6 - 1))
if __name__ == "__main__":
main()

43
d12.py Normal file
View File

@ -0,0 +1,43 @@
import lib
EXAMPLE = """
"""
def solve(lines: list[str]):
res = 0
# g = list(map(list, lines))
# for (ri, r) in enumerate(g):
# for (ci, c) in enumerate(r):
# pass
for (i, line) in enumerate(lines):
print(i, line)
# digits = lib.str_to_int_list(line)
# digit = lib.str_to_single_int(line)
return res
def solve2(lines: list[str]):
res = 0
for (i, line) in enumerate(lines):
print(i, line)
return res
def main():
lines = lib.str_to_lines_no_empty(EXAMPLE)
print("Example 1:", solve(lines))
return
lines = lib.str_to_lines_no_empty(open("i12.txt").read())
print("Solution 1:", solve(lines))
return
lines = lib.str_to_lines_no_empty(EXAMPLE)
print("Example 2:", solve2(lines))
return
lines = lib.str_to_lines_no_empty(open("i12.txt").read())
print("Solution 2:", solve2(lines))
if __name__ == "__main__":
main()

6
dx.py
View File

@ -5,6 +5,12 @@ EXAMPLE = """
def solve(lines: list[str]):
res = 0
# g = list(map(list, lines))
# for (ri, r) in enumerate(g):
# for (ci, c) in enumerate(r):
# pass
for (i, line) in enumerate(lines):
print(i, line)
# digits = lib.str_to_int_list(line)

12
get.sh Executable file
View File

@ -0,0 +1,12 @@
#!/bin/bash
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <day>"
exit 1
fi
DAY=$1
SESSION_COOKIE=$(keyring get aoc-session-cookie felixm)
echo $SESSION_COOKIE
curl "https://adventofcode.com/2023/day/$DAY/input" --cookie "session=$SESSION_COOKIE" > "i$DAY.txt"