diff --git a/inputs/day22.txt b/inputs/day22.txt new file mode 100644 index 0000000..8c6c1e4 --- /dev/null +++ b/inputs/day22.txt @@ -0,0 +1,53 @@ +Player 1: +4 +25 +3 +11 +2 +29 +41 +23 +30 +21 +50 +8 +1 +24 +27 +10 +42 +43 +38 +15 +18 +13 +32 +37 +34 + +Player 2: +12 +6 +36 +35 +40 +47 +31 +9 +46 +49 +19 +16 +5 +26 +39 +48 +7 +44 +45 +20 +17 +14 +33 +28 +22 diff --git a/inputs/test.txt b/inputs/test.txt index 1c0ea2f..391cd24 100644 --- a/inputs/test.txt +++ b/inputs/test.txt @@ -1,4 +1,13 @@ -mxmxvkd kfcds sqjhc nhms (contains dairy, fish) -trh fvjkl sbzzf mxmxvkd (contains dairy) -sqjhc fvjkl (contains soy) -sqjhc mxmxvkd sbzzf (contains fish) +Player 1: +9 +2 +6 +3 +1 + +Player 2: +5 +8 +4 +7 +10 diff --git a/src/bin/day22.rs b/src/bin/day22.rs new file mode 100644 index 0000000..21a7b8e --- /dev/null +++ b/src/bin/day22.rs @@ -0,0 +1,60 @@ +use std::error::Error; +use std::fs::File; +use std::io::{self, BufRead}; +use std::vec::Vec; + +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")); + } + + while deck1.len() != 0 && deck2.len() != 0 { + println!("Deck 1: {:?}", deck1); + println!("Deck 2: {:?}", deck2); + let card1 = deck1.remove(0); + let card2 = deck2.remove(0); + if card1 > card2 { + println!("Player 1 wins"); + deck1.push(card1); + deck1.push(card2); + } else { + println!("Player 2 wins"); + deck2.push(card2); + deck2.push(card1); + } + } + + 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::*; +} diff --git a/src/bin/day22_part2.rs b/src/bin/day22_part2.rs new file mode 100644 index 0000000..17ba4b2 --- /dev/null +++ b/src/bin/day22_part2.rs @@ -0,0 +1,96 @@ +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::*; +}