1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
//! # [Day 1: Not Quite Lisp](https://adventofcode.com/2015/day/1)
//!
//! Santa was hoping for a white Christmas, but his weather machine's "snow"
//! function is powered by stars, and he's fresh out! To save Christmas,
//! he needs you to collect fifty stars by December 25th.
//!
//! Collect stars by helping Santa solve puzzles. Two puzzles will be made
//! available on each day in the Advent calendar; the second puzzle is unlocked
//! when you complete the first. Each puzzle grants one star. Good luck!
//!
//! Here's an easy puzzle to warm you up.
//!
//! Santa is trying to deliver presents in a large apartment building, but he
//! can't find the right floor - the directions he got are a little confusing.
//! He starts on the ground floor (floor `0`) and then follows the instructions
//! one character at a time.
//!
//! An opening parenthesis, `(`, means he should go up one floor, and a closing
//! parenthesis, `)`, means he should go down one floor.
//!
//! The apartment building is very tall, and the basement is very deep; he will
//! never find the top or bottom floors.
//!
//! For example:
//!
//! - `(())` and `()()` both result in floor `0`.
//! - `(((` and `(()(()(` both result in floor `3`.
//! - `))(((((` also results in floor `3`.
//! - `())` and `))(` both result in floor `-1` (the first basement level).
//! - `)))` and `)())())` both result in floor `-3`.
//!
//! **To what floor do the instructions take Santa?**
//!
//! # Part Two
//!
//! Now, given the same instructions, find the position of the first character that
//! causes him to enter the basement (floor `-1`). The first character in the
//! instructions has position `1`, the second character has
//! position `2`, and so on.
//!
//! For example:
//!
//! - `)` causes him to enter the basement at character position `1`.
//! - `()())` causes him to enter the basement at character position `5`.
//!
//! **What is the position of the character that causes Santa to first
//! enter the basement?**
/// Part 1: To what floor do the instructions take Santa? procedural style
#[aoc(day1, part1)]
fn part1(input: &str) -> i32 {
let mut sum: i32 = 0;
for char in input.chars() {
match char {
'(' => sum += 1,
')' => sum -= 1,
_ => unreachable!(),
}
}
sum
}
/// Part 1 (alt1): To what floor do the instructions take Santa? functional style
#[aoc(day1, part1, alt1)]
fn part1_alt1(input: &str) -> i32 {
input
.chars()
.map(|char| match char {
'(' => 1,
')' => -1,
_ => unreachable!(),
})
.sum()
}
/// Part 2: What is the position of the character that causes Santa to first enter the basement?
#[aoc(day1, part2)]
fn part2(input: &str) -> Option<usize> {
let mut sum: i32 = 0;
for (idx, char) in input.chars().enumerate() {
match char {
'(' => sum += 1,
')' => sum -= 1,
_ => {}
}
if sum < 0 {
return Some(idx + 1);
}
}
None
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn part1_example() {
// `(())` and `()()` both result in floor `0`.
assert_eq!(part1("(())"), 0);
assert_eq!(part1("()()"), 0);
// `(((` and `(()(()(` both result in floor `3`.
assert_eq!(part1("((("), 3);
assert_eq!(part1("(()(()("), 3);
// `))(((((` also results in floor `3`.
assert_eq!(part1("))((((("), 3);
// `())` and `))(` both result in floor `-1` (the first basement level).
assert_eq!(part1("())"), -1);
assert_eq!(part1("))("), -1);
// `)))` and `)())())` both result in floor `-3`.
assert_eq!(part1(")))"), -3);
assert_eq!(part1(")())())"), -3);
}
#[test]
fn part2_example() {
// `)` causes him to enter the basement at character position `1`.
assert_eq!(part2(")"), Some(1));
// `()())` causes him to enter the basement at character position `5`.
assert_eq!(part2("()())"), Some(5));
}
}