Advertisement
M1ngXU

21

Dec 22nd, 2021
313
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 2.20 KB | None | 0 0
  1. use std::collections::HashMap;
  2. use std::hash::{ Hasher, Hash };
  3. use std::cmp;
  4.  
  5. #[derive(Debug, Copy, Clone, PartialEq, Eq)]
  6. struct Player {
  7.     pos: u16,
  8.     sco: u16
  9. }
  10.  
  11. //p: Players
  12. //t: next player to throw dices
  13. #[derive(Debug, Clone, PartialEq, Eq)]
  14. struct Situation {
  15.     p: Vec::<Player>,
  16.     t: usize
  17. }
  18.  
  19. impl Hash for Player {
  20.     fn hash<H: Hasher>(&self, state: &mut H) {
  21.         self.pos.hash(state);
  22.         self.sco.hash(state);
  23.     }
  24. }
  25.  
  26. impl Hash for Situation {
  27.     fn hash<H: Hasher>(&self, state: &mut H) {
  28.         self.p.hash(state);
  29.         self.t.hash(state);
  30.     }
  31. }
  32.  
  33. impl Situation {
  34.     fn new(pos1: u16, pos2: u16) -> Self {
  35.         Situation {
  36.             p: Vec::from([
  37.                 Player {
  38.                     pos: pos1,
  39.                     sco: 0
  40.                 },
  41.                 Player {
  42.                     pos: pos2,
  43.                     sco: 0
  44.                 }
  45.             ]),
  46.             t: 0
  47.         }
  48.     }
  49.  
  50.     fn get_wins(self, visited: &mut HashMap<Situation, [ u64; 2 ]>) -> [ u64; 2 ] {
  51.         if visited.contains_key(&self) {
  52.             return *visited.get(&self).unwrap();
  53.         }
  54.         let mut res = [ 0, 0 ];
  55.         for a in 1..=3 {
  56.             for b in 1..=3 {
  57.                 for c in 1..=3 {
  58.                     let mut n = self.clone();
  59.                     n.p[n.t].pos = (n.p[n.t].pos + a + b + c - 1) % 10 + 1;
  60.                     n.p[n.t].sco += n.p[n.t].pos;
  61.                     if n.p[n.t].sco >= 21 {
  62.                         res[n.t] += 1;
  63.                     } else {
  64.                         n.t = 1 - n.t;
  65.                         let r = n.get_wins(visited);
  66.                         res[0] += r[0];
  67.                         res[1] += r[1];
  68.                     }
  69.                 }
  70.             }
  71.         }
  72.         visited.insert(self, res);
  73.         res
  74.     }
  75. }
  76.  
  77. fn main() {
  78.     let p1_pos = 4;
  79.     let p2_pos = 8;
  80.     println!(
  81.         " *: {}\n**: {}",
  82.         {
  83.             let mut pls = [
  84.                 Player { pos: p1_pos, sco: 0 },
  85.                 Player { pos: p2_pos, sco: 0 }
  86.             ];
  87.  
  88.             let mut dice = 1;
  89.             let mut throwed = 0;
  90.             let mut next_dice = || {
  91.                 let o = dice;
  92.                 dice = dice % 100 + 1;
  93.                 throwed += 1;
  94.                 o
  95.             };
  96.             (loop {
  97.                 let mut val = 0;
  98.                 for (i, mut p) in pls.iter_mut().enumerate() {
  99.                     p.pos += next_dice() + next_dice() + next_dice();
  100.                     p.pos = (p.pos - 1) % 10 + 1;
  101.                     p.sco += p.pos;
  102.                     if p.sco >= 1000 {
  103.                         val = pls[1 - i].sco as u32;
  104.                         break;
  105.                     }
  106.                 }
  107.                 if val > 0 {
  108.                     break val;
  109.                 }
  110.             } * throwed)
  111.         },
  112.         Situation::new(p1_pos, p2_pos)
  113.             .get_wins(&mut HashMap::new())
  114.             .into_iter().fold(0, | a, b | cmp::max(a, b))
  115.     );
  116. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement