Added day 21 code for part 1 and 2

Signed-off-by: Louis Vallat <louis@louis-vallat.xyz>
This commit is contained in:
Louis Vallat 2022-01-08 13:04:33 +01:00
parent e5acbbf150
commit f30140c81f
No known key found for this signature in database
GPG Key ID: 0C87282F76E61283
4 changed files with 115 additions and 0 deletions

View File

@ -103,3 +103,8 @@ day-20:
stage: build stage: build
script: script:
- cd day20; cargo run --release ./input - cd day20; cargo run --release ./input
day-21:
stage: build
script:
- cd day21; cargo run --release ./input

8
day21/Cargo.toml Normal file
View File

@ -0,0 +1,8 @@
[package]
name = "day21"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

2
day21/input Normal file
View File

@ -0,0 +1,2 @@
Player 1 starting position: 1
Player 2 starting position: 2

100
day21/src/main.rs Normal file
View File

@ -0,0 +1,100 @@
use std::{fs, env, collections::HashMap};
struct Dice {
n: u32,
i: u32
}
impl Dice {
fn new() -> Dice { Dice { n: 0, i: 0 } }
fn get_nb_draw(&self) -> u32 { return self.n; }
fn get_next(&mut self) -> u32 {
self.n += 1;
self.i = (self.i + 1) % 100;
if self.i == 0 { self.i = 100; }
return self.i;
}
}
fn read_input(path: &str) -> String {
return fs::read_to_string(path).expect("Cannot read file.");
}
fn parse_input(s: &str) -> (u8, u8) {
let p = s.lines()
.map(|l| l.split_once(": ").unwrap().1.parse::<u8>().unwrap())
.collect::<Vec<u8>>();
return (p[0], p[1]);
}
fn play_classic(mut v: (u8, u8)) -> (u32, u32) {
let mut d = Dice::new();
let mut s = (0, 0);
let mut p = true;
while s.0 < 1000 && s.1 < 1000 {
let a = d.get_next() + d.get_next() + d.get_next();
let mut x = (if p { v.0 } else { v.1 } as u32 + a) % 10;
if x == 0 { x = 10; }
if p {
v.0 = x as u8;
s.0 += x;
if s.0 >= 1000 { return (d.get_nb_draw(), s.1); }
} else {
v.1 = x as u8;
s.1 += x;
if s.1 >= 1000 { return (d.get_nb_draw(), s.0); }
}
p = !p;
}
return (d.get_nb_draw(), std::cmp::min(s.0, s.1));
}
fn play_quantum(v: (u8, u8), s: (u8, u8), p: bool, c: &mut HashMap<((u8, u8), (u8, u8), bool), (u128, u128)>) {
if s.0 >= 21 {
c.insert((v, s, p), (1, 0));
return;
}
if s.1 >= 21 {
c.insert((v, s, p), (0, 1));
return;
}
for i in 1..=3 {
for j in 1..=3 {
for k in 1..=3 {
let mut a = v;
let mut b = s;
if p {
a.0 = (a.0 + i + j + k) % 10;
if a.0 == 0 { a.0 = 10; }
b.0 += a.0;
} else {
a.1 = (a.1 + i + j + k) % 10;
if a.1 == 0 { a.1 = 10; }
b.1 += a.1;
}
if !c.contains_key(&(a, b, !p)) { play_quantum(a, b, !p, c); }
let r = *c.get(&(a, b, !p)).unwrap();
let x = *c.get(&(v, s, p)).unwrap_or(&(0, 0));
c.insert((v, s, p), (r.0 + x.0, r.1 + x.1));
}
}
}
}
fn main() {
let args: Vec<String> = env::args().collect();
for arg in args.iter().skip(1) {
let input = read_input(&arg);
let vec_in = parse_input(&input);
let c = play_classic(vec_in);
let mut w = HashMap::new();
play_quantum(vec_in, (0, 0), true, &mut w);
let w = w.get(&(vec_in, (0, 0), true)).unwrap();
println!("[{}]", &arg);
println!("\t[Part 1] => Answer is '{}'.", c.0 * c.1);
println!("\t[Part 2] => Answer is '{}'.", std::cmp::max(w.0, w.1));
}
}