Advertisement
nairby

AOC 2023 Day 4

Dec 4th, 2023
844
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 2.17 KB | None | 0 0
  1. use std::env;
  2. use std::io::{self, prelude::*, BufReader};
  3. use std::fs::File;
  4. use std::collections::{HashSet,HashMap};
  5.  
  6. extern crate regex;
  7. use regex::Regex;
  8.  
  9. struct Card {
  10.     id: usize,
  11.     winning: HashSet<usize>,
  12.     my_numbers: HashSet<usize>,
  13. }
  14. impl From<&String> for Card {
  15.     fn from(s: &String) -> Self {
  16.         let re = Regex::new(r"Card[\s]+(\d+): ([\d\s]+) \| ([\d\s]+)").unwrap();
  17.         let matches = re.captures(&s).unwrap();
  18.         Self {
  19.             id:         matches[1].parse().unwrap(),
  20.             winning:    matches[2].split_whitespace().map(|x| x.parse::<usize>().unwrap()).collect(),
  21.             my_numbers: matches[3].split_whitespace().map(|x| x.parse::<usize>().unwrap()).collect(),
  22.         }
  23.     }
  24. }
  25. impl Card {
  26.     pub fn matching_numbers(&self) -> usize {
  27.         self.winning.iter().filter(|n| self.my_numbers.contains(n)).count()
  28.     }
  29.     pub fn score(&self) -> usize {
  30.         let common = self.matching_numbers() as u32;
  31.         if common == 0 { 0 } else { usize::pow(2,common-1) }
  32.     }
  33. }
  34.  
  35. fn solve(input: &str) -> io::Result<()> {
  36.     let file = File::open(input).expect("Input file not found.");
  37.     let reader = BufReader::new(file);
  38.  
  39.     // Input
  40.     let input: Vec<String> = match reader.lines().collect() {
  41.         Err(err) => panic!("Unknown error reading input: {}", err),
  42.         Ok(result) => result,
  43.     };
  44.     let cards: Vec<_> = input.iter().map(Card::from).collect();
  45.  
  46.     // Part 1
  47.     let part1: usize = cards.iter().map(|c| c.score()).sum();
  48.     println!("Part 1: {part1}"); // 27454
  49.  
  50.     // Part 2
  51.     let mut my_cards: HashMap<usize,usize> = HashMap::new();
  52.     for card_id in 1..=cards.len() {
  53.         my_cards.insert(card_id,1);
  54.     }
  55.     for card in cards {
  56.         let count = *my_cards.get(&card.id).unwrap();
  57.         for x in 1..=card.matching_numbers() {
  58.             *my_cards.entry(&card.id+x).or_insert(0) += count;
  59.         }
  60.     }
  61.     let part2: usize = my_cards.iter().map(|(_,v)| v).sum();
  62.     println!("Part 2: {part2}"); // 6857330
  63.  
  64.     Ok(())
  65. }
  66.  
  67. fn main() {
  68.     let args: Vec<String> = env::args().collect();
  69.     let filename = &args[1];
  70.     solve(&filename).unwrap();
  71. }
  72.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement