adventofcode

git clone https://git.ce9e.org/adventofcode.git

commit
4659c1dae09fd1aa649353618b3cfe86cf75cb9c
parent
791c7e1cb91b5745f234173dfb46eff7edb7d703
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2021-12-21 10:21
add elegant solution from reddit

https://neddit.ce9e.org/r/adventofcode/comments/rl6p8y/2021_day_21_solutions/hpeokw2/

Diffstat

A 2021/21/part2_simple.rs 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

1 files changed, 81 insertions, 0 deletions


diff --git a/2021/21/part2_simple.rs b/2021/21/part2_simple.rs

@@ -0,0 +1,81 @@
   -1     1 use std::env::args;
   -1     2 use std::fs::File;
   -1     3 use std::io::BufRead;
   -1     4 use std::io::BufReader;
   -1     5 
   -1     6 fn get_data() -> (u8, u8) {
   -1     7     let path = args().nth(1).unwrap();
   -1     8     let file = File::open(path).unwrap();
   -1     9 
   -1    10     let mut state = 0;
   -1    11     let mut player1 = 0;
   -1    12     let mut player2 = 0;
   -1    13 
   -1    14     for line in BufReader::new(file).lines() {
   -1    15         match state {
   -1    16             0 => {
   -1    17                 player1 = line.unwrap()[28..].parse::<u8>().unwrap();
   -1    18                 state = 1;
   -1    19             },
   -1    20             1 => {
   -1    21                 player2 = line.unwrap()[28..].parse::<u8>().unwrap();
   -1    22                 state = 2;
   -1    23             },
   -1    24             _ => unreachable!(),
   -1    25         }
   -1    26     }
   -1    27 
   -1    28     return (player1 - 1, player2 - 1);
   -1    29 }
   -1    30 
   -1    31 fn index(pos1: u8, pos2: u8, score1: u8, score2: u8) -> usize {
   -1    32     return usize::from(pos1)
   -1    33         + usize::from(pos2) * 10
   -1    34         + usize::from(score1) * 10 * 10
   -1    35         + usize::from(score2) * 10 * 10 * 21;
   -1    36 }
   -1    37 
   -1    38 fn play_dirac(pos1: u8, pos2: u8, score1: u8, score2: u8, mut cache: &mut [Option<(u64, u64)>; 10 * 10 * 21 * 21]) -> (u64, u64) {
   -1    39     // https://neddit.ce9e.org/r/adventofcode/comments/rl6p8y/2021_day_21_solutions/hpeokw2/
   -1    40     if score2 >= 21 {
   -1    41         return (0, 1);
   -1    42     }
   -1    43 
   -1    44     let i = index(pos1, pos2, score1, score2);
   -1    45     match cache[i] {
   -1    46         None => {},
   -1    47         Some(v) => return v,
   -1    48     }
   -1    49 
   -1    50     let mut wins1 = 0;
   -1    51     let mut wins2 = 0;
   -1    52 
   -1    53     for a in [1, 2, 3].iter() {
   -1    54         for b in [1, 2, 3].iter() {
   -1    55             for c in [1, 2, 3].iter() {
   -1    56                 let pos = (pos1 + a + b + c) % 10;
   -1    57                 let score = score1 + (pos + 1);
   -1    58                 // switch players
   -1    59                 let (w2, w1) = play_dirac(pos2, pos, score2, score, &mut cache);
   -1    60                 wins1 += w1;
   -1    61                 wins2 += w2;
   -1    62             }
   -1    63         }
   -1    64     }
   -1    65 
   -1    66     cache[i] = Some((wins1, wins2));
   -1    67 
   -1    68     return (wins1, wins2);
   -1    69 }
   -1    70 
   -1    71 fn main() {
   -1    72     let (pos1, pos2) = get_data();
   -1    73     let mut cache = [None; 10 * 10 * 21 * 21];
   -1    74     let (wins1, wins2) = play_dirac(pos1, pos2, 0, 0, &mut cache);
   -1    75 
   -1    76     if wins1 > wins2 {
   -1    77         println!("{}", wins1);
   -1    78     } else {
   -1    79         println!("{}", wins2);
   -1    80     }
   -1    81 }