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,55 +64,53 @@ pub fn task1() {
|
|||||||
.collect_vec()
|
.collect_vec()
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let fin = (0..10).fold(initial, |map, _| {
|
initial
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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>) {
|
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