Metadata
-
Date
-
Tagged
-
Part of series
-
Older post
-
Newer post
Advent of Code 2015 Day 1
Day 1: Not Quite Lisp
https://adventofcode.com/2015/day/1
Santa’s weather machine’s snow function is powered by stars. During Advent of Code, each puzzle solution rewards you with a star. Hooray, a convenient way to help.
Santa’s in an apartment building and has directions that tell him to go up or down 1 floor.
(
go up one floor)
go down one floor
An example input looks like this:
(()(()(
The building is very tall (and deep!), Santa will never reach the top (or bottom) floor.
Santa starts at the ground floor (number 0
).
Part 1
The question asks what floor Santa ends at after following the instructions.
This asks to turn a sequence of something into a singular answer.
Ideal for your favourite language’s method that does that.
Rust has fold
, JavaScript has reduce
.
Main code for part 1
pub fn part_1(input: &str) -> usize { input.chars().fold(0, |floor, c| match c { '(' => floor + 1, ')' => floor - 1, _ => panic!("invalid input"), })}
Part 2
The question asks for the position of the first character that causes Santa to enter the basement.
The basement starts at -1
.
This was fun, I made 3 variants that do the same thing.
Old reliable
A workhorse.
A for
loop.
let mut floor = 0;for (idx, c) in input.chars().enumerate() { match c { '(' => floor += 1, ')' => floor -= 1, _ => panic!("invalid input"), } if floor < 0 { return idx + 1; }}panic!("Santa never enters the basement");
A short-circuiting fold.
In other words, one that stops as soon as a condition is met.
input .chars() .enumerate() .try_fold(0, |floor, (idx, c)| match c { '(' => Ok(floor + 1), ')' if floor > 0 => Ok(floor - 1), ')' => Err(idx + 1), _ => panic!("invalid input"), }) .unwrap_err()
My favourite
And finally, my favourite, a solution that creates a sequence of the floor Santa is currently on.
input .chars() // create iterator where each item is the current floor Santa is on, starting at floor 0 .scan(0, |floor, c| { match c { '(' => *floor += 1, ')' => *floor -= 1, _ => panic!("invalid input"), } Some(*floor) }) // find the first index where santa enters the basement .position(|floor| floor < 0) .unwrap() + 1
Main code for part 2
pub fn part_2(input: &str) -> usize { input .chars() // create iterator where each item is the current floor Santa is on, starting at floor 0 .scan(0, |floor, c| { match c { '(' => *floor += 1, ')' => *floor -= 1, _ => panic!("invalid input"), } Some(*floor) }) // find the first index where santa enters the basement .position(|floor| floor < 0) .unwrap() + 1}
Final code
pub fn part_1(input: &str) -> usize { input.chars().fold(0, |floor, c| match c { '(' => floor + 1, ')' => floor - 1, _ => panic!("invalid input"), })}
pub fn part_2(input: &str) -> usize { input .chars() // create iterator where each item is the current floor Santa is on, starting at floor 0 .scan(0, |floor, c| { match c { '(' => *floor += 1, ')' => *floor -= 1, _ => panic!("invalid input"), } Some(*floor) }) // find the first index where santa enters the basement .position(|floor| floor < 0) .unwrap() + 1}