#!/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)