diff --git a/Day09/rust/Cargo.toml b/Day09/rust/Cargo.toml new file mode 100644 index 0000000..1ec6963 --- /dev/null +++ b/Day09/rust/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rust" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/Day09/rust/src/main.rs b/Day09/rust/src/main.rs new file mode 100644 index 0000000..4a62f54 --- /dev/null +++ b/Day09/rust/src/main.rs @@ -0,0 +1,67 @@ +use std::fs::File; +use std::io::{self, BufRead, BufReader}; +use std::path::Path; + +fn generate_difference_table(history: &[i32]) -> Vec> { + // Generates a difference table for a given history + let mut table: Vec> = vec![history.to_vec()]; + while !table.last().unwrap().iter().all(|&x| x == 0) { + let next_row: Vec = table + .last() + .unwrap() + .windows(2) + .map(|pair| pair[1] - pair[0]) + .collect(); + table.push(next_row); + } + table +} + +fn extrapolate_previous_value(table: &mut Vec>) -> i32 { + // Extrapolates the previous value from the difference table + for i in (0..table.len() - 1).rev() { + let diff = table[i][0] - table[i + 1][0]; + table[i].insert(0, diff); + } + table[0][0] +} + +fn solve_puzzle(filename: &str) -> Result { + // Solves the puzzle by reading histories from the file and summing their extrapolated previous values + let path = Path::new(filename); + let file = File::open(path)?; + let reader = BufReader::new(file); + + let mut total = 0; + for line in reader.lines() { + let line = line?; + if line.trim().is_empty() { + continue; + } + let history: Vec = line.split_whitespace().map(|s| s.parse().unwrap()).collect(); + let mut diff_table = generate_difference_table(&history); + let prev_value = extrapolate_previous_value(&mut diff_table); + total += prev_value; + } + + Ok(total) +} + +fn test() -> Result<(), io::Error> { + // Runs the test using the test.txt file and asserts the expected outcome + let expected = 2; // Expected result from the test data for the second part + let result = solve_puzzle("../test.txt")?; + assert_eq!(result, expected, "Test failed: Expected {}, got {}", expected, result); + println!("Test passed successfully."); + Ok(()) +} + +fn main() -> Result<(), io::Error> { + // Main function to run the test and then solve the puzzle + println!("Running test for the second part..."); + test()?; + println!("Test completed. Solving the puzzle for the second part..."); + let result = solve_puzzle("../input.txt")?; + println!("Puzzle result for the second part: {}", result); + Ok(()) +}