Compare commits
3 Commits
c5813e168b
...
9d2cd556b2
| Author | SHA1 | Date | |
|---|---|---|---|
| 9d2cd556b2 | |||
| 65d1a85912 | |||
| 9fcc902703 |
21
README.md
21
README.md
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
- Day 1: 40:00 (I don't know what I am doing.)
|
- Day 1: 40:00 (I don't know what I am doing.)
|
||||||
- Day 2: 14:15 (Okay, but far way from leaderboard.)
|
- Day 2: 14:15 (Okay, but far way from leaderboard.)
|
||||||
- Day 3: 1st 20:00, 2nd 70:00... (I had a logic error that took me a while to find.)
|
- Day 3: 1st 20:00, 2nd 70:00... (I had a logic error that took me a while to
|
||||||
|
find.)
|
||||||
- Day 4: 1st 9:06, 2nd 22:31; it wasn't hard but I didn't think quick enough :/
|
- Day 4: 1st 9:06, 2nd 22:31; it wasn't hard but I didn't think quick enough :/
|
||||||
- Day 5: 1st 25:00, 2nd 1:55:00; Required patience and accuracy
|
- 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 6: 13:54; I was slow because I thought it is much harder?
|
||||||
@@ -10,8 +11,10 @@
|
|||||||
- Day 8: 25:00; I was doing pretty decent here.
|
- Day 8: 25:00; I was doing pretty decent here.
|
||||||
- Day 9: 57:00; my input parse function did not consider negative values...
|
- Day 9: 57:00; my input parse function did not consider negative values...
|
||||||
- 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
|
||||||
- Day 12: 52:00 and 22:00 for leaderboard; had the right idea and I am good at this type of problem
|
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 13: 90:00; pretty straightforward but way too slow
|
- Day 13: 90:00; pretty straightforward but way too slow
|
||||||
- Day 14: 5:55 for first and then 48:00; straightforward but slow, ofc
|
- Day 14: 5:55 for first and then 48:00; straightforward but slow, ofc
|
||||||
- Day 15: 4:30 and 31:20; more reading comprehension than programming
|
- Day 15: 4:30 and 31:20; more reading comprehension than programming
|
||||||
@@ -22,4 +25,14 @@
|
|||||||
but didn't realize that I have to compute the outer edges for a while and
|
but didn't realize that I have to compute the outer edges for a while and
|
||||||
after I did, I still got clockwise/counter-clockwise issues. They could have
|
after I did, I still got clockwise/counter-clockwise issues. They could have
|
||||||
made it meaner by using different clock directions for example and input.
|
made it meaner by using different clock directions for example and input.
|
||||||
- Day 19:
|
- Day 19: This one was pretty straightforward and required the interval
|
||||||
|
technique we applied earlier.
|
||||||
|
- Day 20: Part 2 was tough. I had the right idea of printing out the periods of
|
||||||
|
the input conjunction gate pretty early, but then messed up the
|
||||||
|
implementation and thought it wasn't gonna work. Spent a half day thinking up
|
||||||
|
something else before returning to the idea and it worked flawlessly.
|
||||||
|
- Day 21:
|
||||||
|
- Day 22: Not too hard, but definitely way too slow for leaderboard.
|
||||||
|
- Day 23:
|
||||||
|
- Day 24:
|
||||||
|
- Day 25:
|
||||||
|
|||||||
16
d20.py
16
d20.py
@@ -1,5 +1,6 @@
|
|||||||
from lib import *
|
from lib import *
|
||||||
from math import lcm
|
from math import lcm
|
||||||
|
from collections import deque
|
||||||
|
|
||||||
EXAMPLE = """
|
EXAMPLE = """
|
||||||
broadcaster -> a, b, c
|
broadcaster -> a, b, c
|
||||||
@@ -25,10 +26,9 @@ def visualize(modules):
|
|||||||
f.write(" " + m[1] + ' -> ' + cm + "\n")
|
f.write(" " + m[1] + ' -> ' + cm + "\n")
|
||||||
f.write("}")
|
f.write("}")
|
||||||
|
|
||||||
def solve(i: Input, second=False):
|
def solve(input: Input, second=False):
|
||||||
res = 0
|
|
||||||
modules = {}
|
modules = {}
|
||||||
for line in i.lines():
|
for line in input.lines():
|
||||||
if not line: continue
|
if not line: continue
|
||||||
src, dsts = line.split(" -> ")
|
src, dsts = line.split(" -> ")
|
||||||
dsts = dsts.split(", ")
|
dsts = dsts.split(", ")
|
||||||
@@ -48,17 +48,17 @@ def solve(i: Input, second=False):
|
|||||||
|
|
||||||
if second:
|
if second:
|
||||||
# visualize(modules)
|
# visualize(modules)
|
||||||
periods = {d: [] for d in modules["kh"][2].keys()}
|
(feed,) = [m[1] for m in modules.values() if "rx" in m[3]]
|
||||||
|
periods = {d: [] for d in modules[feed][2].keys()}
|
||||||
BUTTON_PUSHES = 10000
|
BUTTON_PUSHES = 10000
|
||||||
else:
|
else:
|
||||||
BUTTON_PUSHES = 1000
|
BUTTON_PUSHES = 1000
|
||||||
|
|
||||||
lo, hi = 0, 0
|
lo, hi = 0, 0
|
||||||
for i in range(BUTTON_PUSHES):
|
for i in range(BUTTON_PUSHES):
|
||||||
qs = [("button module", "broadcaster", 0)]
|
qs = deque([("button module", "broadcaster", 0)])
|
||||||
while qs:
|
while qs:
|
||||||
src, dst, sig = qs[0]
|
src, dst, sig = qs.popleft()
|
||||||
qs = qs[1:]
|
|
||||||
|
|
||||||
if sig == 0:
|
if sig == 0:
|
||||||
lo += 1
|
lo += 1
|
||||||
@@ -87,7 +87,7 @@ def solve(i: Input, second=False):
|
|||||||
|
|
||||||
if new_pulse is not None:
|
if new_pulse is not None:
|
||||||
for nxtdst in m[3]:
|
for nxtdst in m[3]:
|
||||||
if second and nxtdst == "kh" and new_pulse == 1:
|
if second and nxtdst == feed and new_pulse == 1:
|
||||||
# print(f"{i:>4}: {dst[:4]:>4} -{new_pulse}> {nxtdst}")
|
# print(f"{i:>4}: {dst[:4]:>4} -{new_pulse}> {nxtdst}")
|
||||||
periods[dst].append(i)
|
periods[dst].append(i)
|
||||||
qs.append((dst, nxtdst, new_pulse))
|
qs.append((dst, nxtdst, new_pulse))
|
||||||
|
|||||||
121
d22.py
Normal file
121
d22.py
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
from lib import *
|
||||||
|
|
||||||
|
EXAMPLE = """1,0,1~1,2,1
|
||||||
|
0,0,2~2,0,2
|
||||||
|
0,2,3~2,2,3
|
||||||
|
0,0,4~0,2,4
|
||||||
|
2,0,5~2,2,5
|
||||||
|
0,1,6~2,1,6
|
||||||
|
1,1,8~1,1,9
|
||||||
|
"""
|
||||||
|
|
||||||
|
def overlap(a, b):
|
||||||
|
# Could be made generic with for loop.
|
||||||
|
[(ax1, ax2), (ay1, ay2), (az1, az2)] = a
|
||||||
|
[(bx1, bx2), (by1, by2), (bz1, bz2)] = b
|
||||||
|
xo = (bx1 <= ax2 and bx2 >= ax1)
|
||||||
|
yo = (by1 <= ay2 and by2 >= ay1)
|
||||||
|
zo = (bz1 <= az2 and bz2 >= az1)
|
||||||
|
return xo and yo and zo
|
||||||
|
|
||||||
|
def can_overlap(a, b):
|
||||||
|
a, b = list(a), list(b)
|
||||||
|
za1, za2 = a[2]
|
||||||
|
zb1, zb2 = b[2]
|
||||||
|
|
||||||
|
zad = za1 - 1
|
||||||
|
a[2] = (za1 - zad, za2 - zad)
|
||||||
|
|
||||||
|
zbd = zb1 - 1
|
||||||
|
b[2] = (zb1 - zbd, zb2 - zbd)
|
||||||
|
return overlap(a, b)
|
||||||
|
|
||||||
|
def solve(input: Input, second=False):
|
||||||
|
bricks = []
|
||||||
|
for line in input.lines():
|
||||||
|
s = tuple(str_to_ints(line))
|
||||||
|
s = tuple([tuple(sorted([s[i], s[i + 3]])) for i in range(3)])
|
||||||
|
bricks.append(s)
|
||||||
|
|
||||||
|
# Check which bricks can overlap in general
|
||||||
|
d = {i: [] for i in range(len(bricks))}
|
||||||
|
for a in range(len(bricks)):
|
||||||
|
for b in range(a + 1, len(bricks)):
|
||||||
|
if can_overlap(bricks[a], bricks[b]):
|
||||||
|
# print(f"{bricks[a]} can overlap with {bricks[b]}")
|
||||||
|
d[a].append(b)
|
||||||
|
d[b].append(a)
|
||||||
|
|
||||||
|
# Lower bricks as much as possible
|
||||||
|
idxs = sorted(range(len(bricks)), key=lambda i: bricks[i][2][1])
|
||||||
|
for idx_active_idx, idx_active in enumerate(idxs):
|
||||||
|
b = list(bricks[idx_active])
|
||||||
|
lowest_z = 1
|
||||||
|
for idx_to_check in idxs[:idx_active_idx]:
|
||||||
|
if idx_to_check in d[idx_active]:
|
||||||
|
lowest_z = max(lowest_z, bricks[idx_to_check][2][1] + 1)
|
||||||
|
zp = list(b[2])
|
||||||
|
zp[0], zp[1] = lowest_z, zp[1] - (zp[0] - lowest_z)
|
||||||
|
b[2] = tuple(zp)
|
||||||
|
# print(f"{bricks[idx_active]} -> {b}")
|
||||||
|
bricks[idx_active] = b
|
||||||
|
|
||||||
|
# for l, b in zip(LETTERS_UPPER, bricks): print(l, b)
|
||||||
|
|
||||||
|
if second:
|
||||||
|
# Create a map that for each objects, shows what objects it is
|
||||||
|
# supported by.
|
||||||
|
supported_by = {i: set() for i in range(len(bricks))}
|
||||||
|
for i in range(len(bricks)):
|
||||||
|
b = bricks[i]
|
||||||
|
zl = b[2][0]
|
||||||
|
if zl == 1:
|
||||||
|
supported_by[i].add(-1)
|
||||||
|
for ni in d[i]:
|
||||||
|
if bricks[ni][2][1] + 1 == zl:
|
||||||
|
supported_by[i].add(ni)
|
||||||
|
|
||||||
|
res = 0
|
||||||
|
for i in range(len(bricks)):
|
||||||
|
removed = set([i])
|
||||||
|
to_process = [i]
|
||||||
|
while to_process:
|
||||||
|
ri = to_process.pop()
|
||||||
|
for ni in d[ri]:
|
||||||
|
if supported_by[ni].issubset(removed) and not ni in removed:
|
||||||
|
removed.add(ni)
|
||||||
|
to_process.append(ni)
|
||||||
|
res += len(removed) - 1
|
||||||
|
return res
|
||||||
|
|
||||||
|
else:
|
||||||
|
support_map = {i: [] for i in range(len(bricks))}
|
||||||
|
support_bricks = set()
|
||||||
|
# For all bricks, check if it would fall if a particular brick was removed.
|
||||||
|
for i in range(len(bricks)):
|
||||||
|
b = bricks[i]
|
||||||
|
zl = b[2][0]
|
||||||
|
if zl == 1:
|
||||||
|
continue # supported by floor
|
||||||
|
|
||||||
|
for ni in d[i]:
|
||||||
|
if bricks[ni][2][1] + 1 == zl:
|
||||||
|
support_map[i].append(ni)
|
||||||
|
if len(support_map[i]) == 1:
|
||||||
|
support_bricks.add(support_map[i][0])
|
||||||
|
# print(f"{bricks[i]} supported by {support_map[i]}")
|
||||||
|
return len(bricks) - len(support_bricks)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
DAY_INPUT = "i22.txt"
|
||||||
|
|
||||||
|
print("Example 1:", solve(Input(EXAMPLE)))
|
||||||
|
print("Solution 1:", solve(Input(DAY_INPUT)))
|
||||||
|
assert solve(Input(DAY_INPUT)) == 428
|
||||||
|
|
||||||
|
print("Example 2:", solve(Input(EXAMPLE), True))
|
||||||
|
print("Solution 2:", solve(Input(DAY_INPUT), True))
|
||||||
|
assert solve(Input(DAY_INPUT), True) == 35654
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user