From 7a274baf624577fb8410ad90aff9ec3c46a96200 Mon Sep 17 00:00:00 2001 From: LongHairedHacker Date: Sun, 20 Dec 2020 20:13:12 +0100 Subject: [PATCH] Finished day 20 --- src/bin/day20.rs | 172 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 148 insertions(+), 24 deletions(-) diff --git a/src/bin/day20.rs b/src/bin/day20.rs index cca2a41..a84d9a2 100644 --- a/src/bin/day20.rs +++ b/src/bin/day20.rs @@ -10,11 +10,64 @@ struct Tile { pixels: Vec>, } +fn rotate_90(img: &Vec>) -> Vec> { + let mut rot_img: Vec> = Vec::new(); + for rot_y in 0..img[0].len() { + let mut rot_line = Vec::new(); + for rot_x in 0..img.len() { + rot_line.push(img[img.len() - rot_x - 1][rot_y]) + } + rot_img.push(rot_line); + } + + rot_img +} + +fn flip_hor(img: &Vec>) -> Vec> { + img.iter().cloned().rev().collect() +} + +fn count_monsters(img: &Vec>, monster: &Vec>) -> usize { + let mut count = 0usize; + + let img_w = img[0].len(); + let img_h = img.len(); + //println!("Img: {} {}", img_w, img_h); + + let monster_w = monster[0].len(); + let monster_h = monster.len(); + //println!("Monster: {} {}", monster_w, monster_h); + + for base_x in 0..img_w { + for base_y in 0..img_h { + let mut is_monster = true; + for x in 0..monster_w { + for y in 0..monster_h { + if base_x + x >= img_w || base_y + y >= img_h { + is_monster = false; + break; + } + + if !img[base_y + y][base_x + x] && monster[y][x] { + is_monster = false; + break; + } + } + } + if is_monster { + count += 1; + } + } + } + + count +} + impl Tile { fn flip_hor(&self) -> Tile { Tile { id: self.id, - pixels: self.pixels.iter().cloned().rev().collect(), + pixels: flip_hor(&self.pixels), } } @@ -30,19 +83,9 @@ impl Tile { } fn rotate_90(&self) -> Tile { - let len = self.pixels.len(); - let mut rot_pixels = Vec::new(); - for rot_y in 0..len { - let mut rot_line = Vec::new(); - for rot_x in 0..len { - rot_line.push(self.pixels[len - rot_x - 1][rot_y]) - } - rot_pixels.push(rot_line); - } - Tile { id: self.id, - pixels: rot_pixels, + pixels: rotate_90(&self.pixels), } } @@ -192,6 +235,38 @@ fn complete_puzzle( return None; } +fn count_pixels(img: &Vec>) -> usize { + img.iter() + .map(|l| { + l.iter() + .map(|p| if *p { 1 } else { 0 }) + .fold(0, |x, y| x + y) + }) + .fold(0, |x, y| x + y) +} + +fn get_puzzle_size(puzzle: &Vec>) -> (usize, usize) { + let tile_w = puzzle[0][0].pixels[0].len() - 2; + let tile_h = puzzle[0][0].pixels.len() - 2; + let puzzle_w = puzzle[0].len(); + let puzzle_h = puzzle.len(); + + (puzzle_w * tile_w, puzzle_h * tile_h) +} + +fn get_puzzle_pixel(x: usize, y: usize, puzzle: &Vec>) -> bool { + let tile_w = puzzle[0][0].pixels[0].len() - 2; + let tile_h = puzzle[0][0].pixels.len() - 2; + + let puzzle_x = x / tile_w; + let tile_x = x % tile_w; + + let puzzle_y = y / tile_h; + let tile_y = y % tile_h; + + puzzle[puzzle_y][puzzle_x].pixels[tile_y + 1][tile_x + 1] +} + fn main() -> Result<(), Box> { let file = File::open("inputs/day20.txt")?; let mut lines = io::BufReader::new(file).lines().map(|l| l.unwrap()); @@ -230,20 +305,69 @@ fn main() -> Result<(), Box> { let len = (tiles.len() as f64).sqrt() as usize; println!("Images is {} x {} tiles", len, len); - if let Some(p) = complete_puzzle(Vec::new(), &tiles, 0, 0, len) { - println!("Found a solution"); - for y in 0..len { - let line = p[y] - .iter() - .map(|t| t.id.to_string()) - .fold(String::new(), |x, acc| acc + " " + &x); - println!("{}", line); + let p = complete_puzzle(Vec::new(), &tiles, 0, 0, len).expect("No soltuion found."); + println!("Found a solution"); + for y in 0..len { + let line = p[y] + .iter() + .map(|t| t.id.to_string()) + .fold(String::new(), |x, acc| acc + " " + &x); + println!("{}", line); + } + + let answer = p[0][0].id * p[0][len - 1].id * p[len - 1][0].id * p[len - 1][len - 1].id; + println!("Answer1: {}", answer); + + // + // Part 2 + // + + let (p_w, p_h) = get_puzzle_size(&p); + println!("Image size: {} x {}", p_w, p_h); + let mut img = Vec::new(); + for y in 0..p_h { + let mut line = Vec::new(); + for x in 0..p_w { + line.push(get_puzzle_pixel(x, y, &p)); + } + img.push(line); + } + + let monster_str = " # \n# ## ## ###\n # # # # # # \n"; + println!("{}", monster_str); + + let monster_img: Vec> = monster_str + .lines() + .map(|l| l.chars().map(|c| c == '#').collect()) + .collect(); + + let monster_pixels_count = count_pixels(&monster_img); + println!("Monster-Pixels: {}", monster_pixels_count); + + let img_pixel_count = count_pixels(&img); + + let mut next_img = img; + for _ in 0..4 { + let monsters = count_monsters(&next_img, &monster_img); + if monsters > 0 { + println!("Monsters: {}", monsters); + println!( + "Roughness: {}", + img_pixel_count - monsters * monster_pixels_count + ); } - let answer = p[0][0].id * p[0][len - 1].id * p[len - 1][0].id * p[len - 1][len - 1].id; - println!("Answer: {}", answer); - } else { - println!("Sorry nope"); + let flipped = flip_hor(&next_img); + let monsters = count_monsters(&flipped, &monster_img); + if monsters > 0 { + println!("Monsters: {}", monsters); + println!( + "Roughness: {}", + img_pixel_count - monsters * monster_pixels_count + ); + } + + next_img = rotate_90(&next_img); } Ok(())