Last active
December 13, 2022 20:19
-
-
Save jsbueno/978767c888f4a2aecdc2d0f96aa49090 to your computer and use it in GitHub Desktop.
Advent of Code, day 12 - 2022
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
SPOILER ALERT | |
Advent of Code, day 12 - 2022 | |
At least, I am using terminedia for something | |
beyond the 2D vectors - | |
""" | |
import terminedia as TM | |
# And I found a bug - vectors derived from "TM.Directions" will raise on repr | |
# monkeypatch | |
TM.utils.vector.NamedV2.__repr__ = lambda s: f"({s.x,s.y})" | |
gg = TM.ColorGradient([(0, (0,0, 255)), (0.1, (0, 255, 64)), (0.8, (0,128,0)), (0.9, (255,0,0))]) | |
g2 = TM.ColorGradient([(0, (0,0,0)), (1, (255,255,255))]) | |
arrows = { | |
(0, -1): '🡡', | |
(0, 1): '🡣', | |
(1, 0): '🡢', | |
(-1, 0): '🡠' | |
} | |
arrows = { | |
(0, -1): '🡑', | |
(0, 1): '🡓', | |
(1, 0): '🡒', | |
(-1, 0): '🡐' | |
} | |
def display(sc, map_, gradient, g2): | |
shape = sc.shape | |
for y in range(map_.height): | |
for x in range(map_.width): | |
dist, from_dir = map_.pathlayer.get((x, y), (255, ".")) | |
arrow = arrows.get(from_dir, from_dir) | |
shape[x,y] = (arrow, g2[dist / 255], gradient[map_[x,y] / 27], 0) | |
shape[map_.start] = ("S", (255,255, 0), TM.TRANSPARENT, 0) | |
shape[map_.end] = ("E", (255,255,0), TM.TRANSPARENT, 0) | |
sc.update() | |
class Map: | |
def __init__(self, data, strategy="up"): | |
self.strategy = strategy | |
self.load(data) | |
self.reset() | |
def reset(self): | |
self.pathlayer = {} | |
self.paths = {} | |
def run(self): | |
self.reset() | |
current_paths = {(0, (self.start if self.strategy == "up" else self.end), "S")} | |
count = 0 | |
while current_paths: | |
next_paths = set() | |
for distance, pos, from_dir in current_paths: | |
count += 1 | |
if not count % 100: | |
print(count) | |
if distance < self.pathlayer.get(pos, (1_000_000, "."))[0]: | |
self.pathlayer[pos] = (distance, from_dir) | |
else: | |
continue | |
for direction in TM.Directions: | |
new_pos = pos + direction | |
# print(new_pos) | |
if not (0 <= new_pos.x < self.width) or not (0 <= new_pos.y < self.height): | |
continue | |
if self.strategy == "up": | |
if self[new_pos] > self[pos] + 1: | |
continue | |
elif self.strategy == "down": | |
if self[new_pos] < self[pos] - 1: | |
continue | |
else: | |
raise RuntimeError() | |
next_paths.add((distance + 1, new_pos, direction)) | |
current_paths = next_paths | |
def load(self, data): | |
self.data = [] | |
x = y = 0 | |
for y, line in enumerate(data.splitlines()): | |
self.data.append(dline:=[]) | |
for x, char in enumerate(line): | |
if char == "S": | |
self.start = (x, y) | |
char = "a" | |
elif char == "E": | |
self.end = (x, y) | |
char = "z" | |
height = ord(char) - ord("a") | |
dline.append(height) | |
self.width = x + 1 | |
self.height = y + 1 | |
def __getitem__(self, pos): | |
return self.data[pos[1]][pos[0]] | |
def __repr__(self): | |
return "\n".join("".join(chr(char + 97) for char in line) for line in self.data) | |
# part2 | |
#m = Map(data, strategy="down") | |
#min(m.pathlayer.items(), key=lambda it: (m[it[0]], it[1][0])) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment