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)