diff --git a/src/day2/id_range.rs b/src/day2/id_range.rs new file mode 100644 index 0000000..e4b1e33 --- /dev/null +++ b/src/day2/id_range.rs @@ -0,0 +1,60 @@ +use std::string; + +pub struct IDRange { + start: u64, + end: u64, +} + +impl IDRange { + pub fn new(start: u64, end: u64) -> Self { + Self { start, end } + } + + fn values(&self) -> Vec { + (self.start..self.end).collect() + } + + pub fn find_invalid_ids(&self, split_limit: Option) -> Vec { + let mut invalid_ids = vec![]; + for id in self.values() { + let string_id = id.to_string(); + let string_id_len = string_id.len(); + + let split_limit = split_limit.unwrap_or(string_id_len); + for split_limit in (2..=split_limit).rev() { + let mut previous = Option::>::None; + if string_id_len % split_limit != 0 { + // all id's that can't be divided by split_limit are immediately valid + continue; + } + for chunk in string_id + .chars() + .collect::>() + .chunks(string_id_len / split_limit) + { + if let Some(_previous) = &previous { + // we are after first iteration + if _previous != chunk { + // next iteration doesn't have matching chunk, it's a valid ID + // reset previous so it won't be interpreted as final result + previous = None; + break; + } + // everything's fine, we can proceed + } else { + // it's our first iteration + previous = Some(Vec::from(chunk)); + } + } + + // if previous exists, then it's an invalid id + if let Some(_) = &previous { + invalid_ids.push(id); + break; + } + } + } + + invalid_ids + } +} diff --git a/src/day2/input.txt b/src/day2/input.txt new file mode 100644 index 0000000..0af8d7f --- /dev/null +++ b/src/day2/input.txt @@ -0,0 +1 @@ +24-46,124420-259708,584447-720297,51051-105889,6868562486-6868811237,55-116,895924-1049139,307156-347325,372342678-372437056,1791-5048,3172595555-3172666604,866800081-866923262,5446793-5524858,6077-10442,419-818,57540345-57638189,2143479-2274980,683602048-683810921,966-1697,56537997-56591017,1084127-1135835,1-14,2318887654-2318959425,1919154462-1919225485,351261-558210,769193-807148,4355566991-4355749498,809094-894510,11116-39985,9898980197-9898998927,99828221-99856128,9706624-9874989,119-335 \ No newline at end of file diff --git a/src/day2/mod.rs b/src/day2/mod.rs new file mode 100644 index 0000000..ab891db --- /dev/null +++ b/src/day2/mod.rs @@ -0,0 +1,45 @@ +mod id_range; + +use id_range::IDRange; +use std::{collections::HashSet, fs}; + +fn parse_range(string: &str) -> IDRange { + let mut split = string.split("-"); + let lhs = split + .nth(0) + .unwrap() + .parse::() + .expect("lhs not a digit"); + + let rhs = split + .nth(0) + .unwrap() + .parse::() + .expect("rhs not a digit"); + + IDRange::new(lhs, rhs) +} + +pub fn solve_part1() { + let solution = solve(Some(2)); + println!("The solution for part 1 is {}", solution); +} + +pub fn solve_part2() { + let solution = solve(None); + println!("The solution for part 2 is {}", solution); +} + +fn solve(limit: Option) -> u64 { + let file = fs::read_to_string("src/day2/input.txt").expect("You didn't provide input.txt."); + + let mut invalid_ids: HashSet = HashSet::new(); + for line in file.split(",") { + let range = parse_range(line); + for invalid in range.find_invalid_ids(limit) { + invalid_ids.insert(invalid); + } + } + + invalid_ids.iter().sum::() +} diff --git a/src/main.rs b/src/main.rs index 8025c36..1f4bd59 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ mod day1; +mod day2; fn main() { - day1::solve_part1(); + day2::solve_part2(); }