Advent of Code

Day 1

code
Published

November 27, 2022

Advent of code is a fantastic opportunity for programmers to hone their skills. Here’s a solution in Julia for Day 1, 2022.

Input Data

Start by loading data for the sample and our full input.

# https://adventofcode.com/2022/day/1
example = readlines("day_1_ex.txt")
14-element Vector{String}:
 "1000"
 "2000"
 "3000"
 ""
 "4000"
 ""
 "5000"
 "6000"
 ""
 "7000"
 "8000"
 "9000"
 ""
 "10000"

Today’s challenge involves counting the inventory of each elf. A logical starting point is to consider the data structure. A simple vector of vectors should well represent all items of all elves.

struct Inventory
    items::Vector{Vector{Int64}}
end

Inventory has field items which will hold all the items of a particular elf. In order to create the desired vector of vectors, we want the input to be split by new lines. It is easy to write a function which takes in some vector and splits it by some function.

function split_elf_input::Function, input::Vector)
    first, last = firstindex(input), lastindex(input)
    splits = [first-1; findall(λ, input); last]
    split1, split2 = splits[1:end-1], splits[2:end]
    return [input[start+1:finish] for (start, finish) in zip(split1, split2)]
end

We can now write the function that will parse our challenge input into the desired data structure.

function Inventory(input::Vector{Vector{String}})
    filter!.(!isempty, input)
    inventory_input = map(i -> parse.(Int, i), input)
    Inventory(inventory_input)
end

Solve

So, we have everything we need to describe the full elfish inventory. All that’s left is to describe the method of finding the top elf. We can do this in a general way so that we can elect how many of the top elves are returned.

top_elf(inventory::Inventory, nelves = 1) = mapreduce(+, 1:nelves) do elf
    calories, index = findmax(sum.(inventory.items))
    popat!(inventory.items, index)
    return calories
end

Parts one and two differ in the number of top elves required. We can write separate functions to accomodate this.

part_1(input) = top_elf(Inventory(split_elf_input(isempty, input)))
part_2(input) = top_elf(Inventory(split_elf_input(isempty, input)), 3)

Time to solve!

part_1(example)
24000
part_2(example)
45000