summaryrefslogtreecommitdiffstats
path: root/src/bin/2023/day4.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/2023/day4.rs')
-rw-r--r--src/bin/2023/day4.rs58
1 files changed, 58 insertions, 0 deletions
diff --git a/src/bin/2023/day4.rs b/src/bin/2023/day4.rs
new file mode 100644
index 0000000..a93a1d2
--- /dev/null
+++ b/src/bin/2023/day4.rs
@@ -0,0 +1,58 @@
+#![allow(dead_code)]
+#![allow(unused_variables)]
+
+use advent_of_code::prelude::*;
+
+pub fn parse(fh: File) -> Result<Vec<(HashSet<i64>, HashSet<i64>)>> {
+ Ok(parse::raw_lines(fh)
+ .map(|line| {
+ let line = line.split(": ").nth(1).unwrap();
+ let mut parts = line.split(" | ");
+ let winning = parts.next().unwrap();
+ let ours = parts.next().unwrap();
+ (
+ winning
+ .split_whitespace()
+ .map(|s| s.parse().unwrap())
+ .collect(),
+ ours.split_whitespace()
+ .map(|s| s.parse().unwrap())
+ .collect(),
+ )
+ })
+ .collect())
+}
+
+pub fn part1(cards: Vec<(HashSet<i64>, HashSet<i64>)>) -> Result<i64> {
+ let mut total = 0;
+ for (winning, ours) in cards {
+ let matches = (&ours & &winning).len();
+ if matches > 0 {
+ total += 2i64.pow((matches - 1).try_into().unwrap());
+ }
+ }
+ Ok(total)
+}
+
+pub fn part2(cards: Vec<(HashSet<i64>, HashSet<i64>)>) -> Result<i64> {
+ let mut counts = vec![1; cards.len()];
+ for (i, (winning, ours)) in cards.into_iter().enumerate() {
+ let matches = (&ours & &winning).len();
+ for prize in 0..matches {
+ counts[i + 1 + prize] += counts[i];
+ }
+ }
+ Ok(counts.iter().sum())
+}
+
+#[test]
+fn test() {
+ assert_eq!(
+ part1(parse(parse::data(2023, 4).unwrap()).unwrap()).unwrap(),
+ 25183
+ );
+ assert_eq!(
+ part2(parse(parse::data(2023, 4).unwrap()).unwrap()).unwrap(),
+ 5667240
+ );
+}