diff --git a/.gitignore b/.gitignore index 6769e21..00209f6 100644 --- a/.gitignore +++ b/.gitignore @@ -157,4 +157,19 @@ cython_debug/ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ \ No newline at end of file +#.idea/ + +# Generated by Cargo +# will have compiled files and executables +debug/ +target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb \ No newline at end of file diff --git a/Day01/coordinates.txt b/Day01/input.txt similarity index 100% rename from Day01/coordinates.txt rename to Day01/input.txt diff --git a/Day01/part1.py b/Day01/part1.py index 56b4798..9eeedb6 100644 --- a/Day01/part1.py +++ b/Day01/part1.py @@ -45,6 +45,6 @@ def sum_calibration_values(filename): # Main execution if __name__ == "__main__": - filename = "coordinates.txt" + filename = "input.txt" total_calibration_value = sum_calibration_values(filename) print(f"Total Sum of Calibration Values: {total_calibration_value}") diff --git a/Day01/part2.py b/Day01/part2.py index a23433b..f2043d5 100644 --- a/Day01/part2.py +++ b/Day01/part2.py @@ -47,6 +47,6 @@ def sum_calibration_values(file_path): # Main execution if __name__ == "__main__": import sys - filename = sys.argv[1] if len(sys.argv) > 1 else "coordinates.txt" + filename = sys.argv[1] if len(sys.argv) > 1 else "input.txt" total_calibration_value = sum_calibration_values(filename) print(f"Total Sum of Calibration Values: {total_calibration_value}") diff --git a/Day01/rust/Cargo.toml b/Day01/rust/Cargo.toml new file mode 100644 index 0000000..6ecc1cd --- /dev/null +++ b/Day01/rust/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rust_solution_01" +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/Day01/rust/src/main.rs b/Day01/rust/src/main.rs new file mode 100644 index 0000000..b005cf2 --- /dev/null +++ b/Day01/rust/src/main.rs @@ -0,0 +1,97 @@ +use std::fs::File; +use std::io::{self, BufRead}; +use std::path::Path; + +fn main() { + let path = Path::new("../input.txt"); + match read_lines(path) { + Ok(lines) => { + let mut total = 0; + for line in lines { + if let Ok(ip) = line { + let value = extract_calibration_value(&ip); + println!("Line: '{}', Calibration Value: {}", ip, value); + total += value; + } + } + println!("Total Calibration Value: {}", total); + } + Err(e) => println!("Error: {}", e), + } +} + +// Function to read lines from a file +fn read_lines

(filename: P) -> io::Result>> +where + P: AsRef, +{ + let file = File::open(filename)?; + Ok(io::BufReader::new(file).lines()) +} + +fn extract_calibration_value(line: &str) -> u32 { + let digits = extract_digits(line); + match (digits.first(), digits.last()) { + (Some(first), Some(last)) => format!("{}{}", first, last).parse::().unwrap_or(0), + _ => 0, + } +} + +fn extract_digits(line: &str) -> Vec { + let digit_map = vec![ + ("zero", 0), ("one", 1), ("two", 2), ("three", 3), ("four", 4), + ("five", 5), ("six", 6), ("seven", 7), ("eight", 8), ("nine", 9), + ]; + + let mut digits = Vec::new(); + let mut current_line = line.to_string(); + + // Iterate over each character in the line + while !current_line.is_empty() { + let mut found = false; + + // Check for word representations of digits + for (word, digit) in &digit_map { + if current_line.starts_with(word) { + digits.push(*digit); + current_line = current_line[word.len()..].to_string(); + found = true; + break; + } + } + + // Check for single digit characters + if !found { + if let Some(first_char) = current_line.chars().next() { + if let Some(digit) = first_char.to_digit(10) { + digits.push(digit); + } + current_line = current_line[1..].to_string(); + } + } + } + + digits +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_extract_calibration_value() { + let test_cases = vec![ + ("two1nine", 29), + ("eightwothree", 83), + ("abcone2threexyz", 13), + ("xtwone3four", 24), + ("4nineeightseven2", 42), + ("zoneight234", 14), + ("7pqrstsixteen", 76), + ]; + + for (input, expected) in test_cases { + assert_eq!(extract_calibration_value(input), expected, "Failed on input: {}", input); + } + } +} diff --git a/README.md b/README.md index 981ac2e..02c5e2e 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Each day's puzzle solution is in its respective folder, named `DayXX`, where `XX Within each folder, you'll find: - `README.md`: A brief description of the day's problem. -- Source code files: My solution for the day's puzzle, typically in Python. +- Source code files: My solution for the day's puzzle, typically in Python or Rust - `input.txt`: The input data provided for the puzzle. - Additional resources or notes if applicable. @@ -48,6 +48,15 @@ cd Day01 python part2.py ``` +For Rust you have to use the rust project generated in each Day. +Make sure you have Rust and Cargo installed. +You can either test or run the solution: +``` +cd Day01/rust +cargo test +cargo run +``` + Make sure you have Python installed on your machine. The solutions are developed using Python 3.x. ## Feedback and Collaboration