DEV Community

Discussion on: AoC Day 13: Mine Cart Madness

Collapse
 
mustafahaddara profile image
Mustafa Haddara

This is one of those problems that you just gotta grind through, I guess.

Surprisingly, this is the first one where, the first time it compiled, I got the right answer. Of course, getting it to compile took a few tries-- I'm using AoC to learn a new language --but once the syntax issues were ironed out, I just had the solution ready to go.

Only really interesting things are that on the beginning of each tick, I can do

sort!(board.carts, by=c -> (c.y, c.x))

which sorts the array of carts first by y, then by x. Then I can just iterate straight through that array and have the carts in correct order.

I implemented collision checking like so

function check_collisions(carts)
    positions = Set()
    for cart in carts
        pos = (cart.x, cart.y)
        if pos in positions
            return pos
        else
            push!(positions, pos)
        end
    end
    return nothing
end

and sadly have to call it once per cart, per tick. If I only called this at the beginning or end of each tick, then two carts like so:

--><--

would actually end up switching spots, and I'd never notice they overlapped.

For part 2, I replaced my check_collisions method with

function remove_collisions(carts)
    positions = Dict{Tuple{Int, Int}, Array{Cart}}()
    for cart in carts
        pos = (cart.x, cart.y)
        if !haskey(positions, pos)
            positions[pos] = []
        end
        push!(positions[pos], cart)
    end
    carts::Array{Cart} = []
    for c in values(positions)
        if length(c) == 1
            push!(carts, c[1])
        end
    end
    return carts
end

Essentially, instead of merely detecting if there is a collision, this method filters out any carts that have a position that is equal. (Now that I type that out, I realize I could have just called filter()...oh well.)

I'm still calling this once per cart per tick, which is so poorly inefficient that it makes me wince, but there are so few carts in the input that it rarely matters.

Full code here: github.com/MustafaHaddara/advent-o... and github.com/MustafaHaddara/advent-o...

Oh, and last lesson learned: I wrote a print_board() function that didn't actually print the carts! This is really really really stupid...it made that function almost entirely useless.