advent-of-code/aoc2015/src/day01.rs

83 lines
1.8 KiB
Rust

use std::fmt::Write;
use anyhow::{anyhow, bail, Result};
const INPUT: &str = include_str!("../input/day01.txt");
pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
writeln!(res, "part 2: {}", part2(INPUT)?)?;
Ok(res)
}
fn part1(input: &str) -> Result<i64> {
Ok(input
.chars()
.filter_map(|c| match c {
'(' => Some(1),
')' => Some(-1),
_ => None,
})
.sum())
}
fn part2(input: &str) -> Result<usize> {
let mut sum = 0;
let mut res = 0;
for (i, c) in input.chars().enumerate() {
match c {
'(' => sum += 1,
')' => sum -= 1,
_ => bail!("unidentified character in input: {}", c),
};
if sum < 0 {
res = i + 1;
break;
}
}
match res {
0 => Err(anyhow!("never reached the basement...")),
_ => Ok(res),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn part1_provided() {
assert_eq!(part1("(())").unwrap(), 0);
assert_eq!(part1("()()").unwrap(), 0);
assert_eq!(part1("(((").unwrap(), 3);
assert_eq!(part1("(()(()(").unwrap(), 3);
assert_eq!(part1("))(((((").unwrap(), 3);
assert_eq!(part1("())").unwrap(), -1);
assert_eq!(part1("))(").unwrap(), -1);
assert_eq!(part1(")))").unwrap(), -3);
assert_eq!(part1(")())())").unwrap(), -3);
}
#[test]
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 74);
}
#[test]
fn part2_provided() {
assert_eq!(part2(")").unwrap(), 1);
assert_eq!(part2("()())").unwrap(), 5);
}
#[test]
fn part2_real() {
assert_eq!(part2(INPUT).unwrap(), 1795);
}
}