Day 18 part 2

This commit is contained in:
2023-05-27 01:45:15 +02:00
parent 861e31efee
commit 30ef81cfac
2 changed files with 94 additions and 48 deletions

View File

@@ -1,3 +1,3 @@
fn main() {
aoc_2018::tasks::day18::task1();
aoc_2018::tasks::day18::task2();
}

View File

@@ -5,6 +5,54 @@ use itertools::Itertools;
use crate::utils;
pub fn task1() {
let initial = load_initial_map();
let fin = (0..10).fold(initial, |map, _| next_map(map));
let (trees, lumberyards) = resource_value(fin);
println!("Part 1 - {trees} x {lumberyards} = {}", trees * lumberyards);
}
pub fn task2() {
let mut map = load_initial_map();
const MINUTES: i32 = 1000000000;
let mut maps_at_time: HashMap<String, i32> = HashMap::new();
let mut minute = 0;
while minute < MINUTES {
if let Some(time) = maps_at_time.get(&hash(&map)) {
let delta = minute - time;
let remaining_minutes = MINUTES - minute;
let remaining_cycles = remaining_minutes / delta;
minute += remaining_cycles * delta;
}
maps_at_time.insert(hash(&map), minute);
minute += 1;
map = next_map(map);
}
let (trees, lumberyards) = resource_value(map);
println!("Part 1 - {trees} x {lumberyards} = {}", trees * lumberyards);
}
fn hash(map: &HashMap<Pos, char>) -> String {
let mut result = String::new();
let (x_min, x_max) = map.keys().map(|p| p.0).minmax().into_option().unwrap();
let (_y_min, y_max) = map.keys().map(|p| p.1).minmax().into_option().unwrap();
for y in 0..=y_max {
for x in x_min..=x_max {
let s = map[&Pos(x, y)];
result.push(s);
}
}
result
}
fn resource_value(fin: HashMap<Pos, char>) -> (usize, usize) {
let trees = fin.values().filter(|c| **c == '|').count();
let lumberyards = fin.values().filter(|c| **c == '#').count();
(trees, lumberyards)
}
fn load_initial_map() -> HashMap<Pos, char> {
let input = utils::read_file("input/day18.txt");
let initial: HashMap<Pos, char> = input
.lines()
@@ -16,55 +64,53 @@ pub fn task1() {
.collect_vec()
})
.collect();
let fin = (0..10).fold(initial, |map, _| {
printmap(&map);
map.keys()
.map(|p| {
let old = map[p];
let new = match old {
'.' => {
if neighbors(&map, *p)
.into_iter()
.filter(|c| *c == '|')
.count()
>= 3
{
'|'
} else {
'.'
}
}
'|' => {
if neighbors(&map, *p)
.into_iter()
.filter(|c| *c == '#')
.count()
>= 3
{
'#'
} else {
'|'
}
}
'#' => {
if neighbors(&map, *p).contains(&'#') && neighbors(&map, *p).contains(&'|')
{
'#'
} else {
'.'
}
}
_ => panic!("unknown type"),
};
(*p, new)
})
.collect()
});
let trees = fin.values().filter(|c| **c == '|').count();
let lumberyards = fin.values().filter(|c| **c == '#').count();
println!("Part 1 - {trees} x {lumberyards} = {}", trees * lumberyards);
initial
}
fn next_map(map: HashMap<Pos, char>) -> HashMap<Pos, char> {
map.keys()
.map(|p| {
let old = map[p];
let new = match old {
'.' => {
if neighbors(&map, *p)
.into_iter()
.filter(|c| *c == '|')
.count()
>= 3
{
'|'
} else {
'.'
}
}
'|' => {
if neighbors(&map, *p)
.into_iter()
.filter(|c| *c == '#')
.count()
>= 3
{
'#'
} else {
'|'
}
}
'#' => {
if neighbors(&map, *p).contains(&'#') && neighbors(&map, *p).contains(&'|') {
'#'
} else {
'.'
}
}
_ => panic!("unknown type"),
};
(*p, new)
})
.collect()
}
#[allow(dead_code)]
fn printmap(map: &HashMap<Pos, char>) {
println!();
let (x_min, x_max) = map.keys().map(|p| p.0).minmax().into_option().unwrap();