use aoc_2022::file_to_lines; use tracing::*; use tracing_subscriber::EnvFilter; use std::cmp::max; struct Accum { max_sum: i32, current_sum: i32, } impl Accum { fn new() -> Accum { Accum { max_sum: 0, current_sum: 0, } } } fn part_1(input: &[i32]) -> i32 { input .iter() .fold(Accum::new(), |a, &x| { if x == -1 { Accum { max_sum: max(a.max_sum, a.current_sum), current_sum: 0, } } else { Accum { max_sum: a.max_sum, current_sum: a.current_sum + x, } } }) .max_sum } fn part_2(input: &[i32]) -> i32 { let mut calories: Vec = Vec::new(); let last_elf = input .iter() .fold(Accum::new(), |a, &x| { if x == -1 { calories.push(a.current_sum); Accum::new() } else { Accum { max_sum: a.max_sum, current_sum: a.current_sum + x, } } }) .current_sum; calories.push(last_elf); calories.sort(); calories.iter().rev().take(3).sum() } fn parse_input(pathname: &str) -> Vec { file_to_lines(pathname) .iter() .map(|s| if s.is_empty() { -1 } else { s.parse().unwrap() }) .collect() } fn main() { tracing_subscriber::fmt() .with_env_filter(EnvFilter::from_default_env()) .with_target(false) .with_file(true) .with_line_number(true) .without_time() .compact() .init(); let input = parse_input("inputs/day01.txt"); info!("Part 1: {}", part_1(&input)); info!("Part 2: {}", part_2(&input)); } #[cfg(test)] mod tests { use super::*; #[test] fn test_part_1() { let sample = parse_input("samples/day01.txt"); assert_eq!(part_1(&sample), 24000); } #[test] fn test_part_2() { let sample = parse_input("samples/day01.txt"); assert_eq!(part_2(&sample), 45000); } }