day12 not pretty at alllll
This commit is contained in:
parent
75088a6215
commit
491530d857
@ -1,9 +1,11 @@
|
|||||||
import shared
|
import shared
|
||||||
from pprint import pprint as pp
|
from pprint import pprint as pp
|
||||||
|
|
||||||
|
|
||||||
def run(SOMETHING):
|
def run(SOMETHING):
|
||||||
pp(SOMETHING)
|
pp(SOMETHING)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
spl = lambda y: [int(w) for w in y]
|
spl = lambda y: [int(w) for w in y]
|
||||||
rows = [row.rstrip().split() for row in shared.load(3)]
|
rows = [row.rstrip().split() for row in shared.load(3)]
|
||||||
|
@ -3,6 +3,7 @@ import imageio
|
|||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
class Animate:
|
class Animate:
|
||||||
def __init__(self, mx, day="CHANGEME"):
|
def __init__(self, mx, day="CHANGEME"):
|
||||||
self.mx = mx
|
self.mx = mx
|
||||||
@ -14,7 +15,7 @@ class Animate:
|
|||||||
|
|
||||||
def add_frame(self, frame):
|
def add_frame(self, frame):
|
||||||
self.f_count += 1
|
self.f_count += 1
|
||||||
self.write_frame(frame)
|
self.write_frame(frame)
|
||||||
|
|
||||||
def write_frame(self, frame):
|
def write_frame(self, frame):
|
||||||
current = np.zeros_like(self.mx)
|
current = np.zeros_like(self.mx)
|
||||||
@ -24,13 +25,17 @@ class Animate:
|
|||||||
fig, ax = plt.subplots()
|
fig, ax = plt.subplots()
|
||||||
ax.imshow(current, cmap=plt.cm.gray)
|
ax.imshow(current, cmap=plt.cm.gray)
|
||||||
ax.axis("off")
|
ax.axis("off")
|
||||||
_figpath = (f"gif-{self.day}/{self.f_count:05}.png")
|
_figpath = f"gif-{self.day}/{self.f_count:05}.png"
|
||||||
plt.savefig(_figpath)
|
plt.savefig(_figpath)
|
||||||
plt.close()
|
plt.close()
|
||||||
|
|
||||||
def animate(self, frameskip=1):
|
def animate(self, frameskip=1):
|
||||||
with imageio.get_writer(f"gif-{self.day}/day{self.day}.gif", mode="I") as writer:
|
with imageio.get_writer(
|
||||||
names = [f"gif-{self.day}/{x:05}.png" for x in range(0,self.f_count, frameskip)]
|
f"gif-{self.day}/day{self.day}.gif", mode="I"
|
||||||
|
) as writer:
|
||||||
|
names = [
|
||||||
|
f"gif-{self.day}/{x:05}.png" for x in range(0, self.f_count, frameskip)
|
||||||
|
]
|
||||||
print(names)
|
print(names)
|
||||||
for filename in names:
|
for filename in names:
|
||||||
try:
|
try:
|
||||||
|
@ -6,7 +6,7 @@ def run(rows):
|
|||||||
elves = []
|
elves = []
|
||||||
current_elf = 0
|
current_elf = 0
|
||||||
for row in rows:
|
for row in rows:
|
||||||
if row == '':
|
if row == "":
|
||||||
elves.append(current_elf)
|
elves.append(current_elf)
|
||||||
current_elf = 0
|
current_elf = 0
|
||||||
continue
|
continue
|
||||||
@ -15,14 +15,13 @@ def run(rows):
|
|||||||
three = 0
|
three = 0
|
||||||
|
|
||||||
for x in range(3):
|
for x in range(3):
|
||||||
most = max(elves)
|
most = max(elves)
|
||||||
idx = elves.index(most)
|
idx = elves.index(most)
|
||||||
elves.pop(idx)
|
elves.pop(idx)
|
||||||
three += most
|
three += most
|
||||||
print(three)
|
print(three)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
with open(shared.get_fname(1), "r") as f:
|
with open(shared.get_fname(1), "r") as f:
|
||||||
rows = [x.rstrip() for x in f.readlines()]
|
rows = [x.rstrip() for x in f.readlines()]
|
||||||
|
@ -10,31 +10,18 @@ tie = "Y"
|
|||||||
win = "Z"
|
win = "Z"
|
||||||
|
|
||||||
Moves = {
|
Moves = {
|
||||||
"A":rock,
|
"A": rock,
|
||||||
"B":paper,
|
"B": paper,
|
||||||
"C":scissors,
|
"C": scissors,
|
||||||
|
"X": rock,
|
||||||
"X":rock,
|
"Y": paper,
|
||||||
"Y":paper,
|
"Z": scissors,
|
||||||
"Z":scissors,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Scores = {
|
Scores = {rock: 1, paper: 2, scissors: 3}
|
||||||
rock: 1,
|
|
||||||
paper: 2,
|
|
||||||
scissors: 3
|
|
||||||
}
|
|
||||||
|
|
||||||
LosesTo = {
|
LosesTo = {rock: paper, paper: scissors, scissors: rock}
|
||||||
rock: paper,
|
WinsTo = {paper: rock, scissors: paper, rock: scissors}
|
||||||
paper: scissors,
|
|
||||||
scissors: rock
|
|
||||||
}
|
|
||||||
WinsTo = {
|
|
||||||
paper: rock,
|
|
||||||
scissors: paper,
|
|
||||||
rock: scissors
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def winner(opponent, me):
|
def winner(opponent, me):
|
||||||
@ -42,11 +29,16 @@ def winner(opponent, me):
|
|||||||
return 3 + Scores[me]
|
return 3 + Scores[me]
|
||||||
|
|
||||||
# wins
|
# wins
|
||||||
if (opponent == rock and me == paper) or (opponent == paper and me == scissors) or (opponent == scissors and me == rock):
|
if (
|
||||||
|
(opponent == rock and me == paper)
|
||||||
|
or (opponent == paper and me == scissors)
|
||||||
|
or (opponent == scissors and me == rock)
|
||||||
|
):
|
||||||
return 6 + Scores[me]
|
return 6 + Scores[me]
|
||||||
|
|
||||||
return 0 + Scores[me]
|
return 0 + Scores[me]
|
||||||
|
|
||||||
|
|
||||||
def which_move(opponent, me):
|
def which_move(opponent, me):
|
||||||
if me == lose:
|
if me == lose:
|
||||||
return WinsTo[Moves[opponent]]
|
return WinsTo[Moves[opponent]]
|
||||||
@ -61,11 +53,12 @@ def run(moves):
|
|||||||
for move in moves:
|
for move in moves:
|
||||||
opponent, me = move
|
opponent, me = move
|
||||||
my_move = which_move(opponent, me)
|
my_move = which_move(opponent, me)
|
||||||
o_move = Moves[opponent]
|
o_move = Moves[opponent]
|
||||||
pts = winner(o_move, my_move)
|
pts = winner(o_move, my_move)
|
||||||
score += pts
|
score += pts
|
||||||
print(score)
|
print(score)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
rows = [row.rstrip().split() for row in shared.load(2)]
|
rows = [row.rstrip().split() for row in shared.load(2)]
|
||||||
run(rows)
|
run(rows)
|
||||||
|
@ -4,26 +4,33 @@ R = "A"
|
|||||||
P = "B"
|
P = "B"
|
||||||
S = "C"
|
S = "C"
|
||||||
|
|
||||||
X = "X" # lose
|
X = "X" # lose
|
||||||
Y = "Y" # tie
|
Y = "Y" # tie
|
||||||
Z = "Z" # win
|
Z = "Z" # win
|
||||||
|
|
||||||
Moves = {
|
Moves = {
|
||||||
R: {X:S, Y:R, Z:P},
|
R: {X: S, Y: R, Z: P},
|
||||||
P: {X:R, Y:P, Z:S},
|
P: {X: R, Y: P, Z: S},
|
||||||
S: {X:P, Y:S, Z:R},
|
S: {X: P, Y: S, Z: R},
|
||||||
}
|
}
|
||||||
|
|
||||||
Scores = {
|
Scores = {
|
||||||
R: 1, P: 2, S: 3, X: 0, Y: 3, Z: 6,
|
R: 1,
|
||||||
|
P: 2,
|
||||||
|
S: 3,
|
||||||
|
X: 0,
|
||||||
|
Y: 3,
|
||||||
|
Z: 6,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def run(moves):
|
def run(moves):
|
||||||
score = 0
|
score = 0
|
||||||
for o, a in moves:
|
for o, a in moves:
|
||||||
score += Scores[Moves[o][a]] + Scores[a]
|
score += Scores[Moves[o][a]] + Scores[a]
|
||||||
print(score)
|
print(score)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
rows = [row.rstrip().split() for row in shared.load(2)]
|
rows = [row.rstrip().split() for row in shared.load(2)]
|
||||||
run(rows)
|
run(rows)
|
||||||
|
@ -4,17 +4,18 @@ import string
|
|||||||
|
|
||||||
def part1(rucksacks):
|
def part1(rucksacks):
|
||||||
total = 0
|
total = 0
|
||||||
for comp1,comp2 in [(r[:len(r)//2], r[len(r)//2:]) for r in rucksacks]:
|
for comp1, comp2 in [(r[: len(r) // 2], r[len(r) // 2 :]) for r in rucksacks]:
|
||||||
c1 = set(x for x in comp1)
|
c1 = set(x for x in comp1)
|
||||||
c2 = set(x for x in comp2)
|
c2 = set(x for x in comp2)
|
||||||
match = list(c1.intersection(c2))[0]
|
match = list(c1.intersection(c2))[0]
|
||||||
total += string.ascii_letters.index(match) + 1
|
total += string.ascii_letters.index(match) + 1
|
||||||
print(total)
|
print(total)
|
||||||
|
|
||||||
|
|
||||||
def part2(rucksacks):
|
def part2(rucksacks):
|
||||||
total = 0
|
total = 0
|
||||||
for idx in range(0, len(rucksacks), 3):
|
for idx in range(0, len(rucksacks), 3):
|
||||||
r1,r2,r3 = rucksacks[idx:idx+3]
|
r1, r2, r3 = rucksacks[idx : idx + 3]
|
||||||
c1 = set(x for x in r1)
|
c1 = set(x for x in r1)
|
||||||
c2 = set(x for x in r2)
|
c2 = set(x for x in r2)
|
||||||
c3 = set(x for x in r3)
|
c3 = set(x for x in r3)
|
||||||
@ -28,5 +29,6 @@ def main():
|
|||||||
part1(rows)
|
part1(rows)
|
||||||
part2(rows)
|
part2(rows)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
@ -4,27 +4,27 @@ import shared
|
|||||||
def part1(x):
|
def part1(x):
|
||||||
internal = 0
|
internal = 0
|
||||||
for pair in x:
|
for pair in x:
|
||||||
l,r = pair.split(",")
|
l, r = pair.split(",")
|
||||||
l1,l2 = map(int, l.split("-"))
|
l1, l2 = map(int, l.split("-"))
|
||||||
r1,r2 = map(int, r.split("-"))
|
r1, r2 = map(int, r.split("-"))
|
||||||
if l1 <= r1 and l2 >= r2:
|
if l1 <= r1 and l2 >= r2:
|
||||||
internal += 1
|
internal += 1
|
||||||
elif r1 <= l1 and r2 >= l2:
|
elif r1 <= l1 and r2 >= l2:
|
||||||
internal += 1
|
internal += 1
|
||||||
print(internal)
|
print(internal)
|
||||||
|
|
||||||
|
|
||||||
def part2(x):
|
def part2(x):
|
||||||
internal = 0
|
internal = 0
|
||||||
for pair in x:
|
for pair in x:
|
||||||
l,r = pair.split(",")
|
l, r = pair.split(",")
|
||||||
ll = list(sorted(map(int, l.split("-"))))
|
ll = list(sorted(map(int, l.split("-"))))
|
||||||
rl = list(sorted(map(int, r.split("-"))))
|
rl = list(sorted(map(int, r.split("-"))))
|
||||||
|
|
||||||
set1 = set(range(ll[0], ll[1]+1))
|
set1 = set(range(ll[0], ll[1] + 1))
|
||||||
set2 = set(range(rl[0], rl[1]+1))
|
set2 = set(range(rl[0], rl[1] + 1))
|
||||||
if bool(set1 & set2):
|
if bool(set1 & set2):
|
||||||
internal +=1
|
internal += 1
|
||||||
print(internal)
|
print(internal)
|
||||||
|
|
||||||
|
|
||||||
|
150
2022/python/day05.psg.py
Normal file
150
2022/python/day05.psg.py
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
from pprint import pprint as pp
|
||||||
|
import PySimpleGUI as sg
|
||||||
|
from shared import load_rows
|
||||||
|
from scanf import scanf
|
||||||
|
from string import ascii_letters
|
||||||
|
import re
|
||||||
|
|
||||||
|
WATCHERS = {}
|
||||||
|
OUTPUT = []
|
||||||
|
|
||||||
|
|
||||||
|
def load_crates(x):
|
||||||
|
done_crates = False
|
||||||
|
crates = []
|
||||||
|
instructions = []
|
||||||
|
for row in x:
|
||||||
|
if done_crates:
|
||||||
|
instructions.append(row)
|
||||||
|
else:
|
||||||
|
if row == "":
|
||||||
|
done_crates = True
|
||||||
|
else:
|
||||||
|
crates.append(row)
|
||||||
|
crates.pop()
|
||||||
|
return crates, instructions
|
||||||
|
|
||||||
|
|
||||||
|
def to_lists(crates):
|
||||||
|
parsed = []
|
||||||
|
reg = re.compile(r"[\([{})\]]")
|
||||||
|
for row in crates:
|
||||||
|
parsed.append([x for x in reg.sub(" ", row)])
|
||||||
|
parsed = list(zip(*parsed[::-1]))
|
||||||
|
parsed = list(zip(*parsed[::-1]))
|
||||||
|
parsed = list(zip(*parsed[::-1]))
|
||||||
|
cleaned1 = [[x for x in y if x.strip()] for y in parsed if y]
|
||||||
|
cleaned2 = [x for x in cleaned1 if x != []][::-1]
|
||||||
|
return cleaned2
|
||||||
|
|
||||||
|
|
||||||
|
def parse_instructions(crates, instructions):
|
||||||
|
for instruction in instructions:
|
||||||
|
count, _from, _to = scanf("move %d from %d to %d", instruction)
|
||||||
|
update_watchers("count", count)
|
||||||
|
update_output(" ".join(map(str, (count, _from, _to))))
|
||||||
|
_from -= 1 # 1 based yo
|
||||||
|
_to -= 1
|
||||||
|
for x in range(count):
|
||||||
|
value = crates[_from].pop(0)
|
||||||
|
crates[_to].insert(0, value)
|
||||||
|
return crates
|
||||||
|
|
||||||
|
|
||||||
|
def parse_instructions_pt2(crates, instructions):
|
||||||
|
for instruction in instructions:
|
||||||
|
count, _from, _to = scanf("move %d from %d to %d", instruction)
|
||||||
|
_from -= 1 # 1 based yo
|
||||||
|
_to -= 1
|
||||||
|
moving = crates[_from][:count]
|
||||||
|
update_output(" ".join(map(str, (instruction, moving))))
|
||||||
|
for x in range(count):
|
||||||
|
crates[_from].pop(0)
|
||||||
|
for x in reversed(moving):
|
||||||
|
crates[_to].insert(0, x)
|
||||||
|
|
||||||
|
return crates
|
||||||
|
|
||||||
|
|
||||||
|
def part1(x):
|
||||||
|
crates, instructions = load_crates(x)
|
||||||
|
crates = to_lists(crates)
|
||||||
|
crates = parse_instructions(crates, instructions)
|
||||||
|
update_output("".join([c[0] for c in crates]))
|
||||||
|
|
||||||
|
|
||||||
|
def part2(x):
|
||||||
|
crates, instructions = load_crates(x)
|
||||||
|
crates = parse_instructions_pt2(crates, instructions)
|
||||||
|
update_output("".join([c[0] for c in crates]))
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
rows = load_rows(5)
|
||||||
|
sg_window(rows)
|
||||||
|
|
||||||
|
|
||||||
|
sg.Window("Day5")
|
||||||
|
sg.theme("DarkAmber")
|
||||||
|
watch_column = [
|
||||||
|
[sg.Text("Watch Column")],
|
||||||
|
[sg.Text("------------")],
|
||||||
|
[sg.Text("", key="-WATCH-")],
|
||||||
|
]
|
||||||
|
output_column = [
|
||||||
|
[sg.Text("Output Column")],
|
||||||
|
[sg.Text("------------")],
|
||||||
|
[sg.Text("", key="-OUTPUT-")],
|
||||||
|
]
|
||||||
|
|
||||||
|
layout = [
|
||||||
|
[sg.Button("Part1"), sg.Button("Part2"), sg.Button("X")],
|
||||||
|
[
|
||||||
|
sg.Column(watch_column),
|
||||||
|
sg.VSeperator(),
|
||||||
|
sg.Column(output_column),
|
||||||
|
],
|
||||||
|
]
|
||||||
|
|
||||||
|
window = sg.Window("App", layout)
|
||||||
|
|
||||||
|
|
||||||
|
def update_output(new):
|
||||||
|
new = new.split("\n")
|
||||||
|
global OUTPUT
|
||||||
|
OUTPUT.extend(new)
|
||||||
|
if len(OUTPUT) > 40:
|
||||||
|
OUTPUT = OUTPUT[len(new) :]
|
||||||
|
window["-OUTPUT-"].update("\n".join(OUTPUT))
|
||||||
|
|
||||||
|
|
||||||
|
def watcher_to_string():
|
||||||
|
s = ""
|
||||||
|
for k, v in WATCHERS.items():
|
||||||
|
s += f"{k}:{v}\n"
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
def update_watchers(k, v):
|
||||||
|
WATCHERS[k] = v
|
||||||
|
window["-WATCH-"].update(watcher_to_string())
|
||||||
|
|
||||||
|
|
||||||
|
def sg_window(rows):
|
||||||
|
while True:
|
||||||
|
event, values = window.Read()
|
||||||
|
if event == "X" or event == sg.WIN_CLOSED:
|
||||||
|
break
|
||||||
|
if event == "Part1":
|
||||||
|
part1(rows)
|
||||||
|
if event == "Part2":
|
||||||
|
part2(rows)
|
||||||
|
|
||||||
|
window.Close()
|
||||||
|
|
||||||
|
# part1(rows)
|
||||||
|
# part2(rows)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
@ -13,41 +13,44 @@ def load_crates(x):
|
|||||||
if done_crates:
|
if done_crates:
|
||||||
instructions.append(row)
|
instructions.append(row)
|
||||||
else:
|
else:
|
||||||
if row == '':
|
if row == "":
|
||||||
done_crates = True
|
done_crates = True
|
||||||
else:
|
else:
|
||||||
crates.append(row)
|
crates.append(row)
|
||||||
crates.pop()
|
crates.pop()
|
||||||
return crates, instructions
|
return crates, instructions
|
||||||
|
|
||||||
|
|
||||||
def to_lists(crates):
|
def to_lists(crates):
|
||||||
parsed = []
|
parsed = []
|
||||||
reg = re.compile(r"[\([{})\]]")
|
reg = re.compile(r"[\([{})\]]")
|
||||||
for row in crates:
|
for row in crates:
|
||||||
parsed.append([x for x in reg.sub(" ",row)])
|
parsed.append([x for x in reg.sub(" ", row)])
|
||||||
parsed = list(zip(*parsed[::-1]))
|
parsed = list(zip(*parsed[::-1]))
|
||||||
parsed = list(zip(*parsed[::-1]))
|
parsed = list(zip(*parsed[::-1]))
|
||||||
parsed = list(zip(*parsed[::-1]))
|
parsed = list(zip(*parsed[::-1]))
|
||||||
cleaned1 = [[x for x in y if x.strip()] for y in parsed if y]
|
cleaned1 = [[x for x in y if x.strip()] for y in parsed if y]
|
||||||
cleaned2 = [x for x in cleaned1 if x != []][::-1]
|
cleaned2 = [x for x in cleaned1 if x != []][::-1]
|
||||||
return cleaned2
|
return cleaned2
|
||||||
|
|
||||||
|
|
||||||
def parse_instructions(crates, instructions):
|
def parse_instructions(crates, instructions):
|
||||||
for instruction in instructions:
|
for instruction in instructions:
|
||||||
count,_from,_to = scanf("move %d from %d to %d", instruction)
|
count, _from, _to = scanf("move %d from %d to %d", instruction)
|
||||||
print(count,_from,_to)
|
print(count, _from, _to)
|
||||||
_from -=1 # 1 based yo
|
_from -= 1 # 1 based yo
|
||||||
_to -=1
|
_to -= 1
|
||||||
for x in range(count):
|
for x in range(count):
|
||||||
value = crates[_from].pop(0)
|
value = crates[_from].pop(0)
|
||||||
crates[_to].insert(0, value)
|
crates[_to].insert(0, value)
|
||||||
return crates
|
return crates
|
||||||
|
|
||||||
|
|
||||||
def parse_instructions_pt2(crates, instructions):
|
def parse_instructions_pt2(crates, instructions):
|
||||||
for instruction in instructions:
|
for instruction in instructions:
|
||||||
count,_from,_to = scanf("move %d from %d to %d", instruction)
|
count, _from, _to = scanf("move %d from %d to %d", instruction)
|
||||||
_from -=1 # 1 based yo
|
_from -= 1 # 1 based yo
|
||||||
_to -=1
|
_to -= 1
|
||||||
moving = crates[_from][:count]
|
moving = crates[_from][:count]
|
||||||
print(instruction, moving)
|
print(instruction, moving)
|
||||||
for x in range(count):
|
for x in range(count):
|
||||||
@ -56,7 +59,7 @@ def parse_instructions_pt2(crates, instructions):
|
|||||||
crates[_to].insert(0, x)
|
crates[_to].insert(0, x)
|
||||||
|
|
||||||
return crates
|
return crates
|
||||||
|
|
||||||
|
|
||||||
def part1(x):
|
def part1(x):
|
||||||
crates, instructions = load_crates(x)
|
crates, instructions = load_crates(x)
|
||||||
@ -64,7 +67,7 @@ def part1(x):
|
|||||||
crates = parse_instructions(crates, instructions)
|
crates = parse_instructions(crates, instructions)
|
||||||
print([c[0] for c in crates])
|
print([c[0] for c in crates])
|
||||||
|
|
||||||
|
|
||||||
def part2(x):
|
def part2(x):
|
||||||
crates, instructions = load_crates(x)
|
crates, instructions = load_crates(x)
|
||||||
crates = to_lists(crates)
|
crates = to_lists(crates)
|
||||||
@ -74,7 +77,7 @@ def part2(x):
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
rows = load_rows(5)
|
rows = load_rows(5)
|
||||||
#part1(rows)
|
# part1(rows)
|
||||||
part2(rows)
|
part2(rows)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
from shared import load_rows
|
from shared import load_rows
|
||||||
|
|
||||||
|
|
||||||
def part1(row, group_size=4):
|
def part1(row, group_size=4):
|
||||||
for x in range(len(row)):
|
for x in range(len(row)):
|
||||||
if (len(set(row[x:x+group_size])) == group_size):
|
if len(set(row[x : x + group_size])) == group_size:
|
||||||
print(x+group_size)
|
print(x + group_size)
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
def part2(row):
|
def part2(row):
|
||||||
part1(row, 14)
|
part1(row, 14)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
rows = load_rows(6)
|
rows = load_rows(6)
|
||||||
for row in rows:
|
for row in rows:
|
||||||
|
@ -8,77 +8,80 @@ from functools import reduce
|
|||||||
import operator
|
import operator
|
||||||
|
|
||||||
PWD = []
|
PWD = []
|
||||||
FS = { "/": {".":{"size":0, "files":[]}} }
|
FS = {"/": {".": {"size": 0, "files": []}}}
|
||||||
|
|
||||||
|
|
||||||
def get_keys(input_dict):
|
def get_keys(input_dict):
|
||||||
for key, value in input_dict.items():
|
for key, value in input_dict.items():
|
||||||
if isinstance(value, dict):
|
if isinstance(value, dict):
|
||||||
for subkey in get_keys(value):
|
for subkey in get_keys(value):
|
||||||
yield key + ',' + subkey
|
yield key + "," + subkey
|
||||||
else:
|
else:
|
||||||
if key in ("files"):
|
if key in ("files"):
|
||||||
continue
|
continue
|
||||||
yield f"{value}"
|
yield f"{value}"
|
||||||
|
|
||||||
|
|
||||||
def getFromDict(mapList):
|
def getFromDict(mapList):
|
||||||
return reduce(operator.getitem, mapList, FS)
|
return reduce(operator.getitem, mapList, FS)
|
||||||
|
|
||||||
|
|
||||||
def setInDict(mapList, value):
|
def setInDict(mapList, value):
|
||||||
getFromDict(mapList[:-1])[mapList[-1]] = value
|
getFromDict(mapList[:-1])[mapList[-1]] = value
|
||||||
|
|
||||||
|
|
||||||
def addInDict(mapList, filename, value):
|
def addInDict(mapList, filename, value):
|
||||||
try:
|
try:
|
||||||
v = getFromDict(mapList[:-1])[mapList[-1]]
|
v = getFromDict(mapList[:-1])[mapList[-1]]
|
||||||
v += value
|
v += value
|
||||||
getFromDict(mapList[:-1])[mapList[-1]] = v
|
getFromDict(mapList[:-1])[mapList[-1]] = v
|
||||||
except KeyError:
|
except KeyError:
|
||||||
getFromDict(mapList[:-1])["."] = {"size": 0, "files":[]}
|
getFromDict(mapList[:-1])["."] = {"size": 0, "files": []}
|
||||||
v = getFromDict(mapList[:-1])[mapList[-1]]
|
v = getFromDict(mapList[:-1])[mapList[-1]]
|
||||||
v["size"] += 0 # Value
|
v["size"] += 0 # Value
|
||||||
v["files"].append(f"{filename}:{value}")
|
v["files"].append(f"{filename}:{value}")
|
||||||
getFromDict(mapList[:-1])[mapList[-1]] = v
|
getFromDict(mapList[:-1])[mapList[-1]] = v
|
||||||
except TypeError:
|
except TypeError:
|
||||||
v = getFromDict(mapList[:-1])["."]
|
v = getFromDict(mapList[:-1])["."]
|
||||||
v["size"] += 0 # value
|
v["size"] += 0 # value
|
||||||
v["files"].append(f"{filename}:{value}")
|
v["files"].append(f"{filename}:{value}")
|
||||||
getFromDict(mapList[:-1])[mapList[-1]] = v
|
getFromDict(mapList[:-1])[mapList[-1]] = v
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def part1(rows):
|
def part1(rows):
|
||||||
build_fs(rows)
|
build_fs(rows)
|
||||||
#calculate_directories()
|
# calculate_directories()
|
||||||
|
|
||||||
|
|
||||||
def calculate_directories():
|
def calculate_directories():
|
||||||
keys = list(get_keys(FS))
|
keys = list(get_keys(FS))
|
||||||
new_FS = {}
|
new_FS = {}
|
||||||
for key in keys:
|
for key in keys:
|
||||||
pwd = key.split(",")
|
pwd = key.split(",")
|
||||||
size = int(pwd.pop()) # split out size
|
size = int(pwd.pop()) # split out size
|
||||||
pwd.pop() # remove .
|
pwd.pop() # remove .
|
||||||
pwd_key = ",".join(pwd)
|
pwd_key = ",".join(pwd)
|
||||||
parent = ",".join(pwd[:-1])
|
parent = ",".join(pwd[:-1])
|
||||||
new_FS[pwd_key] = {"size":size, "full_size":size, "parent":parent}
|
new_FS[pwd_key] = {"size": size, "full_size": size, "parent": parent}
|
||||||
print("made")
|
print("made")
|
||||||
|
|
||||||
#pp(new_FS)
|
# pp(new_FS)
|
||||||
#print("----")
|
# print("----")
|
||||||
#for pwd, directory in new_FS.items():
|
# for pwd, directory in new_FS.items():
|
||||||
# print(pwd, "\t", directory['parent'])
|
# print(pwd, "\t", directory['parent'])
|
||||||
print(new_FS.keys())
|
print(new_FS.keys())
|
||||||
print("keys^")
|
print("keys^")
|
||||||
for pwd, directory in new_FS.items():
|
for pwd, directory in new_FS.items():
|
||||||
parent = directory['parent']
|
parent = directory["parent"]
|
||||||
if parent:
|
if parent:
|
||||||
print(parent)
|
print(parent)
|
||||||
#print(f"{pwd}:{parent} Adding {directory['size']} to fullsize {new_FS[parent]['full_size']}")
|
# print(f"{pwd}:{parent} Adding {directory['size']} to fullsize {new_FS[parent]['full_size']}")
|
||||||
new_FS[parent]["size"] += directory["size"]
|
new_FS[parent]["size"] += directory["size"]
|
||||||
print("added sizes")
|
print("added sizes")
|
||||||
|
|
||||||
sizes = []
|
sizes = []
|
||||||
for k,v in new_FS.items():
|
for k, v in new_FS.items():
|
||||||
sizes.append(v['size'])
|
sizes.append(v["size"])
|
||||||
total = 0
|
total = 0
|
||||||
|
|
||||||
for size in sizes:
|
for size in sizes:
|
||||||
@ -86,7 +89,8 @@ def calculate_directories():
|
|||||||
print("+", size)
|
print("+", size)
|
||||||
total += size
|
total += size
|
||||||
|
|
||||||
print("=" ,total)
|
print("=", total)
|
||||||
|
|
||||||
|
|
||||||
def build_fs(rows):
|
def build_fs(rows):
|
||||||
LS_ING = False
|
LS_ING = False
|
||||||
@ -102,7 +106,7 @@ def build_fs(rows):
|
|||||||
PWD.pop()
|
PWD.pop()
|
||||||
else:
|
else:
|
||||||
PWD.append(parts[2])
|
PWD.append(parts[2])
|
||||||
#print(PWD)
|
# print(PWD)
|
||||||
elif parts[1] == "ls":
|
elif parts[1] == "ls":
|
||||||
LS_ING = True
|
LS_ING = True
|
||||||
continue
|
continue
|
||||||
@ -113,6 +117,7 @@ def build_fs(rows):
|
|||||||
add_file(parts[1], int(parts[0]))
|
add_file(parts[1], int(parts[0]))
|
||||||
jp(FS)
|
jp(FS)
|
||||||
|
|
||||||
|
|
||||||
def jp(d):
|
def jp(d):
|
||||||
output = json.dumps(FS, indent=4)
|
output = json.dumps(FS, indent=4)
|
||||||
output2 = re.sub(r'": \[\s+', '": [', output)
|
output2 = re.sub(r'": \[\s+', '": [', output)
|
||||||
@ -123,26 +128,28 @@ def jp(d):
|
|||||||
|
|
||||||
def add_directory(dirname):
|
def add_directory(dirname):
|
||||||
temp_new_path = PWD + [dirname]
|
temp_new_path = PWD + [dirname]
|
||||||
setInDict(temp_new_path, {".":{"size":0, "files":[]}})
|
setInDict(temp_new_path, {".": {"size": 0, "files": []}})
|
||||||
|
|
||||||
|
|
||||||
def add_file(filename, size):
|
def add_file(filename, size):
|
||||||
#print(".", PWD, filename, size)
|
# print(".", PWD, filename, size)
|
||||||
mapList = PWD + ["."]
|
mapList = PWD + ["."]
|
||||||
addInDict(mapList, filename, size)
|
addInDict(mapList, filename, size)
|
||||||
curr = getFromDict(mapList[:-1])
|
curr = getFromDict(mapList[:-1])
|
||||||
print(curr)
|
print(curr)
|
||||||
#print(curr)
|
# print(curr)
|
||||||
s = curr["."]
|
s = curr["."]
|
||||||
s["size"] += size
|
s["size"] += size
|
||||||
print(size,s)
|
print(size, s)
|
||||||
tmp = mapList + ["size"]
|
tmp = mapList + ["size"]
|
||||||
setInDict(mapList, s)
|
setInDict(mapList, s)
|
||||||
print("-----")
|
print("-----")
|
||||||
|
|
||||||
|
|
||||||
def part2(row):
|
def part2(row):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
rows = load_rows(7)
|
rows = load_rows(7)
|
||||||
part1(rows)
|
part1(rows)
|
||||||
|
@ -3,16 +3,15 @@ import shared
|
|||||||
import matrix
|
import matrix
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def part1(mx):
|
def part1(mx):
|
||||||
SIZE=len(mx)
|
SIZE = len(mx)
|
||||||
MAX_IDX = SIZE -1
|
MAX_IDX = SIZE - 1
|
||||||
data = matrix.matrix_of_size(SIZE, SIZE)
|
data = matrix.matrix_of_size(SIZE, SIZE)
|
||||||
data = matrix.set_matrix_dict(data)
|
data = matrix.set_matrix_dict(data)
|
||||||
|
|
||||||
for row in range(SIZE):
|
for row in range(SIZE):
|
||||||
for col in range(SIZE):
|
for col in range(SIZE):
|
||||||
data[row][col] = { "l": True, "r": True, "u": True, "d": True }
|
data[row][col] = {"l": True, "r": True, "u": True, "d": True}
|
||||||
|
|
||||||
for row, _row in enumerate(mx):
|
for row, _row in enumerate(mx):
|
||||||
# Skip outer edges
|
# Skip outer edges
|
||||||
@ -28,7 +27,7 @@ def part1(mx):
|
|||||||
trees_u_indexes = list(range(0, row))
|
trees_u_indexes = list(range(0, row))
|
||||||
trees_l_indexes = list(range(0, col))
|
trees_l_indexes = list(range(0, col))
|
||||||
trees_d_indexes = list(range(MAX_IDX, row, -1))
|
trees_d_indexes = list(range(MAX_IDX, row, -1))
|
||||||
trees_r_indexes = list(range(col+1, SIZE))
|
trees_r_indexes = list(range(col + 1, SIZE))
|
||||||
|
|
||||||
# Get the trees in the line
|
# Get the trees in the line
|
||||||
trees_u = [mx[y][col] for y in trees_u_indexes]
|
trees_u = [mx[y][col] for y in trees_u_indexes]
|
||||||
@ -45,50 +44,50 @@ def part1(mx):
|
|||||||
# if there's anything as tall, or taller than this tree in that line
|
# if there's anything as tall, or taller than this tree in that line
|
||||||
# then it's not visible
|
# then it's not visible
|
||||||
if highest_u >= _val:
|
if highest_u >= _val:
|
||||||
data[row][col]["u"] = False
|
data[row][col]["u"] = False
|
||||||
|
|
||||||
if highest_l >= _val:
|
if highest_l >= _val:
|
||||||
data[row][col]["l"] = False
|
data[row][col]["l"] = False
|
||||||
|
|
||||||
if highest_d >= _val:
|
if highest_d >= _val:
|
||||||
data[row][col]["d"] = False
|
data[row][col]["d"] = False
|
||||||
|
|
||||||
if highest_r >= _val:
|
if highest_r >= _val:
|
||||||
data[row][col]["r"] = False
|
data[row][col]["r"] = False
|
||||||
|
|
||||||
# count visible
|
# count visible
|
||||||
count = 0
|
count = 0
|
||||||
for row in range(SIZE):
|
for row in range(SIZE):
|
||||||
for col in range(SIZE):
|
for col in range(SIZE):
|
||||||
u = data[row][col]["u"]
|
u = data[row][col]["u"]
|
||||||
l = data[row][col]["l"]
|
l = data[row][col]["l"]
|
||||||
d = data[row][col]["d"]
|
d = data[row][col]["d"]
|
||||||
r = data[row][col]["r"]
|
r = data[row][col]["r"]
|
||||||
if any((r,l,u,d)):
|
if any((r, l, u, d)):
|
||||||
count += 1
|
count += 1
|
||||||
print(count)
|
print(count)
|
||||||
|
|
||||||
|
|
||||||
def part2(mx):
|
def part2(mx):
|
||||||
SIZE=len(mx)
|
SIZE = len(mx)
|
||||||
MAX_IDX = SIZE -1
|
MAX_IDX = SIZE - 1
|
||||||
data = matrix.matrix_of_size(SIZE, SIZE)
|
data = matrix.matrix_of_size(SIZE, SIZE)
|
||||||
data = matrix.set_matrix_dict(data)
|
data = matrix.set_matrix_dict(data)
|
||||||
|
|
||||||
high_score = 0
|
high_score = 0
|
||||||
|
|
||||||
for row in range(SIZE):
|
for row in range(SIZE):
|
||||||
for col in range(SIZE):
|
for col in range(SIZE):
|
||||||
data[row][col] = { "value": mx[row][col]}
|
data[row][col] = {"value": mx[row][col]}
|
||||||
|
|
||||||
for row, _row in enumerate(mx):
|
for row, _row in enumerate(mx):
|
||||||
for col, _val in enumerate(mx[row]):
|
for col, _val in enumerate(mx[row]):
|
||||||
# Get a list of indexes in the current direction to check
|
# Get a list of indexes in the current direction to check
|
||||||
# TODO: slice
|
# TODO: slice
|
||||||
trees_u_indexes = list(range(0, row))
|
trees_u_indexes = list(range(0, row))
|
||||||
trees_l_indexes = list(range(0,col))
|
trees_l_indexes = list(range(0, col))
|
||||||
trees_d_indexes = list(range(MAX_IDX, row, -1))
|
trees_d_indexes = list(range(MAX_IDX, row, -1))
|
||||||
trees_r_indexes = list(range(col+1, SIZE))
|
trees_r_indexes = list(range(col + 1, SIZE))
|
||||||
|
|
||||||
# Grab the trees potentially in sight
|
# Grab the trees potentially in sight
|
||||||
trees_u = [mx[y][col] for y in trees_u_indexes]
|
trees_u = [mx[y][col] for y in trees_u_indexes]
|
||||||
@ -103,17 +102,17 @@ def part2(mx):
|
|||||||
data[row][col]["r"] = trees_r
|
data[row][col]["r"] = trees_r
|
||||||
|
|
||||||
# Calculate score
|
# Calculate score
|
||||||
score = 1 # identity yoooo
|
score = 1 # identity yoooo
|
||||||
cell = data[row][col]
|
cell = data[row][col]
|
||||||
val = cell['value']
|
val = cell["value"]
|
||||||
# Get the score of visible trees in each direction
|
# Get the score of visible trees in each direction
|
||||||
for direction in ("u","l","d","r"):
|
for direction in ("u", "l", "d", "r"):
|
||||||
in_line = cell[direction]
|
in_line = cell[direction]
|
||||||
if not in_line:
|
if not in_line:
|
||||||
# we're on an edge
|
# we're on an edge
|
||||||
score = 0
|
score = 0
|
||||||
break
|
break
|
||||||
|
|
||||||
line_score = 0
|
line_score = 0
|
||||||
for idx, tree in enumerate(in_line):
|
for idx, tree in enumerate(in_line):
|
||||||
# for every tree, check if its as tall or taller,
|
# for every tree, check if its as tall or taller,
|
||||||
@ -126,17 +125,18 @@ def part2(mx):
|
|||||||
high_score = score
|
high_score = score
|
||||||
print(high_score)
|
print(high_score)
|
||||||
|
|
||||||
|
|
||||||
def part2_with_fixes(mx):
|
def part2_with_fixes(mx):
|
||||||
SIZE=len(mx)
|
SIZE = len(mx)
|
||||||
MAX_IDX = SIZE -1
|
MAX_IDX = SIZE - 1
|
||||||
data = matrix.matrix_of_size(SIZE, SIZE)
|
data = matrix.matrix_of_size(SIZE, SIZE)
|
||||||
data = matrix.set_matrix_dict(data)
|
data = matrix.set_matrix_dict(data)
|
||||||
|
|
||||||
high_score = 0
|
high_score = 0
|
||||||
|
|
||||||
for row in range(SIZE):
|
for row in range(SIZE):
|
||||||
for col in range(SIZE):
|
for col in range(SIZE):
|
||||||
data[row][col] = { "value": mx[row][col]}
|
data[row][col] = {"value": mx[row][col]}
|
||||||
|
|
||||||
for row, _row in enumerate(mx):
|
for row, _row in enumerate(mx):
|
||||||
for col, _val in enumerate(mx[row]):
|
for col, _val in enumerate(mx[row]):
|
||||||
@ -148,16 +148,16 @@ def part2_with_fixes(mx):
|
|||||||
data[row][col]["r"] = lineofsight["R"]
|
data[row][col]["r"] = lineofsight["R"]
|
||||||
|
|
||||||
# Calculate score
|
# Calculate score
|
||||||
score = 1 # identity yoooo
|
score = 1 # identity yoooo
|
||||||
val = data[row][col]['value']
|
val = data[row][col]["value"]
|
||||||
# Get the score of visible trees in each direction
|
# Get the score of visible trees in each direction
|
||||||
for direction in ("u","l","d","r"):
|
for direction in ("u", "l", "d", "r"):
|
||||||
in_line = data[row][col][direction]
|
in_line = data[row][col][direction]
|
||||||
if not in_line:
|
if not in_line:
|
||||||
# we're on an edge
|
# we're on an edge
|
||||||
score = 0
|
score = 0
|
||||||
break
|
break
|
||||||
|
|
||||||
line_score = 0
|
line_score = 0
|
||||||
for idx, tree in enumerate(in_line):
|
for idx, tree in enumerate(in_line):
|
||||||
# for every tree, check if its as tall or taller,
|
# for every tree, check if its as tall or taller,
|
||||||
@ -170,6 +170,7 @@ def part2_with_fixes(mx):
|
|||||||
high_score = score
|
high_score = score
|
||||||
print(high_score)
|
print(high_score)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
mx = matrix.load_matrix_file(shared.get_fname(8))
|
mx = matrix.load_matrix_file(shared.get_fname(8))
|
||||||
with shared.elapsed_timer() as elapsed:
|
with shared.elapsed_timer() as elapsed:
|
||||||
@ -183,6 +184,5 @@ def main():
|
|||||||
print(elapsed())
|
print(elapsed())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
@ -5,28 +5,28 @@ import shared
|
|||||||
import matrix
|
import matrix
|
||||||
|
|
||||||
MATRIX_SIZE = 400
|
MATRIX_SIZE = 400
|
||||||
ATRIX_SIZE = 40 # sample
|
ATRIX_SIZE = 40 # sample
|
||||||
HALF = MATRIX_SIZE // 2
|
HALF = MATRIX_SIZE // 2
|
||||||
|
|
||||||
H = [HALF,HALF]
|
H = [HALF, HALF]
|
||||||
T = [HALF,HALF]
|
T = [HALF, HALF]
|
||||||
|
|
||||||
|
|
||||||
# returns (x,y) - so remember to take dx,dy lower
|
# returns (x,y) - so remember to take dx,dy lower
|
||||||
DIRS = {
|
DIRS = {
|
||||||
'U': matrix.M_U, # (0, -1)
|
"U": matrix.M_U, # (0, -1)
|
||||||
'D': matrix.M_D,
|
"D": matrix.M_D,
|
||||||
'L': matrix.M_L,
|
"L": matrix.M_L,
|
||||||
'R': matrix.M_R,
|
"R": matrix.M_R,
|
||||||
|
"UR": matrix.M_UR, # (+1, -1)
|
||||||
'UR': matrix.M_UR, # (+1, -1)
|
"DR": matrix.M_DR,
|
||||||
'DR': matrix.M_DR,
|
"UL": matrix.M_UL,
|
||||||
'UL': matrix.M_UL,
|
"DL": matrix.M_DL,
|
||||||
'DL': matrix.M_DL,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def part1(steps):
|
def part1(steps):
|
||||||
field = matrix.matrix_of_size(MATRIX_SIZE,MATRIX_SIZE)
|
field = matrix.matrix_of_size(MATRIX_SIZE, MATRIX_SIZE)
|
||||||
anim = Animate(field, day="09")
|
anim = Animate(field, day="09")
|
||||||
|
|
||||||
for direction, amount in steps:
|
for direction, amount in steps:
|
||||||
@ -34,21 +34,21 @@ def part1(steps):
|
|||||||
amount = int(amount)
|
amount = int(amount)
|
||||||
for x in range(amount):
|
for x in range(amount):
|
||||||
|
|
||||||
dx,dy = DIRS[direction]
|
dx, dy = DIRS[direction]
|
||||||
H[0] += dy
|
H[0] += dy
|
||||||
H[1] += dx
|
H[1] += dx
|
||||||
HY,bX = H
|
HY, bX = H
|
||||||
# head is in new position
|
# head is in new position
|
||||||
kY,kX = T
|
kY, kX = T
|
||||||
field[kY][kX] = 1 # 'T'
|
field[kY][kX] = 1 # 'T'
|
||||||
|
|
||||||
# Check if same
|
# Check if same
|
||||||
if kY == HY and kX == bX:
|
if kY == HY and kX == bX:
|
||||||
continue
|
continue
|
||||||
touching = False
|
touching = False
|
||||||
for _, d in DIRS.items():
|
for _, d in DIRS.items():
|
||||||
dx,dy = d
|
dx, dy = d
|
||||||
t_y, t_x = H[0]+dy, H[1]+dx
|
t_y, t_x = H[0] + dy, H[1] + dx
|
||||||
if kY == t_y and kX == t_x:
|
if kY == t_y and kX == t_x:
|
||||||
touching = True
|
touching = True
|
||||||
break
|
break
|
||||||
@ -58,66 +58,67 @@ def part1(steps):
|
|||||||
# assume the same row/column, no movement needed
|
# assume the same row/column, no movement needed
|
||||||
tY = 0
|
tY = 0
|
||||||
tX = 0
|
tX = 0
|
||||||
|
|
||||||
# if Head X is less than Tail X, move Tail X 1 left
|
# if Head X is less than Tail X, move Tail X 1 left
|
||||||
if bX < kX:
|
if bX < kX:
|
||||||
tX = -1
|
tX = -1
|
||||||
# if Head X is greater than Tail X, move Tail X 1 left
|
# if Head X is greater than Tail X, move Tail X 1 left
|
||||||
elif bX > kX:
|
elif bX > kX:
|
||||||
tX = 1
|
tX = 1
|
||||||
|
|
||||||
|
|
||||||
# if Head Y is less than Tail Y, move Tail Y 1 up
|
# if Head Y is less than Tail Y, move Tail Y 1 up
|
||||||
if HY < kY:
|
if HY < kY:
|
||||||
tY = -1
|
tY = -1
|
||||||
# if Head Y is greater than Tail Y, move Tail Y 1 down
|
# if Head Y is greater than Tail Y, move Tail Y 1 down
|
||||||
elif HY > kY:
|
elif HY > kY:
|
||||||
tY = 1
|
tY = 1
|
||||||
|
|
||||||
T[0] += tY
|
T[0] += tY
|
||||||
T[1] += tX
|
T[1] += tX
|
||||||
anim.add_frame(field)
|
anim.add_frame(field)
|
||||||
|
|
||||||
field[T[0]][T[1]] = 1 # mark visited tails
|
field[T[0]][T[1]] = 1 # mark visited tails
|
||||||
print(matrix.sum_matrix(field))
|
print(matrix.sum_matrix(field))
|
||||||
anim.animate()
|
anim.animate()
|
||||||
|
|
||||||
|
|
||||||
def part2(steps):
|
def part2(steps):
|
||||||
field = matrix.matrix_of_size(MATRIX_SIZE,MATRIX_SIZE)
|
field = matrix.matrix_of_size(MATRIX_SIZE, MATRIX_SIZE)
|
||||||
anim = Animate(field, day="09")
|
anim = Animate(field, day="09")
|
||||||
S = [[HALF,HALF],] # HEAD ONLY
|
S = [
|
||||||
|
[HALF, HALF],
|
||||||
|
] # HEAD ONLY
|
||||||
_cur_frame = 0
|
_cur_frame = 0
|
||||||
for x in range(9):
|
for x in range(9):
|
||||||
S.append([HALF,HALF])
|
S.append([HALF, HALF])
|
||||||
|
|
||||||
for direction, amount in steps:
|
for direction, amount in steps:
|
||||||
# move HEAD
|
# move HEAD
|
||||||
amount = int(amount)
|
amount = int(amount)
|
||||||
for x in range(amount):
|
for x in range(amount):
|
||||||
HEAD_dx,HEAD_dy = DIRS[direction]
|
HEAD_dx, HEAD_dy = DIRS[direction]
|
||||||
S[0][0] += HEAD_dy
|
S[0][0] += HEAD_dy
|
||||||
S[0][1] += HEAD_dx
|
S[0][1] += HEAD_dx
|
||||||
#print(HEAD_dy,HEAD_dx, S)
|
# print(HEAD_dy,HEAD_dx, S)
|
||||||
# HEAD MOVED one step
|
# HEAD MOVED one step
|
||||||
|
|
||||||
for knot_idx, _ in enumerate(S):
|
for knot_idx, _ in enumerate(S):
|
||||||
if knot_idx == 0:
|
if knot_idx == 0:
|
||||||
# Skip Head
|
# Skip Head
|
||||||
continue
|
continue
|
||||||
knot = S[knot_idx]
|
knot = S[knot_idx]
|
||||||
kY,kX = knot
|
kY, kX = knot
|
||||||
|
|
||||||
bY,bX = S[knot_idx-1]
|
bY, bX = S[knot_idx - 1]
|
||||||
|
|
||||||
# Check if same
|
# Check if same
|
||||||
if kY == bY and kX == bX:
|
if kY == bY and kX == bX:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
touching = False
|
touching = False
|
||||||
for _, d in DIRS.items():
|
for _, d in DIRS.items():
|
||||||
dx,dy = d
|
dx, dy = d
|
||||||
t_y, t_x = S[knot_idx-1][0]+dy, S[knot_idx-1][1]+dx
|
t_y, t_x = S[knot_idx - 1][0] + dy, S[knot_idx - 1][1] + dx
|
||||||
if kY == t_y and kX == t_x:
|
if kY == t_y and kX == t_x:
|
||||||
touching = True
|
touching = True
|
||||||
break
|
break
|
||||||
@ -125,36 +126,35 @@ def part2(steps):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# assume the same row/column, no movement needed
|
# assume the same row/column, no movement needed
|
||||||
tY, tX = 0,0
|
tY, tX = 0, 0
|
||||||
|
|
||||||
# if Head X is less than Tail X, move Tail X 1 left
|
# if Head X is less than Tail X, move Tail X 1 left
|
||||||
if bX < kX:
|
if bX < kX:
|
||||||
tX = -1
|
tX = -1
|
||||||
# if Head X is greater than Tail X, move Tail X 1 left
|
# if Head X is greater than Tail X, move Tail X 1 left
|
||||||
elif bX > kX:
|
elif bX > kX:
|
||||||
tX = 1
|
tX = 1
|
||||||
|
|
||||||
# if Head Y is less than Tail Y, move Tail Y 1 up
|
# if Head Y is less than Tail Y, move Tail Y 1 up
|
||||||
if bY < kY:
|
if bY < kY:
|
||||||
tY = -1
|
tY = -1
|
||||||
# if Head Y is greater than Tail Y, move Tail Y 1 down
|
# if Head Y is greater than Tail Y, move Tail Y 1 down
|
||||||
elif bY > kY:
|
elif bY > kY:
|
||||||
tY = 1
|
tY = 1
|
||||||
|
|
||||||
S[knot_idx][0] += tY
|
S[knot_idx][0] += tY
|
||||||
S[knot_idx][1] += tX
|
S[knot_idx][1] += tX
|
||||||
if _cur_frame % 25 == 0:
|
if _cur_frame % 25 == 0:
|
||||||
anim.add_frame(field)
|
anim.add_frame(field)
|
||||||
_cur_frame += 1
|
_cur_frame += 1
|
||||||
field[S[-1][0]][S[-1][1]] = 1 # mark visited tails
|
field[S[-1][0]][S[-1][1]] = 1 # mark visited tails
|
||||||
print(matrix.sum_matrix(field))
|
print(matrix.sum_matrix(field))
|
||||||
anim.animate()
|
anim.animate()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
rows = [x.split(" ") for x in shared.load_rows(9)]
|
rows = [x.split(" ") for x in shared.load_rows(9)]
|
||||||
#part1(rows)
|
# part1(rows)
|
||||||
part2(rows)
|
part2(rows)
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,9 +3,10 @@ from anim import Animate
|
|||||||
import matrix
|
import matrix
|
||||||
|
|
||||||
cycles = {
|
cycles = {
|
||||||
"noop": 1,
|
"noop": 1,
|
||||||
"addx": 2,
|
"addx": 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def part1(x):
|
def part1(x):
|
||||||
X = 1
|
X = 1
|
||||||
@ -22,23 +23,21 @@ def part1(x):
|
|||||||
for x in range(cycles[opcode]):
|
for x in range(cycles[opcode]):
|
||||||
cycle_count += 1
|
cycle_count += 1
|
||||||
|
|
||||||
if cycle_count == 20 or ((cycle_count -20) % 40 == 0):
|
if cycle_count == 20 or ((cycle_count - 20) % 40 == 0):
|
||||||
signal_strength.append(cycle_count*X)
|
signal_strength.append(cycle_count * X)
|
||||||
|
|
||||||
if opcode == "addx":
|
if opcode == "addx":
|
||||||
X += val
|
X += val
|
||||||
print(sum(signal_strength))
|
print(sum(signal_strength))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def part2(x):
|
def part2(x):
|
||||||
def cycle_to_xy(cycle):
|
def cycle_to_xy(cycle):
|
||||||
x = cycle % 40
|
x = cycle % 40
|
||||||
y = cycle // 40
|
y = cycle // 40
|
||||||
return x,y
|
return x, y
|
||||||
|
|
||||||
screen = matrix.matrix_of_size(40,6)
|
screen = matrix.matrix_of_size(40, 6)
|
||||||
X = 1
|
X = 1
|
||||||
cycle_count = 0
|
cycle_count = 0
|
||||||
for step, instruction in enumerate(x):
|
for step, instruction in enumerate(x):
|
||||||
@ -50,8 +49,8 @@ def part2(x):
|
|||||||
opcode = instruction
|
opcode = instruction
|
||||||
|
|
||||||
for x in range(cycles[opcode]):
|
for x in range(cycles[opcode]):
|
||||||
_x,y = cycle_to_xy(cycle_count)
|
_x, y = cycle_to_xy(cycle_count)
|
||||||
criteria = (X-1, X, X+1)
|
criteria = (X - 1, X, X + 1)
|
||||||
cycle_count += 1
|
cycle_count += 1
|
||||||
if _x in criteria:
|
if _x in criteria:
|
||||||
screen[y][_x] = 1
|
screen[y][_x] = 1
|
||||||
@ -59,15 +58,16 @@ def part2(x):
|
|||||||
if opcode == "addx":
|
if opcode == "addx":
|
||||||
X += val
|
X += val
|
||||||
|
|
||||||
matrix.ppmx(screen,pad=False, space=False)
|
matrix.ppmx(screen, pad=False, space=False)
|
||||||
anim = Animate(screen, day="10")
|
anim = Animate(screen, day="10")
|
||||||
anim.add_frame(screen)
|
anim.add_frame(screen)
|
||||||
print("wrote gif-10/day10.gif")
|
print("wrote gif-10/day10.gif")
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
rows = [row for row in shared.load(10)]
|
rows = [row for row in shared.load(10)]
|
||||||
part1(rows)
|
part1(rows)
|
||||||
print("%"*40)
|
print("%" * 40)
|
||||||
part2(rows)
|
part2(rows)
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,10 +29,10 @@ def load_monkeys(lines):
|
|||||||
try:
|
try:
|
||||||
by = int(line.split(" ")[-1])
|
by = int(line.split(" ")[-1])
|
||||||
except ValueError:
|
except ValueError:
|
||||||
by = None # know None means by self
|
by = None # know None means by self
|
||||||
if '*' in op:
|
if "*" in op:
|
||||||
operand = operator.mul
|
operand = operator.mul
|
||||||
elif '+' in op:
|
elif "+" in op:
|
||||||
operand = operator.add
|
operand = operator.add
|
||||||
elif line.lstrip().startswith("Test"):
|
elif line.lstrip().startswith("Test"):
|
||||||
div = int(line.split(" ")[-1])
|
div = int(line.split(" ")[-1])
|
||||||
@ -41,19 +41,14 @@ def load_monkeys(lines):
|
|||||||
elif line.lstrip().startswith("If false"):
|
elif line.lstrip().startswith("If false"):
|
||||||
false = int(line.split(" ")[-1])
|
false = int(line.split(" ")[-1])
|
||||||
monkey = Monkey(
|
monkey = Monkey(
|
||||||
number=count,
|
number=count, items=items, op=operand, by=by, div=div, t=true, f=false
|
||||||
items=items,
|
)
|
||||||
op=operand,
|
|
||||||
by=by,
|
|
||||||
div=div,
|
|
||||||
t=true,
|
|
||||||
f=false
|
|
||||||
)
|
|
||||||
monkeys.append(monkey)
|
monkeys.append(monkey)
|
||||||
count+=1
|
count += 1
|
||||||
lcm = math.lcm(*[m.div for m in monkeys])
|
lcm = math.lcm(*[m.div for m in monkeys])
|
||||||
return monkeys, lcm
|
return monkeys, lcm
|
||||||
|
|
||||||
|
|
||||||
def part1(lines):
|
def part1(lines):
|
||||||
monkeys, _ = load_monkeys(lines)
|
monkeys, _ = load_monkeys(lines)
|
||||||
|
|
||||||
@ -78,7 +73,7 @@ def part1(lines):
|
|||||||
total = counts[-1] * counts[-2]
|
total = counts[-1] * counts[-2]
|
||||||
print(total)
|
print(total)
|
||||||
|
|
||||||
|
|
||||||
def part2(lines):
|
def part2(lines):
|
||||||
monkeys, lcm = load_monkeys(lines)
|
monkeys, lcm = load_monkeys(lines)
|
||||||
|
|
||||||
|
116
2022/python/day12.py
Normal file
116
2022/python/day12.py
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
import shared
|
||||||
|
import matrix
|
||||||
|
from dijkstar import Graph, find_path, algorithm
|
||||||
|
|
||||||
|
|
||||||
|
#def dj_walk(mx, start, end):
|
||||||
|
# def next_cost(c, val):
|
||||||
|
# if val > c+1:
|
||||||
|
# return 9999
|
||||||
|
# else:
|
||||||
|
# return val
|
||||||
|
#
|
||||||
|
# start = start[1], start[0]
|
||||||
|
# end = end[1], end[0]
|
||||||
|
#
|
||||||
|
# # Dijkstra from RedBlobGames
|
||||||
|
# frontier = PriorityQueue()
|
||||||
|
# frontier.put(start, 0)
|
||||||
|
# came_from = dict()
|
||||||
|
# cost_so_far = dict()
|
||||||
|
# came_from[start] = None
|
||||||
|
# cost_so_far[start] = 0
|
||||||
|
# last = None
|
||||||
|
# while not frontier.empty():
|
||||||
|
# x, y = frontier.get()
|
||||||
|
# cur = (x, y)
|
||||||
|
# if cur == end:
|
||||||
|
# break
|
||||||
|
# for _n in matrix.get_neighbors(mx, x=x, y=y, _dict=True):
|
||||||
|
# nxt = (_n["x"], _n["y"])
|
||||||
|
# v = _n["value"]
|
||||||
|
#
|
||||||
|
# new_cost = next_cost(cost_so_far[cur], v)
|
||||||
|
# if nxt not in cost_so_far or new_cost < cost_so_far[nxt]:
|
||||||
|
# cost_so_far[nxt] = new_cost
|
||||||
|
# priority = new_cost
|
||||||
|
# frontier.put(nxt, priority)
|
||||||
|
# came_from[nxt] = cur
|
||||||
|
# last = cur
|
||||||
|
# print(len(cost_so_far))
|
||||||
|
|
||||||
|
criteria = lambda _cur, _neighbor: _neighbor - _cur <= 1
|
||||||
|
def build_graph(mx):
|
||||||
|
graph = Graph()
|
||||||
|
for y, row in enumerate(mx):
|
||||||
|
for x, _ in enumerate(row):
|
||||||
|
neighbors = matrix.valid_neighbors(mx, x=x, y=y, criteria=criteria)
|
||||||
|
for neighbor in neighbors:
|
||||||
|
graph.add_edge((y, x), (neighbor['y'],neighbor['x']), 1)
|
||||||
|
return graph
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#SEEN = []
|
||||||
|
#def walk(mx, y, x, seen=[]):
|
||||||
|
# print(len(seen))
|
||||||
|
# valid_next = matrix.valid_neighbors(mx, y, x, criteria=criteria)
|
||||||
|
# print(valid_next)
|
||||||
|
# matrix.highlight( mx, red=seen, green=[ *valid_next, ], blue=[ END, ],)
|
||||||
|
# for next_yx in valid_next:
|
||||||
|
# if next_yx not in seen:
|
||||||
|
# seen.append(next_yx)
|
||||||
|
# _y, _x = next_yx
|
||||||
|
# walk(mx, _y, _x, seen)
|
||||||
|
# else:
|
||||||
|
# seen.append(next_yx)
|
||||||
|
|
||||||
|
def elev(yx):
|
||||||
|
y,x = yx
|
||||||
|
return mx[y][x]
|
||||||
|
|
||||||
|
def part1(mx):
|
||||||
|
start = matrix.find_in_matrix(mx, "S")
|
||||||
|
end = matrix.find_in_matrix(mx, "E")
|
||||||
|
mx[start[0]][start[1]] = "a"
|
||||||
|
mx[end[0]][end[1]] = "z"
|
||||||
|
matrix.apply_to_all(mx, lambda x: ord(x) - ord('a'))
|
||||||
|
|
||||||
|
#walk(mx, cur[0],cur[0], seen=[(cur[0],cur[1])])
|
||||||
|
#dj_walk(mx, cur, END)
|
||||||
|
graph = build_graph(mx)
|
||||||
|
path = find_path(graph, start, end)
|
||||||
|
print(len(path.nodes))
|
||||||
|
|
||||||
|
|
||||||
|
def part2(mx):
|
||||||
|
end = matrix.find_in_matrix(mx, "E")
|
||||||
|
s = matrix.find_in_matrix(mx, "S")
|
||||||
|
mx[s[0]][s[1]] = "a"
|
||||||
|
mx[end[0]][end[1]] = "z"
|
||||||
|
|
||||||
|
starts = matrix.find_in_matrix(mx, 'a', one=False)
|
||||||
|
matrix.apply_to_all(mx, lambda x: ord(x) - ord('a'))
|
||||||
|
graph = build_graph(mx)
|
||||||
|
|
||||||
|
n_counts = []
|
||||||
|
for start in starts:
|
||||||
|
#walk(mx, cur[0],cur[0], seen=[(cur[0],cur[1])])
|
||||||
|
#dj_walk(mx, cur, END)
|
||||||
|
try:
|
||||||
|
path = find_path(graph, start, end)
|
||||||
|
n_counts.append(len(path.nodes)-1)
|
||||||
|
except algorithm.NoPathError:
|
||||||
|
pass
|
||||||
|
print(n_counts)
|
||||||
|
print(min(n_counts))
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
mx = matrix.load_matrix_file(shared.get_fname(12), matrix.split_word_to_chr_list)
|
||||||
|
#part1(mx)
|
||||||
|
part2(mx)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
@ -1,10 +1,28 @@
|
|||||||
|
from copy import deepcopy
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
from typing import List, Dict, Tuple
|
from typing import List, Dict, Tuple
|
||||||
|
|
||||||
|
split_word_to_chr_list = lambda y: [w for w in y]
|
||||||
split_word_to_int_list = lambda y: [int(w) for w in y]
|
split_word_to_int_list = lambda y: [int(w) for w in y]
|
||||||
split_line_to_int_list = lambda y: [int(w) for w in y.split(" ") if w]
|
split_line_to_int_list = lambda y: [int(w) for w in y.split(" ") if w]
|
||||||
|
|
||||||
|
|
||||||
|
class colors:
|
||||||
|
# HEADER = '\033[95m'
|
||||||
|
BLUE = "\033[94m"
|
||||||
|
GREEN = "\033[92m"
|
||||||
|
YELLOW = "\033[93m"
|
||||||
|
RED = "\033[91m"
|
||||||
|
ENDC = "\033[0m"
|
||||||
|
|
||||||
|
|
||||||
|
def apply_to_all(mx, func):
|
||||||
|
for row_num, row in enumerate(mx):
|
||||||
|
for col_num, val in enumerate(row):
|
||||||
|
mx[row_num][col_num] = func(val)
|
||||||
|
|
||||||
|
|
||||||
def rotate(m, right=True): # -90
|
def rotate(m, right=True): # -90
|
||||||
"""
|
"""
|
||||||
Takes a matrix, and rotates all of the values 90 degrees to the left
|
Takes a matrix, and rotates all of the values 90 degrees to the left
|
||||||
@ -17,7 +35,7 @@ def rotate(m, right=True): # -90
|
|||||||
|
|
||||||
def load_matrix_file(name, func=None):
|
def load_matrix_file(name, func=None):
|
||||||
"""
|
"""
|
||||||
Open a file and split all space separated word lists to integers as a matrix
|
Open a file and split all space separated word lists to integers as a matrix
|
||||||
"""
|
"""
|
||||||
with open(name, "r") as f:
|
with open(name, "r") as f:
|
||||||
my_file = []
|
my_file = []
|
||||||
@ -28,13 +46,26 @@ def load_matrix_file(name, func=None):
|
|||||||
return [split_word_to_int_list(x) for x in my_file]
|
return [split_word_to_int_list(x) for x in my_file]
|
||||||
|
|
||||||
|
|
||||||
|
def find_in_matrix(mx, what, one=True):
|
||||||
|
coords = []
|
||||||
|
for row_num, row in enumerate(mx):
|
||||||
|
for col_num, val in enumerate(row):
|
||||||
|
if val == what:
|
||||||
|
coord = (row_num, col_num)
|
||||||
|
if one is True:
|
||||||
|
return coord
|
||||||
|
else:
|
||||||
|
coords.append(coord)
|
||||||
|
return coords
|
||||||
|
|
||||||
|
|
||||||
def get_neighbors(matrix, x, y, _dict=False):
|
def get_neighbors(matrix, x, y, _dict=False):
|
||||||
neighbors = []
|
neighbors = []
|
||||||
# left
|
# left
|
||||||
try:
|
try:
|
||||||
if x - 1 >= 0:
|
if x - 1 >= 0:
|
||||||
if _dict:
|
if _dict:
|
||||||
neighbors.append({'x':x - 1,'y':y,'value':matrix[y][x - 1]})
|
neighbors.append({"x": x - 1, "y": y, "value": matrix[y][x - 1]})
|
||||||
else:
|
else:
|
||||||
neighbors.append([(x - 1, y), matrix[y][x - 1]])
|
neighbors.append([(x - 1, y), matrix[y][x - 1]])
|
||||||
except IndexError:
|
except IndexError:
|
||||||
@ -42,7 +73,7 @@ def get_neighbors(matrix, x, y, _dict=False):
|
|||||||
# right
|
# right
|
||||||
try:
|
try:
|
||||||
if _dict:
|
if _dict:
|
||||||
neighbors.append({'x':x + 1,'y':y,'value':matrix[y][x + 1]})
|
neighbors.append({"x": x + 1, "y": y, "value": matrix[y][x + 1]})
|
||||||
else:
|
else:
|
||||||
neighbors.append([(x + 1, y), matrix[y][x + 1]])
|
neighbors.append([(x + 1, y), matrix[y][x + 1]])
|
||||||
except IndexError:
|
except IndexError:
|
||||||
@ -52,7 +83,7 @@ def get_neighbors(matrix, x, y, _dict=False):
|
|||||||
try:
|
try:
|
||||||
if y - 1 >= 0:
|
if y - 1 >= 0:
|
||||||
if _dict:
|
if _dict:
|
||||||
neighbors.append({'x':x,'y':y-1,'value':matrix[y-1][x]})
|
neighbors.append({"x": x, "y": y - 1, "value": matrix[y - 1][x]})
|
||||||
else:
|
else:
|
||||||
neighbors.append([(x, y - 1), matrix[y - 1][x]])
|
neighbors.append([(x, y - 1), matrix[y - 1][x]])
|
||||||
except IndexError:
|
except IndexError:
|
||||||
@ -61,7 +92,7 @@ def get_neighbors(matrix, x, y, _dict=False):
|
|||||||
# down
|
# down
|
||||||
try:
|
try:
|
||||||
if _dict:
|
if _dict:
|
||||||
neighbors.append({'x':x,'y':y+1,'value':matrix[y+1][x]})
|
neighbors.append({"x": x, "y": y + 1, "value": matrix[y + 1][x]})
|
||||||
else:
|
else:
|
||||||
neighbors.append([(x, y + 1), matrix[y + 1][x]])
|
neighbors.append([(x, y + 1), matrix[y + 1][x]])
|
||||||
except IndexError:
|
except IndexError:
|
||||||
@ -69,6 +100,19 @@ def get_neighbors(matrix, x, y, _dict=False):
|
|||||||
|
|
||||||
return neighbors
|
return neighbors
|
||||||
|
|
||||||
|
|
||||||
|
def valid_neighbors(matrix, x, y, criteria=None):
|
||||||
|
if criteria is None:
|
||||||
|
raise Exception("Please pass in a lambda for criteria")
|
||||||
|
cur = matrix[y][x]
|
||||||
|
neighbors = get_neighbors(matrix, x, y, _dict=True)
|
||||||
|
valid = []
|
||||||
|
for neighbor in neighbors:
|
||||||
|
if criteria(cur, neighbor['value']):
|
||||||
|
valid.append(neighbor)
|
||||||
|
return valid
|
||||||
|
|
||||||
|
|
||||||
def sum_matrix(mtx):
|
def sum_matrix(mtx):
|
||||||
total = 0
|
total = 0
|
||||||
for row in mtx:
|
for row in mtx:
|
||||||
@ -80,27 +124,20 @@ M_UL, M_U, M_UR = (-1, -1), (0, -1), (1, -1)
|
|||||||
M_L, M_R = (-1, 0), (1, 0)
|
M_L, M_R = (-1, 0), (1, 0)
|
||||||
M_DL, M_D, M_DR = (-1, 1), (0, 1), (1, 1)
|
M_DL, M_D, M_DR = (-1, 1), (0, 1), (1, 1)
|
||||||
|
|
||||||
|
|
||||||
def get_neighbor_coords(matrix, c, r, diagonals=True):
|
def get_neighbor_coords(matrix, c, r, diagonals=True):
|
||||||
height = len(matrix)
|
height = len(matrix)
|
||||||
width = len(matrix[0])
|
width = len(matrix[0])
|
||||||
if diagonals:
|
if diagonals:
|
||||||
coords = (
|
coords = (M_UL, M_U, M_UR, M_L, M_R, M_DL, M_D, M_DR)
|
||||||
M_UL, M_U, M_UR,
|
|
||||||
M_L, M_R,
|
|
||||||
M_DL, M_D, M_DR
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
coords = (
|
coords = (M_U, M_L, M_R, M_D)
|
||||||
M_U,
|
|
||||||
M_L,M_R,
|
|
||||||
M_D
|
|
||||||
)
|
|
||||||
neighbors = []
|
neighbors = []
|
||||||
|
|
||||||
for _c, _r in coords:
|
for _c, _r in coords:
|
||||||
try:
|
try:
|
||||||
value = matrix[r + _r][c + _c] # Try to get a value error
|
value = matrix[r + _r][c + _c] # Try to get a value error
|
||||||
if (r+_r>=0 and c+_c >= 0):
|
if r + _r >= 0 and c + _c >= 0:
|
||||||
neighbors.append(
|
neighbors.append(
|
||||||
[{"c": c + _c, "r": r + _r}, value]
|
[{"c": c + _c, "r": r + _r}, value]
|
||||||
) # woo, no error, this coord is valid
|
) # woo, no error, this coord is valid
|
||||||
@ -108,37 +145,39 @@ def get_neighbor_coords(matrix, c, r, diagonals=True):
|
|||||||
pass # okay we out of bounds boizzzz
|
pass # okay we out of bounds boizzzz
|
||||||
return neighbors
|
return neighbors
|
||||||
|
|
||||||
def line_of_sight_coords(matrix, row,col) -> Dict[str,List[Tuple[int,int]]]:
|
|
||||||
"""
|
|
||||||
Takes a matrix, a row, and a column
|
|
||||||
calculates the coordinates to the edge for all four cardinal directions
|
|
||||||
|
|
||||||
returns a dict with a list of tuple coordes TRAVELING AWAY from the
|
def line_of_sight_coords(matrix, row, col) -> Dict[str, List[Tuple[int, int]]]:
|
||||||
requested coordinate
|
"""
|
||||||
|
Takes a matrix, a row, and a column
|
||||||
|
calculates the coordinates to the edge for all four cardinal directions
|
||||||
|
|
||||||
|
returns a dict with a list of tuple coordes TRAVELING AWAY from the
|
||||||
|
requested coordinate
|
||||||
"""
|
"""
|
||||||
height, width = get_size(matrix)
|
height, width = get_size(matrix)
|
||||||
|
|
||||||
col_ids = list(range(0, height))
|
col_ids = list(range(0, height))
|
||||||
row_ids = list(range(0, width))
|
row_ids = list(range(0, width))
|
||||||
|
|
||||||
up_ids,down_ids = list(reversed(col_ids[:col])), col_ids[col+1:]
|
up_ids, down_ids = list(reversed(col_ids[:col])), col_ids[col + 1 :]
|
||||||
left_ids,right_ids = list(reversed(row_ids[:row])), row_ids[row+1:]
|
left_ids, right_ids = list(reversed(row_ids[:row])), row_ids[row + 1 :]
|
||||||
|
|
||||||
left = [(r,col) for r in left_ids]
|
left = [(r, col) for r in left_ids]
|
||||||
right = [(r,col) for r in right_ids]
|
right = [(r, col) for r in right_ids]
|
||||||
up = [(row,c) for c in up_ids]
|
up = [(row, c) for c in up_ids]
|
||||||
down = [(row,c) for c in down_ids]
|
down = [(row, c) for c in down_ids]
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'U':up,
|
"U": up,
|
||||||
'L':left,
|
"L": left,
|
||||||
'D':down,
|
"D": down,
|
||||||
'R':right,
|
"R": right,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def line_of_sight(mx, row, col):
|
def line_of_sight(mx, row, col):
|
||||||
"""
|
"""
|
||||||
renders a line of sight coord calculation, into the values
|
renders a line of sight coord calculation, into the values
|
||||||
"""
|
"""
|
||||||
coords = line_of_sight_coords(mx, row, col)
|
coords = line_of_sight_coords(mx, row, col)
|
||||||
los = defaultdict(list)
|
los = defaultdict(list)
|
||||||
@ -148,22 +187,23 @@ def line_of_sight(mx, row, col):
|
|||||||
return los
|
return los
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_size(matrix):
|
def get_size(matrix):
|
||||||
height = len(matrix)
|
height = len(matrix)
|
||||||
width = len(matrix[0])
|
width = len(matrix[0])
|
||||||
return height, width
|
return height, width
|
||||||
|
|
||||||
|
|
||||||
def row_col_from_int(matrix, x):
|
def row_col_from_int(matrix, x):
|
||||||
h,w = get_size(matrix)
|
h, w = get_size(matrix)
|
||||||
col = x % w
|
col = x % w
|
||||||
row = x // h
|
row = x // h
|
||||||
return row,col
|
return row, col
|
||||||
|
|
||||||
|
|
||||||
def matrix_of_size(width, height, default=0):
|
def matrix_of_size(width, height, default=0):
|
||||||
return [[default] * width for x in range(height)]
|
return [[default] * width for x in range(height)]
|
||||||
|
|
||||||
|
|
||||||
def set_matrix_dict(m):
|
def set_matrix_dict(m):
|
||||||
for x in range(len(m)):
|
for x in range(len(m)):
|
||||||
for y in range(len(m[x])):
|
for y in range(len(m[x])):
|
||||||
@ -173,7 +213,7 @@ def set_matrix_dict(m):
|
|||||||
|
|
||||||
def pmx(*matrices, pad=True, space=True):
|
def pmx(*matrices, pad=True, space=True):
|
||||||
"""
|
"""
|
||||||
print a matrix of integers, zero turns to `.` for clarity
|
print a matrix of integers, zero turns to `.` for clarity
|
||||||
"""
|
"""
|
||||||
if len(matrices) > 1:
|
if len(matrices) > 1:
|
||||||
matrices = list(zip(*matrices))
|
matrices = list(zip(*matrices))
|
||||||
@ -195,9 +235,10 @@ def pmx(*matrices, pad=True, space=True):
|
|||||||
f = lambda x: f"{int(x)or '.'} "
|
f = lambda x: f"{int(x)or '.'} "
|
||||||
print("".join([f(x) for x in c]))
|
print("".join([f(x) for x in c]))
|
||||||
|
|
||||||
|
|
||||||
def ppmx(*matrices, pad=True, space=True):
|
def ppmx(*matrices, pad=True, space=True):
|
||||||
"""
|
"""
|
||||||
print a matrix of anything, Falsy values turns to `.` for clarity
|
print a matrix of anything, Falsy values turns to `.` for clarity
|
||||||
"""
|
"""
|
||||||
if len(matrices) > 1:
|
if len(matrices) > 1:
|
||||||
matrices = list(zip(*matrices))
|
matrices = list(zip(*matrices))
|
||||||
@ -218,3 +259,23 @@ def ppmx(*matrices, pad=True, space=True):
|
|||||||
if space:
|
if space:
|
||||||
f = lambda x: f"{x or '.'} "
|
f = lambda x: f"{x or '.'} "
|
||||||
print("".join([f(x) for x in c]))
|
print("".join([f(x) for x in c]))
|
||||||
|
|
||||||
|
|
||||||
|
def highlight(matrix, red=[], green=[], blue=[]):
|
||||||
|
"""
|
||||||
|
print a matrix of anything, Falsy values turns to `.` for clarity
|
||||||
|
"""
|
||||||
|
mx = deepcopy(matrix)
|
||||||
|
for (y, x) in red:
|
||||||
|
try:
|
||||||
|
new = f"{colors.RED}{mx[y][x]}{colors.ENDC}"
|
||||||
|
mx[y][x] = new
|
||||||
|
except IndexError:
|
||||||
|
breakpoint()
|
||||||
|
for (y, x) in green:
|
||||||
|
new = f"{colors.GREEN}{mx[y][x]}{colors.ENDC}"
|
||||||
|
mx[y][x] = new
|
||||||
|
for (y, x) in blue:
|
||||||
|
new = f"{colors.BLUE}{mx[y][x]}{colors.ENDC}"
|
||||||
|
mx[y][x] = new
|
||||||
|
ppmx(mx, pad=False, space=False)
|
||||||
|
@ -4,13 +4,16 @@ from pathlib import Path
|
|||||||
|
|
||||||
spl = lambda y: [int(w) for w in y]
|
spl = lambda y: [int(w) for w in y]
|
||||||
|
|
||||||
|
|
||||||
def load_rows(day):
|
def load_rows(day):
|
||||||
return [row for row in load(day)]
|
return [row for row in load(day)]
|
||||||
|
|
||||||
|
|
||||||
def load(day):
|
def load(day):
|
||||||
path = Path(get_fname(day))
|
path = Path(get_fname(day))
|
||||||
return path.read_text().rstrip().split("\n")
|
return path.read_text().rstrip().split("\n")
|
||||||
|
|
||||||
|
|
||||||
def get_fname(day: int) -> str:
|
def get_fname(day: int) -> str:
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
@ -27,6 +30,7 @@ def load_char_matrix(f):
|
|||||||
my_file.append(line.rstrip())
|
my_file.append(line.rstrip())
|
||||||
return [list(x) for x in my_file]
|
return [list(x) for x in my_file]
|
||||||
|
|
||||||
|
|
||||||
def load_file_char_matrix(name):
|
def load_file_char_matrix(name):
|
||||||
with open(name, "r") as f:
|
with open(name, "r") as f:
|
||||||
return load_char_matrix(f)
|
return load_char_matrix(f)
|
||||||
@ -38,21 +42,27 @@ def load_int_matrix(f):
|
|||||||
my_file.append(line.rstrip())
|
my_file.append(line.rstrip())
|
||||||
return [list(map(int, x)) for x in my_file]
|
return [list(map(int, x)) for x in my_file]
|
||||||
|
|
||||||
|
|
||||||
def load_file_int_matrix(name):
|
def load_file_int_matrix(name):
|
||||||
with open(name, "r") as f:
|
with open(name, "r") as f:
|
||||||
return load_int_matrix(f)
|
return load_int_matrix(f)
|
||||||
|
|
||||||
|
|
||||||
def load_word_matrix(f):
|
def load_word_matrix(f):
|
||||||
my_file = []
|
my_file = []
|
||||||
for line in f:
|
for line in f:
|
||||||
my_file.append(line.rstrip())
|
my_file.append(line.rstrip())
|
||||||
return [x.split(" ") for x in my_file]
|
return [x.split(" ") for x in my_file]
|
||||||
|
|
||||||
|
|
||||||
def load_file_word_matrix(name):
|
def load_file_word_matrix(name):
|
||||||
with open(name, "r") as f:
|
with open(name, "r") as f:
|
||||||
return load_word_matrix(f)
|
return load_word_matrix(f)
|
||||||
|
|
||||||
|
|
||||||
#############
|
#############
|
||||||
|
|
||||||
|
|
||||||
def rotate(WHAT, times=1):
|
def rotate(WHAT, times=1):
|
||||||
what = WHAT
|
what = WHAT
|
||||||
for x in range(times):
|
for x in range(times):
|
||||||
@ -60,11 +70,10 @@ def rotate(WHAT, times=1):
|
|||||||
return what
|
return what
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def elapsed_timer():
|
def elapsed_timer():
|
||||||
start = default_timer()
|
start = default_timer()
|
||||||
elapser = lambda: default_timer() - start
|
elapser = lambda: default_timer() - start
|
||||||
yield lambda: elapser()
|
yield lambda: elapser()
|
||||||
end = default_timer()
|
end = default_timer()
|
||||||
elapser = lambda: end-start
|
elapser = lambda: end - start
|
||||||
|
Loading…
Reference in New Issue
Block a user