AoC2020/src/bin/day22_part2.rs

97 lines
2.9 KiB
Rust

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<u32>, mut deck2: Vec<u32>) -> (Vec<u32>, Vec<u32>) {
let mut deck_configs1: HashSet<Vec<u32>> = HashSet::new();
let mut deck_configs2: HashSet<Vec<u32>> = 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<u32> = deck1.iter().cloned().take(card1 as usize).collect();
let rec_deck2: Vec<u32> = 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<dyn Error>> {
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<u32> = 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<u32> = 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::*;
}