2023-14: Implement part two
This commit is contained in:
parent
ae9f6e1829
commit
186f9802b7
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue