Day 5

Part 1

  • Read in input file
with open("day5/input.txt") as f:
    input = f.read().splitlines()

First 100 lines of input looks like this:

['    [M]             [Z]     [V]    ',
 '    [Z]     [P]     [L]     [Z] [J]',
 '[S] [D]     [W]     [W]     [H] [Q]',
 '[P] [V] [N] [D]     [P]     [C] [V]',
 '[H] [B] [J] [V] [B] [M]     [N] [P]',
 '[V] [F] [L] [Z] [C] [S] [P] [S] [G]',
 '[F] [J] [M] [G] [R] [R] [H] [R] [L]',
 '[G] [G] [G] [N] [V] [V] [T] [Q] [F]',
 ' 1   2   3   4   5   6   7   8   9 ',
 '',
 'move 6 from 9 to 3',
 'move 2 from 2 to 1',
 'move 1 from 8 to 2',
 'move 3 from 7 to 2',
 'move 7 from 6 to 9',
 'move 1 from 9 to 5',
 'move 3 from 5 to 7',
 'move 6 from 8 to 6',
 'move 1 from 7 to 8',
 'move 6 from 6 to 5',
 'move 4 from 5 to 8',
 'move 9 from 2 to 9',
 'move 1 from 2 to 3',
 'move 3 from 1 to 3',
 'move 3 from 5 to 1',
 'move 10 from 3 to 5',
 'move 4 from 4 to 6',
 'move 2 from 7 to 6',
 'move 2 from 6 to 9',
 'move 6 from 8 to 6',
 'move 1 from 4 to 3',
 'move 1 from 4 to 5',
 'move 1 from 4 to 1',
 'move 2 from 3 to 1',
 'move 1 from 3 to 7',
 'move 8 from 1 to 9',
 'move 1 from 1 to 2',
 'move 1 from 2 to 7',
 'move 6 from 6 to 3',
 'move 7 from 3 to 5',
 'move 14 from 5 to 6',
 'move 2 from 1 to 3',
 'move 5 from 5 to 8',
 'move 5 from 8 to 1',
 'move 2 from 7 to 1',
 'move 5 from 6 to 9',
 'move 8 from 9 to 3',
 'move 13 from 9 to 3',
 'move 7 from 1 to 4',
 'move 6 from 4 to 1',
 'move 22 from 3 to 1',
 'move 1 from 9 to 3',
 'move 2 from 6 to 1',
 'move 1 from 3 to 4',
 'move 7 from 9 to 8',
 'move 2 from 1 to 7',
 'move 2 from 3 to 2',
 'move 2 from 6 to 9',
 'move 2 from 7 to 8',
 'move 1 from 3 to 6',
 'move 9 from 8 to 6',
 'move 1 from 2 to 4',
 'move 8 from 1 to 2',
 'move 1 from 9 to 4',
 'move 3 from 4 to 1',
 'move 1 from 4 to 6',
 'move 10 from 6 to 5',
 'move 5 from 2 to 9',
 'move 6 from 9 to 3',
 'move 2 from 5 to 3',
 'move 2 from 9 to 7',
 'move 7 from 5 to 8',
 'move 5 from 6 to 2',
 'move 3 from 3 to 7',
 'move 3 from 3 to 5',
 'move 4 from 5 to 8',
 'move 1 from 3 to 5',
 'move 6 from 6 to 8',
 'move 1 from 5 to 7',
 'move 9 from 8 to 9',
 'move 1 from 3 to 1',
 'move 7 from 2 to 7',
 'move 9 from 7 to 6',
 'move 2 from 2 to 3',
 'move 7 from 9 to 3',
 'move 9 from 6 to 8',
 'move 7 from 3 to 4',
 'move 2 from 7 to 6',
 'move 4 from 4 to 5',
 'move 3 from 5 to 6',
 'move 2 from 7 to 4',
 'move 5 from 4 to 7',
 'move 13 from 8 to 4',
 'move 2 from 9 to 4',
 'move 2 from 8 to 7',
 'move 6 from 7 to 5',
 'move 6 from 4 to 2',
 'move 1 from 7 to 5',
 'move 3 from 2 to 7',
 'move 1 from 7 to 8']
  • Create a generator that returns the totals each time it iterates
