advent-of-code/2024/16/numpy_test.py
2024-12-25 12:59:49 +01:00

136 lines
3.4 KiB
Python

#!/usr/bin/env python3
import sys
import numpy as np
import scipy as sp
dtype = np.int32
input_file = sys.argv[1]
with open(input_file) as fd:
lines = [line.rstrip() for line in fd.readlines()]
height = len(lines)
width = len(lines[0])
start = height - 2, 1
stop = 1, width - 2
directions = [
(-1, 0), # ^ North
(0, 1), # > East
(1, 0), # v South
(0, -1), # < West
]
directions_keys = ("^", ">", "v", "<")
walls = np.zeros((height, width), dtype)
for i in range(height):
for j in range(width):
if lines[i][j] == "#":
walls[i, j] = 1
invwalls = 1 - walls
# print("Walls")
# print(walls)
# TEST 4
scores = np.zeros((height, width, len(directions)), dtype)
scores[start[0], start[1], 1] = 1
for i in range(1000):
print("Step", i)
oldscores = scores.copy()
for od, odir in enumerate(directions):
for nd, ndir in enumerate(directions):
score = scores[:, :, nd]
moved = sp.ndimage.shift(oldscores[:, :, od], ndir)
increment = 1 if nd == od else 1001
moved = (moved + increment) * (moved > 0)
moved = moved * invwalls
mask = (moved > 0) & ((score == 0) | (score > moved))
scores[:, :, nd] = (score * ~mask) + (moved * mask)
# for d, dir in enumerate(directions):
# print("Direction", directions_keys[d])
# print(scores[:, :, d])
if (scores == oldscores).all():
break
else:
print("Limit!")
end_score = min(filter(lambda d: d > 0, scores[stop])) - 1
print(f"{end_score=}")
# TEST 3
# scores = [np.zeros((height, width), dtype) for _ in directions]
# scores[1][start] = 1
#
# for i in range(100):
# print("Step", i)
# for od, odir in enumerate(directions):
# oldscore = scores[od].copy()
# for nd, ndir in enumerate(directions):
# score = scores[nd]
# moved = sp.ndimage.shift(oldscore, ndir)
# increment = 1 if nd == od else 1001
# moved = (moved + increment) * (moved > 0)
# moved = moved * invwalls
# mask = (moved > 0) & ((score == 0) | (score > moved))
# scores[nd] = (score * ~mask) + (moved * mask)
#
# final_score = None
# for d, dir in enumerate(directions):
# print("Direction", directions_keys[d])
# print(scores[d])
# end_score = scores[d][stop]
# if end_score > 0:
# if final_score is None or end_score < final_score:
# final_score = end_score
#
# if final_score:
# final_score -= 1
# print(f"{final_score=}")
# break
# else:
# print("Limit!")
# TEST 2
# score = np.zeros((height, width), dtype)
# score[start] = 1
#
# for i in range(10):
# print("Step", i)
# oldscore = score.copy()
# for nd, ndir in enumerate(directions):
# moved = sp.ndimage.shift(oldscore, ndir)
# moved = (moved + 1) * (moved > 0)
# moved = moved * invwalls
# mask = (moved > 0) & ((score == 0) | (score > moved))
# score = (score * ~mask) + (moved * mask)
# print(score)
# TEST 1
# directions = np.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]], dtype)
#
# visited = np.zeros((height, width), dtype)
# visited[start] = 1
#
# for i in range(1000):
# print("Step", i)
# new = sp.signal.convolve2d(visited, directions, mode="same")
# visited = (((new > 0) - walls) > 0)
# print(visited * 1)
# if visited[stop]:
# break
# else:
# print("Limit!")
# print(i)