From 42f299d11b6f2721775cf770a0a267b4918749f0 Mon Sep 17 00:00:00 2001 From: Sven Weidauer Date: Mon, 20 Dec 2021 13:01:42 +0100 Subject: [PATCH] Day 20 --- AoC21.xcodeproj/project.pbxproj | 99 ++++++++++++++++ day20.swift | 192 ++++++++++++++++++++++++++++++++ 2 files changed, 291 insertions(+) create mode 100644 day20.swift diff --git a/AoC21.xcodeproj/project.pbxproj b/AoC21.xcodeproj/project.pbxproj index 93eab85..ca5d4b9 100644 --- a/AoC21.xcodeproj/project.pbxproj +++ b/AoC21.xcodeproj/project.pbxproj @@ -27,6 +27,8 @@ 265112982767D171009B7607 /* common.swift in Sources */ = {isa = PBXBuildFile; fileRef = 269BE5CB2762A08800871C85 /* common.swift */; }; 2680ECD2276F23FE00CAB23C /* day19.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2680ECD1276F23FE00CAB23C /* day19.swift */; }; 2680ECD3276F240200CAB23C /* common.swift in Sources */ = {isa = PBXBuildFile; fileRef = 269BE5CB2762A08800871C85 /* common.swift */; }; + 2680ECE02770A2FC00CAB23C /* day20.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2680ECDF2770A2FC00CAB23C /* day20.swift */; }; + 2680ECE12770A30300CAB23C /* common.swift in Sources */ = {isa = PBXBuildFile; fileRef = 269BE5CB2762A08800871C85 /* common.swift */; }; 269BE5BC2762959C00871C85 /* day8part2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 269BE5BB2762959B00871C85 /* day8part2.swift */; }; 269BE5CA2762A05300871C85 /* day9.swift in Sources */ = {isa = PBXBuildFile; fileRef = 269BE5C82762A04F00871C85 /* day9.swift */; }; 269BE5CC2762A08800871C85 /* common.swift in Sources */ = {isa = PBXBuildFile; fileRef = 269BE5CB2762A08800871C85 /* common.swift */; }; @@ -137,6 +139,15 @@ ); runOnlyForDeploymentPostprocessing = 1; }; + 2680ECD62770A2E900CAB23C /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; 269BE5B22762958800871C85 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -189,6 +200,8 @@ 265112962767D16D009B7607 /* day13.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = day13.swift; sourceTree = ""; }; 2680ECCA276F23E800CAB23C /* Day19 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Day19; sourceTree = BUILT_PRODUCTS_DIR; }; 2680ECD1276F23FE00CAB23C /* day19.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = day19.swift; sourceTree = ""; }; + 2680ECD82770A2E900CAB23C /* Day20 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Day20; sourceTree = BUILT_PRODUCTS_DIR; }; + 2680ECDF2770A2FC00CAB23C /* day20.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = day20.swift; sourceTree = ""; }; 269BE5B42762958800871C85 /* Day8Part2 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Day8Part2; sourceTree = BUILT_PRODUCTS_DIR; }; 269BE5BB2762959B00871C85 /* day8part2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = day8part2.swift; sourceTree = ""; }; 269BE5C12762A03F00871C85 /* Day9 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Day9; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -276,6 +289,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 2680ECD52770A2E900CAB23C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 269BE5B12762958800871C85 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -303,6 +323,7 @@ 263BA594275E974800839C92 = { isa = PBXGroup; children = ( + 2680ECDF2770A2FC00CAB23C /* day20.swift */, 2680ECD1276F23FE00CAB23C /* day19.swift */, 263D3E41276E10AE00B0AC5B /* day18.swift */, 263D3E32276DDA6600B0AC5B /* day17.swift */, @@ -339,6 +360,7 @@ 263D3E2B276DDA5400B0AC5B /* Day17 */, 263D3E39276E109D00B0AC5B /* Day18 */, 2680ECCA276F23E800CAB23C /* Day19 */, + 2680ECD82770A2E900CAB23C /* Day20 */, ); name = Products; sourceTree = ""; @@ -533,6 +555,23 @@ productReference = 2680ECCA276F23E800CAB23C /* Day19 */; productType = "com.apple.product-type.tool"; }; + 2680ECD72770A2E900CAB23C /* Day20 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2680ECDE2770A2E900CAB23C /* Build configuration list for PBXNativeTarget "Day20" */; + buildPhases = ( + 2680ECD42770A2E900CAB23C /* Sources */, + 2680ECD52770A2E900CAB23C /* Frameworks */, + 2680ECD62770A2E900CAB23C /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Day20; + productName = Day20; + productReference = 2680ECD82770A2E900CAB23C /* Day20 */; + productType = "com.apple.product-type.tool"; + }; 269BE5B32762958800871C85 /* Day8Part2 */ = { isa = PBXNativeTarget; buildConfigurationList = 269BE5BA2762958800871C85 /* Build configuration list for PBXNativeTarget "Day8Part2" */; @@ -636,6 +675,10 @@ CreatedOnToolsVersion = 13.2.1; LastSwiftMigration = 1320; }; + 2680ECD72770A2E900CAB23C = { + CreatedOnToolsVersion = 13.2.1; + LastSwiftMigration = 1320; + }; 269BE5B32762958800871C85 = { CreatedOnToolsVersion = 13.1; LastSwiftMigration = 1310; @@ -675,6 +718,7 @@ 263D3E2A276DDA5400B0AC5B /* Day17 */, 263D3E38276E109D00B0AC5B /* Day18 */, 2680ECC9276F23E800CAB23C /* Day19 */, + 2680ECD72770A2E900CAB23C /* Day20 */, ); }; /* End PBXProject section */ @@ -779,6 +823,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 2680ECD42770A2E900CAB23C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2680ECE12770A30300CAB23C /* common.swift in Sources */, + 2680ECE02770A2FC00CAB23C /* day20.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 269BE5B02762958800871C85 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1276,6 +1329,43 @@ }; name = Release; }; + 2680ECDC2770A2E900CAB23C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 722B335UM5; + ENABLE_HARDENED_RUNTIME = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/../Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 12.1; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 2680ECDD2770A2E900CAB23C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 722B335UM5; + ENABLE_HARDENED_RUNTIME = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/../Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 12.1; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; 269BE5B82762958800871C85 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1468,6 +1558,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 2680ECDE2770A2E900CAB23C /* Build configuration list for PBXNativeTarget "Day20" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2680ECDC2770A2E900CAB23C /* Debug */, + 2680ECDD2770A2E900CAB23C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 269BE5BA2762958800871C85 /* Build configuration list for PBXNativeTarget "Day8Part2" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/day20.swift b/day20.swift new file mode 100644 index 0000000..e948e75 --- /dev/null +++ b/day20.swift @@ -0,0 +1,192 @@ + +@main +struct Day20: Puzzle { + func run() { + var image = Image(input) + for i in 0..<50 { + image = image.run(map: map) + if i == 1 { + print("Part 1:", image.countLitPixels()) + } + } + print("Part 2:", image.countLitPixels()) + } +} + +struct Image { + var width: Int + var height: Int + var pixels: [Bool] + var border: Bool + + init(_ string: String) { + pixels = [] + width = 0 + height = 1 + border = false + for char in string { + if char.isNewline { + width = 0 + height += 1 + continue + } + + pixels.append(char == "#") + width += 1 + } + } + + init(width: Int, height: Int, border: Bool) { + self.width = width + self.height = height + self.border = border + self.pixels = Array(repeating: false, count: width * height) + } + + subscript(x: Int, y: Int) -> Bool { + get { + guard 0.. Int { + var index = 0 + for i in -1...1 { + for j in -1...1 { + index = index << 1 | (self[x + j, y + i] ? 1 : 0) + } + } + return index + } + + func run(map: [Bool]) -> Image { + var outputImage = Image(width: width + 2, height: height + 2, border: map[borderIndex]) + for y in -1...height { + for x in -1...width { + outputImage[x + 1, y + 1] = map[lookupIndex(x: x, y: y)] + } + } + return outputImage + } + + func countLitPixels() -> Int { + pixels.lazy.filter { $0 }.count + } +} + +let map = "#####.#.###.###.#.#.####.#####.####.#..####.##.####...##......#.##.##.#.#..#.##.###.#.#.#.##.#..#.####.#.#.##.#..........###.##...#.#...#.#.###..#...##.####.##...###.....##..##..##.#......#.#.##.#.#.##.#.......###.##.#.###.##..##.......##....#.##....#..###.######.##...##.##...#.#.##...##.##.#....##.####..#..#..##.##.#.#..#....#######.###.##...#.####..#.#.#.##...##..##.#.#.#.##.#.......###..######..###..##......###..###.#.#.#.......#.....##.#.##..#.##.#.##.####..#.##....##.#.#..#.####.##.#.#.##...#..##.####." + .map { $0 == "#" } + +let input = """ +.###..###..#.####.#....#..##.###.........#.#.#..#.#...##...#.#........##..#..#.##....#.##.#...###.## +.##......#.#..###.######.#.#.######...#..##...#......###..###..####..####..##..#.##.#.#.#....##..##. +.##.##..###..#...###....#...##..#..######...#.#.##.#..####.#..#..###.######.#.#..#..##...##.#.#.#.#. +..#..##..####...###.#...###.#.####...#####...#####.#.#########.##..####...#....##....##..#.#..#...## +.#.#..#.###....###.#.#..###.#..#####.#.###...####.##.###.#..####.###...#...#.##.#..#..#...##....#### +######....#..##.#..#.##.#.#.##.#.#####.#..###.#####..#######..##..#..#........##.##..#...#..##..#.## +.#.##########.##...#.###..##...#....#.##..##.###..#####...#..##.#.....##..####.#.#.##..#...#..#.#.#. +.##..#.#..#..##.###..#.#.##..#.#...########.##..#....##...#..#.####.#.#..####..#.#..##.#.......##..# +##..##...###.##..#.#.#.###.#..####.##.....#.###.##.##......#.......#.#####.#..##.#.##.#..##.###.##.# +..#..###.....##..####.......####.###.#..##.##.#######.####..#.######.###.#.#..###..###.##.###.##..#. +.##.#..#..#.####.#.#.#..#....#...##.....##..##..##.##.#..##...#..#...##.###.##.##........#.#..#..### +....#.######.#..#......####.##....##.#..#..##...#...#...#.##...##..###.......##.....#..#..#..#####.. +###..##.....##.##.###.##..#.#.###..####.#.#....#.##.#.....#######.##.....#..#####.##..#..#####.##.## +#.#.#..#.#.#..........##.##......#.###...#.###.##.######..#...#...#.......###...#..#.##...#.#.##..## +##...##.###.#.##..##....#.#.#..##.###.##.#...#.#..##..#..##...#..##...##..#.####..#..##.#.#...##.... +...#..###.####.#.####.#.#.#....#.##.##..#####..#####.#.####.##..##.###....###..#....#..##.#.#..#..#. +..#.#.###...###...#####.####..#.#...###.###..#.##....#.#.#.....#..#...#..#.##..####......##.#.###... +#.##.....##...#.#...#####.#.##.##..##.#.##....#.##.....#.###..#..##....###.....#####..####..#..##... +#...##....##..#..####...#...###...##.##..##..#....###.#....#########.##..##.#.#.######.###..####.##. +##.#.##.#.#..#......##.#..#...##..#.#..##.###..##.......##..#.#...#.#..#.#.#....##..######.##...#... +.#..##..#....##..#.##..##...#..##...#....#.#.##..#...##.##.#..#.#.#.##.#..#.#.......#.###..######..# +#..##.#.##.#..##...####.##.#...####...##.###..#..#.#.#..###..##.#....#####.###..#...#..#..####...##. +#.####....######.....#.##..####....###.##....###.####...##.#....####.#..##..#..##..#.##.####.#.....# +...#.#.###...####..#..#.#..#.##...###.#.#.##.#...#.#.#.##.##...#.#####.#....#..##.#...#.##....##.... +#..##..#.##..#.#.#..#..###.##.....####..##..##..#######...##.#.....##..#...########..#.#.#.....##... +.#...##...##..##.#..##......#.##......#.###.##.##...##....####.##.#.....#.#.#.#.##.#.##.#..#..##..#. +.#..#..###.#.#.##..#..#...#..##..#.##...##..#...######..##.#.######........###.#..##..##..######.##. +#####..##.####.....###.###.########.###...#########..#.#.###.#..#####..#..###.#####.#.....#..##..##. +........#....###..####.#.###...#.###.........#.......#..#.#..###.##.#...#.###.##..#...##.##.##.#.### +.##....##.#..##.##...####..########.#####..#.#.#...#.##..#.##..######.###.#..##.#..#...###..#.##.### +#..#.##.##..#.#.#...##....#.#..#..###...###..#..#..##.#.....#..#..#.#.####...#.####.#.#.#.#.#.....#. +###..##.##..##.###.#.#....#..........##.#....#.#.##......#.##.#...#####.##....#.#.#....#.###.#.####. +###.....##..#....#..##.##....#..##.##.#...#..#.#####.####.#..##...#...##.###..##.####..##...##.####. +#.#..#.#.#.#..#..#.###..###.##.###.#....#..###.#.###.....##..#.#.##.#....#.#.#.#.#...#.##.######.##. +##....###...#...#.######.#.#.#....#..#.###.#.##..##...#.....##.#...##.#.#####.##.#.##########.####.. +...#.#.#..###.#....##.#....##.#..##...#.##....#...#####.#.....##..#.##.##.....#.##.#.#..##.##.#..#.# +###.##.########.##..##.#...###.##.##.#.#...##..###...##.##.##.#..#...#.#.##.....##.....#..##.#.#.### +#.###.#......####..###.....#.##.###..###....###.....#..#.#.##.##....#.#....#.######.#...##...######. +#.#####.###..#.#..........#.######.#####.####.##.##....###..#.###.#.......#....##.#.######..#.###.#. +#.#.##..#...##...#..#.#...#.##..#.####.#.......####.##..#.##..##.#....#.#.....#..#..#...#..#.##.#.#. +####.#.##..##....####.#.##.#.##..#.#.#.#####.####.#.##..##.#.####.#..##..#.###.#...#.##...#.#..###.. +#.###...#.#...##.####...###..#..##.#.##.#.#.######...##.##.#.####..#.###..#.##...##..##.#.#.#.####.# +....#.##..##..####......###.#.....#....######.#...##..#..##.###...##.#####..#.##...#...##.#.#####.## +..##...#..##.......#.#.###.#...#####........###...#....#...##.##...###....##.##.#..####....##..##.#. +.#..###.##......##..#...##......##.#.##..##..###.#.#.#.##...#...#.#.....#.#.#.......#..###..####.### +...#..#..##...#..##.##.#####.#.##.#.#...##.####.###...###.#.##.##.##..#.##..#..##.#.###....###..#### +#......#...#.#.#.#.#..#...#....###.##.##...######....#.###.##..##.##..#.#..#.####.#.####.......##.#. +#.###.#..####....##.##.###.##.#.#######..##.##.#.#..#...#.#..####.##..#.##.#....#....#.##.#.#.##...# +##...###..##.#.##...##..####.#.#.#####.#.#.##..........#....#...#..##.###....###.#.#.###.###....#.#. +###.#.##..#....#.#.#.##.######..####.#...##.##...###..###..##.........##.##.#.###...##.#####...###.# +..###..#.##..######.#....#...##.#.....#..######.....#.####.#..###..#..##.##...##..##....##..###..##. +#.#.#############.#..##.#.#..#####.#.#.....#....####.#....#..##..###.#...#.##...###.##...##...#..##. +##..##........##.#.##.###..#.#.##..#...#.##.###.#.###########..#.#.#.##..#....#....#.#..#...##...#.. +#.#.#...##...#.#.##.#..##.#.####.##.#....##..#..#.....#...######.#...##...####.#....#.........#.#... +##..#.#.##...#....#.##..##.##.###.#.....#.########.##.....#....######..##......#.#...##..##.#.####.. +.##.....###..######..#...#......#..#....##.##...#.##...#.#.###...##...#.#.#..#.#..#.#..#.##..###.### +#..#....#...###.#..#########..##.#.......#.###..###...#....#..##.########.#....#.#..###.##.#......#. +###..#..##....####...###.....#....###...#.#..#...#..#.#####...#.####.......#.##.#.....##.##...##.### +..###..#.###..#.##.......###..##...##....#.#.##.#.....###..###.#..####.#####.#..#.#...###.#.####.#.. +#.##.#..##.####.#####.#.#.#...######.#.#.#....#.#.#.#...#.##.......###...#.#######...##..###.#.###.# +..##.#....#####.#..##.#..#.#.#.#.#####.#.###...#..##.#.#.####.#.#....##..###.#.##....##..#####.###.. +.....#####.#..#.#.....##.#..###.#.##..#..#..#...#.#....#.##.#.#..#...####...#.#..#.##.##.##.#.#...#. +##.##.######....#....#..##.##.##..###..##.#..####.#.##.#...##.#.##.###.######..#####.....#.##.##.### +.#.##.#...#..#######.####.....###.#.#.#...###....#.#.#...#..#.#.....###...###.#...#.#.....##..#...## +.#####..##.####.##.###.##.##..##..####...#.#.###....#.#.....#...#####...###.##.####....#.###.##.#### +.#...#....###.########.##..##.##.##...###..#...#..###..#..#.#.###.#...#.#..##..###.#.....#...####.#. +#.#.#..#.##..###.#.###.##.##...##.#.##.#.#.##......#.....###.#.####..##.#.##..#...###...#..##..#...# +.##....######.#.##....#.#.#...#....###...##.##.#.#..##.#....#.##.###.#.####..##...###.#..#.....#.### +...#.####......#.##...#...####......#..#######.#.#.##..##....####.##....##.##..#.##..###...####.#.#. +####..####..##..#...#.#.....#..#..#.......#.##.#.....#.#.##.#..#####...##.#....##........#.........# +.#.#.#......##..#.###.##....#.#..######.##.#.#..#...#...#....###.....###.###....##.#.##..#.#..##.#.# +.##..###....#.#.#.#..#...##.#.##..#.#.##..#.#####.#...#..#...#####.###..##..#.....#.##..##.####.#.#. +..#..##.####....##.##.#...##.##.#..##.###.#..#.###...#...##.#.##.##.#.#..##.##.##..#.....#..####.##. +.#..#..#.#.#.###...###.##.##..##..##....##...#####.#.#...###.##.#.#....##.#..#...#.#..##...#.####... +#####......##....#.##..##.##..#..#.##..#.##.#.######..##..##...#..#.#..#.###..####.#.###..#.#..###.# +.####..#....#.##....#.##.#...#.###..###...##.##.##.#..#..##..#.....#.#########..#...#..####.##....## +####.###..##.#.#.##.#.####.###.###.#...#####.....#.#....#..####.#.#...####.##....#..##.#....#.#.###. +##.##...##...#.#####..#...#.#.##.#.##.#....#..#..####.#.#####.#...#...#..##.##.###..###.#....####..# +.##.####..###..#.####.#.....###....#...#..#...###.....#.####.#....##.####..#.###..#.###...#....##... +#....#...###.#...#.##.#.....#.##.###.....#.##...#...##.##...###.##...##..#####...#....#....#..###.#. +#.#...##.#.#..##..##..###..##...####.#.#..##..##.##..##.#.###.##...###.#.##.##.##..##..###..###..#.# +.##..###...#.####..#####.#.###....###.#..##..####.##..#.##.....###...#...#..##.###.#.#######.....#.. +.####....##..##......##.#......#.##..##.##.###..###.......###....####.#.##..#.####..##.#.#.#.##.#..# +##...#####.#.....##..###...###.#...##..#####.#..###...#####..###......#...#.###.##..##...#.###...### +..###.#...###..#.##.##.##.#.##.....##.###..##..##.##..###....###..#.......###.##...##....#..##..##.# +#..#...##.###.#...#.##...#.##.###.##...##.#...##.#.#.#..#....###.#.......#.##.#..###.#.##.##..####.# +##...####.......#..##.#.#.#..#.##....#.##.##.#.####..##....###.####.#.###..#.##..##......#.#.#..#### +###...#..##.#.......##..#.#...##...#...##..##.#.#..#.#.#.####.##.##.###..#.##.####..####....####.#.. +#..###.##.....###..##.##.###.###.#.#....##.#######....#####.##.#....###.##..#...#..#.##.#.#.#.#..#.. +.#.....#..###..##.#..##.##.###.##..#....###...##........#....####..#.##########...#....###.#...##.## +#.....#.#.#####.#.######.#....##..#...#.##.#..##..#####...######.#.####...#.####.###..#.##....##...# +.#.#...#.#..#.##.#..####..#..#.....##.#....#.#######.#.#..#.#.#.#.###...##..####..##.##.##..#.###... +.#..#.##.#..##.#.##....##..###..#........#.##.#.##.#..##.#.###.#.#..#...#..####.##...#.....#.###...# +..#....##..#..#.##.##.#..###......#.#..#.####..##.#.######..#######..##.##.#..##....#.##.....#.###.. +.#....#..#....#...#.###...#.#...##..#..##.######..#..###.##..###.#.##...#.#..#.###.#..###.##...#..#. +##...##.####.##..####.#.#....#....#.###.##.###.##.##..#.#.#.....##...#.#..#####.##..#.#.....#.#.#### +.....#.#.##..######....#...#.##..#...#..#...#.##..##..##.....#...##..#.#.####......#.#.##..#.#.#..#. +#.##...##.##..###..#....#...####..##....#.#....#..#.#.....######.....##....#..###.......##......#.#. +#.##.....##.#.#...#.#######.###..#..#...##...#.#.####.#########...#..#....#.....##.#.#.###.##..#.#.. +.#.......#.##.....#####.#..#...###.##...#.#..#.###.#.#.#.#########.##.###...####...##.##...###.#.#.# +"""