21/2 optimizations
This commit is contained in:
parent
b262f734b5
commit
b733d05353
@ -10,8 +10,8 @@ fn part1((p1, p2): Parsed) -> usize {
|
||||
.cycle()
|
||||
.skip(1)
|
||||
.step_by(3)
|
||||
.scan(GameState { odd_round: false, scores: [(p1, 0), (p2, 0)] }, |mut game, die| {
|
||||
advance_game(&mut game, die * 3);
|
||||
.scan(GameState { odd_round: false, scores: [(p1, 0), (p2, 0)] }, |game, die| {
|
||||
advance_game(game, die * 3);
|
||||
Some((game.scores[0].1, game.scores[1].1))
|
||||
})
|
||||
.zip(1..)
|
||||
@ -31,23 +31,27 @@ struct GameState {
|
||||
const POSSIBLE_ROLLS: [(u16, usize); 7] = [(6, 7), (5, 6), (7, 6), (4, 3), (8, 3), (3, 1), (9, 1)];
|
||||
|
||||
fn part2((p1, p2): Parsed) -> usize {
|
||||
let start = GameState { odd_round: false, scores: [(p1, 0), (p2, 0)] };
|
||||
let mut games = FnvHashMap::default();
|
||||
games.insert(start, 1);
|
||||
games.insert(GameState { odd_round: false, scores: [(p1, 0), (p2, 0)] }, 1);
|
||||
let mut wins = [0, 0];
|
||||
let mut storage = Vec::with_capacity(100_000);
|
||||
while !games.is_empty() {
|
||||
for k in games.clone().keys() {
|
||||
let (start, count) = games.remove_entry(k).unwrap();
|
||||
for (start, count) in games.drain() {
|
||||
for &(die, count2) in &POSSIBLE_ROLLS {
|
||||
let mut new_state = start;
|
||||
advance_game(&mut new_state, die);
|
||||
if new_state.scores[start.odd_round as usize].1 >= 21 {
|
||||
wins[new_state.odd_round as usize] += count * count2;
|
||||
} else {
|
||||
*games.entry(new_state).or_insert(0) += count * count2;
|
||||
storage.push((new_state, count * count2));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Of all the versions I’ve tried, temporarily storing in a vector and then sorting back
|
||||
// into the map was by far the fastest.
|
||||
for (k, v) in storage.drain(..) {
|
||||
*games.entry(k).or_insert(0) += v;
|
||||
}
|
||||
}
|
||||
wins[0].max(wins[1])
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user