feat: implement day14
This commit is contained in:
parent
b8ab75d049
commit
3dc1cddf07
192
src/day14.rs
192
src/day14.rs
@ -1,5 +1,9 @@
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::hash::Hash;
|
||||
use std::time::Instant;
|
||||
use itertools::Itertools;
|
||||
use std::hash::Hasher;
|
||||
|
||||
enum Direction{
|
||||
North,
|
||||
@ -12,7 +16,7 @@ pub fn execute_task01(content: &str) {
|
||||
let gravity_1 = solve_01(content).unwrap();
|
||||
let duration = start.elapsed();
|
||||
|
||||
//assert_eq!(10165598, gravity_1);
|
||||
assert_eq!(108955, gravity_1);
|
||||
println!("Day14 - Task01 - Duration: {duration:?} - One time gravity: {}", gravity_1)
|
||||
}
|
||||
|
||||
@ -21,31 +25,81 @@ pub fn execute_task02(content: &str) {
|
||||
let gravity_1000000 = solve_02(content).unwrap();
|
||||
let duration = start.elapsed();
|
||||
|
||||
//assert_eq!(678728808158, gravity_1000000);
|
||||
assert_eq!(106689, gravity_1000000);
|
||||
println!("Day14 - Task02 - Duration: {duration:?} - 1 Million time gravity: {}", gravity_1000000)
|
||||
}
|
||||
|
||||
|
||||
fn solve_01(content: &str) -> anyhow::Result<usize> {
|
||||
let map = content
|
||||
let mut map = content
|
||||
.lines()
|
||||
.map(|chars| chars.chars().collect_vec())
|
||||
.collect_vec();
|
||||
|
||||
move_direction(&mut map, Direction::North);
|
||||
|
||||
|
||||
|
||||
todo!()
|
||||
Ok(map
|
||||
.iter()
|
||||
.rev()
|
||||
.enumerate()
|
||||
.map(|(i, row)| row.iter().filter(|c| c == &&'O').count() * (i+1))
|
||||
.sum())
|
||||
}
|
||||
|
||||
fn solve_02(content: &str) -> anyhow::Result<usize> {
|
||||
todo!()
|
||||
let mut map = content
|
||||
.lines()
|
||||
.map(|chars| chars.chars().collect_vec())
|
||||
.collect_vec();
|
||||
|
||||
let mut set: HashMap<u64, i32> = HashMap::new();
|
||||
let circles = 1_000_000_000;
|
||||
let mut from = 0;
|
||||
let mut to = 0;
|
||||
|
||||
for i in 1..=circles {
|
||||
move_direction(&mut map, Direction::North);
|
||||
move_direction(&mut map, Direction::West);
|
||||
move_direction(&mut map, Direction::South);
|
||||
move_direction(&mut map, Direction::East);
|
||||
|
||||
let hash = calculate_hash(&map);
|
||||
if let Some(step) = set.get(&hash) {
|
||||
from = step.clone();
|
||||
to = i;
|
||||
break;
|
||||
} else {
|
||||
set.insert(hash, i);
|
||||
}
|
||||
}
|
||||
|
||||
let new_start = (circles - to) / (to - from) * (to -from);
|
||||
|
||||
for i in new_start+from+1 ..=circles {
|
||||
move_direction(&mut map, Direction::North);
|
||||
move_direction(&mut map, Direction::West);
|
||||
move_direction(&mut map, Direction::South);
|
||||
move_direction(&mut map, Direction::East);
|
||||
}
|
||||
|
||||
Ok(map
|
||||
.iter()
|
||||
.rev()
|
||||
.enumerate()
|
||||
.map(|(i, row)| row.iter().filter(|c| c == &&'O').count() * (i+1))
|
||||
.sum())
|
||||
}
|
||||
|
||||
fn move_direction(map: &Vec<Vec<char>>, direction: Direction) {
|
||||
fn calculate_hash<T: Hash>(t: &T) -> u64 {
|
||||
let mut s = DefaultHasher::new();
|
||||
t.hash(&mut s);
|
||||
s.finish()
|
||||
}
|
||||
|
||||
fn move_direction(map: &mut Vec<Vec<char>>, direction: Direction) {
|
||||
match direction {
|
||||
Direction::North => {
|
||||
let mut stones = vec![0; map.len()];
|
||||
let mut stones = vec![0; map[0].len()];
|
||||
|
||||
for row in 0..map.len() {
|
||||
let width = map[row].len();
|
||||
@ -53,23 +107,103 @@ fn move_direction(map: &Vec<Vec<char>>, direction: Direction) {
|
||||
let char = map[row][col].clone();
|
||||
|
||||
match char {
|
||||
'0' => {
|
||||
if stones[col] != row - 1 {
|
||||
|
||||
'O' => {
|
||||
if row > 0 && stones[col] != row {
|
||||
map[stones[col]][col] = 'O';
|
||||
map[row][col] = '.';
|
||||
stones[col] += 1;
|
||||
} else {
|
||||
stones[col] = row +1;
|
||||
}
|
||||
},
|
||||
'#' => stones[col] = row,
|
||||
'#' => stones[col] = row + 1,
|
||||
'.' => (),
|
||||
_ => unreachable!()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Direction::South => {
|
||||
let mut stones = vec![map.len() - 1; map[0].len()];
|
||||
|
||||
for i in 0..map.len() {
|
||||
let row = map.len() -1 - i;
|
||||
let width = map[row].len();
|
||||
for col in 0..width {
|
||||
let char = map[row][col].clone();
|
||||
|
||||
match char {
|
||||
'O' => {
|
||||
if stones[col] != row {
|
||||
map[stones[col]][col] = 'O';
|
||||
map[row][col] = '.';
|
||||
stones[col] -= 1;
|
||||
} else if row > 0 {
|
||||
stones[col] = row - 1;
|
||||
}
|
||||
},
|
||||
'#' => if row > 0 { stones[col] = row - 1 },
|
||||
'.' => (),
|
||||
_ => unreachable!()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Direction::West => {
|
||||
let width = map[0].len();
|
||||
let height = map.len();
|
||||
|
||||
let mut stones = vec![0; height];
|
||||
|
||||
for col in 0..width {
|
||||
for row in 0..height {
|
||||
let char = map[row][col].clone();
|
||||
|
||||
match char {
|
||||
'O' => {
|
||||
if col > 0 && stones[row] != col {
|
||||
map[row][stones[row]] = 'O';
|
||||
map[row][col] = '.';
|
||||
stones[row] += 1;
|
||||
} else {
|
||||
stones[row] = col + 1;
|
||||
}
|
||||
},
|
||||
'#' => stones[row] = col + 1,
|
||||
'.' => (),
|
||||
_ => unreachable!()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Direction::East => {
|
||||
let width = map[0].len();
|
||||
let height = map.len();
|
||||
|
||||
let mut stones = vec![width - 1; height];
|
||||
|
||||
for i in 0..width {
|
||||
let col = width - 1 - i;
|
||||
for row in 0..height {
|
||||
let char = map[row][col].clone();
|
||||
|
||||
match char {
|
||||
'O' => {
|
||||
if stones[row] != col {
|
||||
map[row][stones[row]] = 'O';
|
||||
map[row][col] = '.';
|
||||
stones[row] -= 1;
|
||||
} else if col > 0 {
|
||||
stones[row] = col - 1;
|
||||
}
|
||||
},
|
||||
'#' => if col > 0 { stones[row] = col - 1 },
|
||||
'.' => (),
|
||||
_ => unreachable!()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Direction::South => {}
|
||||
Direction::East => {}
|
||||
Direction::West => {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,18 +228,18 @@ O.#..O.#.#
|
||||
|
||||
#[test]
|
||||
fn test_solve_02() {
|
||||
let example = r#"...#......
|
||||
.......#..
|
||||
#.........
|
||||
..........
|
||||
......#...
|
||||
.#........
|
||||
.........#
|
||||
..........
|
||||
.......#..
|
||||
#...#....."#;
|
||||
let example = r#"O....#....
|
||||
O.OO#....#
|
||||
.....##...
|
||||
OO.#O....O
|
||||
.O.....O#.
|
||||
O.#..O.#.#
|
||||
..O..#O..O
|
||||
.......O..
|
||||
#....###..
|
||||
#OO..#...."#;
|
||||
|
||||
let result = solve_02(example).unwrap();
|
||||
|
||||
assert_eq!(1030, result);
|
||||
assert_eq!(64, result);
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
use std::hash::Hash;
|
||||
use std::time::Instant;
|
||||
use itertools::Itertools;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Lens {
|
||||
@ -51,7 +49,7 @@ fn solve_02(content: &str) -> anyhow::Result<usize> {
|
||||
hash: hash_string(label),
|
||||
value: num.parse().unwrap(),
|
||||
};
|
||||
let mut lable_box = &mut boxes[lens.hash as usize];
|
||||
let lable_box = &mut boxes[lens.hash as usize];
|
||||
|
||||
if let Some(item) = lable_box.iter_mut().filter(|box_lens| box_lens.label == lens.label).next() { // already exists
|
||||
item.value = lens.value
|
||||
@ -62,7 +60,7 @@ fn solve_02(content: &str) -> anyhow::Result<usize> {
|
||||
} else { // is dash (-)
|
||||
let label = part.replace("-", "");
|
||||
let hash = hash_string(label.as_str());
|
||||
let mut lable_box= &mut boxes[hash as usize];
|
||||
let lable_box= &mut boxes[hash as usize];
|
||||
|
||||
for i in 0..lable_box.len() {
|
||||
let lens = &lable_box[i];
|
||||
|
@ -61,6 +61,9 @@ fn main() {
|
||||
day11::execute_task01(CONTENT11);
|
||||
day11::execute_task02(CONTENT11);
|
||||
println!();
|
||||
day14::execute_task01(CONTENT14);
|
||||
day14::execute_task02(CONTENT14);
|
||||
println!();
|
||||
day15::execute_task01(CONTENT15);
|
||||
day15::execute_task02(CONTENT15);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user