Do day 13 and add cleaner solution to day 18.

This commit is contained in:
felixm 2023-12-24 11:51:31 -05:00
parent 30a8489313
commit 053d07dd27
4 changed files with 115 additions and 7 deletions

View File

@ -12,7 +12,9 @@
- Day 10: 180:00; this one was hard for me. - Day 10: 180:00; this one was hard for me.
- Day 11: 68:00; okay but not elegant and way too slow ofc; x-ray solution would have been neat - Day 11: 68:00; okay but not elegant and way too slow ofc; x-ray solution would have been neat
- Day 12: 52:00 and 22:00 for leaderboard; had the right idea and I am good at this type of problem - Day 12: 52:00 and 22:00 for leaderboard; had the right idea and I am good at this type of problem
- ... - Day 13: 90:00; pretty straightforward but way too slow
- Day 14:
- Day 15:
- Day 16: 00:27:30 745; best placement so far, of course still horribly slow - Day 16: 00:27:30 745; best placement so far, of course still horribly slow
- Day 17: a couple of hours; I realized that I need A* after a while; reused - Day 17: a couple of hours; I realized that I need A* after a while; reused
implementation from Project Euler but improved with heapq which was super fun implementation from Project Euler but improved with heapq which was super fun

92
d13.py Normal file
View File

@ -0,0 +1,92 @@
from lib import *
EXAMPLE = """
#.##..##.
..#.##.#.
##......#
##......#
..#.##.#.
..##..##.
#.#.##.#.
#...##..#
#....#..#
..##..###
#####.##.
#####.##.
..##..###
#....#..#
""".replace("\n", "", count=1)
def solve(i: Input, second=False):
res = 0
ps = i.paras()
for p in ps:
g = Input(p).grid2()
row_res, col_res = [], []
rows = g.rows()
cols = g.cols()
for i_row in range(len(rows) - 1):
for i in range(min(i_row + 1, len(rows) - i_row - 1)):
if rows[i_row - i] != rows[i_row + i + 1]:
break
else:
if not second:
res += (i_row + 1) * 100
row_res.append(i_row)
for i_col in range(len(cols) - 1):
for i in range(min(i_col + 1, len(cols) - i_col - 1)):
if cols[i_col - i] != cols[i_col + i + 1]:
break
else:
if not second:
res += (i_col + 1)
col_res.append(i_col)
if not second:
continue
for c in g.all_coords():
g[c] = '.' if g[c] == '#' else '#'
rows = g.rows()
cols = g.cols()
for i_row in range(len(rows) - 1):
for i in range(min(i_row + 1, len(rows) - i_row - 1)):
if rows[i_row - i] != rows[i_row + i + 1]:
break
else:
if not i_row in row_res:
res += (i_row + 1) * 100
row_res.append(i_row)
for i_col in range(len(cols) - 1):
for i in range(min(i_col + 1, len(cols) - i_col - 1)):
if cols[i_col - i] != cols[i_col + i + 1]:
break
else:
if not i_col in col_res:
res += (i_col + 1)
col_res.append(i_col)
g[c] = '.' if g[c] == '#' else '#'
if len(row_res + col_res) != 2:
raise Exception("Unexpected amount of mirrors!!")
return res
def main():
DAY_INPUT = "i13.txt"
print("Example 1:", solve(Input(EXAMPLE)))
print("Solution 1:", solve(Input(DAY_INPUT)))
assert 29846 == solve(Input(DAY_INPUT))
print("Example 2:", solve(Input(EXAMPLE), True))
print("Solution 2:", solve(Input(DAY_INPUT), True))
assert 25401 == solve(Input(DAY_INPUT), True)
if __name__ == "__main__":
main()

22
d18.py
View File

@ -51,8 +51,7 @@ def solve(i: Input, second=False):
to_visit.append(nc) to_visit.append(nc)
return len(set(coords)) return len(set(coords))
def area(ins):
def calc(ins):
c = (0, 0) c = (0, 0)
corners = [] corners = []
for i, (count, d) in enumerate(ins): for i, (count, d) in enumerate(ins):
@ -86,6 +85,20 @@ def calc(ins):
return int(shoelace_area(corners)) return int(shoelace_area(corners))
def area2(ins):
# Solution based on Shoelace area and the idea that the outside area is
# perimate * 1 // 2, and then +1 (for four quarter corners). All other
# corners cancel out to zero.
c = (0, 0)
corners = []
perimeter = 0
for i, (count, d) in enumerate(ins):
c = (c[0] + count * d[0], c[1] + count * d[1])
corners.append(c)
perimeter += count
return int(shoelace_area(corners)) + perimeter // 2 + 1
def solve2(i: Input, second=False): def solve2(i: Input, second=False):
lines = i.lines() lines = i.lines()
ins = [] ins = []
@ -97,7 +110,8 @@ def solve2(i: Input, second=False):
d = int(c[:5], 16) d = int(c[:5], 16)
m = {"0": Grid2D.E, "1": Grid2D.S, "2": Grid2D.W, "3": Grid2D.N}[c[5]] m = {"0": Grid2D.E, "1": Grid2D.S, "2": Grid2D.W, "3": Grid2D.N}[c[5]]
ins.append((d, m)) ins.append((d, m))
return calc(ins) assert area(ins) == area2(ins)
return area(ins)
def debug(): def debug():
@ -113,7 +127,7 @@ def debug():
] ]
# Should be 14 but is 2 because it's going counter-clockwise, but mapping # Should be 14 but is 2 because it's going counter-clockwise, but mapping
# only works for clockwise. # only works for clockwise.
print(calc(ins)) print(area(ins))
def main(): def main():

2
lib.py
View File

@ -133,7 +133,7 @@ class Input:
return self.text.splitlines() return self.text.splitlines()
def paras(self) -> list[list[str]]: def paras(self) -> list[list[str]]:
return [p.splitlines() for p in self.text.split("\n\n")] return [p for p in self.text.split("\n\n")]
def grid2(self) -> Grid2D: def grid2(self) -> Grid2D:
return Grid2D(self.text) return Grid2D(self.text)