151 lines
3.4 KiB
Python
151 lines
3.4 KiB
Python
|
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()
|