Refactor 2024:15
Solution is still 100 lines, but now it is based on a singular BFS oriented box push algorithm.
This commit is contained in:
parent
7688ddb763
commit
f5c3ee938a
2 changed files with 47 additions and 75 deletions
|
|
@ -16,7 +16,9 @@ except ValueError:
|
||||||
name = None
|
name = None
|
||||||
|
|
||||||
print(
|
print(
|
||||||
f"\nAdvent of Code {year}" "\n###################" "\n\nby Anders Englöf Ytterström"
|
f"\n\033[95m\033[1mAdvent of Code {year}\033[0m"
|
||||||
|
"\n###################"
|
||||||
|
"\n\n\033[96mby Anders Englöf Ytterström\033[0m"
|
||||||
)
|
)
|
||||||
|
|
||||||
Path("./input").mkdir(parents=True, exist_ok=True)
|
Path("./input").mkdir(parents=True, exist_ok=True)
|
||||||
|
|
@ -110,10 +112,10 @@ for i in [str(n).zfill(2) for n in range(1, 26)]:
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
if p1:
|
if p1:
|
||||||
print(f" 1) {p1}")
|
print(f" \033[92m1)\033[0m {p1}")
|
||||||
stars += 1
|
stars += 1
|
||||||
if p2:
|
if p2:
|
||||||
print(f" 2) {p2}")
|
print(f" \033[92m2)\033[0m {p2}")
|
||||||
stars += 1
|
stars += 1
|
||||||
except IOError:
|
except IOError:
|
||||||
pass
|
pass
|
||||||
|
|
|
||||||
|
|
@ -33,101 +33,71 @@ def solve(data):
|
||||||
for move in movements:
|
for move in movements:
|
||||||
r, c = pos
|
r, c = pos
|
||||||
dr, dc = O[move]
|
dr, dc = O[move]
|
||||||
moved = False
|
move_boxes = True
|
||||||
|
blocked = False
|
||||||
|
|
||||||
match move:
|
if (r + dr, c + dc) not in grid:
|
||||||
case "^":
|
|
||||||
targets = [((v, c), grid[(v, c)]) for v in range(r)][::-1]
|
|
||||||
case "<":
|
|
||||||
targets = [((r, v), grid[(r, v)]) for v in range(c)][::-1]
|
|
||||||
case "v":
|
|
||||||
targets = [((v, c), grid[(v, c)]) for v in range(r + 1, H)]
|
|
||||||
case ">":
|
|
||||||
targets = [((r, v), grid[(r, v)]) for v in range(c + 1, W)]
|
|
||||||
|
|
||||||
if "." not in map(lambda pv: pv[1], targets):
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if grid[(r + dr, c + dc)] == ".":
|
match grid[(r + dr, c + dc)]:
|
||||||
moved = True
|
case ".":
|
||||||
|
move_boxes = False
|
||||||
|
case "#":
|
||||||
|
move_boxes = False
|
||||||
|
continue
|
||||||
|
|
||||||
if grid[(r + dr, c + dc)] == "O" or (
|
if move_boxes:
|
||||||
grid[(r + dr, c + dc)] in "[]" and dc != 0
|
seen = set()
|
||||||
):
|
|
||||||
canmove = False
|
|
||||||
flips = []
|
|
||||||
|
|
||||||
for tpos, tvalue in targets:
|
Q = [(r + dr, c + dc)]
|
||||||
flips.append((tpos, tvalue))
|
|
||||||
|
|
||||||
if tvalue == "#":
|
|
||||||
break
|
|
||||||
|
|
||||||
if tvalue == ".":
|
|
||||||
canmove = True
|
|
||||||
break
|
|
||||||
|
|
||||||
if canmove:
|
|
||||||
rotated = [value for _, value in flips]
|
|
||||||
rotated = rotated[-1:] + rotated[:-1]
|
|
||||||
|
|
||||||
for offset, pos in enumerate(flips):
|
|
||||||
grid[pos[0]] = rotated[offset]
|
|
||||||
|
|
||||||
moved = True
|
|
||||||
|
|
||||||
if grid[(r + dr, c + dc)] in "[]" and dc == 0 and dr != 0:
|
|
||||||
canmove = True
|
|
||||||
bs = set()
|
|
||||||
bmod = O[move][0]
|
|
||||||
|
|
||||||
Q = [(r + bmod, c)]
|
|
||||||
|
|
||||||
while Q:
|
while Q:
|
||||||
rr, cc = Q.pop(0)
|
rr, cc = Q.pop(0)
|
||||||
|
|
||||||
if (rr, cc) in bs:
|
if (rr, cc) in seen:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
bs.add((rr, cc))
|
if (rr, cc) not in grid:
|
||||||
|
continue
|
||||||
|
|
||||||
if grid[(rr, cc)] == "#":
|
if grid[(rr, cc)] == "#":
|
||||||
canmove = False
|
blocked = True
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if grid[(rr, cc)] in "@.":
|
seen.add((rr, cc))
|
||||||
|
|
||||||
|
if grid[(rr, cc)] in ".":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
match grid[(rr, cc)]:
|
Q.append((rr + dr, cc + dc))
|
||||||
case "]":
|
if dr != 0:
|
||||||
Q.append((rr + bmod, cc))
|
match grid[(rr, cc)]:
|
||||||
Q.append((rr, cc - 1))
|
case "]":
|
||||||
case "[":
|
Q.append((rr, cc - 1))
|
||||||
Q.append((rr + bmod, cc))
|
case "[":
|
||||||
Q.append((rr, cc + 1))
|
Q.append((rr, cc + 1))
|
||||||
|
|
||||||
if canmove:
|
if blocked:
|
||||||
patchset = {
|
continue
|
||||||
(rr, cc): (rr + bmod, cc)
|
|
||||||
for rr, cc in bs
|
|
||||||
if grid[(rr, cc)] != "."
|
|
||||||
}
|
|
||||||
|
|
||||||
dotset = set(bs) - set(patchset.values())
|
patchset = {
|
||||||
|
(rr, cc): (rr + dr, cc + dc)
|
||||||
|
for rr, cc in seen
|
||||||
|
if grid[(rr, cc)] != "."
|
||||||
|
}
|
||||||
|
|
||||||
for psf, pst in sorted(patchset.items())[::-bmod]:
|
dotset = set(seen) - set(patchset.values())
|
||||||
psnv = grid[psf]
|
|
||||||
grid[pst] = psnv
|
|
||||||
|
|
||||||
for rk in dotset:
|
for oldpos, newpos in sorted(patchset.items())[:: -(dr + dc)]:
|
||||||
grid[rk] = "."
|
value = grid[oldpos]
|
||||||
|
grid[newpos] = value
|
||||||
|
|
||||||
moved = True
|
for dot in dotset:
|
||||||
|
grid[dot] = "."
|
||||||
|
|
||||||
if moved:
|
grid[(r, c)] = "."
|
||||||
grid[(r, c)] = "."
|
grid[(r + dr, c + dc)] = "@"
|
||||||
grid[(r + dr, c + dc)] = "@"
|
pos = r + dr, c + dc
|
||||||
pos = r + dr, c + dc
|
|
||||||
|
|
||||||
answers.append(sum(k[0] * 100 + k[1] for k, v in grid.items() if v in "O["))
|
answers.append(sum(k[0] * 100 + k[1] for k, v in grid.items() if v in "O["))
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue