Day 18 part 2
This commit is contained in:
@@ -1,3 +1,3 @@
|
|||||||
fn main() {
|
fn main() {
|
||||||
aoc_2018::tasks::day18::task1();
|
aoc_2018::tasks::day18::task2();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,54 @@ use itertools::Itertools;
|
|||||||
use crate::utils;
|
use crate::utils;
|
||||||
|
|
||||||
pub fn task1() {
|
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 input = utils::read_file("input/day18.txt");
|
||||||
let initial: HashMap<Pos, char> = input
|
let initial: HashMap<Pos, char> = input
|
||||||
.lines()
|
.lines()
|
||||||
@@ -16,8 +64,10 @@ pub fn task1() {
|
|||||||
.collect_vec()
|
.collect_vec()
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let fin = (0..10).fold(initial, |map, _| {
|
initial
|
||||||
printmap(&map);
|
}
|
||||||
|
|
||||||
|
fn next_map(map: HashMap<Pos, char>) -> HashMap<Pos, char> {
|
||||||
map.keys()
|
map.keys()
|
||||||
.map(|p| {
|
.map(|p| {
|
||||||
let old = map[p];
|
let old = map[p];
|
||||||
@@ -47,8 +97,7 @@ pub fn task1() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
'#' => {
|
'#' => {
|
||||||
if neighbors(&map, *p).contains(&'#') && neighbors(&map, *p).contains(&'|')
|
if neighbors(&map, *p).contains(&'#') && neighbors(&map, *p).contains(&'|') {
|
||||||
{
|
|
||||||
'#'
|
'#'
|
||||||
} else {
|
} else {
|
||||||
'.'
|
'.'
|
||||||
@@ -59,12 +108,9 @@ pub fn task1() {
|
|||||||
(*p, new)
|
(*p, new)
|
||||||
})
|
})
|
||||||
.collect()
|
.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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
fn printmap(map: &HashMap<Pos, char>) {
|
fn printmap(map: &HashMap<Pos, char>) {
|
||||||
println!();
|
println!();
|
||||||
let (x_min, x_max) = map.keys().map(|p| p.0).minmax().into_option().unwrap();
|
let (x_min, x_max) = map.keys().map(|p| p.0).minmax().into_option().unwrap();
|
||||||
|
|||||||
Reference in New Issue
Block a user