day 22
This commit is contained in:
parent
06001471d2
commit
0750f8732e
53
data/day22/input
Normal file
53
data/day22/input
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
Player 1:
|
||||||
|
26
|
||||||
|
8
|
||||||
|
2
|
||||||
|
17
|
||||||
|
19
|
||||||
|
29
|
||||||
|
41
|
||||||
|
7
|
||||||
|
25
|
||||||
|
33
|
||||||
|
50
|
||||||
|
16
|
||||||
|
36
|
||||||
|
37
|
||||||
|
32
|
||||||
|
4
|
||||||
|
46
|
||||||
|
12
|
||||||
|
21
|
||||||
|
48
|
||||||
|
11
|
||||||
|
6
|
||||||
|
13
|
||||||
|
23
|
||||||
|
9
|
||||||
|
|
||||||
|
Player 2:
|
||||||
|
27
|
||||||
|
47
|
||||||
|
15
|
||||||
|
45
|
||||||
|
10
|
||||||
|
14
|
||||||
|
3
|
||||||
|
44
|
||||||
|
31
|
||||||
|
39
|
||||||
|
42
|
||||||
|
5
|
||||||
|
49
|
||||||
|
24
|
||||||
|
22
|
||||||
|
20
|
||||||
|
30
|
||||||
|
1
|
||||||
|
35
|
||||||
|
38
|
||||||
|
18
|
||||||
|
43
|
||||||
|
28
|
||||||
|
40
|
||||||
|
34
|
98
src/bin/day22.rs
Normal file
98
src/bin/day22.rs
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
use std::collections::{VecDeque, HashSet};
|
||||||
|
|
||||||
|
type Deck = VecDeque<u32>;
|
||||||
|
|
||||||
|
const INPUT: &str = include_str!("../../data/day22/input");
|
||||||
|
|
||||||
|
fn parse_player(block: &str) -> (u32, Deck) {
|
||||||
|
let block = block.strip_prefix("Player ").unwrap();
|
||||||
|
let player = block[..1].parse::<u32>().unwrap();
|
||||||
|
let block = block[1..].strip_prefix(":").unwrap().trim();
|
||||||
|
let deck = block.lines().map(|s| s.parse::<u32>().unwrap()).collect();
|
||||||
|
(player, deck)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn score(deck: &Deck) -> u64 {
|
||||||
|
deck.iter().rev().enumerate().map(|(pos, &value)| {
|
||||||
|
((pos + 1) as u64) * (value as u64)
|
||||||
|
}).sum::<u64>()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn crab(mut deck1: Deck, mut deck2: Deck) {
|
||||||
|
while !deck1.is_empty() && !deck2.is_empty() {
|
||||||
|
let c1 = deck1.pop_front().unwrap();
|
||||||
|
let c2 = deck2.pop_front().unwrap();
|
||||||
|
if c1 > c2 {
|
||||||
|
deck1.push_back(c1);
|
||||||
|
deck1.push_back(c2);
|
||||||
|
} else {
|
||||||
|
assert!(c2 > c1);
|
||||||
|
deck2.push_back(c2);
|
||||||
|
deck2.push_back(c1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if deck2.is_empty() {
|
||||||
|
println!("Player 1 won: {:?}", deck1);
|
||||||
|
println!("Score: {}", score(&deck1));
|
||||||
|
} else {
|
||||||
|
println!("Player 2 won: {:?}", deck2);
|
||||||
|
println!("Score: {}", score(&deck2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _crab_rec(deck1: &mut Deck, deck2: &mut Deck) -> bool {
|
||||||
|
// println!("Rec Combat: {:?}, {:?}", deck1, deck2);
|
||||||
|
let mut previous_rounds = HashSet::new();
|
||||||
|
while !deck1.is_empty() && !deck2.is_empty() {
|
||||||
|
if !previous_rounds.insert((deck1.clone(), deck2.clone())) {
|
||||||
|
// prevent infinite loop; player 1 wins
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
let c1 = deck1.pop_front().unwrap();
|
||||||
|
let c2 = deck2.pop_front().unwrap();
|
||||||
|
let p1_won = if deck1.len() >= c1 as usize && deck2.len() >= c2 as usize {
|
||||||
|
let mut deck1: Deck = deck1.iter().copied().take(c1 as usize).collect();
|
||||||
|
let mut deck2: Deck = deck2.iter().copied().take(c2 as usize).collect();
|
||||||
|
assert_eq!(deck1.len(), c1 as usize);
|
||||||
|
assert_eq!(deck2.len(), c2 as usize);
|
||||||
|
// recurse
|
||||||
|
_crab_rec(&mut deck1, &mut deck2)
|
||||||
|
} else {
|
||||||
|
assert_ne!(c1, c2);
|
||||||
|
c1 > c2
|
||||||
|
};
|
||||||
|
if p1_won {
|
||||||
|
deck1.push_back(c1);
|
||||||
|
deck1.push_back(c2);
|
||||||
|
} else {
|
||||||
|
deck2.push_back(c2);
|
||||||
|
deck2.push_back(c1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deck2.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn crab_rec(mut deck1: Deck, mut deck2: Deck) {
|
||||||
|
let p1_won = _crab_rec(&mut deck1, &mut deck2);
|
||||||
|
if p1_won {
|
||||||
|
println!("Player 1 won recursive combat: {:?}", deck1);
|
||||||
|
println!("Score: {}", score(&deck1));
|
||||||
|
} else {
|
||||||
|
println!("Player 2 won recursive combat: {:?}", deck2);
|
||||||
|
println!("Score: {}", score(&deck2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let (deck1, deck2) = {
|
||||||
|
let pos = INPUT.find("\n\n").unwrap();
|
||||||
|
let (id1, deck1) = parse_player(&INPUT[..pos]);
|
||||||
|
let (id2, deck2) = parse_player(&INPUT[pos+2..]);
|
||||||
|
assert_eq!(id1, 1);
|
||||||
|
assert_eq!(id2, 2);
|
||||||
|
(deck1, deck2)
|
||||||
|
};
|
||||||
|
|
||||||
|
crab(deck1.clone(), deck2.clone());
|
||||||
|
crab_rec(deck1, deck2);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user