advent_of_code_2022

My (attempted) solutions to the 2022 Advent of Code
git clone https://git.eamoncaddigan.net/advent_of_code_2022.git
Log | Files | Refs | README

day_5.jl (3011B)


      1 #!/usr/bin/env julia
      2 # https://adventofcode.com/2022/day/5
      3 using AdventOfCode
      4 
      5 example = readlines(IOBuffer("""
      6         [D]    
      7     [N] [C]    
      8     [Z] [M] [P]
      9      1   2   3 
     10 
     11     move 1 from 2 to 1
     12     move 3 from 1 to 3
     13     move 2 from 2 to 1
     14     move 1 from 1 to 2"""))
     15 input = readlines("data/day_5.txt")
     16 
     17 # This just splits the input (array of strings) into the starting stacks of
     18 # crates and the rearrangement procedure
     19 function split_input(input)
     20     splitpoint = findfirst(input .== "")
     21     (input[1:splitpoint-1], input[splitpoint+1:end])
     22 end
     23 
     24 # Read the map of the starting crate stacks and return an array of arrays
     25 function parse_stack(cratestack)
     26     stacks = []
     27     for line = cratestack[1:end-1]
     28         crates = split(line, "")[2:4:end]
     29         for (i, crate) = enumerate(crates)
     30             if length(stacks) < i
     31                 push!(stacks, [])
     32             end
     33             if crate != " "
     34                 push!(stacks[i], crate)
     35             end
     36         end
     37     end
     38     reverse.(stacks)
     39 end
     40 
     41 # Apply an instruction to the crate stacks. Does nothing with invalid
     42 # instructions (doesn't throw warnings or errors either).
     43 function apply_instruction!(stacks, instruction)
     44     m = match(r"move (\d+) from (\d+) to (\d+)", instruction)
     45     if !isnothing(m)
     46         (numtomove, from, to) = parse.(Int, m.captures)
     47         while numtomove > 0
     48             push!(stacks[to], pop!(stacks[from]))
     49             numtomove -= 1
     50         end
     51     end
     52     stacks
     53 end
     54 
     55 # Apply all the instructions to the crate stacks
     56 function apply_all_instructions!(stacks, instructions)
     57     for instruction = instructions
     58         apply_instruction!(stacks, instruction)
     59     end
     60     stacks
     61 end
     62 
     63 function part_1(input)
     64     (cratestack, instructions) = split_input(input)
     65     stacks = apply_all_instructions!(parse_stack(cratestack), instructions)
     66     reduce(*, last.(stacks))
     67 end
     68 @assert part_1(example) == "CMZ"
     69 @info part_1(input)
     70 
     71 ## Part 2
     72 
     73 # Need a new function for applying instructions. Wish I was smarter about Julia
     74 # polymorphism, but whatever.
     75 
     76 # Apply an instruction to the crate stacks. Does nothing with invalid
     77 # instructions (doesn't throw warnings or errors either).
     78 function apply_instruction_2!(stacks, instruction)
     79     m = match(r"move (\d+) from (\d+) to (\d+)", instruction)
     80     if !isnothing(m)
     81         (numtomove, from, to) = parse.(Int, m.captures)
     82         push!(stacks[to], stacks[from][end-numtomove+1:end]...)
     83         deleteat!(stacks[from],
     84                   lastindex(stacks[from])-numtomove+1:lastindex(stacks[from]))
     85     end
     86     stacks
     87 end
     88 
     89 # Apply all the instructions to the crate stacks
     90 function apply_all_instructions_2!(stacks, instructions)
     91     for instruction = instructions
     92         apply_instruction_2!(stacks, instruction)
     93     end
     94     stacks
     95 end
     96 
     97 function part_2(input)
     98     (cratestack, instructions) = split_input(input)
     99     stacks = apply_all_instructions_2!(parse_stack(cratestack), instructions)
    100     reduce(*, last.(stacks))
    101 end
    102 @assert part_2(example) == "MCD"
    103 @info part_2(input)