Skip to content

Instantly share code, notes, and snippets.

@jsbueno
Last active December 13, 2022 20:19
Show Gist options
  • Save jsbueno/978767c888f4a2aecdc2d0f96aa49090 to your computer and use it in GitHub Desktop.
Save jsbueno/978767c888f4a2aecdc2d0f96aa49090 to your computer and use it in GitHub Desktop.
Advent of Code, day 12 - 2022
"""
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