diff --git a/2023-rust/README.md b/2023-rust/README.md index 0a93b37..34894b0 100644 --- a/2023-rust/README.md +++ b/2023-rust/README.md @@ -9,11 +9,12 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www. | Day | Part 1 | Part 2 | | :---: | :---: | :---: | -| [Day 1](./src/bin/01.rs) | `64.7µs` | `634.0µs` | -| [Day 2](./src/bin/02.rs) | `40.8µs` | `46.7µs` | -| [Day 3](./src/bin/03.rs) | `426.2µs` | `429.9µs` | +| [Day 1](./src/bin/01.rs) | `64.6µs` | `639.8µs` | +| [Day 2](./src/bin/02.rs) | `41.8µs` | `48.0µs` | +| [Day 3](./src/bin/03.rs) | `430.0µs` | `424.2µs` | +| [Day 4](./src/bin/04.rs) | `98.3µs` | `47.2ms` | -**Total: 1.64ms** +**Total: 48.95ms** ## Usage diff --git a/2023-rust/src/bin/04.rs b/2023-rust/src/bin/04.rs index 2299df5..3bc0115 100644 --- a/2023-rust/src/bin/04.rs +++ b/2023-rust/src/bin/04.rs @@ -1,9 +1,12 @@ +use std::collections::{HashMap, VecDeque}; + use itertools::Itertools; advent_of_code::solution!(4); +#[derive(Clone)] struct ScratchCard { - index: u32, + id: u32, winning_numbers: Vec, numbers: Vec, } @@ -18,6 +21,16 @@ impl ScratchCard { .fold(1, |acc, _| acc * 2); fold / 2 } + + pub fn copies(&self) -> Vec { + self.winning_numbers + .iter() + .map(|number| self.numbers.contains(number)) + .filter(|contained| *contained) + .enumerate() + .map(|(i, _)| self.id + i as u32 + 1) + .collect_vec() + } } pub fn part_one(input: &str) -> Option { @@ -28,7 +41,22 @@ pub fn part_one(input: &str) -> Option { } pub fn part_two(input: &str) -> Option { - None + let cards = parse_input(input); + + let lookup: HashMap> = + cards.iter().map(|card| (card.id, card.copies())).collect(); + + let mut queue = VecDeque::from(cards.iter().map(|card| card.id).collect::>()); + + let mut total = 0; + while let Some(card) = queue.pop_front() { + total += 1; + + let copies = lookup.get(&card).unwrap(); + queue.extend(copies); + } + + Some(total) } fn parse_input(input: &str) -> Vec { @@ -38,8 +66,9 @@ fn parse_input(input: &str) -> Vec { .filter_map(|line| line.split_once(':')) .map(|(index, numbers)| { let (winning, mine) = numbers.split_once('|').unwrap(); + let parsed_index: u32 = index.trim().parse().unwrap(); ScratchCard { - index: index.trim().parse().unwrap(), + id: parsed_index - 1, winning_numbers: parse_numbers(winning), numbers: parse_numbers(mine), } @@ -67,6 +96,6 @@ mod tests { #[test] fn test_part_two() { let result = part_two(&advent_of_code::template::read_file("examples", DAY)); - assert_eq!(result, None); + assert_eq!(result, Some(30)); } }