Skip to content

Instantly share code, notes, and snippets.

@MrAntex
Created December 7, 2022 00:02
Show Gist options
  • Save MrAntex/d65105e100337ab126135c25c73ea563 to your computer and use it in GitHub Desktop.
Save MrAntex/d65105e100337ab126135c25c73ea563 to your computer and use it in GitHub Desktop.
'''
This is an animated solution to the part 1 of Day 5 of the 2022 Advent Of Code challenge.
The problem can be found here: https://adventofcode.com/2022/day/5
The input file for this program is the file named "input.txt" in the same folder as this file.
First time trying to draw something in the terminal, so it's a bit messy, but it works.
I'm trying to get better at Python, so please feel free to suggest anything that I could have done better (or a question).
'''
import time
import os
import copy
# Color codes
OKGREEN = '\033[92m'
FAIL = '\033[91m'
OKCYAN = '\033[96m'
WARNING = '\033[93m'
BOLD = '\033[1m'
ENDC = '\033[0m'
mx = 15
delay = 0.09 # Delay in seconds between each frame, change this to make the animation faster or slower (/!\ too fast and your terminal may blink)
currentCol = 0
crates = []
# Update max height of drawing (if needed, to avoid resizing everytime)
def updateMax():
global mx
if mx - max([len(c) for c in crates]) < 6:
mx = max([len(c) for c in crates])+8
elif mx - max([len(c) for c in crates]) > 10:
mx = max([len(c) for c in crates])+6
# Get height of heightest column in a range
def getLocalMax(b1, b2):
if b1 > b2:
b1, b2 = b2, b1
return max([len(cr) for cr in crates[b1:b2+1]])
# Get height needed to go above the highest column in a range for a given column
def getNeededHeight(current, dest):
return ((getLocalMax(current, dest))+2)-len(crates[current])
# Move crane claw vertically from ystart to ystop
def goVert(ystart, ystop, col, c):
# Managing the direction of the movement
for y in range(ystart, ystop+(-1 if ystart > ystop else 1), -1 if ystart > ystop else 1):
showCrates(col, y, c)
time.sleep(delay)
# Move crane claw horizontally from xstart to xstop
def goSlide(xstart, xstop, c):
# Managing the direction of the movement
for x in range(xstart, xstop+(-1 if xstart > xstop else 1), -1 if xstart > xstop else 1):
# We need to stay at the height of the highest column in the range
showCrates(x, (getLocalMax(xstart, xstop)+2)-len(crates[x])+1, c)
time.sleep(delay)
# Execute an instruction, move nb crates from column fr to column to
def instruction(fr, nb, to):
global currentCol
global mx
# If the crane is not already in the right column
if fr != currentCol:
# Go up
goVert(2, getNeededHeight(currentCol, fr)+1, currentCol, ' ')
# Slide to the right column
goSlide(currentCol, fr, ' ')
# Go Down
goVert(getNeededHeight(fr, currentCol), 2, fr, ' ')
# Main moving loop
for i in range(nb):
# Removing crate from column
c = crates[fr].pop(0)
# Go up with the picked crate
goVert(2, getNeededHeight(fr, to)+1, fr, c)
# Slide to the destination column
goSlide(fr, to, c)
# Go down with the crate
goVert(getNeededHeight(to, fr), 2, to, c)
# Inserting crate in destination column
crates[to].insert(0, c)
# Update max height because the columns have changed
updateMax()
currentCol = to
# If there are still crates to move
if nb > 1 and i < nb-1:
# Go up
goVert(2, getNeededHeight(to, fr)+1, to, ' ')
# Slide to the fr column
goSlide(to, fr, ' ')
# Go down with the claw
goVert(getNeededHeight(fr, to), 2, fr, ' ')
# Main drawing function to draw the crates and the crane giving it a column, a height and a held crate letter
def showCrates(x, y, letter):
# Clearing the screen (works on linux and windows)
os.system('cls' if os.name == 'nt' else 'clear')
tmpCrates = copy.deepcopy(crates)
# Height of the highest column
localMx = max([len(crate) for crate in crates])
# Inserting spaces to make all columns the same height
for c in tmpCrates:
while len(c) < mx:
c.insert(0, ' ')
# Drawing
# Rows
for row in range(mx):
print("", end='')
# Columns
for col in range(l):
cratePile = tmpCrates[col]
# Drawing every element
if row == mx-localMx-4 and col > x: # Top arm of the crane
print(f"{WARNING}===={ENDC}", end='')
elif row == mx-localMx-4 and col == x: # Tip of the arm
print(f"{WARNING} /={ENDC}", end='')
elif row >= mx-localMx-3 and row < mx-len(crates[x])-y and col == x: # Cable
print(f"{WARNING} | {ENDC}", end='')
elif row == mx-len(crates[x])-y and col == x: # Cable-claw thing
print(f"{WARNING} A {ENDC}", end='')
elif row == mx-len(crates[x])-y+1 and col == x: # Claw with crate
print(f"{WARNING}[{OKGREEN}{letter}{WARNING}]{ENDC} {ENDC}", end='')
elif cratePile[row] != ' ': # Non-empty crates
if row == mx-len(crates[col]): # Top crate
print(f"{OKGREEN}[{cratePile[row]}]{ENDC} ", end='')
else: # Other crates
print("["+cratePile[row]+"] ", end='')
else: # Empty crates
print(" ", end='')
# Drawing the crane
if row >= mx-localMx-3:
print(f"{WARNING} || {ENDC}", end='')
if row == mx-localMx-4:
print(f"{WARNING}============\==-_{ENDC}", end='')
print()
print(" ", end='')
# Drawing the column numbers
for i in range(l):
print(f" {BOLD}{str(i+1)}{ENDC} ", end='')
# Drawing the bottom of the crane
print(f" {WARNING}{BOLD}_/=[||]=\_{ENDC} ", end='')
print()
print(" ", end='')
# Drawing top crates of each column
for i in range(l):
if len(crates[i]) > 0:
print(f"{OKCYAN}{BOLD}[{crates[i][0]}]{ENDC} ", end='')
else:
print(f"{FAIL}[/]{ENDC} ", end='')
print()
# Opening the input file
with open("input.txt") as input_file:
lines = input_file.readlines()
# Getting the number of columns
emptyLine = lines.index("\n")
l = max([len(line) for line in lines[:emptyLine+1]])//4
# Filing the crates columns
for col in range(1, l*4, 4):
crates.append([])
lin = 0
# While we are not at the base of the column (aka a number)
while not lines[lin][col].isnumeric():
char = lines[lin][col]
if char != ' ':
crates[col//4].append(char)
lin += 1
# Initializing the max height
updateMax()
# Getting the instructions
for line in lines[emptyLine+1:]:
words = line.split(' ')
instruction(int(words[3])-1, int(words[1]), int(words[5])-1)
# Printing the result
res = ""
for crate in crates:
res += crate[0]
print()
print(f"{BOLD} > {res} <{ENDC}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment