2023-14: Implement part two

This commit is contained in:
Mathis 2023-12-23 21:52:39 +01:00
parent ae9f6e1829
commit 186f9802b7
1 changed files with 176 additions and 0 deletions

View File

@ -0,0 +1,176 @@
use std::collections::HashMap;
use super::common::Rock;
pub fn part_two(input_lines: Vec<String>) -> String {
let n = 1000000000;
let mut platform: Vec<Vec<Rock>> = Vec::new();
for line in input_lines {
let mut row: Vec<Rock> = Vec::new();
for c in line.chars() {
match c {
'.' => row.push(Rock::N),
'#' => row.push(Rock::S),
'O' => row.push(Rock::R),
_ => panic!("Invalid character: {}", c),
}
}
platform.push(row);
}
let mut memory: HashMap<String, usize> = HashMap::new();
let mut i = 0;
while i < n {
// println!("{}", i);
platform = cycle(platform.clone());
let hashed_platform = hash_platform(&platform);
if memory.contains_key(&hashed_platform) {
let cycle = &memory[&hashed_platform];
// println!("Cycle found at {} - {}, lenght: {}", cycle, i, i - cycle);
let cycle_length = i - cycle;
let remaining_cycles = (n - i) / cycle_length;
i = i + remaining_cycles * cycle_length + 1;
continue;
} else {
memory.insert(hashed_platform, i);
}
i += 1;
}
let result = count_load(&platform);
result.to_string()
// String::from("Not implemented")
}
fn tilt_north(mut platform : Vec<Vec<Rock>>) -> Vec<Vec<Rock>> {
for i in 0..platform.len() {
for j in 0..platform[i].len() {
if platform[i][j] == Rock::R {
let mut k = i;
while k >= 1 && platform[k - 1][j] == Rock::N {
k -= 1;
}
platform[i][j] = Rock::N;
platform[k][j] = Rock::R;
}
}
}
platform
}
fn tilt_west(mut platform : Vec<Vec<Rock>>) -> Vec<Vec<Rock>> {
for i in 0..platform.len() {
for j in 0..platform[i].len() {
if platform[i][j] == Rock::R {
let mut k = j;
while k >= 1 && platform[i][k - 1] == Rock::N {
k -= 1;
}
platform[i][j] = Rock::N;
platform[i][k] = Rock::R;
}
}
}
platform
}
fn tilt_south(mut platform : Vec<Vec<Rock>>) -> Vec<Vec<Rock>> {
for i in (0..platform.len()).rev() {
for j in (0..platform[i].len()).rev() {
if platform[i][j] == Rock::R {
let mut k = i;
while k + 1 < platform.len() && platform[k + 1][j] == Rock::N {
k += 1;
}
platform[i][j] = Rock::N;
platform[k][j] = Rock::R;
}
}
}
platform
}
fn tilt_east(mut platform : Vec<Vec<Rock>>) -> Vec<Vec<Rock>>{
for i in (0..platform.len()).rev() {
for j in (0..platform[i].len()).rev() {
if platform[i][j] == Rock::R {
let mut k = j;
while k + 1 < platform[i].len() && platform[i][k + 1] == Rock::N {
k += 1;
}
platform[i][j] = Rock::N;
platform[i][k] = Rock::R;
}
}
}
platform
}
fn cycle(mut platform: Vec<Vec<Rock>>) -> Vec<Vec<Rock>> {
platform = tilt_north(platform);
// println!("Tilt North:");
// print_platform(&platform);
platform = tilt_west(platform);
// println!("Tilt West:");
// print_platform(&platform);
platform = tilt_south(platform);
// println!("Tilt South:");
// print_platform(&platform);
platform = tilt_east(platform);
// println!("Tilt East:");
// print_platform(&platform);
// println!();
return platform.to_vec();
}
fn count_load(platform : &Vec<Vec<Rock>>) -> usize {
let mut count = 0;
for i in 0..platform.len() {
for j in 0..platform[i].len() {
if platform[i][j] == Rock::R {
count += platform.len() - i;
}
}
}
count
}
fn hash_platform(platform : &Vec<Vec<Rock>>) -> String {
let mut hash = String::new();
for i in 0..platform.len() {
for j in 0..platform[i].len() {
hash.push(match platform[i][j] {
Rock::N => '.',
Rock::S => '#',
Rock::R => 'O',
});
}
hash.push('\n');
}
hash
}