diff options
| author | nekineki <nekineki@nekineki.net> | 2023-12-14 07:56:14 +0100 |
|---|---|---|
| committer | nekineki <nekineki@nekineki.net> | 2023-12-14 08:18:50 +0100 |
| commit | 1383458f70da63f82cf577957d5a0798898752e6 (patch) | |
| tree | 6a4e0fdfc41b678e4e1c7b0f69088efb2c77b3c1 /2023/day14.rs | |
| parent | e2d2c3cedf0cd4af66f413f920e9181f4b0bb710 (diff) | |
day14
Diffstat (limited to '2023/day14.rs')
| -rw-r--r-- | 2023/day14.rs | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/2023/day14.rs b/2023/day14.rs new file mode 100644 index 0000000..cb5ea93 --- /dev/null +++ b/2023/day14.rs @@ -0,0 +1,133 @@ +#![allow(dead_code)] +use std::collections::HashMap; +use std::fs::File; +use std::io::Read; + +#[derive(Hash, Eq, Debug, PartialEq, Clone, Copy)] +enum Spc { + Rol, + Fix, + Non, +} + +fn new_north_y(x: usize, y: usize, m: &Vec<Vec<Spc>>) -> usize { + for yi in (0..y).rev() { + if m[yi][x] != Spc::Non { + return yi + 1; + } + } + // reached the end of map + return 0; +} + +fn rotate_positive(m: Vec<Vec<Spc>>) -> Vec<Vec<Spc>> { + let mut out: Vec<Vec<Spc>> = Vec::new(); + for i in (0..m[0].len()).rev() { + let mut r: Vec<Spc> = Vec::new(); + for j in 0..m.len() { + r.push(m[j][i]); + } + out.push(r); + } + out +} + +fn print_m(m: &Vec<Vec<Spc>>) { + for i in 0..m.len() { + for j in 0..m[0].len() { + let a = match m[i][j] { + Spc::Rol => 'O', + Spc::Fix => '#', + Spc::Non => '.', + }; + print!("{}", a); + } + println!(); + } + println!(); +} + +fn calc_load(m: &Vec<Vec<Spc>>) -> usize { + let mut load = 0; + for i in 0..m[0].len() { + for j in 0..m.len() { + if m[j][i] == Spc::Rol { + load += m.len() - j; + } + } + } + load +} + +fn main() { + // let filename = "in/day14.ref"; + let filename = "in/day14.pzl"; + + let mut f = File::open(filename).expect("cannot open file"); + let mut content = String::new(); + f.read_to_string(&mut content).expect("cannot read file"); + let lines = content.trim_end().split('\n'); + + let mut m: Vec<Vec<Spc>> = Vec::new(); + for line in lines { + let mut r: Vec<Spc> = Vec::new(); + for c in line.chars() { + let s = match c { + 'O' => Spc::Rol, + '#' => Spc::Fix, + '.' => Spc::Non, + _ => panic!(), + }; + r.push(s); + } + m.push(r); + } + let mut m2 = m.clone(); + + for i in 0..m[0].len() { + for j in 0..m.len() { + if m[j][i] == Spc::Rol { + let new_y = new_north_y(i, j, &m); + m[j][i] = Spc::Non; + m[new_y][i] = Spc::Rol; + } + } + } + let res1 = calc_load(&m); + + let mut mm: HashMap<Vec<Vec<Spc>>, u64> = HashMap::new(); + let mut cm: HashMap<u64, usize> = HashMap::new(); + + let mut c0 = 0; + let mut c1 = 0; + for cycle in 0..1000000000 { + for _ in 0..4 { + for i in 0..m2[0].len() { + for j in 0..m2.len() { + if m2[j][i] == Spc::Rol { + let new_y = new_north_y(i, j, &m2); + m2[j][i] = Spc::Non; + m2[new_y][i] = Spc::Rol; + } + } + } + m2 = rotate_positive(m2); + m2 = rotate_positive(m2); + m2 = rotate_positive(m2); + } + if let Some(cycle_start) = mm.insert(m2.clone(), cycle) { + c0 = cycle_start; + c1 = cycle; + break; + } + cm.insert(cycle, calc_load(&m2)); + } + + // ne vem zakaj rabis ta - 1 + let res2 = cm[&((1000000000 - c0 - 1) % (c1 - c0) + c0)]; + + println!("res1: {}", res1); + println!("res2: {}", res2); + assert_eq!(res1, 103333); + assert_eq!(res2, 97241); +} |
