use aoc_runner_derive::aoc; // PROBLEM 1 solution #[aoc(day1, part1)] pub fn part1(input: &str) -> u64 { let mut val = 50u64; let mut pass = 0u64; let mod_val = 100; for line in input.lines() { let line = line.trim(); let (sign, num) = line.split_at(1); let num_val = num.parse::().unwrap(); let add_val = match sign.as_bytes()[0] { b'R' => num_val, b'L' => mod_val - (num_val % mod_val), c => panic!("Invalid direction {c}"), }; val = (val + add_val) % mod_val; if val == 0 { pass += 1 } } pass } // PROBLEM 2 solution fn advance(mut start: i64, mut n: i64) -> (i64, i64) { let mut zero_crossings = 0; while n != 0 { if n > 0 { start += 1; if start == 100 { start = 0; zero_crossings += 1; } n -= 1 } else { start -= 1; if start == 0 { zero_crossings += 1; } if start == -1 { start = 99; } n += 1 } } (start, zero_crossings) } #[aoc(day1, part2)] pub fn part2(input: &str) -> i64 { let mut val = 50; let mut pass = 0i64; for line in input.lines() { let line = line.trim(); let (sign, num) = line.split_at(1); let num_val = num.parse::().unwrap(); let (new_val, add_pass) = match sign.as_bytes()[0] { b'R' => advance::<100>(val, num_val), b'L' => advance::<100>(val, -num_val), c => panic!("Invalid direction {c}"), }; val = new_val; pass += add_pass; } pass } #[cfg(test)] mod tests { use crate::day1::*; const EXAMPLE: &str = "L68 L30 R48 L5 R60 L55 L1 L99 R14 L82"; #[test] fn problem1_example() { assert_eq!(part1(EXAMPLE), 3); } #[test] fn problem2_example() { assert_eq!(part2(EXAMPLE), 6); } }