From b7b9654a005bb4bb201525aa5878967ee7fd0509 Mon Sep 17 00:00:00 2001 From: Tyler Hallada Date: Thu, 13 Dec 2018 01:21:36 -0500 Subject: [PATCH] Day 2 part 2 --- inputs/2_test_part2.txt | 7 +++ src/day2.rs | 106 ++++++++++++++++++++++++++++++++++++++-- src/main.rs | 3 +- 3 files changed, 111 insertions(+), 5 deletions(-) create mode 100644 inputs/2_test_part2.txt diff --git a/inputs/2_test_part2.txt b/inputs/2_test_part2.txt new file mode 100644 index 0000000..3e1abfc --- /dev/null +++ b/inputs/2_test_part2.txt @@ -0,0 +1,7 @@ +abcde +fghij +klmno +pqrst +fguij +axcye +wvxyz diff --git a/src/day2.rs b/src/day2.rs index 0fbe7e1..d179fff 100644 --- a/src/day2.rs +++ b/src/day2.rs @@ -1,14 +1,18 @@ +use std::collections::HashMap; use std::error::Error; use std::fs::File; use std::io::{BufRead, BufReader}; -use std::collections::HashMap; const INPUT: &str = "inputs/2.txt"; -pub fn solve() -> Result> { +pub fn solve_part1() -> Result> { calculate_checksum(INPUT) } +pub fn solve_part2() -> Result, Box> { + find_most_common_id_overlap(INPUT) +} + fn calculate_checksum(filename: &str) -> Result> { let mut two_count = 0; let mut three_count = 0; @@ -30,14 +34,108 @@ fn calculate_checksum(filename: &str) -> Result> { Ok(two_count * three_count) } +fn find_most_common_id_overlap(filename: &str) -> Result, Box> { + let file = File::open(filename)?; + let mut read_lines: Vec = Vec::new(); + for line in BufReader::new(file).lines() { + let line_ref = &line?; + for line_before in read_lines.iter() { + match ids_are_diff_by_n(line_ref, &line_before, 1) { + Some(common) => return Ok(Some(common)), + None => (), + } + } + + read_lines.push(line_ref.to_owned()); + } + Ok(None) +} + +fn ids_are_diff_by_n(first: &String, second: &String, n: usize) -> Option { + if first.len() != second.len() { + return None; + } + + let mut diff_count = 0; + let mut common = String::new(); + let mut first_chars = first.chars(); + let mut second_chars = second.chars(); + + for _ in 0..first.len() { + let first_char = first_chars.next(); + let second_char = second_chars.next(); + + if first_char != second_char { + diff_count += 1 + } else { + common.push(first_char?); + } + + if diff_count > n { + return None; + } + } + + Some(common) +} + #[cfg(test)] mod tests { use super::*; - const TEST_INPUT: &str = "inputs/2_test.txt"; + const TEST_INPUT_PART_1: &str = "inputs/2_test.txt"; + const TEST_INPUT_PART_2: &str = "inputs/2_test_part2.txt"; #[test] fn calculates_correct_checksum() { - assert_eq!(calculate_checksum(TEST_INPUT).unwrap(), 12); + assert_eq!(calculate_checksum(TEST_INPUT_PART_1).unwrap(), 12); + } + + #[test] + fn ids_are_diff_by_1() { + assert_eq!( + ids_are_diff_by_n(&String::from("abcdef"), &String::from("abbdef"), 1).unwrap(), + "abdef" + ); + assert_eq!( + ids_are_diff_by_n(&String::from("abcdef"), &String::from("abcdee"), 1).unwrap(), + "abcde" + ); + assert_eq!( + ids_are_diff_by_n(&String::from("abcdef"), &String::from("bbcdef"), 1).unwrap(), + "bcdef" + ); + } + + #[test] + fn ids_are_diff_by_2() { + assert_eq!( + ids_are_diff_by_n(&String::from("abcdef"), &String::from("abbdxf"), 2).unwrap(), + "abdf" + ); + } + + #[test] + fn ids_are_diff_by_n_len_unequal_false() { + assert_eq!( + ids_are_diff_by_n(&String::from("abcdef"), &String::from("abbdeff"), 1), + None + ); + } + + #[test] + fn ids_are_diff_by_1_too_many_diffs() { + assert_eq!( + ids_are_diff_by_n(&String::from("abcdef"), &String::from("abbdxf"), 1), + None + ); + } + + #[test] + fn finds_most_common_id_overlap() { + assert_eq!( + find_most_common_id_overlap(TEST_INPUT_PART_2).unwrap().unwrap(), + "fgij" + ); } } diff --git a/src/main.rs b/src/main.rs index 816f178..2a2d172 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,5 +5,6 @@ fn main() { println!("Day 1:"); println!("{}", day1::solve().unwrap()); println!("Day 2:"); - println!("{}", day2::solve().unwrap()); + println!("{}", day2::solve_part1().unwrap()); + println!("{}", day2::solve_part2().unwrap().unwrap()); }