with open("day5/sample.txt") as f:
    samples = f.read().splitlines() 
pprint(samples)
['    [D]    ',
 '[N] [C]    ',
 '[Z] [M] [P]',
 ' 1   2   3 ',
 '',
 'move 1 from 2 to 1',
 'move 3 from 1 to 3',
 'move 2 from 2 to 1',
 'move 1 from 1 to 2']
  • create function that can compute the number of stacks

get_stack_count

 get_stack_count (input:list[str])

Return the count of stacks given the input

Type Details
input list list of strings
Returns int
print(get_stack_count(samples))
3
  • create a function to initialize n stacks

init_stacks

 init_stacks (n:int)

Create a list of n stacks

Type Details
n int n of stacks
Returns list
init_stacks(3)
[[], [], []]
  • create a function to split the samples into the stacks and the moves

split_stack_moves

 split_stack_moves (samples:list[str])

Split the input and separate the stack section from the moves

Type Details
samples list list of strings
Returns any type: ignore
stacks,moves = split_stack_moves(samples)
pprint(stacks)
pprint(moves)
['    [D]    ', '[N] [C]    ', '[Z] [M] [P]']
['move 1 from 2 to 1',
 'move 3 from 1 to 3',
 'move 2 from 2 to 1',
 'move 1 from 1 to 2']
  • create a function that parses the stacks printout into a real stack data structure

build_stacks

 build_stacks (stack_inputs:list[str], n_stacks:int)

Build the real stack structure from the printed version

Type Details
stack_inputs list list of strings representing a list of stacks
n_stacks int number of stacks
Returns list
n_stacks = get_stack_count(samples)
stacks = build_stacks(stacks, n_stacks)
print(stacks, n_stacks)
[['Z', 'N'], ['M', 'C', 'D'], ['P']] 3
  • build a function that can parse a move statement

parse_move

 parse_move (move:str)

Parse the move statement and return the ntokens,from,to values

Type Details
move str string with format move n from a to b
Returns (<class ‘int’>, <class ‘int’>, <class ‘int’>) type: ignore
print(parse_move("move 1 from 2 to 1"))
(1, 2, 1)
  • build a function that can execute a move

execute_move

 execute_move (stacks:list[list[str]], n_tokens:int, from_stack:int,
               to_stack:int)

Executes a move of n_tokens from a stack to another stack

Type Details
stacks list list of stacks of tokens
n_tokens int count of tokens to move
from_stack int from the stack (start from position 1)
to_stack int to the stack (start from position 1)
print("before move:")
pprint(stacks)
print("performing move 1 from 2 to 1")
execute_move(stacks,1,2,1)
print("after move:")
pprint(stacks)
before move:
[['Z', 'N'], ['M', 'C', 'D'], ['P']]
performing move 1 from 2 to 1
after move:
[['Z', 'N', 'D'], ['M', 'C'], ['P']]
  • create a function to process the moves

process_moves

 process_moves (input:list[str])

Initializes the stacks and processes the moves

Type Details
input list inputs with stacks and moves
final_stacks = process_moves(samples)
pprint(final_stacks)
[['C'], ['M'], ['P', 'D', 'N', 'Z']]
  • create a function to grab the top element for each stack and concatenate them into a string

get_top_elements

 get_top_elements (stacks:list[list[str]])

Gets the top tokens from each stack and concatenates to form a string

Type Details
stacks list a list of stacks of token
print(get_top_elements(final_stacks))
CMZ
  • Finally the answer for the top elements given the input
input_stacks = process_moves(input)
answer1 = get_top_elements(input_stacks)
print(f'the correct answer for part 1 is {answer1}')
the correct answer for part 1 is FCVRLMVQP

Part 2

input_stacks2 = process_moves2(input)
answer2 = get_top_elements(input_stacks2)
print(f'the correct answer for part 2 is {answer2}')
the correct answer for part 2 is RWLWGJGFD