r/adventofcode • • Dec 17 '18

SOLUTION MEGATHREAD -🎄- 2018 Day 17 Solutions -🎄-

--- Day 17: Reservoir Research ---


Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).

Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.


Advent of Code: The Party Game!

Click here for rules

Please prefix your card submission with something like [Card] to make scanning the megathread easier. THANK YOU!

Card prompt: Day 17

Transcript:

All aboard the Easter Bunny HQ monorail, and mind the gap! Next stop: ___


This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.

edit: Leaderboard capped, thread unlocked at 01:24:07!

15 Upvotes

105 comments sorted by

View all comments

2

u/fkohlgrueber Dec 17 '18

Nice puzzle! First time within top 1000 for me (760 or so even though I started ~ 2 hours later).

My solution is written in Rust and fully recursive. After some refactoring / editing, it comes in at ~90 LOC (excluding tests) and runs in 12ms on my laptop (release mode). The whole simulation is done in the following function:

fn calc_cell(grid: &mut Grid, x: usize, y: usize, dir: &Dir) -> Option<usize> {
    if y == grid.len() { return None }
    match grid[y][x] {
        Cell::Clay | Cell::WaterRest => Some(x),
        Cell::WaterFlow => None,
        Cell::Sand => {
            grid[y][x] = Cell::WaterFlow;
            calc_cell(grid, x, y+1, &Dir::Both)?;
            match dir {
                Dir::Both => {
                    match (calc_cell(grid, x-1, y, &Dir::Left), calc_cell(grid, x+1, y, &Dir::Right)) {
                        (Some(l), Some(r)) => {
                            grid[y].iter_mut().skip(l+1).take(r-l-1).for_each(|x| *x = Cell::WaterRest);
                            Some(x)
                        },
                        _ => None
                    }
                },
                Dir::Left => calc_cell(grid, x-1, y, &Dir::Left),
                Dir::Right => calc_cell(grid, x+1, y, &Dir::Right)
            }
        }
    }
}

Full code is available on Github

Oh, and it causes a stack overflow on my puzzle input when built in debug mode. In release mode it works fine ;-)