diff --git a/day04/Cargo.lock b/day04/Cargo.lock new file mode 100644 index 0000000..b8f9a18 --- /dev/null +++ b/day04/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "day04" +version = "0.1.0" diff --git a/day04/Cargo.toml b/day04/Cargo.toml new file mode 100644 index 0000000..0e45553 --- /dev/null +++ b/day04/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "day04" +version = "0.1.0" +edition = "2021" diff --git a/day04/src/main.rs b/day04/src/main.rs new file mode 100644 index 0000000..01e2221 --- /dev/null +++ b/day04/src/main.rs @@ -0,0 +1,61 @@ +use std::collections::{HashMap, HashSet}; +use std::io::{stdin, BufRead}; + +fn main() { + let input = stdin().lock().lines().map(|l| l.unwrap()); + let mut total_score = 0; + let mut card_counts = HashMap::new(); + let mut total_single_cards = 0; + + for (id, line) in input.enumerate() { + let card = line.split_once(':').unwrap().1; + let (entries, winners) = card.split_once('|').unwrap(); + + let entset = entries + .trim() + .split(' ') + .filter(|num| !num.is_empty()) + .collect::>(); + let winset = winners + .trim() + .split(' ') + .filter(|num| !num.is_empty()) + .collect::>(); + + let common = entset.intersection(&winset); + let num_in_common = common.count(); + total_score += to_score(num_in_common); + + let repeat_count = card_counts.get(&(id + 1)).unwrap_or(&0).to_owned(); + + let r = to_range(id, num_in_common); + for win_card_copy in r { + let current_count = card_counts.get(&win_card_copy).unwrap_or(&0); + card_counts.insert(win_card_copy, current_count + 1 + repeat_count); + } + + total_single_cards = id + 1; + } + + let card_total = card_counts.iter().fold(0, |total, count| total + count.1); + + println!( + "P1: {} P2: {}", + total_score, + total_single_cards + card_total + ); +} + +fn to_range(id: usize, win_count: usize) -> std::ops::Range { + let start = id + 2; + let end = start + win_count; + start..end +} + +fn to_score(entries: usize) -> usize { + if entries == 0 { + 0 + } else { + 1 << (entries - 1) + } +}