From cfd9b4f2ad1a09bedf7f764f84448a61faab54a3 Mon Sep 17 00:00:00 2001 From: Justin Wernick Date: Tue, 19 Apr 2022 20:26:02 +0200 Subject: Refile for merging repos --- 2018/src/bin/day_18.rs | 123 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 2018/src/bin/day_18.rs (limited to '2018/src/bin/day_18.rs') diff --git a/2018/src/bin/day_18.rs b/2018/src/bin/day_18.rs new file mode 100644 index 0000000..3908ea7 --- /dev/null +++ b/2018/src/bin/day_18.rs @@ -0,0 +1,123 @@ +extern crate advent_of_code_2018; +use advent_of_code_2018::*; + +extern crate arrayvec; +use arrayvec::ArrayVec; + +use std::error::Error; +use std::path::PathBuf; + +use std::collections::HashMap; + +// cargo watch -cs "cargo run --release --bin day_18" + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +enum State { + Open, + Trees, + Lumber +} + +fn main() -> Result<(), Box> { + let input = read_file(&PathBuf::from("inputs/18.txt"))?; + +// println!("Input: {:?}", input); + + let map = input.iter().map(|line| { + line.chars().map(|c| match c { + '.' => State::Open, + '|' => State::Trees, + '#' => State::Lumber, + _ => panic!("Unknown character {}", c) + }).collect::>() + }).collect::>(); +// debug!(map); + + let after_10 = simulate(&map, 10); + let trees_count_10: usize = after_10.iter().map(|row| row.iter().filter(|&&x| x == State::Trees).count()).sum(); + let lumber_count_10: usize = after_10.iter().map(|row| row.iter().filter(|&&x| x == State::Lumber).count()).sum(); + debug!(trees_count_10); + debug!(lumber_count_10); + debug!(trees_count_10 * lumber_count_10); + + let after_many = simulate(&map, 1000000000); + let trees_count_many: usize = after_many.iter().map(|row| row.iter().filter(|&&x| x == State::Trees).count()).sum(); + let lumber_count_many: usize = after_many.iter().map(|row| row.iter().filter(|&&x| x == State::Lumber).count()).sum(); + debug!(trees_count_many); + debug!(lumber_count_many); + debug!(trees_count_many * lumber_count_many); + + + Ok(()) +} + + +fn simulate(start_map: &Vec>, duration: u32) -> Vec> { + let mut previous_maps = HashMap::new(); + + let mut map = start_map.clone(); + + let mut t = 0; + while t < duration { + let map0 = map.clone(); + for y in 0..map.len() { + for x in 0..map[y].len() { + let adjacent = [ + (x.wrapping_sub(1), y.wrapping_sub(1)), + (x, y.wrapping_sub(1)), + (x+1, y.wrapping_sub(1)), + (x.wrapping_sub(1), y), + (x+1, y), + (x.wrapping_sub(1), y+1), + (x, y+1), + (x+1, y+1) + ].iter().map(|&(other_x,other_y)| { + if other_y >= map0.len() || other_x >= map0[other_y].len() { + State::Open + } else { + map0[other_y][other_x] + } + }).collect::>(); + + let adjacent_trees = adjacent.iter().filter(|&&x| x == State::Trees).count(); + let adjacent_lumber = adjacent.iter().filter(|&&x| x == State::Lumber).count(); + + map[y][x] = match (map0[y][x], adjacent_trees, adjacent_lumber) { + (State::Open, trees, _) if trees >= 3 => State::Trees, + (State::Open, _, _) => State::Open, + (State::Trees, _, lumber) if lumber >= 3 => State::Lumber, + (State::Trees, _, _) => State::Trees, + (State::Lumber, trees, lumber) if trees >= 1 && lumber >= 1 => State::Lumber, + (State::Lumber, _, _) => State::Open + } + } + } + + t += match previous_maps.get(&map) { + Some(previous_t) => { + let period = t + 1 - previous_t; + let whole_periods = (duration - t - 1) / period; + (period * whole_periods) + 1 + }, + None => 1 + }; + previous_maps.insert(map.clone(), t); + } + + map +} + +fn debug_print(map: &Vec>) { + for row in map { + for c in row { + print!("{}", match c { + State::Open => '.', + State::Trees => '|', + State::Lumber => '#' + }); + } + println!(); + } + println!(); + println!(); +} -- cgit v1.2.3