Skip to content

Commit 4433d07

Browse files
committed
aoc 2023 day 23
1 parent 9714f44 commit 4433d07

File tree

1 file changed

+174
-0
lines changed
  • miscellaneous/advent-of-code/2023

1 file changed

+174
-0
lines changed
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
from collections import defaultdict, deque, Counter
2+
# d = deque()
3+
# d.append(5)
4+
# x = d.popleft()
5+
import re
6+
# m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
7+
# # or re.search
8+
# >>> m.group(0) # The entire match
9+
# 'Isaac Newton'
10+
# >>> m.group(1) # The first parenthesized subgroup.
11+
# 'Isaac'
12+
# >>> m.group(2) # The second parenthesized subgroup.
13+
# 'Newton'
14+
# >>> m.group(1, 2) # Multiple arguments give us a tuple.
15+
# ('Isaac', 'Newton')
16+
from heapq import heappush, heappop
17+
# >>> heap = []
18+
# >>> data = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]
19+
# >>> for item in data:
20+
# ... heappush(heap, item)
21+
# heap[0] is the smallest item
22+
import string
23+
# string.ascii_lowercase == 'abcde...'
24+
# string.ascii_uppercase == 'ABCDE...'
25+
from functools import lru_cache
26+
# @lru_cache(maxsize=None)
27+
import numpy as np
28+
29+
import sys
30+
31+
sys.setrecursionlimit(100000)
32+
33+
def get_ints(s):
34+
return list(map(int, re.findall(r"-?\d+", s))) # copied from mcpower from mserrano on betaveros' recommendation
35+
dirs = [(0,1), (1,0), (0,-1), (-1,0)]
36+
directions = 'RDLU'
37+
octs = [(0,1),(1,1),(1,0),(1,-1),(0,-1),(-1,-1),(-1,0),(-1,1)]
38+
def is_grid_valid(n,m, r,c,):
39+
return (0<=r<n) and (0<=c<m)
40+
def sign_of(x):
41+
if x==0:
42+
return 0
43+
return x/abs(x)
44+
45+
INTERVAL_TYPE_INCLUSIVE = 0
46+
INTERVAL_TYPE_EXCLUSIVE = 1
47+
# def make_interval_class(start_type=INTERVAL_TYPE_INCLUSIVE, end_type=INTERVAL_TYPE_EXCLUSIVE):
48+
# class Interval:
49+
# start_type = start_type
50+
# end_type = end_type
51+
# def __init__(self, start, end):
52+
# self.start = start
53+
# self.end = end
54+
# def merge(interval_a, interval_b):
55+
# interval = (min(interval_a[0], interval_b[0]), max(interval_a[1], interval_b[1]))
56+
# if interval[0] > interval[1]:
57+
# return None
58+
####################################
59+
60+
PART = 1
61+
PART = 2
62+
if PART == 1:
63+
ans = 0
64+
inps = []
65+
while True:
66+
try:
67+
inps.append(input())
68+
except EOFError:
69+
break
70+
for c in range(len(inps[0])):
71+
if inps[0][c] == '.':
72+
sc = c
73+
break
74+
for c in range(len(inps[0])):
75+
if inps[-1][c] == '.':
76+
ec = c
77+
break
78+
R, C = len(inps), len(inps[0])
79+
def dfs(r, c, been):
80+
if r == R-1:
81+
return 0
82+
best = None
83+
for dr, dc in dirs:
84+
if inps[r][c] == '<' and dc != -1:
85+
continue
86+
if inps[r][c] == '>' and dc != 1:
87+
continue
88+
if inps[r][c] == '^' and dr != -1:
89+
continue
90+
if inps[r][c] == 'v' and dr != 1:
91+
continue
92+
nr, nc = r+dr, c+dc
93+
if is_grid_valid(R, C, nr, nc) and inps[nr][nc] in '.<>v^' and (nr, nc) not in been:
94+
been.add((nr, nc))
95+
if inps[nr][nc] != '.':
96+
been = been.copy()
97+
res = dfs(nr, nc, been)
98+
if res is not None:
99+
if best is None:
100+
best = res + 1
101+
else:
102+
best = max(best, res + 1)
103+
return best
104+
105+
106+
ans = dfs(0, sc, {(0, sc)})
107+
print(ans)
108+
else:
109+
ans = 0
110+
inps = []
111+
while True:
112+
try:
113+
inps.append(input())
114+
except EOFError:
115+
break
116+
for c in range(len(inps[0])):
117+
if inps[0][c] == '.':
118+
sc = c
119+
break
120+
for c in range(len(inps[0])):
121+
if inps[-1][c] == '.':
122+
ec = c
123+
break
124+
R, C = len(inps), len(inps[0])
125+
junctions = [(0, sc), (R-1, ec)]
126+
for r in range(R):
127+
for c in range(C):
128+
neighbor_slides = 0
129+
if inps[r][c] != '.':
130+
continue
131+
for dr, dc in dirs:
132+
nr, nc = r+dr, c+dc
133+
if is_grid_valid(R, C, nr, nc) and inps[nr][nc] in '<>v^':
134+
neighbor_slides += 1
135+
if neighbor_slides >= 3:
136+
junctions.append((r,c,))
137+
def dfs(j, been, start):
138+
r,c = j
139+
if (r,c) in junctions and (r,c) != start:
140+
return [((r,c), 0)]
141+
neighbor_distances = []
142+
for dr, dc in dirs:
143+
nr, nc = r+dr, c+dc
144+
if is_grid_valid(R, C, nr, nc) and inps[nr][nc] in '.<>v^' and (nr, nc) not in been:
145+
been2 = been.copy()
146+
been2.add((nr, nc))
147+
# if inps[nr][nc] != '.':
148+
# been = been.copy()
149+
neighbor_distances.extend(dfs((nr, nc), been2, start))
150+
151+
return [(j, d+1) for (j,d) in neighbor_distances]
152+
153+
neighbor_distancess = dict()
154+
for junction in junctions:
155+
neighbor_distances = dfs(junction, {(junction)}, junction)
156+
neighbor_distancess[junction] = neighbor_distances
157+
def dfs2(junction, been):
158+
if junction == (R-1, ec):
159+
return 0
160+
best = None
161+
for (j, d) in neighbor_distancess[junction]:
162+
been2 = been.copy()
163+
if j not in been2:
164+
been2.add(j)
165+
res = dfs2(j, been2)
166+
if res is not None:
167+
if best is None:
168+
best = res + d
169+
else:
170+
best = max(best, res + d)
171+
return best
172+
print('starting dfs2')
173+
ans = dfs2((0, sc), {(0, sc)})
174+
print(ans)

0 commit comments

Comments
 (0)