Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::env;
- use std::io::{self};
- use std::collections::HashMap;
- type Point = (isize,isize);
- fn pixel_from(ch: char) -> bool {
- match ch {
- '#' => true,
- '.' => false,
- _ => unreachable!(),
- }
- }
- fn enhancement_index(pt: &Point, map: &HashMap<Point,bool>, canvas: bool) -> usize {
- let square_indices = vec![
- (pt.0-1,pt.1-1),
- (pt.0+0,pt.1-1),
- (pt.0+1,pt.1-1),
- (pt.0-1,pt.1+0),
- (pt.0+0,pt.1+0),
- (pt.0+1,pt.1+0),
- (pt.0-1,pt.1+1),
- (pt.0+0,pt.1+1),
- (pt.0+1,pt.1+1),
- ];
- let mut index = String::new();
- for square in square_indices {
- match map.get(&square) {
- Some(true) => index.push_str("1"),
- Some(false) => index.push_str("0"),
- _ => {
- match canvas {
- true => index.push_str("0"),
- false => index.push_str("1"),
- }
- }
- }
- }
- usize::from_str_radix(&index,2).unwrap()
- }
- fn map_extents(map: &HashMap<Point,bool>) -> (isize,isize,isize,isize) {
- let xmin = &map.keys().map(|&pt| pt.0).min().unwrap();
- let ymin = &map.keys().map(|&pt| pt.1).min().unwrap();
- let xmax = &map.keys().map(|&pt| pt.0).max().unwrap();
- let ymax = &map.keys().map(|&pt| pt.1).max().unwrap();
- (*xmin,*ymin,*xmax,*ymax)
- }
- fn solve(input: &str) -> io::Result<()> {
- // Input
- let input_str = std::fs::read_to_string(input).unwrap();
- let input_str = input_str.trim();
- let input: Vec<_> = input_str.split("\n\n").collect();
- // Build algorithm
- let algorithm: HashMap<usize,bool> =
- input[0]
- .chars()
- .enumerate()
- .map(|(i,ch)| (i,pixel_from(ch)))
- .collect();
- // Build initial image
- let mut image: HashMap<Point,bool> = HashMap::new();
- for (y,line) in input[1].split("\n").enumerate() {
- for (x,ch) in line.chars().enumerate() {
- let (x,y) = (x.try_into().unwrap(),y.try_into().unwrap());
- image.insert((x,y),pixel_from(ch));
- }
- }
- // Apply algorithm
- let mut part1 = 0;
- for step in 0..50 {
- let image_before = image.clone();
- let (xmin,ymin,xmax,ymax) = map_extents(&image_before);
- let canvas = step % 2 == 0;
- for y in (ymin-1)..=(ymax+1) {
- for x in (xmin-1)..=(xmax+1) {
- let new_px = algorithm[&enhancement_index(&(x,y),&image_before,canvas)];
- image.insert((x,y),new_px);
- }
- }
- if step == 2 { part1 = image.iter().filter(|&(_,v)| *v).count(); }
- }
- println!("Part 1: {}", part1); // 5395
- let part2 = image.iter().filter(|&(_,v)| *v).count();
- println!("Part 2: {}", part2); // 17584
- Ok(())
- }
- fn main() {
- let args: Vec<String> = env::args().collect();
- let filename = &args[1];
- solve(&filename).unwrap();
- }
Advertisement
Add Comment
Please, Sign In to add comment