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 std::time::Instant;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
use std::hash::Hasher;
|
||||||
|
|
||||||
enum Direction{
|
enum Direction{
|
||||||
North,
|
North,
|
||||||
@ -12,7 +16,7 @@ pub fn execute_task01(content: &str) {
|
|||||||
let gravity_1 = solve_01(content).unwrap();
|
let gravity_1 = solve_01(content).unwrap();
|
||||||
let duration = start.elapsed();
|
let duration = start.elapsed();
|
||||||
|
|
||||||
//assert_eq!(10165598, gravity_1);
|
assert_eq!(108955, gravity_1);
|
||||||
println!("Day14 - Task01 - Duration: {duration:?} - One time gravity: {}", 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 gravity_1000000 = solve_02(content).unwrap();
|
||||||
let duration = start.elapsed();
|
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)
|
println!("Day14 - Task02 - Duration: {duration:?} - 1 Million time gravity: {}", gravity_1000000)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn solve_01(content: &str) -> anyhow::Result<usize> {
|
fn solve_01(content: &str) -> anyhow::Result<usize> {
|
||||||
let map = content
|
let mut map = content
|
||||||
.lines()
|
.lines()
|
||||||
.map(|chars| chars.chars().collect_vec())
|
.map(|chars| chars.chars().collect_vec())
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
|
|
||||||
|
move_direction(&mut map, Direction::North);
|
||||||
|
|
||||||
|
Ok(map
|
||||||
|
.iter()
|
||||||
todo!()
|
.rev()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, row)| row.iter().filter(|c| c == &&'O').count() * (i+1))
|
||||||
|
.sum())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn solve_02(content: &str) -> anyhow::Result<usize> {
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_direction(map: &Vec<Vec<char>>, direction: Direction) {
|
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 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 {
|
match direction {
|
||||||
Direction::North => {
|
Direction::North => {
|
||||||
let mut stones = vec![0; map.len()];
|
let mut stones = vec![0; map[0].len()];
|
||||||
|
|
||||||
for row in 0..map.len() {
|
for row in 0..map.len() {
|
||||||
let width = map[row].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();
|
let char = map[row][col].clone();
|
||||||
|
|
||||||
match char {
|
match char {
|
||||||
'0' => {
|
'O' => {
|
||||||
if stones[col] != row - 1 {
|
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!()
|
_ => unreachable!()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Direction::South => {}
|
|
||||||
Direction::East => {}
|
|
||||||
Direction::West => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,18 +228,18 @@ O.#..O.#.#
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_solve_02() {
|
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();
|
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 std::time::Instant;
|
||||||
use itertools::Itertools;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct Lens {
|
struct Lens {
|
||||||
@ -51,7 +49,7 @@ fn solve_02(content: &str) -> anyhow::Result<usize> {
|
|||||||
hash: hash_string(label),
|
hash: hash_string(label),
|
||||||
value: num.parse().unwrap(),
|
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
|
if let Some(item) = lable_box.iter_mut().filter(|box_lens| box_lens.label == lens.label).next() { // already exists
|
||||||
item.value = lens.value
|
item.value = lens.value
|
||||||
@ -62,7 +60,7 @@ fn solve_02(content: &str) -> anyhow::Result<usize> {
|
|||||||
} else { // is dash (-)
|
} else { // is dash (-)
|
||||||
let label = part.replace("-", "");
|
let label = part.replace("-", "");
|
||||||
let hash = hash_string(label.as_str());
|
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() {
|
for i in 0..lable_box.len() {
|
||||||
let lens = &lable_box[i];
|
let lens = &lable_box[i];
|
||||||
|
@ -61,6 +61,9 @@ fn main() {
|
|||||||
day11::execute_task01(CONTENT11);
|
day11::execute_task01(CONTENT11);
|
||||||
day11::execute_task02(CONTENT11);
|
day11::execute_task02(CONTENT11);
|
||||||
println!();
|
println!();
|
||||||
|
day14::execute_task01(CONTENT14);
|
||||||
|
day14::execute_task02(CONTENT14);
|
||||||
|
println!();
|
||||||
day15::execute_task01(CONTENT15);
|
day15::execute_task01(CONTENT15);
|
||||||
day15::execute_task02(CONTENT15);
|
day15::execute_task02(CONTENT15);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user