NickyMeulemanNime
Metadata
  • Date

  • By

    • Nicky Meuleman
  • Tagged

  • Part of series

    • 1. Advent of Code 2015 Day 1
    • 2. Advent of Code 2015 Day 2
    • 3. Advent of Code 2015 Day 3
    • 4. Advent of Code 2015 Day 4
  • Older post

    Advent of Code 2022 Day 25

  • Newer post

    Advent of Code 2015 Day 3

Table of contents
  1. Day 1: Not Quite Lisp
  2. Part 1
    1. Main code for part 1
  3. Part 2
    1. Old reliable
    2. A short-circuiting fold.
    3. My favourite
    4. Main code for part 2
  4. Final code

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:

input.txt
(()(()(

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

day_01.rs
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

day_01.rs
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

day_01.rs
1pub fn part_1(input: &str) -> usize {
2 input.chars().fold(0, |floor, c| match c {
3 '(' => floor + 1,
4 ')' => floor - 1,
5 _ => panic!("invalid input"),
6 })
7}
8
9pub fn part_2(input: &str) -> usize {
10 input
11 .chars()
12 // create iterator where each item is the current floor Santa is on, starting at floor 0
13 .scan(0, |floor, c| {
14 match c {
15 '(' => *floor += 1,
16 ')' => *floor -= 1,
17 _ => panic!("invalid input"),
18 }
19 Some(*floor)
20 })
21 // find the first index where santa enters the basement
22 .position(|floor| floor < 0)
23 .unwrap()
24 + 1
25}

Series navigation for: Advent of Code 2015

2. Advent of Code 2015 Day 2

Designed and developed by Nicky Meuleman

Built with Gatsby. Hosted on Netlify.