summaryrefslogtreecommitdiff
path: root/2023/day14.rs
diff options
context:
space:
mode:
authornekineki <nekineki@nekineki.net>2023-12-14 07:56:14 +0100
committernekineki <nekineki@nekineki.net>2023-12-14 08:18:50 +0100
commit1383458f70da63f82cf577957d5a0798898752e6 (patch)
tree6a4e0fdfc41b678e4e1c7b0f69088efb2c77b3c1 /2023/day14.rs
parente2d2c3cedf0cd4af66f413f920e9181f4b0bb710 (diff)
day14
Diffstat (limited to '2023/day14.rs')
-rw-r--r--2023/day14.rs133
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);
+}