use std::collections::HashSet; use std::error::Error; use std::fs::File; use std::io::{self, BufRead}; use std::vec::Vec; fn recursive_combat(mut deck1: Vec, mut deck2: Vec) -> (Vec, Vec) { let mut deck_configs1: HashSet> = HashSet::new(); let mut deck_configs2: HashSet> = HashSet::new(); while deck1.len() != 0 && deck2.len() != 0 { println!("Deck 1: {:?}", deck1); println!("Deck 2: {:?}", deck2); if deck_configs1.contains(&deck1) || deck_configs2.contains(&deck2) { println!("Player 1 wins by deck configuration."); return (deck1, Vec::new()); } deck_configs1.insert(deck1.clone()); deck_configs2.insert(deck2.clone()); let card1 = deck1.remove(0); let card2 = deck2.remove(0); if deck1.len() as u32 >= card1 && deck2.len() as u32 >= card2 { println!("Recursing !"); let rec_deck1: Vec = deck1.iter().cloned().take(card1 as usize).collect(); let rec_deck2: Vec = deck2.iter().cloned().take(card2 as usize).collect(); let (result_deck1, result_deck2) = recursive_combat(rec_deck1, rec_deck2); if result_deck1.len() > result_deck2.len() { println!("Player 1 wins by recursion"); deck1.push(card1); deck1.push(card2); } else { println!("Player 2 wins by recursion"); deck2.push(card2); deck2.push(card1); } } else { if card1 > card2 { println!("Player 1 wins"); deck1.push(card1); deck1.push(card2); } else { println!("Player 2 wins"); deck2.push(card2); deck2.push(card1); } } } return (deck1, deck2); } fn main() -> Result<(), Box> { let file = File::open("inputs/day22.txt")?; let mut lines = io::BufReader::new(file).lines().map(|l| l.unwrap()); lines.next(); let mut deck1: Vec = Vec::new(); while let Some(line) = lines.next() { if line == "" { break; } deck1.push(line.parse().expect("Unable to parse card number")); } lines.next(); let mut deck2: Vec = Vec::new(); while let Some(line) = lines.next() { if line == "" { break; } deck2.push(line.parse().expect("Unable to parse card number")); } let (deck1, deck2) = recursive_combat(deck1, deck2); let winning_deck = if deck1.len() != 0 { deck1 } else { deck2 }; let points = winning_deck .iter() .rev() .enumerate() .map(|(pos, card)| ((pos + 1) as u32) * card) .fold(0, |p, acc| p + acc); println!("Points: {}", points); Ok(()) } #[cfg(test)] mod tests { use crate::*; }