#[derive(Debug, PartialEq)]\r
pub struct Card {\r
pub id: u32,\r
- pub count: u32,\r
pub winning: Vec<u32>,\r
pub numbers: Vec<u32>,\r
}\r
let (wins, vals) = nums.split_once("|").unwrap();\r
let winning: Vec<u32> = wins.trim().split_whitespace().map(|x| x.parse::<u32>().unwrap()).collect();\r
let values: Vec<u32> = vals.trim().split_whitespace().map(|x| x.parse::<u32>().unwrap()).collect();\r
- Ok( Card {id: id, count: 1, winning: winning, numbers: values} )\r
+ Ok( Card {id: id, winning: winning, numbers: values} )\r
}\r
}\r
\r
let card = "Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53".parse::<Card>().unwrap();\r
assert_eq!(card.matches(), 4);\r
}\r
-\r
- #[test]\r
- fn test_count_change() {\r
- let mut card = Card {id: 1, count: 1, winning: vec![], numbers: vec![] };\r
- card.count += 1;\r
- assert_eq!(card.count, 2);\r
- }\r
}
\ No newline at end of file
-pub mod card;\r
+extern crate clap;\r
\r
+pub mod card;\r
use card::Card;\r
\r
use std::error::Error;\r
-use std::env;\r
use std::fs::File;\r
use std::io::{prelude::*, BufReader};\r
\r
+use clap::{Parser, ArgAction};\r
+\r
+/// Advent of Code 2023 day 4\r
+#[derive(Parser, Default, Debug)]\r
+struct Arguments {\r
+ /// specify the input data filename\r
+ filename: String,\r
+ #[arg(short, long, action=ArgAction::SetTrue)]\r
+ /// enable additional debug output\r
+ debug: Option<bool>,\r
+}\r
+\r
+/// Calculate the answer for part 1 of the puzzle.\r
+fn part1(cards: &Vec<Card>) -> u32{\r
+ cards.iter().map(|c| c.points()).sum()\r
+}\r
+\r
+/// Calculate the answer for part 2\r
+fn part2(cards: &Vec<Card>) -> u32{\r
+ let mut counts = vec![1; cards.len()];\r
+ for card in cards {\r
+ let current_ndx = (card.id - 1) as usize;\r
+ let current_count = counts[current_ndx];\r
+ // get the cards we won based on the number of matches in the\r
+ // current card.\r
+ let num = card.matches();\r
+ let begin = (card.id) as usize;\r
+ let end = (card.id + num) as usize;\r
+ for ndx in begin..end {\r
+ // for each of the won cards, update the count of these\r
+ // cards with the number of the current card we have.\r
+ counts[ndx] += current_count;\r
+ }\r
+ }\r
+ counts.iter().sum()\r
+}\r
+\r
fn main() -> Result<(), Box<dyn Error>> {\r
- let args: Vec<String> = env::args().collect();\r
- if args.len() > 1 {\r
- let input = File::open(&args[1]).expect("no such file");\r
- let buffered = BufReader::new(input);\r
- let cards: Vec<Card> = buffered.lines()\r
- .map(|x| x.expect("something").parse::<Card>().unwrap())\r
- .collect();\r
+ let args = Arguments::parse();\r
+\r
+ let input = File::open(args.filename).expect("no such file");\r
+ let buffered = BufReader::new(input);\r
+ let cards: Vec<Card> = buffered.lines()\r
+ .map(|x| x.expect("something").parse::<Card>().unwrap())\r
+ .collect();\r
+ if args.debug.is_some() {\r
for card in &cards {\r
println!("{:?}", card);\r
}\r
- let points: u32 = cards.iter().map(|c| c.points()).sum();\r
- println!("part 1: {}", points);\r
-\r
}\r
+ println!("part 1: {}", part1(&cards));\r
+ println!("part 2: {}", part2(&cards));\r
+\r
Ok(())\r
}\r