diff --git a/2020/day20_jurassic_jigsaw/Cargo.toml b/2020/day20_jurassic_jigsaw/Cargo.toml new file mode 100644 index 0000000..efef167 --- /dev/null +++ b/2020/day20_jurassic_jigsaw/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "day20_jurassic_jigsaw" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/2020/day20_jurassic_jigsaw/challenge.txt b/2020/day20_jurassic_jigsaw/challenge.txt new file mode 100644 index 0000000..958c559 --- /dev/null +++ b/2020/day20_jurassic_jigsaw/challenge.txt @@ -0,0 +1,295 @@ +The high-speed train leaves the forest and quickly carries you south. You can even see a desert in the distance! Since you have some spare time, you might as well see if there was anything interesting in the image the Mythical Information Bureau satellite captured. + +After decoding the satellite messages, you discover that the data actually contains many small images created by the satellite's *camera array*. The camera array consists of many cameras; rather than produce a single square image, they produce many smaller square image *tiles* that need to be *reassembled back into a single image*. + +Each camera in the camera array returns a single monochrome *image tile* with a random unique *ID number*. The tiles (your puzzle input) arrived in a random order. + +Worse yet, the camera array appears to be malfunctioning: each image tile has been *rotated and flipped to a random orientation*. Your first task is to reassemble the original image by orienting the tiles so they fit together. + +To show how the tiles should be reassembled, each tile's image data includes a border that should line up exactly with its adjacent tiles. All tiles have this border, and the border lines up exactly when the tiles are both oriented correctly. Tiles at the edge of the image also have this border, but the outermost edges won't line up with any other tiles. + +For example, suppose you have the following nine tiles: + +``` +Tile 2311: +..##.#..#. +##..#..... +#...##..#. +####.#...# +##.##.###. +##...#.### +.#.#.#..## +..#....#.. +###...#.#. +..###..### + +Tile 1951: +#.##...##. +#.####...# +.....#..## +#...###### +.##.#....# +.###.##### +###.##.##. +.###....#. +..#.#..#.# +#...##.#.. + +Tile 1171: +####...##. +#..##.#..# +##.#..#.#. +.###.####. +..###.#### +.##....##. +.#...####. +#.##.####. +####..#... +.....##... + +Tile 1427: +###.##.#.. +.#..#.##.. +.#.##.#..# +#.#.#.##.# +....#...## +...##..##. +...#.##### +.#.####.#. +..#..###.# +..##.#..#. + +Tile 1489: +##.#.#.... +..##...#.. +.##..##... +..#...#... +#####...#. +#..#.#.#.# +...#.#.#.. +##.#...##. +..##.##.## +###.##.#.. + +Tile 2473: +#....####. +#..#.##... +#.##..#... +######.#.# +.#...#.#.# +.######### +.###.#..#. +########.# +##...##.#. +..###.#.#. + +Tile 2971: +..#.#....# +#...###... +#.#.###... +##.##..#.. +.#####..## +.#..####.# +#..#.#..#. +..####.### +..#.#.###. +...#.#.#.# + +Tile 2729: +...#.#.#.# +####.#.... +..#.#..... +....#..#.# +.##..##.#. +.#.####... +####.#.#.. +##.####... +##..#.##.. +#.##...##. + +Tile 3079: +#.#.#####. +.#..###### +..#....... +######.... +####.#..#. +.#...#.##. +#.#####.## +..#.###... +..#....... +..#.###... + +``` + +By rotating, flipping, and rearranging them, you can find a square arrangement that causes all adjacent borders to line up: + +``` +#...##.#.. ..###..### #.#.#####. +..#.#..#.# ###...#.#. .#..###### +.###....#. ..#....#.. ..#....... +###.##.##. .#.#.#..## ######.... +.###.##### ##...#.### ####.#..#. +.##.#....# ##.##.###. .#...#.##. +#...###### ####.#...# #.#####.## +.....#..## #...##..#. ..#.###... +#.####...# ##..#..... ..#....... +#.##...##. ..##.#..#. ..#.###... + +#.##...##. ..##.#..#. ..#.###... +##..#.##.. ..#..###.# ##.##....# +##.####... .#.####.#. ..#.###..# +####.#.#.. ...#.##### ###.#..### +.#.####... ...##..##. .######.## +.##..##.#. ....#...## #.#.#.#... +....#..#.# #.#.#.##.# #.###.###. +..#.#..... .#.##.#..# #.###.##.. +####.#.... .#..#.##.. .######... +...#.#.#.# ###.##.#.. .##...#### + +...#.#.#.# ###.##.#.. .##...#### +..#.#.###. ..##.##.## #..#.##..# +..####.### ##.#...##. .#.#..#.## +#..#.#..#. ...#.#.#.. .####.###. +.#..####.# #..#.#.#.# ####.###.. +.#####..## #####...#. .##....##. +##.##..#.. ..#...#... .####...#. +#.#.###... .##..##... .####.##.# +#...###... ..##...#.. ...#..#### +..#.#....# ##.#.#.... ...##..... + +``` + +For reference, the IDs of the above tiles are: + +``` +1951 2311 3079 +2729 1427 2473 +2971 1489 1171 + +``` + +To check that you've assembled the image correctly, multiply the IDs of the four corner tiles together. If you do this with the assembled tiles from the example above, you get `1951 * 3079 * 2971 * 1171` = *`20899048083289`*. + +Assemble the tiles into an image. *What do you get if you multiply together the IDs of the four corner tiles?* + +Your puzzle answer was `7901522557967`. + +\--- Part Two --- +---------- + +Now, you're ready to *check the image for sea monsters*. + +The borders of each tile are not part of the actual image; start by removing them. + +In the example above, the tiles become: + +``` +.#.#..#. ##...#.# #..##### +###....# .#....#. .#...... +##.##.## #.#.#..# #####... +###.#### #...#.## ###.#..# +##.#.... #.##.### #...#.## +...##### ###.#... .#####.# +....#..# ...##..# .#.###.. +.####... #..#.... .#...... + +#..#.##. .#..###. #.##.... +#.####.. #.####.# .#.###.. +###.#.#. ..#.#### ##.#..## +#.####.. ..##..## ######.# +##..##.# ...#...# .#.#.#.. +...#..#. .#.#.##. .###.### +.#.#.... #.##.#.. .###.##. +###.#... #..#.##. ######.. + +.#.#.### .##.##.# ..#.##.. +.####.## #.#...## #.#..#.# +..#.#..# ..#.#.#. ####.### +#..####. ..#.#.#. ###.###. +#####..# ####...# ##....## +#.##..#. .#...#.. ####...# +.#.###.. ##..##.. ####.##. +...###.. .##...#. ..#..### + +``` + +Remove the gaps to form the actual image: + +``` +.#.#..#.##...#.##..##### +###....#.#....#..#...... +##.##.###.#.#..######... +###.#####...#.#####.#..# +##.#....#.##.####...#.## +...########.#....#####.# +....#..#...##..#.#.###.. +.####...#..#.....#...... +#..#.##..#..###.#.##.... +#.####..#.####.#.#.###.. +###.#.#...#.######.#..## +#.####....##..########.# +##..##.#...#...#.#.#.#.. +...#..#..#.#.##..###.### +.#.#....#.##.#...###.##. +###.#...#..#.##.######.. +.#.#.###.##.##.#..#.##.. +.####.###.#...###.#..#.# +..#.#..#..#.#.#.####.### +#..####...#.#.#.###.###. +#####..#####...###....## +#.##..#..#...#..####...# +.#.###..##..##..####.##. +...###...##...#...#..### + +``` + +Now, you're ready to search for sea monsters! Because your image is monochrome, a sea monster will look like this: + +``` + # +# ## ## ### + # # # # # # + +``` + +When looking for this pattern in the image, *the spaces can be anything*; only the `#` need to match. Also, you might need to rotate or flip your image before it's oriented correctly to find sea monsters. In the above image, *after flipping and rotating it* to the appropriate orientation, there are *two* sea monsters (marked with `*O*`): + +``` +.####...#####..#...###.. +#####..#..#.#.####..#.#. +.#.#...#.###...#.##.O#.. +#.O.##.OO#.#.OO.##.OOO## +..#O.#O#.O##O..O.#O##.## +...#.#..##.##...#..#..## +#.##.#..#.#..#..##.#.#.. +.###.##.....#...###.#... +#.####.#.#....##.#..#.#. +##...#..#....#..#...#### +..#.##...###..#.#####..# +....#.##.#.#####....#... +..##.##.###.....#.##..#. +#...#...###..####....##. +.#.##...#.##.#.#.###...# +#.###.#..####...##..#... +#.###...#.##...#.##O###. +.O##.#OO.###OO##..OOO##. +..O#.O..O..O.#O##O##.### +#.#..##.########..#..##. +#.#####..#.#...##..#.... +#....##..#.#########..## +#...#.....#..##...###.## +#..###....##.#...##.##.# + +``` + +Determine how rough the waters are in the sea monsters' habitat by counting the number of `#` that are *not* part of a sea monster. In the above example, the habitat's water roughness is *`273`*. + +*How many `#` are not part of a sea monster?* + +Your puzzle answer was `2476`. + +Both parts of this puzzle are complete! They provide two gold stars: \*\* + +At this point, you should [return to your Advent calendar](/2020) and try another puzzle. + +If you still want to see it, you can [get your puzzle input](20/input). \ No newline at end of file diff --git a/2020/day20_jurassic_jigsaw/src/lib.rs b/2020/day20_jurassic_jigsaw/src/lib.rs new file mode 100644 index 0000000..3e802e0 --- /dev/null +++ b/2020/day20_jurassic_jigsaw/src/lib.rs @@ -0,0 +1,249 @@ +use core::fmt::Display; +use std::{num::ParseIntError, collections::BTreeSet}; + +#[derive(Debug, PartialEq, Eq)] +pub enum ParseError { + ImageCorrupted(String), + ParseIntError(std::num::ParseIntError), + LineMalformed(String), +} + +impl From for ParseError { + fn from(value: ParseIntError) -> Self { + Self::ParseIntError(value) + } +} + +impl Display for ParseError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::ImageCorrupted(s) => write!(f, "Image data seem to be corrupted: {s}"), + Self::ParseIntError(e) => write!(f, "Unable to parse into integer: {e}"), + Self::LineMalformed(v) => write!(f, "Line is malformed: {v}"), + } + } +} + +const SIDE_LENGTH: usize = 10; +const MONSTER_PATTERN: &str = +" # +# ## ## ### + # # # # # # "; +const MONSTER_SIZE: usize = 15; + +#[derive(Clone)] +struct Tile { + id: usize, + pixels: [[bool; SIDE_LENGTH]; SIDE_LENGTH], + neighbours: [Option; 4], +} + +impl TryFrom<&str> for Tile { + type Error = ParseError; + + fn try_from(value: &str) -> Result { + let lines: Vec<_> = value.lines().collect(); + if lines.len() != 11 { + return Err(Self::Error::ImageCorrupted(format!("Image contains {} lines instead of 11.", lines.len()))); + } + if let Some(id_str) = lines[0].split_whitespace().last() { + let id = id_str[..id_str.len()-1].parse()?; + let mut pixels = [[false; SIDE_LENGTH]; SIDE_LENGTH]; + + for (y, line) in lines.iter().skip(1).enumerate() { + if line.len() != SIDE_LENGTH { + return Err(Self::Error::LineMalformed(line.to_string())); + } + for (x, c) in line.chars().enumerate() { + match c { + '.' => (), + '#' => pixels[y][x] = true, + _ => return Err(Self::Error::LineMalformed(line.to_string())), + } + } + } + let neighbours = [None; 4]; + Ok(Self { id, pixels, neighbours}) + } else { + Err(Self::Error::LineMalformed(lines[0].to_string())) + } + } +} + +impl Tile { + fn flip_horizontally(&mut self) { + let old_pixels = self.pixels.clone(); + self.pixels.iter_mut().enumerate().for_each(|(y, row)| row.iter_mut().enumerate().for_each(|(x, p)| *p = old_pixels[y][SIDE_LENGTH-x-1])); + } + + fn rotate_left(&mut self) { + let old_pixels = self.pixels.clone(); + self.pixels.iter_mut().enumerate().for_each(|(y, row)| row.iter_mut().enumerate().for_each(|(x, p)| *p = old_pixels[x][SIDE_LENGTH-y-1])); + } + + fn rotate_180(&mut self) { + let old_pixels = self.pixels.clone(); + self.pixels.iter_mut().enumerate().for_each(|(y, row)| row.iter_mut().enumerate().for_each(|(x, p)| *p = old_pixels[SIDE_LENGTH-y-1][SIDE_LENGTH-x-1])); + } + + fn borders(&self) -> [[bool; SIDE_LENGTH]; 4] { + let mut copied = self.clone(); + copied.rotate_left(); + [ + self.pixels[0], // top + copied.pixels[SIDE_LENGTH-1], // left + self.pixels[SIDE_LENGTH-1], // bottom + copied.pixels[0], // right + ] + } + + fn neighbours_count(&self) -> usize { + self.neighbours.iter().filter(|neighbour| neighbour.is_some()).count() + } +} + +pub fn run(input: &str) -> Result<(usize, usize), ParseError> { + let mut tiles: Vec<_> = input.split("\n\n").map(Tile::try_from).collect::, _>>()?; + find_neighbours(&mut tiles); + + let first = tiles.iter().filter(|tile| tile.neighbours_count() == 2).map(|tile| tile.id).product(); + + let image = assemble(&tiles); + let monsters = count_monsters(&image); + + let second = image.iter().map(|row| row.iter().filter(|b| **b).count()).sum::() - monsters * MONSTER_SIZE; + Ok((first, second)) +} + +fn find_neighbours(tiles: &mut [Tile]) { + let mut open_set = BTreeSet::from([0]); + let mut todo: Vec<_> = (0..tiles.len()).collect(); + while let Some(target_idx) = open_set.pop_first() { + todo.remove(todo.iter().position(|t| *t == target_idx).unwrap()); + let mut target = tiles[target_idx].clone(); + let target_borders = target.borders(); + + todo.iter().for_each(|other_idx| { + let mut other = &mut tiles[*other_idx]; + for _ in 0..4 { + for (side, other_border) in other.borders().into_iter().enumerate() { + let mut rev = other_border; + rev.reverse(); + if target_borders[(side+2)%4] == other_border { + other.neighbours[side] = Some(target_idx); + target.neighbours[(side+2)%4] = Some(*other_idx); + open_set.insert(*other_idx); + return; + } else if target_borders[(side+2)%4] == rev { + other.flip_horizontally(); + if side % 2 == 1 { + other.rotate_180(); + } + open_set.insert(*other_idx); + other.neighbours[side] = Some(target_idx); + target.neighbours[(side+2)%4] = Some(*other_idx); + return; + } + } + other.rotate_left(); + } + }); + tiles[target_idx] = target; + } +} + +fn assemble(tiles: &[Tile]) -> Vec> { + let offset_factor = SIDE_LENGTH-2; + let first_idx = tiles.iter().position(|t| t.neighbours[0].is_none() && t.neighbours[1].is_none()).unwrap(); + + let mut tile_ids = vec![vec![first_idx]]; + let mut current_idx = first_idx; + while let Some(next) = tiles[current_idx].neighbours[2] { + tile_ids.push(vec![next]); + current_idx = next; + } + + for row in tile_ids.iter_mut() { + current_idx = row[0]; + while let Some(next) = tiles[current_idx].neighbours[3] { + row.push(next); + current_idx = next; + } + + } + + let mut res = vec![vec![false; offset_factor*tile_ids[0].len()]; offset_factor*tile_ids.len()]; + + tile_ids.iter().enumerate().for_each(|(tile_y, tile_row)| { + tile_row.iter().enumerate().for_each(|(tile_x, tile_idx)| { + tiles[*tile_idx].pixels.iter().skip(1).take(offset_factor).enumerate().for_each(|(y, row)| { + row.iter().skip(1).take(offset_factor).enumerate().for_each(|(x, b)| { + if *b { + res[tile_y*offset_factor+y][tile_x*offset_factor+x] = true; + } + }); + }); + }); + }); + res +} + +fn count_monsters(image: &[Vec]) -> usize { + let mut monster: Vec> = MONSTER_PATTERN.lines().map(|l| l.chars().map(|c| c == '#').collect::>()).collect(); + let mut monsters = Vec::new(); + for _ in 0..4 { + let old_width = monster[0].len(); + + let mut flipped_monster = monster.clone(); + flipped_monster.iter_mut().enumerate().for_each(|(y, row)| row.iter_mut().enumerate().for_each(|(x, p)| *p = monster[y][old_width-x-1])); + monsters.push(flipped_monster); + + let mut rotated_monster = vec![vec![false; monster.len()]; old_width]; + rotated_monster.iter_mut().enumerate().for_each(|(y, row)| row.iter_mut().enumerate().for_each(|(x, p)| *p = monster[x][old_width-y-1])); + monsters.push(rotated_monster.clone()); + std::mem::swap(&mut monster, &mut rotated_monster); + } + + let mut monster_count = 0; + + for monster in monsters { + let height = monster.len(); + let width = monster[0].len(); + for y_offset in 0..(image.len()-height) { + 'pos: for x_offset in 0..(image[0].len()-width) { + for (row_idx, row) in image.iter().skip(y_offset).take(height).enumerate() { + for (col_idx, pix) in row.iter().skip(x_offset).take(width).enumerate() { + if monster[row_idx][col_idx] && !pix { + continue 'pos; + } + } + } + monster_count += 1; + } + } + } + + monster_count +} + +#[cfg(test)] +mod tests { + use super::*; + use std::fs::read_to_string; + + fn read_file(name: &str) -> String { + read_to_string(name).expect(&format!("Unable to read file: {name}")[..]).trim().to_string() + } + + #[test] + fn test_sample() { + let sample_input = read_file("tests/sample_input"); + assert_eq!(run(&sample_input), Ok((20899048083289, 273))); + } + + #[test] + fn test_challenge() { + let challenge_input = read_file("tests/challenge_input"); + assert_eq!(run(&challenge_input), Ok((7901522557967, 2476))); + } +} diff --git a/2020/day20_jurassic_jigsaw/tests/challenge_input b/2020/day20_jurassic_jigsaw/tests/challenge_input new file mode 100644 index 0000000..f0ed580 --- /dev/null +++ b/2020/day20_jurassic_jigsaw/tests/challenge_input @@ -0,0 +1,1728 @@ +Tile 2957: +#..##.#.#. +...#...... +.#....#... +....#.#... +#.......#. +#........# +.....#..#. +.....##.## +#......#.. +###...#### + +Tile 3499: +#.#.#..### +##.#...#.# +..###...## +...##...#. +...##..### +####..#... +#.#...#..# +##....#... +#..#...#.. +.####.###. + +Tile 3583: +.#######.# +.....##... +#........# +####..#.#. +..#...#... +.#.##..#.. +.#.#..###. +.........# +...#...#.# +.#.#.##.#. + +Tile 2309: +.######... +.#..#....# +#...##.... +#.#....##. +....#....# +.##...##.# +###....... +###..#...# +#...#.#.## +.##.###..# + +Tile 1297: +#..#.####. +.#.#....## +..#....#.# +........## +.#....##.# +....#..#.# +.#...#...# +.....#.#.# +#...###... +##..#.#### + +Tile 3779: +#...#..##. +.....###.# +#.##..##.. +.####...#. +#.....#... +#..###.#.. +#....#.### +#......#.# +..#.##.#.. +.###.....# + +Tile 1471: +#.##.....# +...#.##... +....#.#### +#.#.....#. +..#.#...#. +#.#...#..# +.#.......# +...#..##.# +##...###.. +.######.#. + +Tile 3803: +##..###..# +#..#...... +#.#.#....# +.#..##..## +...#.#.#.# +...##.#... +........## +........#. +.......### +#.#.####.# + +Tile 2473: +#.#####.#. +##.......# +#.##...##. +..#....#.# +#.#...#.## +......#.## +#..#...... +#.#...#.#. +#...###... +#...#.##.. + +Tile 1193: +#..##...#. +....#.#..# +...#....#. +.#........ +#.#....#.# +#...#..... +.###...#.# +#..#..#.#. +#.##....#. +#.##.###.# + +Tile 1879: +#..#..##.# +##....#... +...##....# +#.##..#.#. +#..#.#.#.. +#.###..... +#.##...... +#..#...... +.......#.# +.##..##..# + +Tile 1049: +######.#.. +#.#...#... +#.#.....#. +###.###..# +###...#..# +##.##..#.. +#......#.. +...##..#.. +.###...... +#.#...#### + +Tile 2917: +#..##.###. +........## +#..#.#.#.. +#..#...... +.......#.. +#.#.#..#.. +##....#.#. +......#.#. +##...##### +##.##..#.# + +Tile 1619: +.#####.#.# +.....##... +##.#...... +..##..#.#. +.#.......# +#.##...... +#####..... +#...#.###. +..#....#.# +#..#.#..## + +Tile 1663: +#.###.##.. +####..##.# +..##...#.. +.###...##. +.#.##..... +........## +#.#..#..#. +#..#..##.. +#.###..#.. +##..##.### + +Tile 3571: +..#.##.### +.##..#..## +#...#...#. +#.##.###.# +......#..# +#..####.## +#.##...### +.#.#.#...# +....#....# +##.....##. + +Tile 2969: +#..#...#.# +.#...#..## +##..#..### +#.....##.. +......#... +...#.....# +#.......#. +#..#..##.. +#.#.##.### +#..###...# + +Tile 2657: +.###.##.#. +#.#.....## +##....#.## +.#.#..##.. +##..#.##.# +#.....#.## +#..##..#.. +#......... +#.##.#..#. +..#..#.#.# + +Tile 1693: +.###.#.##. +###....#.. +##.#..##.# +#.....##.# +.#.##.#..# +...#.#.... +#.....#... +#....##... +##.###.... +#.#.#..#.# + +Tile 3257: +.####.#... +##..##.### +#......... +.......##. +......#..# +###.....#. +....#####. +#####...#. +###....#.. +#.#.#.##.# + +Tile 2707: +..#...##.# +.#.....#.. +#...#...#. +##...#.##. +.##....... +#.##...... +.##.....#. +##........ +...##..#.. +.#.##.###. + +Tile 1723: +#..##.##.# +#.#.....#. +...#.##... +#.....##.# +...#...... +.#.#....## +#..#..#.## +..#......# +.##...#... +##...#.#.# + +Tile 2333: +#..#.##### +##.#..##.# +#........# +...#.#..## +....#....# +.####...## +##...#..## +##...#.... +#.....#..# +#.#..#...# + +Tile 2909: +##.#....## +#.#..####. +.#.##..... +#.#...#... +..#..#..#. +.....#.... +#...#.#### +#.....#..# +#.##..#..# +#####.#.#. + +Tile 1637: +##.##...#. +.#.#..#... +...#.##.#. +#...#..#.. +.###.##..# +.#......#. +........#. +.........# +#.......#. +..#...#.#. + +Tile 2129: +.#....#.#. +......##.# +....#..#.. +#.#......# +.#.......# +..#....#.# +#..#...... +#..#..#.## +#.#.#.#.## +#.###.#..# + +Tile 3083: +#####.#.#. +#..#.....# +#......#.. +.#...###.# +#.####..## +#####....# +#..##..... +.......#.# +#........# +#.....#.#. + +Tile 3929: +##..##...# +#..#..#... +..##...#.# +#......##. +..#.#...## +.......... +...#...##. +##......## +#..#...#.. +#.#.#.##.# + +Tile 2239: +...#.#..## +.....##... +#..#.....# +..#.##...# +#.#....##. +#.##...... +.##......# +.......#.. +..#.#..#.# +#....#..## + +Tile 3793: +###...##.# +...##.#..# +.....##.#. +.......... +.##.....#. +.......#.# +##...#...# +##....#..# +###...#... +#######..# + +Tile 3581: +##..###.#. +#........# +.#...#...# +.#.#...##. +#....#.... +........## +.#..##.#.. +.#..#.#.#. +....#.#..# +#.##.####. + +Tile 1553: +#...##.#.. +##......#. +##...#.##. +.#..#.#### +#...##.#.# +...##..### +......##.. +#.##.#..## +...##..##. +#..#..##.. + +Tile 2203: +.#....###. +..#.#....# +..#..#...# +#..##..#.# +#.......## +....#..... +#.#......# +...#....## +#..###..## +..#..#.... + +Tile 1847: +..####.... +###....... +#..#..#... +..#....### +#....#...# +#.#.#....# +.....##... +....#.#..# +##.#...#.# +..#..####. + +Tile 1367: +.##..#..#. +##......#. +##.#...#.. +........## +..#..###.# +#...#..... +....#..#.# +..#..#..## +..####..#. +##....##.# + +Tile 2633: +#.##...### +###....### +#...##.### +##........ +#..##..... +#.##.##... +.#.##.#..# +#.##....#. +.........# +#####.##.. + +Tile 1697: +#.####.### +.#.###..#. +##....#.#. +#..#...... +.#..#..... +#..####... +##...#.... +....#..##. +..#..#.#.. +######..#. + +Tile 1571: +.#####...# +#.....#... +#..#.....# +..#.#..#.# +.####...## +...#.#.### +#....#...# +#..#.....# +.........# +....###.## + +Tile 3889: +...#..#..# +......#### +#.#.##...# +....#..... +##.#...#.. +..#....#.# +..#.#....# +.###.#..#. +..#.####.. +...#..#### + +Tile 1039: +...#...... +#...#..... +##........ +#...#...## +..#.....#. +.##......# +.....##..# +..#..####. +#........# +.#..###.## + +Tile 2339: +#..##.##.. +..#...#..# +#.....#..# +..#.##.#.. +###......# +##..#.#..# +....#..#.# +#....#...# +#....#.#.. +####.##### + +Tile 1583: +.###.##.## +.....#..## +..###.#... +..##...#.# +..#....#.# +#....##..# +........## +#...##.#.# +...#.#..#. +.#.....#.# + +Tile 3881: +.#..####.# +..#..#...# +..#...##.. +#......... +.....#.#.. +..#.....#. +#.##...... +...##...#. +..#....#.. +#...#.###. + +Tile 1123: +.####.#.#. +##....#.#. +#..#.###.# +.####.###. +..##...... +##.#...... +.#..##.... +#...####.. +.#..#.#..# +..##.#.#.. + +Tile 2243: +..#...#... +......#.## +.......... +.#.#..#..# +#.#....##. +...#...##. +##..#..... +..##.##..# +#.#.....#. +##...#.##. + +Tile 2063: +#.....#..# +.#.#.#.... +#....##..# +#..##...#. +###.....#. +..#....#.. +#..#...#.# +.........# +...#...... +.#...#..## + +Tile 1621: +..#.##.#.# +##...#..## +..#..##..# +....#..... +......###. +#.#......# +..#.#...## +#.......## +#......#.# +.#..#...#. + +Tile 3331: +#..####... +..#..##.## +..###..... +..#..#.... +...#..#... +#.#.#....# +#....###.. +.###.#..#. +#....#...# +..##.##.#. + +Tile 1259: +###.####.. +#.....##.. +#...#....# +....##..#. +##.#.##..# +#.......## +.....#...# +......##.. +#.#...#.## +.##......# + +Tile 3407: +....##.#.# +#.#....#.. +#....##... +...##.#..# +####....## +.#....#..# +#..#..##.. +#####..### +##....#... +..#.#..### + +Tile 1033: +..#......# +#....#.#.. +#.#.#.###. +#.#.##.#.# +.#.#..##.. +...##...## +#####..... +...#...##. +####....## +##..##.### + +Tile 3089: +.#...##..# +.........# +#.#.....## +....####.# +.....#..#. +.##.##..## +#.....#..# +#..#...... +#.#.#...## +#.#...##.. + +Tile 2297: +#.#.#.#### +##..#..... +#...#..... +.......... +.....#.... +..#.#...#. +.....#.#.# +......##.# +#..#...### +.......#.# + +Tile 3259: +.####..... +.##.#..#.. +#........# +.#.##..#.# +#.###.#.#. +#.#....##. +#........# +#.....#.#. +#.......## +#.#....... + +Tile 3457: +#.####..#. +##......## +#....##.#. +#.......#. +######.... +.....#.##. +..#..#.... +#..#####.# +#..#...#.. +.#.##...## + +Tile 1423: +##.#.#.### +.........# +..####.##. +#......#.. +...#.#.... +#.#..##... +#.....#.## +.##..##### +#####.#.#. +.######.## + +Tile 2741: +.#..#..#.# +....##..#. +#..#..#### +#...#...## +#...##.#.. +#...#..##. +##........ +#..#####.. +..##.....# +##..###.#. + +Tile 3187: +####.#...# +.......#.. +#........# +#..##..#.. +.##.#...#. +..#.###... +#..##....# +....#.##.# +#........# +.###..##.. + +Tile 1117: +###.#.#.## +.#.....### +#....#...# +.#.......# +##..##..## +##.##...#. +##.#.#...# +#..####..# +..#..#...# +.#.###.##. + +Tile 3271: +.....#..#. +......##.. +.###.#.#.# +##..#....# +#.#...##.. +.........# +.#...#.... +.#..#.##.# +.......... +.#.#....## + +Tile 3067: +..#.###.#. +..##...#.# +..#...#.## +#.......#. +#..#.#..## +..##..#.#. +.....#.#.. +#......... +#.#......# +.##.#.##.. + +Tile 1429: +..#.##.#.# +.......... +.#.##.#.#. +##...###.. +##.#...#.# +#.....#.#. +##........ +##...#...# +.....##..# +##.#.###.# + +Tile 1801: +#......### +#......... +#...#..... +#........# +#......#.. +#.......#. +#..#...... +..#.#..### +........## +..#..#...# + +Tile 3853: +###...#.## +#...#..#.. +....#...#. +#.#....#.# +......#... +#...##.### +.#.#.#...# +#..##.#.## +....##...# +#...####.# + +Tile 3109: +..#...##.# +#.#..##.#. +#.##.##..# +..#.##...# +.....#..## +###.#..### +.##.#.#.#. +...#.#.##. +#..##..#.# +#.##..#### + +Tile 1301: +.##..#.### +##..#...## +#...#..#.. +..#.#....# +..#....#.. +#.#.#.#..# +#.#....#.. +.........# +.....#..#. +#..#.##.## + +Tile 2017: +....##.### +#........# +##........ +...#...#.# +.......### +.###...### +......##.. +.#.##..... +.#....#### +#.....#..# + +Tile 2621: +...#.#.### +###..#.### +..#.#.#.## +.......#.. +.#.......# +#.#....### +#...#...#. +.#.#..#... +#.#...##.. +####..#..# + +Tile 3697: +...##..##. +..#......# +##..#.#... +#....###.. +..#.#..#.. +##.#.##..# +.#.#.....# +#..#.....# +##......#. +##...###.# + +Tile 2711: +##..###... +#....#.#.. +##..##.#.. +#...#...## +#..#..#... +.#....#..# +##.#..#... +#.##.....# +.......... +#.###..#.# + +Tile 3533: +...#..#.## +..#.#....# +##.#.#.... +.#.#.#...# +.....#..## +##....###. +##.##....# +.##...#..# +....##.#.# +#.#..##### + +Tile 1907: +#.######.. +#.......#. +......#### +#.#.#.##.# +.......... +......#.## +#.#..#...# +#...#..### +...##..... +##...#.##. + +Tile 2213: +####.###.# +##........ +#.....#... +..#....#.. +.....#...# +....##.... +...#.#..## +....#.#..# +##.....##. +#....##.## + +Tile 1229: +.#.#.##..# +....##...# +......#..# +.#.......# +..#.#..... +#....#.... +#.##.....# +.##......# +##.#..#..# +#..#..#.#. + +Tile 3797: +#..##.#### +.##..###.. +#......... +.......##. +.##..#.... +#.#.##...# +#....#...# +#......... +..#...#..# +##.#...##. + +Tile 1087: +##..###### +.#..#...## +##.##.#.#. +....#..... +.......... +..####.### +##.###.#.. +....#...#. +#......#.# +#.####.#.# + +Tile 2687: +......#... +.#.#...#.# +#..#.#...# +#...#.#.## +.#....##.# +##....#... +#.#....#.. +##...#.... +#........# +##.##.#### + +Tile 1051: +#.#####..# +#.#...#..# +#...#..#.# +.#.##..#.# +......##.. +#...##.... +........#. +##.......# +#......#.. +.#...###.# + +Tile 3739: +##.#.####. +#...###... +.###...#.. +###....... +.........# +#....#..#. +.....#...# +..#......# +....#..... +#####.#.## + +Tile 2087: +...#####.# +.##.#....# +#...#..##. +#.##.....# +......#... +#.#.#..#.. +..##..#.#. +#..#...### +##.....#.. +.##.#..### + +Tile 2683: +..#.....#. +..#.#.#..# +##.......# +.#..#...#. +#..#.#...# +#...###### +#...##.#.. +##..##.... +#....#.#.. +.#####.### + +Tile 2137: +###.#....# +.....#..## +.......... +..##...#.. +.#..##..## +#..##..#.. +##..#..... +...#.....# +.#...##... +##....#### + +Tile 1031: +#######... +#......#.. +...###.##. +.#...#.#.# +##..#.#..# +.#.......# +.#........ +.......#.. +##..#.##.# +#.##..##.. + +Tile 2887: +.....##.## +.....#..## +.##.....## +...#.#.#.# +#...#....# +#......##. +.........# +.#..##..## +#.#...#.## +##...##.## + +Tile 2729: +####.#..## +#...##..#. +#...##.##. +...#.....# +..#..#.#.. +.##..##..# +.###.##... +##........ +.##...##.. +#..##..#.# + +Tile 3517: +#.#..##.## +#.......## +..#.#..#.. +.#.....#.. +..#.##.##. +#.#......# +##.#...... +#.#.##..## +#.#....#.. +###..##..# + +Tile 3191: +##...###.. +##...##... +#..#...#.# +##..####.# +###...#..# +..##...#.. +....##.##. +##...##... +#.###.##.. +.#..#....# + +Tile 1381: +#..#.#.#.# +....#....# +#.##..#..# +#.##...##. +.#..#..... +#...#....# +#.....#..# +####..##.. +###.##.### +#.....##.# + +Tile 2111: +.#.#.#..#. +.....#.#.. +...#...... +##...##... +##.#...#.# +#.#..##..# +.####....# +...#####.# +#.#....... +#.#..###.. + +Tile 3541: +####.###.# +..#.....## +#..#.#...# +.#.##.##.# +.#...#...# +.......... +#.#..#.#.. +#......... +#..#...##. +.######### + +Tile 1997: +#####.#.## +.#.#..#.## +##..#.#.#. +##.##..#.# +##..#....# +.#.##....# +.......... +#.##...##. +#......... +#.#.##...# + +Tile 1597: +####.#.#.# +##.....##. +##...#.#.. +......#... +.#....#..# +.##...#... +#....#.... +......#... +#..#.#..#. +...#.##.## + +Tile 2347: +##.#.....# +#...#.#.## +#..#...... +.#...#...# +...#....#. +#.#...#... +#.......## +#....#.... +#......... +#.##.##.## + +Tile 3767: +##.#.#..## +....##.#.. +#...###.#. +#.#.#..... +#......#.. +...##..### +.#...##.#. +......#... +..#..##... +.#.#.#..## + +Tile 2003: +...#####.. +#.#.#.#... +#.#..#...# +#.#..##### +#...#..#.. +#.##.....# +##...###.# +#.......#. +...#....## +..#.###.#. + +Tile 1523: +#...##.... +...#....#. +.##.##.### +#......##. +.........# +...#.....# +#.#....#.. +###.....## +##...#..## +...##.##.# + +Tile 3079: +...##....# +.#..#.##.# +#.##.##### +#.#....... +.#.......# +...##..... +#....#...# +#...####.# +#...###... +#...#.#.## + +Tile 1069: +........## +.#..###..# +#...#..... +#......... +.......#.. +..#..###.# +#..#..#..# +...###.#.# +..##...#.. +#.#.##.... + +Tile 2089: +##...#..#. +..#..##..# +......#... +.......#.# +#.####.... +...#...... +#......#.. +#...###.#. +...##..#.# +##.##.###. + +Tile 3863: +##....#.## +.##......# +#........# +....##..#. +.......#.# +##..##..## +..##.....# +.###.#.... +#.#....... +..###..##. + +Tile 2663: +.#.#.##.## +....#..... +##.##...## +..#....... +##.#...#.# +#....##..# +#...#..### +.....##... +#........# +#.###.#... + +Tile 1019: +..#....### +#..#.#..#. +.....#...# +....#.#... +..#.#....# +..#.##...# +..#..#...# +.##....#.. +..#....### +#.##.##.#. + +Tile 3709: +#..#....#. +##.##..... +#.......## +.#.#...#.# +.##.####.# +#..#.###.. +#..#.##### +#........# +.......... +.##..###.. + +Tile 3023: +##.###.#.# +..###....# +#...##...# +#........# +.#.#.....# +#.....#..# +.......... +#..#.#.... +#...#.#..# +#..#####.# + +Tile 3623: +..#.#..#.# +#.#.#....# +......#... +#...#....# +#........# +##..#..... +#.##.....# +..#.#..... +..#......# +#.##..#..# + +Tile 2161: +.######.#. +.........# +#..#.#...# +.##....... +.....#.#.# +......#.## +#.#####... +##.#...... +#.##...#.# +#.#.#####. + +Tile 3037: +##.....### +...#...... +#.#.#..#.. +...#.#..#. +.....#.#.# +#...#...#. +..#.#...## +#....##### +....#....# +...##...## + +Tile 2539: +#.##..##.. +.##..#.### +#.#####... +.#...##... +##.###...# +#......... +#.....#### +.#.#....## +#.....#... +##.#.####. + +Tile 1361: +#..###.### +...#..#... +.....#.#.# +.......### +#.#......# +#.#...#..# +###......# +##.#....#. +#...#.#..# +#......#.. + +Tile 1873: +...#.#..#. +###......# +#.#.#.#### +#........# +#..#.#.#.# +..#.....## +#....#..#. +...#...... +.......... +##....#..# + +Tile 3701: +.#..#.#... +.#...#.#.. +####.#..## +#.###...## +#...###... +#..#...... +.......##. +#....#..#. +##..###... +.#.#.####. + +Tile 3557: +##.#####.# +####.....# +..##...... +###.##..#. +#####..... +......#.## +....#.##.# +....#.#... +..##.#.... +##.##.#.## + +Tile 2659: +.#.#..#.## +.#.....### +##....#.#. +#.##..#..# +...##..... +###....... +#..#.....# +##.#####.# +..##.#..## +#..####.## + +Tile 2269: +#.#.#.#.#. +#..#.#...# +##..#.#.#. +#....#.#.. +#..#....## +.##..##..# +.#.#...#.# +#...##..#. +#......#.# +##.#.#..## + +Tile 3121: +#...##..#. +#.#.....#. +..#......# +.##..#..## +##....##.. +##..#..#.. +#........# +.###.####. +##.....#.# +#.#...#..# + +Tile 2939: +..##.#.### +...##....# +#.#...#.## +##..##...# +#..####..# +#....#...# +#.#....... +#.#...#..# +#.......#. +...#..#.## + +Tile 3967: +.#.....##. +#.#.#..... +..#####..# +..##.#..## +.#...#.... +#.....#... +....#.#... +...##.#..# +...##..#.. +##...#...# + +Tile 2113: +#..##.###. +........#. +###..###.# +.......#.. +#..##.#.#. +..##...#.. +###.....## +....#...#. +##..##.#.. +...##.#.#. + +Tile 1871: +..#..##### +.#..#.##.# +.....#..#. +##.#....#. +.##....#.. +#....#..#. +...#...... +.#..#..... +#..#.....# +##.#.#.... + +Tile 2531: +..#.#..##. +#.....#..# +#.#....... +...##.##.# +.##..#.#.. +#...##...# +......##.# +..#....... +#.#.....## +##.#..##.. + +Tile 2543: +#.#..#..## +##.##.#... +...#.##... +#.#......# +.#.#...#.# +..##.#...# +###.#...## +#.##..#..# +#.##...#.. +.#.###.... + +Tile 3041: +.###...... +.........# +#..##..... +##.#....## +###..#.### +...#.##.#. +.##...##.# +#...#....# +###...##.# +####..#..# + +Tile 1559: +##..##.... +#.##....#. +.#.#...... +.......... +#...#.#... +#.##....## +.#........ +#.....#.## +#.......#. +....#..#.# + +Tile 2617: +#.##.##.#. +...#...#.# +......#.#. +#..#...... +#.#..#.#.. +......##.# +#......#.. +.#.....#.. +###...#..# +#.#..##..# + +Tile 1861: +..#.#..### +##.....#.. +..#.....#. +#......... +.####...## +...#..##.# +#...#####. +....#.##.. +.##..#..#. +#.####.##. + +Tile 1747: +##...#..#. +#....#...# +##...#.### +#...#..... +#.##.#..## +...#...... +.....#..#. +...#.##... +.#..###... +#...###..# + +Tile 2579: +##.###.### +..#.#..#.# +.##..#.#.. +##..#.#### +##..#..### +...#.#...# +#..#.....# +.##.#...#. +.#...##... +#....##..# + +Tile 3761: +.#.###.### +#....#.... +#.#.....## +.###...#.# +###...##.# +.###.....# +...#...#.. +.....#.#.# +.#.##.#..# +##..####.# + +Tile 3463: +######..#. +.#..##...# +...##...## +.#...##.#. +.#.#...#.# +.........# +#........# +..##...#.# +#...#....# +#.###..... + +Tile 2521: +###.##.... +###.##.#.. +#..##..... +..#...#..# +.#.#.....# +##...#...# +..#......# +..#..##..# +#........# +#########. + +Tile 2647: +####.#.##. +#..#.#...# +#.......#. +.........# +#.####.... +#.#..#..#. +#........# +#.#......# +##..#..#.. +...##..... + +Tile 3847: +.....#..#. +#.....###. +##......## +###.....## +#....#.#.. +#.##.##... +.#..#.##.. +#...#.#### +.........# +.##.####.. + +Tile 2027: +.##...#.## +...#..##.. +#...#.###. +#......### +#.......#. +#....###.# +#.#.##.... +.........# +.......#.. +..#..##..# + +Tile 3347: +.###.#...# +....##...# +#...##...# +.#.#.#...# +#.#.#..#.# +#.#..#.##. +##..#..... +..#..#.#.. +.#......## +..#..##### + +Tile 3911: +###....#.# +....##.##. +#.#.#....# +...#.....# +...##..#.. +..###.#.#. +....#..... +#..##....# +#.##.#.#.. +.#..##...# + +Tile 1741: +####.##... +...##...#. +...#...... +#...##..#. +..#...#..# +#......... +.#...#.... +#..#.#..## +#......... +#...#..#.# + +Tile 3137: +.#....#.## +#......#.. +#.#...#... +##....#... +#.#.#.#..# +....#....# +..##.....# +##.......# +........## +..#..###.# + +Tile 2417: +##...##..# +##.....#.# +....##.... +.#...#...# +....##.### +#...#..#.# +#....#...# +..#...#..# +#..#...#.. +...#.####. + +Tile 2803: +#.###..### +#....#...# +#.#....... +#..##..... +.#....#... +.#...#.... +#.#..#...# +#.##.##... +.#.##.#### +.####..... + +Tile 2267: +.#.#.#..## +..#.#....# +#...#....# +...#..###. +...##..... +#.#....... +.#...#.... +##..#.#.#. +.#..##.#.# +####.#.##. + +Tile 1613: +..##.#.#.# +.......##. +......#### +......##.. +##.#.....# +#.......## +#...#..#.. +.......#.. +#......#.. +#.#.#....# + +Tile 2777: +.####.##.# +#..#.....# +##.###.### +###.#..... +.##..#...# +.#.#...#.. +#......... +...#...### +...#....#. +#.#.###..# + +Tile 3923: +#####..#.# +....#.#..# +#.#..#..## +...##..... +#.#....... +.........# +..#.####.# +#.#..####. +#####..#.# +#.##.###.# + +Tile 3919: +...###.### +##.#.....# +#......... +##....##.# +.#.....#.. +.....#.... +...####..# +..#.##.#.. +....#....# +.##.....#. + diff --git a/2020/day20_jurassic_jigsaw/tests/sample_input b/2020/day20_jurassic_jigsaw/tests/sample_input new file mode 100644 index 0000000..b07aa4b --- /dev/null +++ b/2020/day20_jurassic_jigsaw/tests/sample_input @@ -0,0 +1,107 @@ +Tile 2311: +..##.#..#. +##..#..... +#...##..#. +####.#...# +##.##.###. +##...#.### +.#.#.#..## +..#....#.. +###...#.#. +..###..### + +Tile 1951: +#.##...##. +#.####...# +.....#..## +#...###### +.##.#....# +.###.##### +###.##.##. +.###....#. +..#.#..#.# +#...##.#.. + +Tile 1171: +####...##. +#..##.#..# +##.#..#.#. +.###.####. +..###.#### +.##....##. +.#...####. +#.##.####. +####..#... +.....##... + +Tile 1427: +###.##.#.. +.#..#.##.. +.#.##.#..# +#.#.#.##.# +....#...## +...##..##. +...#.##### +.#.####.#. +..#..###.# +..##.#..#. + +Tile 1489: +##.#.#.... +..##...#.. +.##..##... +..#...#... +#####...#. +#..#.#.#.# +...#.#.#.. +##.#...##. +..##.##.## +###.##.#.. + +Tile 2473: +#....####. +#..#.##... +#.##..#... +######.#.# +.#...#.#.# +.######### +.###.#..#. +########.# +##...##.#. +..###.#.#. + +Tile 2971: +..#.#....# +#...###... +#.#.###... +##.##..#.. +.#####..## +.#..####.# +#..#.#..#. +..####.### +..#.#.###. +...#.#.#.# + +Tile 2729: +...#.#.#.# +####.#.... +..#.#..... +....#..#.# +.##..##.#. +.#.####... +####.#.#.. +##.####... +##..#.##.. +#.##...##. + +Tile 3079: +#.#.#####. +.#..###### +..#....... +######.... +####.#..#. +.#...#.##. +#.#####.## +..#.###... +..#....... +..#.###...