diff --git a/inputs/1_test_part2.txt b/inputs/1_test_part2.txt new file mode 100644 index 0000000..78cd296 --- /dev/null +++ b/inputs/1_test_part2.txt @@ -0,0 +1,5 @@ ++7 ++7 +-2 +-7 +-4 diff --git a/inputs/1_test_part2_2.txt b/inputs/1_test_part2_2.txt new file mode 100644 index 0000000..bdee386 --- /dev/null +++ b/inputs/1_test_part2_2.txt @@ -0,0 +1,5 @@ ++3 ++3 ++4 +-2 +-4 diff --git a/inputs/1_test_part2_3.txt b/inputs/1_test_part2_3.txt new file mode 100644 index 0000000..f6f3cf5 --- /dev/null +++ b/inputs/1_test_part2_3.txt @@ -0,0 +1,5 @@ +-6 ++3 ++8 ++5 +-6 diff --git a/src/day1.rs b/src/day1.rs index 7fcaaef..ddb86d9 100644 --- a/src/day1.rs +++ b/src/day1.rs @@ -1,13 +1,19 @@ use std::error::Error; use std::fs::File; use std::io::{BufRead, BufReader}; +use std::collections::HashSet; const INPUT: &str = "inputs/1.txt"; +const LOOP_LIMIT: u16 = 1000; -pub fn solve() -> Result> { +pub fn solve_part1() -> Result> { calculate_resulting_frequency(INPUT) } +pub fn solve_part2() -> Result, Box> { + find_repeating_frequency(INPUT) +} + fn calculate_resulting_frequency(filename: &str) -> Result> { let mut freq: i32 = 0; let file = File::open(filename)?; @@ -18,14 +24,65 @@ fn calculate_resulting_frequency(filename: &str) -> Result> { Ok(freq) } +fn find_repeating_frequency(filename: &str) -> Result, Box> { + let freqs = read_frequencies(filename)?; + let mut result_freqs = HashSet::new(); + let mut freq: i32 = 0; + let mut loop_count = 0; + while loop_count < LOOP_LIMIT { + for adjustment in &freqs { + freq += adjustment; + if result_freqs.contains(&freq) { + return Ok(Some(freq)) + } else { + result_freqs.insert(freq); + } + } + loop_count += 1 + } + Ok(None) +} + +fn read_frequencies(filename: &str) -> Result, Box> { + let mut freqs: Vec = Vec::new(); + let file = File::open(filename)?; + for line in BufReader::new(file).lines() { + freqs.push(line?.parse()?); + } + Ok(freqs) +} + #[cfg(test)] mod tests { use super::*; const TEST_INPUT: &str = "inputs/1_test.txt"; + const TEST_INPUT_PART_2: &str = "inputs/1_test_part2.txt"; + const TEST_INPUT_PART_2_2: &str = "inputs/1_test_part2_2.txt"; + const TEST_INPUT_PART_2_3: &str = "inputs/1_test_part2_3.txt"; #[test] fn finds_resulting_frequency() { assert_eq!(calculate_resulting_frequency(TEST_INPUT).unwrap(), 3); } + + #[test] + fn finds_repeating_frequency() { + assert_eq!(find_repeating_frequency(TEST_INPUT_PART_2).unwrap().unwrap(), 14); + } + + #[test] + fn finds_repeating_frequency_2() { + assert_eq!(find_repeating_frequency(TEST_INPUT_PART_2_2).unwrap().unwrap(), 10); + } + + #[test] + fn finds_repeating_frequency_3() { + assert_eq!(find_repeating_frequency(TEST_INPUT_PART_2_3).unwrap().unwrap(), 5); + } + + #[test] + fn reads_frequencies_file() { + assert_eq!(read_frequencies(TEST_INPUT).unwrap(), vec![5, -5, 3]); + } } diff --git a/src/main.rs b/src/main.rs index 2a2d172..a807a0f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,8 @@ mod day2; fn main() { println!("Day 1:"); - println!("{}", day1::solve().unwrap()); + println!("{}", day1::solve_part1().unwrap()); + println!("{}", day1::solve_part2().unwrap().unwrap()); println!("Day 2:"); println!("{}", day2::solve_part1().unwrap()); println!("{}", day2::solve_part2().unwrap().unwrap());