diff --git a/src/day1.rs b/src/day1.rs new file mode 100644 index 0000000..3ea16c7 --- /dev/null +++ b/src/day1.rs @@ -0,0 +1,100 @@ +use aoc_runner_derive::aoc; +use std::io::{BufRead, BufReader, Lines}; +use std::time::{Duration, Instant}; + +// 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); + } +}