├── .gitignore ├── .idea ├── .gitignore ├── advent-2020-kotlin.iml ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── compiler.xml ├── copyright │ ├── Default.xml │ └── profiles_settings.xml ├── gradle.xml ├── jarRepositories.xml ├── misc.xml ├── modules.xml └── vcs.xml ├── LICENSE ├── README.md ├── build.gradle.kts ├── gradle └── wrapper │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── src ├── main ├── kotlin │ └── com │ │ └── ginsberg │ │ └── advent2020 │ │ ├── Day01.kt │ │ ├── Day02.kt │ │ ├── Day03.kt │ │ ├── Day04.kt │ │ ├── Day05.kt │ │ ├── Day06.kt │ │ ├── Day07.kt │ │ ├── Day08.kt │ │ ├── Day09.kt │ │ ├── Day10.kt │ │ ├── Day11.kt │ │ ├── Day12.kt │ │ ├── Day13.kt │ │ ├── Day14.kt │ │ ├── Day15.kt │ │ ├── Day16.kt │ │ ├── Day17.kt │ │ ├── Day18.kt │ │ ├── Day19.kt │ │ ├── Day20.kt │ │ ├── Day21.kt │ │ ├── Day22.kt │ │ ├── Day23.kt │ │ ├── Day24.kt │ │ ├── Day25.kt │ │ ├── Extensions.kt │ │ ├── Movement.kt │ │ └── Resources.kt └── resources │ ├── day01.txt │ ├── day02.txt │ ├── day03.txt │ ├── day04.txt │ ├── day05.txt │ ├── day06.txt │ ├── day07.txt │ ├── day08.txt │ ├── day09.txt │ ├── day10.txt │ ├── day11.txt │ ├── day12.txt │ ├── day13.txt │ ├── day14.txt │ ├── day15.txt │ ├── day16.txt │ ├── day17.txt │ ├── day18.txt │ ├── day19.txt │ ├── day20.txt │ ├── day21.txt │ ├── day22.txt │ ├── day24.txt │ └── day25.txt └── test ├── kotlin └── com │ └── ginsberg │ └── advent2020 │ ├── Day01Test.kt │ ├── Day02Test.kt │ ├── Day03Test.kt │ ├── Day04Test.kt │ ├── Day05Test.kt │ ├── Day06Test.kt │ ├── Day07Test.kt │ ├── Day08Test.kt │ ├── Day09Test.kt │ ├── Day10Test.kt │ ├── Day11Test.kt │ ├── Day12Test.kt │ ├── Day13Test.kt │ ├── Day14Test.kt │ ├── Day15Test.kt │ ├── Day16Test.kt │ ├── Day17Test.kt │ ├── Day18Test.kt │ ├── Day19Test.kt │ ├── Day20Test.kt │ ├── Day21Test.kt │ ├── Day22Test.kt │ ├── Day23Test.kt │ ├── Day24Test.kt │ ├── Day25Test.kt │ └── ResourcesTest.kt └── resources ├── day20_test.txt └── read_file_test_1.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | 25 | build/ 26 | .gradle/ 27 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/advent-2020-kotlin.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 21 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/copyright/Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 19 | 20 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2020 Todd Ginsberg 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Advent of Code 2020 Solutions in Kotlin 2 | 3 | [![license](https://img.shields.io/github/license/tginsberg/advent-2020-kotlin)]() 4 | 5 | This repo is my personal attempt at solving the [Advent of Code 2020](http://adventofcode.com/2020) set of problems with the Kotlin programming language. 6 | 7 | I am trying to solve these on the day they are posted with clear, idiomatic solutions. That means in some cases I will sacrifice performance for a more clear solution. While I will endeavour to have these done day-of I can't promise it because work and life can get in the way. Plus, some of these problems can get quite involved, so solving it clearly and writing up an explanation might take me longer than a day. We'll see how it goes! :) 8 | 9 | Past years, also in Kotlin: 10 | * 2017 - [GitHub](https://github.com/tginsberg/advent-2017-kotlin/) and [Blog Posts](https://todd.ginsberg.com/post/advent-of-code/2017/) 11 | * 2018 - [GitHub](https://github.com/tginsberg/advent-2018-kotlin/) and [Blog Posts](https://todd.ginsberg.com/post/advent-of-code/2018/) 12 | * 2019 - [GitHub](https://github.com/tginsberg/advent-2019-kotlin/) and [Blog Posts](https://todd.ginsberg.com/post/advent-of-code/2019/) 13 | 14 | #### Daily Solution Index for 2020 15 | | Day | Title | Links | 16 | | --------|-----------------------------------------------|--------------------------------------------- | 17 | | 1 | Report Repair | [\[Blog Post\]](https://todd.ginsberg.com/post/advent-of-code/2020/day1/) [\[Code\]](https://github.com/tginsberg/advent-2020-kotlin/blob/master/src/main/kotlin/com/ginsberg/advent2020/Day01.kt) [\[AoC\]](http://adventofcode.com/2020/day/1) | 18 | | 2 | Password Philosophy | [\[Blog Post\]](https://todd.ginsberg.com/post/advent-of-code/2020/day2/) [\[Code\]](https://github.com/tginsberg/advent-2020-kotlin/blob/master/src/main/kotlin/com/ginsberg/advent2020/Day02.kt) [\[AoC\]](http://adventofcode.com/2020/day/2) | 19 | | 3 | Toboggan Trajectory | [\[Blog Post\]](https://todd.ginsberg.com/post/advent-of-code/2020/day3/) [\[Code\]](https://github.com/tginsberg/advent-2020-kotlin/blob/master/src/main/kotlin/com/ginsberg/advent2020/Day03.kt) [\[AoC\]](http://adventofcode.com/2020/day/3) | 20 | | 4 | Passport Processing | [\[Blog Post\]](https://todd.ginsberg.com/post/advent-of-code/2020/day4/) [\[Code\]](https://github.com/tginsberg/advent-2020-kotlin/blob/master/src/main/kotlin/com/ginsberg/advent2020/Day04.kt) [\[AoC\]](http://adventofcode.com/2020/day/4) | 21 | | 5 | Binary Boarding | [\[Blog Post\]](https://todd.ginsberg.com/post/advent-of-code/2020/day5/) [\[Code\]](https://github.com/tginsberg/advent-2020-kotlin/blob/master/src/main/kotlin/com/ginsberg/advent2020/Day05.kt) [\[AoC\]](http://adventofcode.com/2020/day/5) | 22 | | 6 | Custom Customs | [\[Blog Post\]](https://todd.ginsberg.com/post/advent-of-code/2020/day6/) [\[Code\]](https://github.com/tginsberg/advent-2020-kotlin/blob/master/src/main/kotlin/com/ginsberg/advent2020/Day06.kt) [\[AoC\]](http://adventofcode.com/2020/day/6) | 23 | | 7 | Handy Haversacks | [\[Blog Post\]](https://todd.ginsberg.com/post/advent-of-code/2020/day7/) [\[Code\]](https://github.com/tginsberg/advent-2020-kotlin/blob/master/src/main/kotlin/com/ginsberg/advent2020/Day07.kt) [\[AoC\]](http://adventofcode.com/2020/day/7) | 24 | | 8 | Handheld Halting | [\[Blog Post\]](https://todd.ginsberg.com/post/advent-of-code/2020/day8/) [\[Code\]](https://github.com/tginsberg/advent-2020-kotlin/blob/master/src/main/kotlin/com/ginsberg/advent2020/Day08.kt) [\[AoC\]](http://adventofcode.com/2020/day/8) | 25 | | 9 | Encoding Error | [\[Blog Post\]](https://todd.ginsberg.com/post/advent-of-code/2020/day9/) [\[Code\]](https://github.com/tginsberg/advent-2020-kotlin/blob/master/src/main/kotlin/com/ginsberg/advent2020/Day09.kt) [\[AoC\]](http://adventofcode.com/2020/day/9) | 26 | | 10 | Adapter Array | [\[Blog Post\]](https://todd.ginsberg.com/post/advent-of-code/2020/day10/) [\[Code\]](https://github.com/tginsberg/advent-2020-kotlin/blob/master/src/main/kotlin/com/ginsberg/advent2020/Day10.kt) [\[AoC\]](http://adventofcode.com/2020/day/10) | 27 | | 11 | Seating System | [\[Blog Post\]](https://todd.ginsberg.com/post/advent-of-code/2020/day11/) [\[Code\]](https://github.com/tginsberg/advent-2020-kotlin/blob/master/src/main/kotlin/com/ginsberg/advent2020/Day11.kt) [\[AoC\]](http://adventofcode.com/2020/day/11) | 28 | | 12 | Rain Risk | [\[Blog Post\]](https://todd.ginsberg.com/post/advent-of-code/2020/day12/) [\[Code\]](https://github.com/tginsberg/advent-2020-kotlin/blob/master/src/main/kotlin/com/ginsberg/advent2020/Day12.kt) [\[AoC\]](http://adventofcode.com/2020/day/12) | 29 | | 13 | Shuttle Search | [\[Blog Post\]](https://todd.ginsberg.com/post/advent-of-code/2020/day13/) [\[Code\]](https://github.com/tginsberg/advent-2020-kotlin/blob/master/src/main/kotlin/com/ginsberg/advent2020/Day13.kt) [\[AoC\]](http://adventofcode.com/2020/day/13) | 30 | | 14 | Docking Data | [\[Blog Post\]](https://todd.ginsberg.com/post/advent-of-code/2020/day14/) [\[Code\]](https://github.com/tginsberg/advent-2020-kotlin/blob/master/src/main/kotlin/com/ginsberg/advent2020/Day14.kt) [\[AoC\]](http://adventofcode.com/2020/day/14) | 31 | | 15 | Rambunctious Recitation | [\[Blog Post\]](https://todd.ginsberg.com/post/advent-of-code/2020/day15/) [\[Code\]](https://github.com/tginsberg/advent-2020-kotlin/blob/master/src/main/kotlin/com/ginsberg/advent2020/Day15.kt) [\[AoC\]](http://adventofcode.com/2020/day/15) | 32 | | 16 | Ticket Translation | [\[Blog Post\]](https://todd.ginsberg.com/post/advent-of-code/2020/day16/) [\[Code\]](https://github.com/tginsberg/advent-2020-kotlin/blob/master/src/main/kotlin/com/ginsberg/advent2020/Day16.kt) [\[AoC\]](http://adventofcode.com/2020/day/16) | 33 | | 17 | Conway Cubes | [\[Blog Post\]](https://todd.ginsberg.com/post/advent-of-code/2020/day17/) [\[Code\]](https://github.com/tginsberg/advent-2020-kotlin/blob/master/src/main/kotlin/com/ginsberg/advent2020/Day17.kt) [\[AoC\]](http://adventofcode.com/2020/day/17) | 34 | | 18 | Operation Order | [\[Blog Post\]](https://todd.ginsberg.com/post/advent-of-code/2020/day18/) [\[Code\]](https://github.com/tginsberg/advent-2020-kotlin/blob/master/src/main/kotlin/com/ginsberg/advent2020/Day18.kt) [\[AoC\]](http://adventofcode.com/2020/day/18) | 35 | | 19 | Monster Messages | [\[Blog Post\]](https://todd.ginsberg.com/post/advent-of-code/2020/day19/) [\[Code\]](https://github.com/tginsberg/advent-2020-kotlin/blob/master/src/main/kotlin/com/ginsberg/advent2020/Day19.kt) [\[AoC\]](http://adventofcode.com/2020/day/19) | 36 | | 20 | Jurassic Jigsaw | [\[Blog Post\]](https://todd.ginsberg.com/post/advent-of-code/2020/day20/) [\[Code\]](https://github.com/tginsberg/advent-2020-kotlin/blob/master/src/main/kotlin/com/ginsberg/advent2020/Day20.kt) [\[AoC\]](http://adventofcode.com/2020/day/20) | 37 | | 21 | Allergen Assessment | [\[Blog Post\]](https://todd.ginsberg.com/post/advent-of-code/2020/day21/) [\[Code\]](https://github.com/tginsberg/advent-2020-kotlin/blob/master/src/main/kotlin/com/ginsberg/advent2020/Day21.kt) [\[AoC\]](http://adventofcode.com/2020/day/21) | 38 | | 22 | Crab Combat | [\[Blog Post\]](https://todd.ginsberg.com/post/advent-of-code/2020/day22/) [\[Code\]](https://github.com/tginsberg/advent-2020-kotlin/blob/master/src/main/kotlin/com/ginsberg/advent2020/Day22.kt) [\[AoC\]](http://adventofcode.com/2020/day/22) | 39 | | 23 | Crab Cups | [\[Blog Post\]](https://todd.ginsberg.com/post/advent-of-code/2020/day23/) [\[Code\]](https://github.com/tginsberg/advent-2020-kotlin/blob/master/src/main/kotlin/com/ginsberg/advent2020/Day23.kt) [\[AoC\]](http://adventofcode.com/2020/day/23) | 40 | | 24 | Lobby Layout | [\[Blog Post\]](https://todd.ginsberg.com/post/advent-of-code/2020/day24/) [\[Code\]](https://github.com/tginsberg/advent-2020-kotlin/blob/master/src/main/kotlin/com/ginsberg/advent2020/Day24.kt) [\[AoC\]](http://adventofcode.com/2020/day/24) | 41 | | 25 | Combo Breaker | [\[Blog Post\]](https://todd.ginsberg.com/post/advent-of-code/2020/day25/) [\[Code\]](https://github.com/tginsberg/advent-2020-kotlin/blob/master/src/main/kotlin/com/ginsberg/advent2020/Day25.kt) [\[AoC\]](http://adventofcode.com/2020/day/25) | 42 | 43 | 44 | Copyright © 2020 by Todd Ginsberg. 45 | -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 6 | 7 | /* 8 | * Copyright (c) 2020 by Todd Ginsberg 9 | */ 10 | 11 | plugins { 12 | kotlin("jvm") version "1.4.20" 13 | } 14 | 15 | repositories { 16 | mavenCentral() 17 | } 18 | 19 | dependencies { 20 | testApi("org.junit.jupiter:junit-jupiter-engine:5.7.0") 21 | testImplementation("org.assertj:assertj-core:3.18.1") 22 | } 23 | 24 | tasks { 25 | withType { 26 | kotlinOptions { 27 | jvmTarget = "1.8" 28 | freeCompilerArgs = listOf("-Xjsr305=strict") 29 | } 30 | } 31 | test { 32 | useJUnitPlatform() 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2020 by Todd Ginsberg 3 | # 4 | 5 | distributionBase=GRADLE_USER_HOME 6 | distributionPath=wrapper/dists 7 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip 8 | zipStoreBase=GRADLE_USER_HOME 9 | zipStorePath=wrapper/dists 10 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright (c) 2020 by Todd Ginsberg 5 | # 6 | 7 | ############################################################################## 8 | ## 9 | ## Gradle start up script for UN*X 10 | ## 11 | ############################################################################## 12 | 13 | # Attempt to set APP_HOME 14 | # Resolve links: $0 may be a link 15 | PRG="$0" 16 | # Need this for relative symlinks. 17 | while [ -h "$PRG" ] ; do 18 | ls=`ls -ld "$PRG"` 19 | link=`expr "$ls" : '.*-> \(.*\)$'` 20 | if expr "$link" : '/.*' > /dev/null; then 21 | PRG="$link" 22 | else 23 | PRG=`dirname "$PRG"`"/$link" 24 | fi 25 | done 26 | SAVED="`pwd`" 27 | cd "`dirname \"$PRG\"`/" >/dev/null 28 | APP_HOME="`pwd -P`" 29 | cd "$SAVED" >/dev/null 30 | 31 | APP_NAME="Gradle" 32 | APP_BASE_NAME=`basename "$0"` 33 | 34 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 35 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 36 | 37 | # Use the maximum available, or set MAX_FD != -1 to use that value. 38 | MAX_FD="maximum" 39 | 40 | warn () { 41 | echo "$*" 42 | } 43 | 44 | die () { 45 | echo 46 | echo "$*" 47 | echo 48 | exit 1 49 | } 50 | 51 | # OS specific support (must be 'true' or 'false'). 52 | cygwin=false 53 | msys=false 54 | darwin=false 55 | nonstop=false 56 | case "`uname`" in 57 | CYGWIN* ) 58 | cygwin=true 59 | ;; 60 | Darwin* ) 61 | darwin=true 62 | ;; 63 | MINGW* ) 64 | msys=true 65 | ;; 66 | NONSTOP* ) 67 | nonstop=true 68 | ;; 69 | esac 70 | 71 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 72 | 73 | # Determine the Java command to use to start the JVM. 74 | if [ -n "$JAVA_HOME" ] ; then 75 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 76 | # IBM's JDK on AIX uses strange locations for the executables 77 | JAVACMD="$JAVA_HOME/jre/sh/java" 78 | else 79 | JAVACMD="$JAVA_HOME/bin/java" 80 | fi 81 | if [ ! -x "$JAVACMD" ] ; then 82 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 83 | 84 | Please set the JAVA_HOME variable in your environment to match the 85 | location of your Java installation." 86 | fi 87 | else 88 | JAVACMD="java" 89 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 90 | 91 | Please set the JAVA_HOME variable in your environment to match the 92 | location of your Java installation." 93 | fi 94 | 95 | # Increase the maximum file descriptors if we can. 96 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 97 | MAX_FD_LIMIT=`ulimit -H -n` 98 | if [ $? -eq 0 ] ; then 99 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 100 | MAX_FD="$MAX_FD_LIMIT" 101 | fi 102 | ulimit -n $MAX_FD 103 | if [ $? -ne 0 ] ; then 104 | warn "Could not set maximum file descriptor limit: $MAX_FD" 105 | fi 106 | else 107 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 108 | fi 109 | fi 110 | 111 | # For Darwin, add options to specify how the application appears in the dock 112 | if $darwin; then 113 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 114 | fi 115 | 116 | # For Cygwin or MSYS, switch paths to Windows format before running java 117 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 118 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 119 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 120 | JAVACMD=`cygpath --unix "$JAVACMD"` 121 | 122 | # We build the pattern for arguments to be converted via cygpath 123 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 124 | SEP="" 125 | for dir in $ROOTDIRSRAW ; do 126 | ROOTDIRS="$ROOTDIRS$SEP$dir" 127 | SEP="|" 128 | done 129 | OURCYGPATTERN="(^($ROOTDIRS))" 130 | # Add a user-defined pattern to the cygpath arguments 131 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 132 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 133 | fi 134 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 135 | i=0 136 | for arg in "$@" ; do 137 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 138 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 139 | 140 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 141 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 142 | else 143 | eval `echo args$i`="\"$arg\"" 144 | fi 145 | i=`expr $i + 1` 146 | done 147 | case $i in 148 | 0) set -- ;; 149 | 1) set -- "$args0" ;; 150 | 2) set -- "$args0" "$args1" ;; 151 | 3) set -- "$args0" "$args1" "$args2" ;; 152 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 153 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 154 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 155 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 156 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 157 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 158 | esac 159 | fi 160 | 161 | # Escape application args 162 | save () { 163 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 164 | echo " " 165 | } 166 | APP_ARGS=`save "$@"` 167 | 168 | # Collect all arguments for the java command, following the shell quoting and substitution rules 169 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 170 | 171 | exec "$JAVACMD" "$@" 172 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 34 | 35 | @rem Find java.exe 36 | if defined JAVA_HOME goto findJavaFromJavaHome 37 | 38 | set JAVA_EXE=java.exe 39 | %JAVA_EXE% -version >NUL 2>&1 40 | if "%ERRORLEVEL%" == "0" goto init 41 | 42 | echo. 43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 44 | echo. 45 | echo Please set the JAVA_HOME variable in your environment to match the 46 | echo location of your Java installation. 47 | 48 | goto fail 49 | 50 | :findJavaFromJavaHome 51 | set JAVA_HOME=%JAVA_HOME:"=% 52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 53 | 54 | if exist "%JAVA_EXE%" goto init 55 | 56 | echo. 57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 58 | echo. 59 | echo Please set the JAVA_HOME variable in your environment to match the 60 | echo location of your Java installation. 61 | 62 | goto fail 63 | 64 | :init 65 | @rem Get command-line arguments, handling Windows variants 66 | 67 | if not "%OS%" == "Windows_NT" goto win9xME_args 68 | 69 | :win9xME_args 70 | @rem Slurp the command line arguments. 71 | set CMD_LINE_ARGS= 72 | set _SKIP=2 73 | 74 | :win9xME_args_slurp 75 | if "x%~1" == "x" goto execute 76 | 77 | set CMD_LINE_ARGS=%* 78 | 79 | :execute 80 | @rem Setup the command line 81 | 82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 83 | 84 | @rem Execute Gradle 85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 86 | 87 | :end 88 | @rem End local scope for the variables with windows NT shell 89 | if "%ERRORLEVEL%"=="0" goto mainEnd 90 | 91 | :fail 92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 93 | rem the _cmd.exe /c_ return code! 94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 95 | exit /b 1 96 | 97 | :mainEnd 98 | if "%OS%"=="Windows_NT" endlocal 99 | 100 | :omega 101 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | rootProject.name = "advent-2020-kotlin" 6 | -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Day01.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | /** 6 | * Advent of Code 2020, Day 1 - Report Repair 7 | * Problem Description: http://adventofcode.com/2020/day/1 8 | * Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2020/day1/ 9 | */ 10 | package com.ginsberg.advent2020 11 | 12 | class Day01(data: List) { 13 | 14 | private val input = data.sorted() 15 | 16 | fun solvePart1(): Int = 17 | input.mapIndexedNotNull { idx, a -> 18 | input 19 | .drop(idx + 1) 20 | .dropWhile { a + it < 2020 } 21 | .take(1) 22 | .firstOrNull { a + it == 2020 } 23 | ?.let { a * it } 24 | }.first() 25 | 26 | fun solvePart2(): Int = 27 | input.mapIndexedNotNull { aIdx, a -> 28 | input 29 | .drop(aIdx + 1) 30 | .mapIndexedNotNull { bIdx, b -> 31 | input 32 | .drop(bIdx + 1) 33 | .dropWhile { a + b + it < 2020 } 34 | .take(1) 35 | .firstOrNull { a + b + it == 2020 } 36 | ?.let { a * b * it } 37 | }.firstOrNull() 38 | }.first() 39 | 40 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Day02.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | /** 6 | * Advent of Code 2020, Day 2 - Password Philosophy 7 | * Problem Description: http://adventofcode.com/2020/day/2 8 | * Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2020/day2/ 9 | */ 10 | package com.ginsberg.advent2020 11 | 12 | class Day02(input: List) { 13 | 14 | private val data: List = input.map { PasswordRow.of(it) } 15 | 16 | fun solvePart1(): Int = 17 | data.count { it.validPart1 } 18 | 19 | fun solvePart2(): Int = 20 | data.count { it.validPart2 } 21 | 22 | data class PasswordRow(val range: IntRange, val letter: Char, val password: String) { 23 | 24 | val validPart1 = password.count { it == letter } in range 25 | 26 | val validPart2 = (password[range.first-1] == letter) xor (password[range.last-1] == letter) 27 | 28 | companion object { 29 | 30 | private val pattern = """^(\d+)-(\d+) (\w): (.+)$""".toRegex() 31 | 32 | fun of(input: String): PasswordRow { 33 | val (min, max, letter, password) = pattern.find(input)!!.destructured 34 | return PasswordRow(min.toInt() .. max.toInt(), letter.first(), password) 35 | } 36 | } 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Day03.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | /** 6 | * Advent of Code 2020, Day 3 - Toboggan Trajectory 7 | * Problem Description: http://adventofcode.com/2020/day/3 8 | * Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2020/day3/ 9 | */ 10 | package com.ginsberg.advent2020 11 | 12 | class Day03(private val forest: List) { 13 | 14 | private val width: Int = forest.first().length 15 | private val height: Int = forest.size 16 | 17 | fun solvePart1(): Int = 18 | treesOnSlope(3 to 1) 19 | 20 | fun solvePart2(): Long = 21 | listOf(1 to 1, 3 to 1, 5 to 1, 7 to 1, 1 to 2) 22 | .map { treesOnSlope(it).toLong() } 23 | .reduce { a, b -> a * b } 24 | 25 | private fun treesOnSlope(slope: Pair) = 26 | path(slope).count { it in forest } 27 | 28 | private fun path(slope: Pair): Sequence> = generateSequence(Pair(0,0)) { prev -> 29 | (prev + slope).takeIf { next -> next.second < height } 30 | } 31 | 32 | private operator fun Pair.plus(that: Pair): Pair = 33 | Pair(this.first+that.first, this.second+that.second) 34 | 35 | private operator fun List.contains(location: Pair): Boolean = 36 | this[location.second][location.first % width] == '#' 37 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Day04.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | /** 6 | * Advent of Code 2020, Day 4 - Passport Processing 7 | * Problem Description: http://adventofcode.com/2020/day/4 8 | * Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2020/day4/ 9 | */ 10 | package com.ginsberg.advent2020 11 | 12 | class Day04(input: String) { 13 | 14 | private val passports: List = input.split("\n\n") 15 | 16 | fun solvePart1(): Int = 17 | passports 18 | .count { passport -> expectedFields.all { passport.contains(it)} } 19 | 20 | fun solvePart2(): Int = 21 | passports 22 | .count { passport -> fieldPatterns.all { it.containsMatchIn(passport) } } 23 | 24 | companion object { 25 | 26 | private val expectedFields = listOf("byr:", "iyr:", "eyr:", "hgt:", "hcl:", "ecl:", "pid:") 27 | 28 | private val fieldPatterns = listOf( 29 | """\bbyr:(19[2-9][0-9]|200[0-2])\b""", 30 | """\biyr:(201[0-9]|2020)\b""", 31 | """\beyr:(202[0-9]|2030)\b""", 32 | """\bhgt:((1([5-8][0-9]|9[0-3])cm)|((59|6[0-9]|7[0-6])in))\b""", 33 | """\bhcl:#[0-9a-f]{6}\b""", 34 | """\becl:(amb|blu|brn|gry|grn|hzl|oth)\b""", 35 | """\bpid:[0-9]{9}\b""" 36 | ).map { it.toRegex() } 37 | } 38 | 39 | } 40 | 41 | -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Day05.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | /** 6 | * Advent of Code 2020, Day 5 - Binary Boarding 7 | * Problem Description: http://adventofcode.com/2020/day/5 8 | * Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2020/day5/ 9 | */ 10 | package com.ginsberg.advent2020 11 | 12 | class Day05(private val input: List) { 13 | 14 | fun solvePart1(): Int = 15 | input.map { seatId(it) }.maxOrNull() ?: throw IllegalStateException("No answer") 16 | 17 | fun solvePart2(): Int = 18 | input.map { seatId(it) }.sorted().zipWithNext().first { it.second - it.first != 1 }.first + 1 19 | 20 | private fun seatId(pattern: String): Int = 21 | pattern.map { if (it in setOf('B', 'R')) '1' else '0' }.joinToString("").toInt(2) 22 | } 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Day06.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | /** 6 | * Advent of Code 2020, Day 6 - Custom Customs 7 | * Problem Description: http://adventofcode.com/2020/day/6 8 | * Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2020/day6/ 9 | */ 10 | package com.ginsberg.advent2020 11 | 12 | class Day06(input: String) { 13 | 14 | private val answers: List> = input 15 | .split("\n\n") 16 | .map { it.lines().filter { line -> line.isNotBlank() } } 17 | 18 | fun solvePart1(): Int = 19 | answers.sumBy { it.joinToString("").toSet().size } 20 | 21 | fun solvePart2(): Int = 22 | answers.sumBy { group -> 23 | group 24 | .joinToString("") 25 | .groupingBy { it } 26 | .eachCount() 27 | .count { it.value == group.size } 28 | } 29 | } 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Day07.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | /** 6 | * Advent of Code 2020, Day 7 - Handy Haversacks 7 | * Problem Description: http://adventofcode.com/2020/day/7 8 | * Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2020/day7/ 9 | */ 10 | package com.ginsberg.advent2020 11 | 12 | class Day07(input: List) { 13 | 14 | private val relationships: Set = parseInput(input) 15 | 16 | fun solvePart1(): Int = 17 | findParents().size - 1 18 | 19 | fun solvePart2(): Int = 20 | baggageCost() - 1 21 | 22 | private fun findParents(bag: String = "shiny gold"): Set = 23 | relationships 24 | .filter { it.child == bag } 25 | .flatMap { findParents(it.parent) }.toSet() + bag 26 | 27 | private fun baggageCost(bag: String = "shiny gold"): Int = 28 | relationships 29 | .filter { it.parent == bag } 30 | .sumBy { it.cost * baggageCost(it.child) } + 1 31 | 32 | private fun parseInput(input: List): Set = 33 | input.filterNot { it.contains("no other") }.flatMap { row -> 34 | val parts = row.replace(unusedText, "").split(whitespace) 35 | val parent = parts.take(2).joinToString(" ") 36 | parts.drop(2).windowed(3, 3, false).map { child -> 37 | BagRule( 38 | parent, 39 | child.first().toInt(), 40 | child.drop(1).joinToString(" ") 41 | ) 42 | } 43 | }.toSet() 44 | 45 | private data class BagRule(val parent: String, val cost: Int, val child: String) 46 | 47 | companion object { 48 | private val unusedText = """bags|bag|contain|,|\.""".toRegex() 49 | private val whitespace = """\s+""".toRegex() 50 | } 51 | } 52 | 53 | 54 | -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Day08.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | /** 6 | * Advent of Code 2020, Day 8 - Handheld Halting 7 | * Problem Description: http://adventofcode.com/2020/day/8 8 | * Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2020/day8/ 9 | */ 10 | package com.ginsberg.advent2020 11 | 12 | class Day08(input: List) { 13 | 14 | private val instructions: List = input.map { Instruction.of(it) } 15 | 16 | fun solvePart1(): Int = 17 | Computer(instructions).run { 18 | runUntilTerminate() 19 | accumulator 20 | } 21 | 22 | fun solvePart2(): Int = 23 | instructions 24 | .indices 25 | .asSequence() 26 | .mapNotNull { index -> instructions.flipIndexOrNull(index) } 27 | .mapNotNull { inst -> 28 | Computer(inst).run { 29 | if (runUntilTerminate() == Computer.ExecutionState.HALTED) accumulator 30 | else null 31 | } 32 | }.first() 33 | 34 | 35 | private fun List.flipIndexOrNull(index: Int): List? = 36 | this[index].flipOrNull()?.let { flipped -> 37 | this.toMutableList().apply { this[index] = flipped } 38 | } 39 | 40 | data class Instruction(val name: String, val argument: Int) { 41 | fun flipOrNull(): Instruction? = 42 | when (name) { 43 | "jmp" -> Instruction("nop", argument) 44 | "nop" -> Instruction("jmp", argument) 45 | else -> null 46 | } 47 | 48 | companion object { 49 | fun of(input: String): Instruction = 50 | input.split(" ").run { 51 | Instruction(this.first(), this.last().toInt()) 52 | } 53 | } 54 | } 55 | 56 | data class Computer(val instructions: List) { 57 | enum class ExecutionState { 58 | HALTED, 59 | INFINITE_LOOP, 60 | RUNNING 61 | } 62 | 63 | private val executed = mutableSetOf() 64 | private var instructionPointer: Int = 0 65 | var accumulator: Int = 0 66 | 67 | fun runUntilTerminate(): ExecutionState = 68 | generateSequence { executeStep() }.first { it != ExecutionState.RUNNING } 69 | 70 | private fun executeStep(): ExecutionState { 71 | return when (instructionPointer) { 72 | in executed -> ExecutionState.INFINITE_LOOP 73 | !in instructions.indices -> ExecutionState.HALTED 74 | else -> { 75 | val current = instructions[instructionPointer] 76 | executed += instructionPointer 77 | 78 | when (current.name) { 79 | "acc" -> { 80 | accumulator += current.argument 81 | instructionPointer += 1 82 | } 83 | "jmp" -> instructionPointer += current.argument 84 | "nop" -> instructionPointer += 1 85 | } 86 | ExecutionState.RUNNING 87 | } 88 | } 89 | } 90 | } 91 | } 92 | 93 | 94 | -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Day09.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | /** 6 | * Advent of Code 2020, Day 9 - Encoding Error 7 | * Problem Description: http://adventofcode.com/2020/day/9 8 | * Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2020/day9/ 9 | */ 10 | package com.ginsberg.advent2020 11 | 12 | class Day09(private val input: List) { 13 | 14 | fun solvePart1(preamble: Int = 25): Long = 15 | input.windowed(preamble+1, 1, false).first { !it.preambleIsValid() }.last() 16 | 17 | fun solvePart2(preamble: Int = 25): Long { 18 | val target = solvePart1(preamble) 19 | val range = input.takeWhile { it != target }.findRangeSummingTo(target) 20 | return range.minOrNull()!! + range.maxOrNull()!! 21 | } 22 | 23 | private fun List.preambleIsValid(): Boolean { 24 | val target = this.last() 25 | val subjects = this.dropLast(1).toSet() 26 | return subjects.any { target - it in subjects } 27 | } 28 | 29 | private fun List.findRangeSummingTo(target: Long): List = 30 | this.indices.mapNotNull { start -> 31 | this.indices.drop(start+1).reversed().mapNotNull { end -> 32 | this.subList(start, end).takeIf { it.sum() == target } 33 | }.firstOrNull() 34 | }.first() 35 | } 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Day10.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | /** 6 | * Advent of Code 2020, Day 10 - Adapter Array 7 | * Problem Description: http://adventofcode.com/2020/day/10 8 | * Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2020/day10/ 9 | */ 10 | package com.ginsberg.advent2020 11 | 12 | class Day10(input: List) { 13 | 14 | private val adapters: List = input.plus(0).plus(input.maxOrNull()!! + 3).sorted() 15 | 16 | fun solvePart1(): Int = 17 | adapters 18 | .asSequence() 19 | .zipWithNext() 20 | .map { it.second - it.first } 21 | .groupingBy { it } 22 | .eachCount() 23 | .run { 24 | getOrDefault(1, 1) * getOrDefault(3, 1) 25 | } 26 | 27 | fun solvePart2(): Long { 28 | val pathsByAdapter: MutableMap = mutableMapOf(0 to 1L) 29 | 30 | adapters.drop(1).forEach { adapter -> 31 | pathsByAdapter[adapter] = (1 .. 3).map { lookBack -> 32 | pathsByAdapter.getOrDefault(adapter - lookBack, 0) 33 | }.sum() 34 | } 35 | 36 | return pathsByAdapter.getValue(adapters.last()) 37 | } 38 | 39 | } 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Day11.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | /** 6 | * Advent of Code 2020, Day 11 - Seating System 7 | * Problem Description: http://adventofcode.com/2020/day/11 8 | * Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2020/day11/ 9 | */ 10 | package com.ginsberg.advent2020 11 | 12 | typealias Seats = Array 13 | typealias Seat = Pair 14 | 15 | class Day11(input: List) { 16 | 17 | private val seats: Seats = input.map { it.toCharArray() }.toTypedArray() 18 | 19 | fun solvePart1(): Int = 20 | findStableMap(4, this::countImmediateNeighbors) 21 | 22 | fun solvePart2(): Int = 23 | findStableMap(5, this::countFarNeighbors) 24 | 25 | private fun findStableMap(tolerance: Int, countFunction: (Seats, Seat) -> Int): Int = 26 | generateSequence(seats) { it.next(tolerance, countFunction) } 27 | .zipWithNext() 28 | .first { it.first.contentDeepEquals(it.second) } 29 | .first 30 | .occupied() 31 | 32 | private fun Seats.next(tolerance: Int, countFunction: (Seats, Seat) -> Int): Seats = 33 | this.mapIndexed { x, row -> 34 | row.mapIndexed { y, spot -> 35 | val occupied = countFunction(this, Seat(x, y)) 36 | when { 37 | spot == 'L' && occupied == 0 -> '#' 38 | spot == '#' && occupied >= tolerance -> 'L' 39 | else -> spot 40 | } 41 | }.toCharArray() 42 | }.toTypedArray() 43 | 44 | private fun countImmediateNeighbors(seats: Seats, seat: Seat): Int = 45 | neighbors 46 | .map { it + seat } 47 | .filter { it in seats } 48 | .count { seats[it.first][it.second] == '#' } 49 | 50 | private fun countFarNeighbors(seats: Seats, seat: Seat): Int = 51 | neighbors 52 | .mapNotNull { findSeatOnVector(seats, seat, it) } 53 | .count { it == '#' } 54 | 55 | private fun findSeatOnVector(seats: Seats, seat: Seat, vector: Seat): Char? = 56 | generateSequence(seat + vector) { it + vector } 57 | .map { if (it in seats) seats[it.first][it.second] else null } 58 | .first { it == null || it != '.' } 59 | 60 | private fun Seats.occupied(): Int = 61 | this.sumBy { it.count { row -> row == '#' } } 62 | 63 | private operator fun Seats.contains(seat: Seat): Boolean = 64 | seat.first in this.indices && seat.second in this.first().indices 65 | 66 | private operator fun Seat.plus(that: Seat): Seat = 67 | Seat(this.first + that.first, this.second + that.second) 68 | 69 | companion object { 70 | // @formatter:off 71 | private val neighbors = sequenceOf( 72 | -1 to -1, -1 to 0, -1 to 1, 73 | 0 to -1, 0 to 1, 74 | 1 to -1, 1 to 0, 1 to 1 75 | ) 76 | // @formatter:on 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Day12.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | /** 6 | * Advent of Code 2020, Day 12 - Rain Risk 7 | * Problem Description: http://adventofcode.com/2020/day/12 8 | * Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2020/day12/ 9 | */ 10 | package com.ginsberg.advent2020 11 | 12 | class Day12(private val input: List) { 13 | 14 | fun solvePart1(): Int = 15 | input.fold(Ship(Point2D.ORIGIN, Direction.East)) { ship, instruction -> 16 | val command = instruction.first() 17 | val amount = instruction.substring(1).toInt() 18 | when (command) { 19 | 'N' -> ship.move(Direction.North, amount) 20 | 'S' -> ship.move(Direction.South, amount) 21 | 'E' -> ship.move(Direction.East, amount) 22 | 'W' -> ship.move(Direction.West, amount) 23 | 'F' -> ship.forward(amount) 24 | 'L' -> ship.turnLeft(amount / 90) 25 | 'R' -> ship.turnRight(amount / 90) 26 | else -> throw IllegalArgumentException("Unknown instruction: $instruction") 27 | } 28 | }.at distanceTo Point2D.ORIGIN 29 | 30 | fun solvePart2(): Int { 31 | var waypoint = Waypoint() 32 | var ship = Ship() 33 | input.forEach { instruction -> 34 | val command = instruction.first() 35 | val amount = instruction.substring(1).toInt() 36 | when (command) { 37 | 'N' -> waypoint = waypoint.move(Direction.North, amount) 38 | 'S' -> waypoint = waypoint.move(Direction.South, amount) 39 | 'E' -> waypoint = waypoint.move(Direction.East, amount) 40 | 'W' -> waypoint = waypoint.move(Direction.West, amount) 41 | 'F' -> ship = ship.copy(at = ship.at + (waypoint.at * amount)) 42 | 'L' -> waypoint = waypoint.turnLeft(amount / 90) 43 | 'R' -> waypoint = waypoint.turnRight(amount / 90) 44 | else -> throw IllegalArgumentException("Unknown instruction: $instruction") 45 | } 46 | } 47 | return Point2D.ORIGIN distanceTo ship.at 48 | } 49 | 50 | 51 | data class Waypoint(val at: Point2D = Point2D(-1, 10)) { 52 | fun move(dir: Direction, amount: Int): Waypoint = 53 | Waypoint(at + (dir.offset * amount)) 54 | 55 | fun turnLeft(amount: Int): Waypoint = 56 | (0 until amount).fold(this) { carry, _ -> 57 | Waypoint(carry.at.rotateLeft()) 58 | } 59 | 60 | fun turnRight(amount: Int): Waypoint = 61 | (0 until amount).fold(this) { carry, _ -> 62 | Waypoint(carry.at.rotateRight()) 63 | } 64 | } 65 | 66 | data class Ship(val at: Point2D = Point2D.ORIGIN, val facing: Direction = Direction.East) { 67 | 68 | fun forward(amount: Int): Ship = 69 | copy(at = at + (facing.offset * amount)) 70 | 71 | fun move(dir: Direction, amount: Int): Ship = 72 | copy(at = at + (dir.offset * amount)) 73 | 74 | fun turnLeft(times: Int): Ship = 75 | (0 until times).fold(this) { carry, _ -> 76 | carry.copy(facing = carry.facing.turnLeft) 77 | } 78 | 79 | fun turnRight(times: Int): Ship = 80 | (0 until times).fold(this) { carry, _ -> 81 | carry.copy(facing = carry.facing.turnRight) 82 | } 83 | } 84 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Day13.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | /** 6 | * Advent of Code 2020, Day 13 - Shuttle Search 7 | * Problem Description: http://adventofcode.com/2020/day/13 8 | * Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2020/day13/ 9 | */ 10 | package com.ginsberg.advent2020 11 | 12 | class Day13(input: List) { 13 | 14 | private val startTime: Int = input.first().toInt() 15 | private val busses: List = input 16 | .last() 17 | .split(",") 18 | .mapNotNull { s -> if (s == "x") null else s.toInt() } 19 | 20 | private val indexedBusses: List = input 21 | .last() 22 | .split(",") 23 | .mapIndexedNotNull { index, s -> if (s == "x") null else IndexedBus(index, s.toLong()) } 24 | 25 | fun solvePart1(): Int = 26 | generateSequence(startTime) { it + 1 } 27 | .mapNotNull { time -> 28 | busses 29 | .firstOrNull { bus -> time % bus == 0 } 30 | ?.let { bus -> Pair(time, bus) } 31 | } 32 | .first() 33 | .run { (first - startTime) * second } 34 | 35 | fun solvePart2(): Long { 36 | var stepSize = indexedBusses.first().bus 37 | var time = 0L 38 | indexedBusses.drop(1).forEach { (offset, bus) -> 39 | while ((time + offset) % bus != 0L) { 40 | time += stepSize 41 | } 42 | stepSize *= bus // New Ratio! 43 | } 44 | return time 45 | } 46 | 47 | data class IndexedBus(val index: Int, val bus: Long) 48 | } 49 | -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Day14.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | /** 6 | * Advent of Code 2020, Day 14 - Docking Data 7 | * Problem Description: http://adventofcode.com/2020/day/14 8 | * Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2020/day14/ 9 | */ 10 | package com.ginsberg.advent2020 11 | 12 | class Day14(private val input: List) { 13 | 14 | private val memory: MutableMap = mutableMapOf() 15 | 16 | fun solvePart1(): Long { 17 | var mask = DEFAULT_MASK 18 | input.forEach { instruction -> 19 | if (instruction.startsWith("mask")) { 20 | mask = instruction.substringAfter("= ") 21 | } else { 22 | val address = instruction.substringAfter("[").substringBefore("]").toLong() 23 | val value = instruction.substringAfter("= ") 24 | memory[address] = value maskedWith mask 25 | } 26 | } 27 | 28 | return memory.values.sum() 29 | } 30 | 31 | fun solvePart2(): Long { 32 | var mask = DEFAULT_MASK 33 | input.forEach { instruction -> 34 | if (instruction.startsWith("mask")) { 35 | mask = instruction.substringAfter("= ") 36 | } else { 37 | val unmaskedAddress = instruction.substringAfter("[").substringBefore("]") 38 | val value = instruction.substringAfter("= ").toLong() 39 | unmaskedAddress.generateAddressMasks(mask).forEach { address -> 40 | memory[address] = value 41 | } 42 | 43 | } 44 | } 45 | 46 | return memory.values.sum() 47 | } 48 | 49 | private infix fun String.maskedWith(mask: String): Long = 50 | this.toBinary().zip(mask).map { (valueChar, maskChar) -> 51 | maskChar.takeUnless { it == 'X' } ?: valueChar 52 | }.joinToString("").toLong(2) 53 | 54 | private fun String.toBinary(): String = 55 | this.toLong().toString(2).padStart(36, '0') 56 | 57 | private fun String.generateAddressMasks(mask: String): List { 58 | val addresses = mutableListOf(this.toBinary().toCharArray()) 59 | mask.forEachIndexed { idx, bit -> 60 | when (bit) { 61 | '1' -> addresses.forEach { it[idx] = '1' } 62 | 'X' -> { 63 | addresses.forEach { it[idx] = '1' } 64 | addresses.addAll( 65 | addresses.map { 66 | it.copyOf().apply { 67 | this[idx] = '0' 68 | } 69 | } 70 | ) 71 | } 72 | } 73 | } 74 | return addresses.map { it.joinToString("").toLong(2) } 75 | } 76 | 77 | companion object { 78 | const val DEFAULT_MASK = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" 79 | } 80 | } 81 | 82 | -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Day15.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | /** 6 | * Advent of Code 2020, Day 15 - Rambunctious Recitation 7 | * Problem Description: http://adventofcode.com/2020/day/15 8 | * Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2020/day15/ 9 | */ 10 | package com.ginsberg.advent2020 11 | 12 | class Day15(input: String) { 13 | 14 | private val startingNumbers = input.split(",").map { it.toInt() } 15 | 16 | fun solve(turns: Int): Int = 17 | memoryGame().drop(turns-1).first() 18 | 19 | private fun memoryGame(): Sequence = sequence { 20 | yieldAll(startingNumbers) 21 | val memory = startingNumbers.mapIndexed { index, i -> i to index }.toMap().toMutableMap() 22 | var turns = startingNumbers.size 23 | var sayNext = 0 24 | while(true) { 25 | yield(sayNext) 26 | val lastTimeSpoken = memory[sayNext] ?: turns 27 | memory[sayNext] = turns 28 | sayNext = turns - lastTimeSpoken 29 | turns++ 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Day16.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | /** 6 | * Advent of Code 2020, Day 16 - Ticket Translation 7 | * Problem Description: http://adventofcode.com/2020/day/16 8 | * Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2020/day16/ 9 | */ 10 | package com.ginsberg.advent2020 11 | 12 | class Day16(input: List) { 13 | 14 | private val ticketRules: Map> = parseTicketRules(input) 15 | private val allRuleRanges: List = ticketRules.values.flatten() 16 | private val ourTicket: List = parseOurTicket(input) 17 | private val nearbyTickets: List> = parseNearbyTickets(input) 18 | 19 | fun solvePart1(): Int = 20 | nearbyTickets.sumBy { ticket -> 21 | ticket.filter { field -> 22 | allRuleRanges.none { rule -> field in rule } 23 | }.sum() 24 | } 25 | 26 | fun solvePart2(): Long { 27 | val validTickets = nearbyTickets.filter { it.isValidTicket() } 28 | 29 | val possibleFieldRules: Map> = ticketRules.keys.map { rule -> 30 | rule to ourTicket.indices.filter { column -> 31 | validTickets.columnPassesRule(column, rule) 32 | }.toMutableSet() 33 | }.toMap() 34 | 35 | val foundRules = reduceRules(possibleFieldRules) 36 | 37 | return foundRules.entries 38 | .filter { it.key.startsWith("departure") } 39 | .map { ourTicket[it.value].toLong() } 40 | .reduce { a, b -> a * b } 41 | } 42 | 43 | private fun reduceRules(possibleRules: Map>): Map { 44 | val foundRules = mutableMapOf() 45 | while(foundRules.size < possibleRules.size) { 46 | possibleRules.entries 47 | .filter { (_, possibleValues) -> possibleValues.size == 1 } 48 | .forEach { (rule, possibleValues) -> 49 | val columnNumber = possibleValues.first() 50 | foundRules[rule] = columnNumber 51 | possibleRules.values.forEach { it.remove(columnNumber) } 52 | } 53 | } 54 | return foundRules 55 | } 56 | 57 | private fun List>.columnPassesRule(column: Int, fieldName: String): Boolean = 58 | this.all { ticket -> 59 | ticketRules.getValue(fieldName).any { rule -> ticket[column] in rule } 60 | } 61 | 62 | private fun List.isValidTicket(): Boolean = 63 | this.all { field -> 64 | allRuleRanges.any { rule -> 65 | field in rule 66 | } 67 | } 68 | 69 | private fun parseTicketRules(input: List): Map> = 70 | input.takeWhile { it.isNotEmpty() }.map { line -> 71 | val (name, start1, end1, start2, end2) = ticketRuleRegex.matchEntire(line)!!.destructured 72 | name to listOf( 73 | start1.toInt() .. end1.toInt(), 74 | start2.toInt() .. end2.toInt() 75 | ) 76 | }.toMap() 77 | 78 | private fun parseOurTicket(input: List): List = 79 | input.dropWhile { it != "your ticket:" }.drop(1).first().split(",").map { it.toInt() } 80 | 81 | private fun parseNearbyTickets(input: List): List> = 82 | input.dropWhile { it != "nearby tickets:" }.drop(1).map { row -> 83 | row.split(",").map { it.toInt() } 84 | } 85 | 86 | companion object { 87 | private val ticketRuleRegex = """^([a-z ]+): (\d+)-(\d+) or (\d+)-(\d+)$""".toRegex() 88 | } 89 | 90 | } 91 | 92 | -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Day17.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | /** 6 | * Advent of Code 2020, Day 17 - Conway Cubes 7 | * Problem Description: http://adventofcode.com/2020/day/17 8 | * Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2020/day17/ 9 | */ 10 | package com.ginsberg.advent2020 11 | 12 | class Day17(private val input: List) { 13 | 14 | fun solvePart1() = 15 | solve { x, y -> 16 | Point3D(x, y, 0) 17 | } 18 | 19 | fun solvePart2(): Int = 20 | solve { x, y -> 21 | Point4D(x, y, 0, 0) 22 | } 23 | 24 | private fun solve(rounds: Int = 6, pointFunction: (Int, Int) -> Point): Int { 25 | var conwayGrid = parseInput(input, pointFunction) 26 | repeat(rounds) { 27 | conwayGrid = conwayGrid.nextCycle() 28 | } 29 | return conwayGrid.count { it.value } 30 | } 31 | 32 | private fun Map.nextCycle(): Map { 33 | val nextMap = this.toMutableMap() 34 | keys.forEach { point -> 35 | point.neighbors.forEach { neighbor -> 36 | nextMap.putIfAbsent(neighbor, false) 37 | } 38 | } 39 | nextMap.entries.forEach { (point, active) -> 40 | val activeNeighbors = point.neighbors.count { this.getOrDefault(it, false) } 41 | nextMap[point] = when { 42 | active && activeNeighbors in setOf(2, 3) -> true 43 | !active && activeNeighbors == 3 -> true 44 | else -> false 45 | } 46 | } 47 | return nextMap 48 | } 49 | 50 | private fun parseInput(input: List, pointFunction: (Int, Int) -> Point): Map = 51 | input.flatMapIndexed { x, row -> 52 | row.mapIndexed { y, point -> 53 | pointFunction(x, y) to (point == '#') 54 | } 55 | }.toMap() 56 | 57 | } 58 | 59 | -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Day18.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | /** 6 | * Advent of Code 2020, Day 18 - Operation Order 7 | * Problem Description: http://adventofcode.com/2020/day/18 8 | * Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2020/day18/ 9 | */ 10 | package com.ginsberg.advent2020 11 | 12 | class Day18(input: List) { 13 | 14 | private val equations = input.map { it.replace(" ", "") } 15 | 16 | fun solvePart1(): Long = 17 | equations.sumOf { solvePart1(it.iterator()) } 18 | 19 | fun solvePart2(): Long = 20 | equations.sumOf { solvePart2(it.iterator()) } 21 | 22 | private fun solvePart1(equation: CharIterator): Long { 23 | val numbers = mutableListOf() 24 | var op = '+' 25 | while (equation.hasNext()) { 26 | when (val next = equation.nextChar()) { 27 | '(' -> numbers += solvePart1(equation) 28 | ')' -> break 29 | in setOf('+', '*') -> op = next 30 | else -> numbers += next.asLong() 31 | } 32 | if (numbers.size == 2) { 33 | val a = numbers.removeLast() 34 | val b = numbers.removeLast() 35 | numbers += if (op == '+') a + b else a * b 36 | } 37 | } 38 | return numbers.first() 39 | } 40 | 41 | private fun solvePart2(equation: CharIterator): Long { 42 | val multiplyThese = mutableListOf() 43 | var added = 0L 44 | while (equation.hasNext()) { 45 | val next = equation.nextChar() 46 | when { 47 | next == '(' -> added += solvePart2(equation) 48 | next == ')' -> break 49 | next == '*' -> { 50 | multiplyThese += added 51 | added = 0L 52 | } 53 | next.isDigit() -> added += next.asLong() 54 | } 55 | } 56 | return (multiplyThese + added).product() 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Day19.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | /** 6 | * Advent of Code 2020, Day 19 - Monster Messages 7 | * Problem Description: http://adventofcode.com/2020/day/19 8 | * Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2020/day19/ 9 | */ 10 | package com.ginsberg.advent2020 11 | 12 | class Day19(input: List) { 13 | 14 | private val rules: MutableMap>> = parseRules(input) 15 | private val messages: List = input.dropWhile { it.isNotBlank() }.drop(1) 16 | 17 | fun solvePart1(): Int = countRuleMatches() 18 | 19 | fun solvePart2(): Int { 20 | rules[8] = listOf( 21 | listOf(RuleReference(42)), 22 | listOf(RuleReference(42), RuleReference(8)) 23 | ) 24 | rules[11] = listOf( 25 | listOf(RuleReference(42), RuleReference(31)), 26 | listOf(RuleReference(42), RuleReference(11), RuleReference(31)) 27 | ) 28 | return countRuleMatches() 29 | } 30 | 31 | private fun countRuleMatches(): Int = 32 | messages.count { message -> 33 | message.ruleMatch(0).any { it == message.length } 34 | } 35 | 36 | private fun parseRules(input: List): MutableMap>> = 37 | input.takeWhile{ it.isNotBlank() }.map { line -> 38 | val (id, rhs) = line.split(": ") 39 | val sides = rhs.split(" | ") 40 | id.toInt() to sides.map { side -> 41 | side.split(' ').map { part -> 42 | if (part.startsWith('"')) Atom(part[1]) 43 | else RuleReference(part.toInt()) 44 | } 45 | } 46 | }.toMap().toMutableMap() 47 | 48 | private fun String.ruleMatch(ruleId: Int, position: Int = 0): List = 49 | rules.getValue(ruleId).flatMap { listOfRules -> // OR Rule 50 | var positions = listOf(position) 51 | listOfRules.forEach { rule -> // AND Rule 52 | positions = positions.mapNotNull { idx -> 53 | when { 54 | rule is Atom && getOrNull(idx) == rule.symbol -> 55 | listOf(idx + 1) // End condition 56 | rule is RuleReference -> 57 | ruleMatch(rule.id, idx) 58 | else -> 59 | null 60 | } 61 | }.flatten() 62 | } 63 | positions 64 | } 65 | 66 | interface Rule 67 | class Atom(val symbol: Char) : Rule 68 | class RuleReference(val id: Int) : Rule 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Day20.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | /** 6 | * Advent of Code 2020, Day 20 - Jurassic Jigsaw 7 | * Problem Description: http://adventofcode.com/2020/day/20 8 | * Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2020/day20/ 9 | */ 10 | package com.ginsberg.advent2020 11 | 12 | import kotlin.math.sqrt 13 | 14 | class Day20(input: String) { 15 | 16 | private val tiles: List = parseInput(input) 17 | private val image: List> = createImage() 18 | 19 | fun solvePart1(): Long = 20 | image.first().first().id * image.first().last().id * 21 | image.last().first().id * image.last().last().id 22 | 23 | fun solvePart2(): Int { 24 | val seaMonsterOffsets = listOf( 25 | Point2D(0, 18), Point2D(1, 0), Point2D(1, 5), Point2D(1, 6), Point2D(1, 11), Point2D(1, 12), 26 | Point2D(1, 17), Point2D(1, 18), Point2D(1, 19), Point2D(2, 1), Point2D(2, 4), Point2D(2, 7), 27 | Point2D(2, 10), Point2D(2, 13), Point2D(2, 16) 28 | ) 29 | 30 | return imageToSingleTile() 31 | .orientations() 32 | .first { it.maskIfFound(seaMonsterOffsets) } 33 | .body 34 | .sumBy { row -> 35 | row.count { char -> char == '#' } 36 | } 37 | } 38 | 39 | private fun imageToSingleTile(): Tile { 40 | val rowsPerTile = tiles.first().body.size 41 | val body = image.flatMap { row -> 42 | (1 until rowsPerTile - 1).map { y -> 43 | row.joinToString("") { it.insetRow(y) }.toCharArray() 44 | } 45 | }.toTypedArray() 46 | return Tile(0, body) 47 | } 48 | 49 | private fun createImage(): List> { 50 | val width = sqrt(tiles.count().toFloat()).toInt() 51 | var mostRecentTile: Tile = findTopCorner() 52 | var mostRecentRowHeader: Tile = mostRecentTile 53 | return (0 until width).map { row -> 54 | (0 until width).map { col -> 55 | when { 56 | row == 0 && col == 0 -> 57 | mostRecentTile 58 | col == 0 -> { 59 | mostRecentRowHeader = 60 | mostRecentRowHeader.findAndOrientNeighbor(Orientation.South, Orientation.North, tiles) 61 | mostRecentTile = mostRecentRowHeader 62 | mostRecentRowHeader 63 | } 64 | else -> { 65 | mostRecentTile = 66 | mostRecentTile.findAndOrientNeighbor(Orientation.East, Orientation.West, tiles) 67 | mostRecentTile 68 | } 69 | } 70 | } 71 | } 72 | } 73 | 74 | private fun findTopCorner(): Tile = 75 | tiles 76 | .first { tile -> tile.sharedSideCount(tiles) == 2 } 77 | .orientations() 78 | .first { 79 | it.isSideShared(Orientation.South, tiles) && it.isSideShared(Orientation.East, tiles) 80 | } 81 | 82 | private enum class Orientation { 83 | North, East, South, West 84 | } 85 | 86 | private class Tile(val id: Long, var body: Array) { 87 | 88 | private val sides: Set = Orientation.values().map { sideFacing(it) }.toSet() 89 | private val sidesReversed = sides.map { it.reversed() }.toSet() 90 | 91 | fun sharedSideCount(tiles: List): Int = 92 | sides.sumOf { side -> 93 | tiles 94 | .filterNot { it.id == id } 95 | .count { tile -> tile.hasSide(side) } 96 | } 97 | 98 | fun isSideShared(dir: Orientation, tiles: List): Boolean = 99 | tiles 100 | .filterNot { it.id == id } 101 | .any { tile -> tile.hasSide(sideFacing(dir)) } 102 | 103 | fun findAndOrientNeighbor(mySide: Orientation, theirSide: Orientation, tiles: List): Tile { 104 | val mySideValue = sideFacing(mySide) 105 | return tiles 106 | .filterNot { it.id == id } 107 | .first { it.hasSide(mySideValue) } 108 | .also { it.orientToSide(mySideValue, theirSide) } 109 | } 110 | 111 | fun insetRow(row: Int): String = 112 | body[row].drop(1).dropLast(1).joinToString("") 113 | 114 | fun maskIfFound(mask: List): Boolean { 115 | var found = false 116 | val maxWidth = mask.maxByOrNull { it.y }!!.y 117 | val maxHeight = mask.maxByOrNull { it.x }!!.x 118 | (0..(body.size - maxHeight)).forEach { x -> 119 | (0..(body.size - maxWidth)).forEach { y -> 120 | val lookingAt = Point2D(x, y) 121 | val actualSpots = mask.map { it + lookingAt } 122 | if (actualSpots.all { body[it.x][it.y] == '#' }) { 123 | found = true 124 | actualSpots.forEach { body[it.x][it.y] = '0' } 125 | } 126 | } 127 | } 128 | return found 129 | } 130 | 131 | fun orientations(): Sequence = sequence { 132 | repeat(2) { 133 | repeat(4) { 134 | yield(this@Tile.rotateClockwise()) 135 | } 136 | this@Tile.flip() 137 | } 138 | } 139 | 140 | private fun hasSide(side: String): Boolean = 141 | side in sides || side in sidesReversed 142 | 143 | private fun flip(): Tile { 144 | body = body.map { it.reversed().toCharArray() }.toTypedArray() 145 | return this 146 | } 147 | 148 | private fun rotateClockwise(): Tile { 149 | body = body.mapIndexed { x, row -> 150 | row.mapIndexed { y, _ -> 151 | body[y][x] 152 | }.reversed().toCharArray() 153 | }.toTypedArray() 154 | return this 155 | } 156 | 157 | private fun sideFacing(dir: Orientation): String = 158 | when (dir) { 159 | Orientation.North -> body.first().joinToString("") 160 | Orientation.South -> body.last().joinToString("") 161 | Orientation.West -> body.map { row -> row.first() }.joinToString("") 162 | Orientation.East -> body.map { row -> row.last() }.joinToString("") 163 | } 164 | 165 | private fun orientToSide(side: String, direction: Orientation) = 166 | orientations().first { it.sideFacing(direction) == side } 167 | 168 | } 169 | 170 | private fun parseInput(input: String): List = 171 | input.split("\n\n").map { it.lines() }.map { tileText -> 172 | val id = tileText.first().substringAfter(" ").substringBefore(":").toLong() 173 | val body = tileText.drop(1).map { it.toCharArray() }.toTypedArray() 174 | Tile(id, body) 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Day21.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | /** 6 | * Advent of Code 2020, Day 21 - Allergen Assessment 7 | * Problem Description: http://adventofcode.com/2020/day/21 8 | * Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2020/day21/ 9 | */ 10 | package com.ginsberg.advent2020 11 | 12 | class Day21(input: List) { 13 | 14 | private val food: Map, Set> = parseInput(input) 15 | private val allIngredients: Set = food.keys.flatten().toSet() 16 | private val allAllergies: Set = food.values.flatten().toSet() 17 | 18 | fun solvePart1(): Int { 19 | val safeIngredients = safeIngredients() 20 | return food.keys.sumOf { recipe -> 21 | recipe.count { it in safeIngredients } 22 | } 23 | } 24 | 25 | fun solvePart2(): String { 26 | val ingredientsByAllergy = ingredientsByAllergy() 27 | val found: MutableMap = mutableMapOf() 28 | 29 | while (ingredientsByAllergy.isNotEmpty()) { 30 | val singles = ingredientsByAllergy 31 | .filter { it.value.size == 1 } 32 | .map { it.key to it.value.first() } 33 | .toMap() 34 | found.putAll(singles) 35 | singles.keys.forEach { ingredientsByAllergy.remove(it) } 36 | ingredientsByAllergy.values.forEach { it.removeAll(singles.values) } 37 | } 38 | 39 | return found.entries.sortedBy { it.key }.joinToString(",") { it.value } 40 | } 41 | 42 | private fun ingredientsByAllergy(): MutableMap> { 43 | val safeIngredients = safeIngredients() 44 | 45 | return allAllergies.map { allergy -> 46 | allergy to food.entries 47 | .filter { allergy in it.value } 48 | .map { it.key - safeIngredients } 49 | .reduce { a, b -> a intersect b } 50 | .toMutableSet() 51 | }.toMap().toMutableMap() 52 | } 53 | 54 | private fun safeIngredients(): Set = 55 | allIngredients subtract allAllergies.flatMap { allergy -> 56 | food 57 | .filter { allergy in it.value } 58 | .map { it.key } 59 | .reduce { carry, ingredients -> ingredients intersect carry } 60 | }.toSet() 61 | 62 | private fun parseInput(input: List): Map, Set> = 63 | input.map { line -> 64 | val ingredients = line.substringBefore(" (").split(" ").toSet() 65 | val allergies = line.substringAfter("(contains ").substringBefore(")").split(", ").toSet() 66 | ingredients to allergies 67 | }.toMap() 68 | } 69 | -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Day22.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | /** 6 | * Advent of Code 2020, Day 22 - Crab Combat 7 | * Problem Description: http://adventofcode.com/2020/day/22 8 | * Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2020/day22/ 9 | */ 10 | package com.ginsberg.advent2020 11 | 12 | import java.util.Objects 13 | 14 | typealias Deck = MutableList 15 | 16 | class Day22(input: List) { 17 | 18 | private val deck1: Deck = input.drop(1).takeWhile { it.isNotBlank() }.map { it.toInt() }.toMutableList() 19 | private val deck2: Deck = input.dropWhile { it.isNotBlank() }.drop(2).map { it.toInt() }.toMutableList() 20 | 21 | fun solvePart1(): Int = 22 | playUntilWinner().score() 23 | 24 | fun solvePart2(): Int = 25 | playUntilWinner(true).score() 26 | 27 | private fun playUntilWinner(allowRecursive: Boolean = false): Deck = 28 | if (playGame(deck1, deck2, allowRecursive)) deck1 else deck2 29 | 30 | private fun playGame(deckA: Deck, deckB: Deck, allowRecursive: Boolean): Boolean { 31 | val history = mutableSetOf(Objects.hash(deckA, deckB)) 32 | deckA.pairedWith(deckB).forEach { (a, b) -> 33 | val winner = when { 34 | allowRecursive && deckA.size >= a && deckB.size >= b -> 35 | playGame( 36 | deckA.take(a).toMutableList(), 37 | deckB.take(b).toMutableList(), 38 | true 39 | ) 40 | else -> a > b 41 | } 42 | if (winner) deckA.addAll(listOf(a, b)) else deckB.addAll(listOf(b, a)) 43 | 44 | if(allowRecursive) { 45 | Objects.hash(deckA, deckB).also { 46 | if (it in history) return true else history += it 47 | } 48 | } 49 | } 50 | return deckA.isNotEmpty() 51 | } 52 | 53 | private fun Deck.score(): Int = 54 | this.foldIndexed(0) { index, acc, current -> acc + (current * (size - index)) } 55 | 56 | private fun Deck.pairedWith(other: Deck): Sequence> = sequence { 57 | while (this@pairedWith.isNotEmpty() && other.isNotEmpty()) { 58 | yield(Pair(this@pairedWith.removeFirst(), other.removeFirst())) 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Day23.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | /** 6 | * Advent of Code 2020, Day 23 - Crab Cups 7 | * Problem Description: http://adventofcode.com/2020/day/23 8 | * Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2020/day23/ 9 | */ 10 | package com.ginsberg.advent2020 11 | 12 | 13 | class Day23(private val input: String) { 14 | 15 | fun solvePart1(roundsToPlay: Int): String = 16 | Cups(input) 17 | .playRounds(roundsToPlay) 18 | .toString() 19 | 20 | fun solvePart2(roundsToPlay: Int): Long = 21 | Cups(input, 1_000_000) 22 | .playRounds(roundsToPlay) 23 | .nextAsList(2) 24 | .map { it.value.toLong() } 25 | .product() 26 | 27 | private class Cups(order: String, numberOfCups: Int = order.length) { 28 | val cups: List = List(numberOfCups+1) { Cup(it) } 29 | var currentCup: Cup = cups[order.first().asInt()] 30 | 31 | init { 32 | val cupIdsInOrder = order.map { it.asInt() } + (order.length + 1 .. numberOfCups) 33 | cupIdsInOrder 34 | .map { cups[it] } 35 | .fold(cups[order.last().asInt()]) { previous, cup -> 36 | cup.also { previous.next = cup } 37 | } 38 | cups[cupIdsInOrder.last()].next = cups[cupIdsInOrder.first()] 39 | } 40 | 41 | fun playRounds(numRounds: Int): Cup { 42 | repeat(numRounds) { 43 | playRound() 44 | } 45 | return cups[1] 46 | } 47 | 48 | private fun playRound() { 49 | val next3: List = currentCup.nextAsList(3) 50 | val destination = calculateDestination(next3.map { it.value }.toSet()) 51 | moveCups(next3, destination) 52 | currentCup = currentCup.next 53 | } 54 | 55 | private fun moveCups(cupsToInsert: List, destination: Cup) { 56 | val prevDest = destination.next 57 | currentCup.next = cupsToInsert.last().next 58 | destination.next = cupsToInsert.first() 59 | cupsToInsert.last().next = prevDest 60 | } 61 | 62 | private fun calculateDestination(exempt: Set): Cup { 63 | var dest = currentCup.value - 1 64 | while(dest in exempt || dest == 0) { 65 | dest = if(dest == 0) cups.size-1 else dest -1 66 | } 67 | return cups[dest] 68 | } 69 | } 70 | 71 | private class Cup(val value: Int) { 72 | lateinit var next: Cup 73 | 74 | fun nextAsList(n: Int): List = 75 | (1 .. n).runningFold(this) { cur, _ -> cur.next }.drop(1) 76 | 77 | override fun toString(): String = buildString { 78 | var current = this@Cup.next 79 | while(current != this@Cup) { 80 | append(current.value.toString()) 81 | current = current.next 82 | } 83 | } 84 | } 85 | } 86 | 87 | -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Day24.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | /** 6 | * Advent of Code 2020, Day 24 - Lobby Layout 7 | * Problem Description: http://adventofcode.com/2020/day/24 8 | * Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2020/day24/ 9 | */ 10 | package com.ginsberg.advent2020 11 | 12 | class Day24(private val input: List) { 13 | 14 | fun solvePart1(): Int = 15 | decorateFloor().size 16 | 17 | fun solvePart2(): Int = 18 | generateSequence(decorateFloor()) { it.nextFloor() } 19 | .drop(100) 20 | .first() 21 | .size 22 | 23 | private fun Set.nextFloor(): Set { 24 | val pointsToEvaluate = this + (this.flatMap { point -> point.hexNeighbors }) 25 | return pointsToEvaluate.filter { tile -> 26 | val adjacentBlackTiles = tile.hexNeighbors.count { it in this } 27 | val black = tile in this 28 | when { 29 | black && (adjacentBlackTiles == 0 || adjacentBlackTiles > 2) -> false 30 | !black && adjacentBlackTiles == 2 -> true 31 | else -> black 32 | } 33 | }.toSet() 34 | } 35 | 36 | private fun decorateFloor(): Set = 37 | input 38 | .map { it.walkPath() } 39 | .groupBy { it } 40 | .filter { it.value.size % 2 == 1 } 41 | .keys 42 | 43 | private fun String.walkPath(): Point3D = 44 | splitPattern 45 | .findAll(this) 46 | .map { it.value } 47 | .fold(Point3D.ORIGIN) { last, dir -> 48 | last.hexNeighbor(dir) 49 | } 50 | 51 | companion object { 52 | private val splitPattern = "([ns]?[ew])".toRegex() 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Day25.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | /** 6 | * Advent of Code 2020, Day 25 - Combo Breaker 7 | * Problem Description: http://adventofcode.com/2020/day/25 8 | * Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2020/day25/ 9 | */ 10 | package com.ginsberg.advent2020 11 | 12 | class Day25(input: List) { 13 | 14 | private val cardPk = input.first().toLong() 15 | private val doorPk = input.last().toLong() 16 | 17 | fun solvePart1(): Long = 18 | transform(findLoopSize(cardPk), doorPk) 19 | 20 | private fun transform(loopSize: Int, subject: Long): Long = 21 | generateSequence(1L) { it.mathPart(subject) }.drop(loopSize).first() 22 | 23 | private fun findLoopSize(target: Long): Int = 24 | generateSequence(1L) { it.mathPart() }.indexOf(target) 25 | 26 | private fun Long.mathPart(subject: Long = 7): Long = 27 | this * subject % 20201227 28 | } 29 | 30 | -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Extensions.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | 8 | fun Iterable.product(): Long = 9 | this.reduce { a, b -> a * b } 10 | 11 | fun Char.asLong(): Long = 12 | this.toString().toLong() 13 | 14 | fun Char.asInt(): Int = 15 | this.toString().toInt() 16 | -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Movement.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import kotlin.math.absoluteValue 8 | 9 | sealed class Direction { 10 | abstract val turnLeft: Direction 11 | abstract val turnRight: Direction 12 | abstract val offset: Point2D 13 | 14 | operator fun invoke(dir: String): Direction = 15 | when (dir) { 16 | "N" -> North 17 | "S" -> South 18 | "E" -> East 19 | "W" -> West 20 | else -> throw IllegalArgumentException("No such direction $dir") 21 | } 22 | 23 | object North : Direction() { 24 | override val turnLeft = West 25 | override val turnRight = East 26 | override val offset = Point2D(-1, 0) 27 | } 28 | 29 | object South : Direction() { 30 | override val turnLeft = East 31 | override val turnRight = West 32 | override val offset = Point2D(1, 0) 33 | } 34 | 35 | object West : Direction() { 36 | override val turnLeft = South 37 | override val turnRight = North 38 | override val offset = Point2D(0, -1) 39 | } 40 | 41 | object East : Direction() { 42 | override val turnLeft = North 43 | override val turnRight = South 44 | override val offset = Point2D(0, 1) 45 | } 46 | } 47 | 48 | 49 | data class Point2D(val x: Int, val y: Int) { 50 | operator fun plus(other: Point2D): Point2D = 51 | Point2D(x + other.x, y + other.y) 52 | 53 | operator fun times(by: Int): Point2D = 54 | Point2D(x * by, y * by) 55 | 56 | infix fun distanceTo(other: Point2D): Int = 57 | (x - other.x).absoluteValue + (y - other.y).absoluteValue 58 | 59 | fun rotateLeft(): Point2D = 60 | Point2D(x = y * -1, y = x) 61 | 62 | fun rotateRight(): Point2D = 63 | Point2D(x = y, y = x * -1) 64 | 65 | companion object { 66 | val ORIGIN = Point2D(0, 0) 67 | } 68 | } 69 | 70 | interface Point { 71 | val neighbors: List 72 | } 73 | 74 | data class Point3D(val x: Int, val y: Int, val z: Int) : Point { 75 | override val neighbors: List by lazy { 76 | (x - 1..x + 1).flatMap { dx -> 77 | (y - 1..y + 1).flatMap { dy -> 78 | (z - 1..z + 1).mapNotNull { dz -> 79 | Point3D(dx, dy, dz).takeUnless { it == this } 80 | } 81 | } 82 | } 83 | } 84 | 85 | val hexNeighbors: List by lazy { 86 | HEX_OFFSETS.map { this + it.value } 87 | } 88 | 89 | operator fun plus(other: Point3D): Point3D = 90 | Point3D(x + other.x, y + other.y, z + other.z) 91 | 92 | fun hexNeighbor(dir: String): Point3D = 93 | if (dir in HEX_OFFSETS) HEX_OFFSETS.getValue(dir) + this 94 | else throw IllegalArgumentException("No dir: $dir") 95 | 96 | companion object { 97 | val ORIGIN = Point3D(0, 0, 0) 98 | val HEX_OFFSETS = mapOf( 99 | "e" to Point3D(1, -1, 0), 100 | "w" to Point3D(-1, 1, 0), 101 | "ne" to Point3D(1, 0, -1), 102 | "nw" to Point3D(0, 1, -1), 103 | "se" to Point3D(0, -1, 1), 104 | "sw" to Point3D(-1, 0, 1), 105 | ) 106 | } 107 | } 108 | 109 | data class Point4D(val x: Int, val y: Int, val z: Int, val w: Int) : Point { 110 | override val neighbors: List by lazy { 111 | (x - 1..x + 1).flatMap { dx -> 112 | (y - 1..y + 1).flatMap { dy -> 113 | (z - 1..z + 1).flatMap { dz -> 114 | (w - 1..w + 1).mapNotNull { dw -> 115 | Point4D(dx, dy, dz, dw).takeUnless { it == this } 116 | } 117 | } 118 | } 119 | } 120 | } 121 | } 122 | 123 | -------------------------------------------------------------------------------- /src/main/kotlin/com/ginsberg/advent2020/Resources.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import java.io.File 8 | import java.net.URI 9 | 10 | internal object Resources { 11 | fun resourceAsString(fileName: String, delimiter: String = ""): String = 12 | resourceAsList(fileName).reduce { a, b -> "$a$delimiter$b" } 13 | 14 | fun resourceAsText(fileName: String): String = 15 | File(fileName.toURI()).readText() 16 | 17 | fun resourceAsList(fileName: String): List = 18 | File(fileName.toURI()).readLines() 19 | 20 | fun resourceAsListOfInt(fileName: String): List = 21 | resourceAsList(fileName).map { it.toInt() } 22 | 23 | fun resourceAsListOfLong(fileName: String): List = 24 | resourceAsList(fileName).map { it.toLong() } 25 | 26 | private fun String.toURI(): URI = 27 | Resources.javaClass.classLoader.getResource(this)?.toURI() ?: throw IllegalArgumentException("Cannot find Resource: $this") 28 | } 29 | 30 | -------------------------------------------------------------------------------- /src/main/resources/day01.txt: -------------------------------------------------------------------------------- 1 | 1587 2 | 1407 3 | 1717 4 | 1596 5 | 1566 6 | 1752 7 | 1925 8 | 1847 9 | 1716 10 | 1726 11 | 1611 12 | 1628 13 | 1853 14 | 1864 15 | 1831 16 | 1942 17 | 1634 18 | 1964 19 | 1603 20 | 1676 21 | 1256 22 | 1906 23 | 1655 24 | 1790 25 | 1666 26 | 1470 27 | 1540 28 | 1544 29 | 1100 30 | 1447 31 | 1384 32 | 1464 33 | 1651 34 | 1572 35 | 907 36 | 1653 37 | 1265 38 | 1510 39 | 1639 40 | 1818 41 | 376 42 | 1378 43 | 1132 44 | 1750 45 | 1491 46 | 1788 47 | 1882 48 | 1779 49 | 1640 50 | 1586 51 | 1525 52 | 1458 53 | 1994 54 | 1782 55 | 1412 56 | 1033 57 | 1416 58 | 1813 59 | 1520 60 | 1968 61 | 715 62 | 1396 63 | 1745 64 | 1506 65 | 1024 66 | 1798 67 | 1870 68 | 1615 69 | 1957 70 | 1718 71 | 1349 72 | 1983 73 | 1387 74 | 1738 75 | 1588 76 | 1321 77 | 1160 78 | 1907 79 | 1861 80 | 1940 81 | 1475 82 | 2004 83 | 1852 84 | 1760 85 | 1608 86 | 1028 87 | 1820 88 | 1495 89 | 1811 90 | 1737 91 | 1417 92 | 1316 93 | 1087 94 | 1803 95 | 1595 96 | 1346 97 | 1971 98 | 1692 99 | 1678 100 | 1330 101 | 1480 102 | 1097 103 | 1898 104 | 1973 105 | 1567 106 | 1733 107 | 1336 108 | 1381 109 | 1327 110 | 1670 111 | 1436 112 | 1989 113 | 1334 114 | 89 115 | 1862 116 | 1715 117 | 1743 118 | 1967 119 | 1765 120 | 1402 121 | 1729 122 | 1749 123 | 1671 124 | 1196 125 | 1650 126 | 1089 127 | 1814 128 | 1783 129 | 1225 130 | 1823 131 | 1746 132 | 2009 133 | 1886 134 | 1748 135 | 1481 136 | 1739 137 | 1912 138 | 1663 139 | 1668 140 | 1314 141 | 1594 142 | 705 143 | 1449 144 | 1731 145 | 1487 146 | 1648 147 | 1466 148 | 1317 149 | 1979 150 | 1799 151 | 1926 152 | 1703 153 | 1656 154 | 1978 155 | 2005 156 | 1865 157 | 1982 158 | 1951 159 | 1892 160 | 1713 161 | 1744 162 | 1598 163 | 1606 164 | 1583 165 | 1895 166 | 1804 167 | 1430 168 | 1816 169 | 1364 170 | 1575 171 | 1918 172 | 1431 173 | 1812 174 | 1471 175 | 1797 176 | 928 177 | 1934 178 | 1156 179 | 94 180 | 1563 181 | 1909 182 | 1453 183 | 1392 184 | 1427 185 | 1819 186 | 1524 187 | 1695 188 | 1866 189 | 2008 190 | 1413 191 | 1698 192 | 1051 193 | 1707 194 | 1904 195 | 1681 196 | 1541 197 | 1621 198 | 1421 199 | 1809 200 | 1576 -------------------------------------------------------------------------------- /src/main/resources/day03.txt: -------------------------------------------------------------------------------- 1 | .............#...#....#.....##. 2 | .#...##.........#.#.........#.# 3 | .....##......#.......#......... 4 | .......#...........#.#......... 5 | #...........#...#..#.#......#.. 6 | .........##....#.#...#......... 7 | .....#.........#.#...........#. 8 | ....#...............##....##... 9 | #.#.............#..#.......#.#. 10 | ...#........................... 11 | ......#..#....#.............#.. 12 | ........#......#.......#....... 13 | ....#.....#..#.#...#.........#. 14 | ..#.#.......#.##...#....#.....# 15 | ...........#.........#..#...... 16 | #...........#.#..#...#.#.#....# 17 | ........#...................... 18 | ....#.#.....#....#.......#..#.. 19 | .............................#. 20 | ....##..........#.....##......# 21 | ......#.....................#.. 22 | ..#.....##.......#............. 23 | ....#.#..............#.#....... 24 | ..#.#........#.....#..##....... 25 | .....#...##.........##....#.#.. 26 | .#....#..#..#...........#...... 27 | .............#.....##........#. 28 | ..#....#............#.........# 29 | ###..........#........#.......# 30 | #...#..#.#.#.........#..#...... 31 | ..#....#......#.............#.. 32 | #...#........#..#...#.....#.... 33 | .#..........#.#........#....... 34 | #.....#.........#..#......#.... 35 | ....#....##........#......#.... 36 | .......#....#.....#..#..#.....# 37 | .........#...#.#...#.##........ 38 | .##.##...........#..##..#...... 39 | .#.##....#........#...#........ 40 | .......##.........##.####.....# 41 | ....#..##....#................. 42 | .#........#..........#......... 43 | ##....##..........##........#.. 44 | #......#...........#....#..#... 45 | .......#..#....##..##.....#.... 46 | .........#.#.#...#.....#....... 47 | ......#...#...#....#......#.... 48 | ##....#..........#....##....##. 49 | ###.........#...#...#.......... 50 | #.....##.#........#.......#.... 51 | #...............#...##.#......# 52 | ..#.....####.###......#......#. 53 | ....#.......#..........#....... 54 | ....##..............#.#.#...... 55 | .......##..#.......#........... 56 | ..#.......##....#.......###...# 57 | ........#...#.......#.#...#.... 58 | .........##....#..#....#....... 59 | ............#.#.......#.#...... 60 | .....#.....#...#....#.##....... 61 | .......#.........#.......#..... 62 | .#..#...#.....#............#.## 63 | .......#.#......##............. 64 | ##.#......#.....#.#............ 65 | .#....#.....#............#...#. 66 | .........#.......#.#........... 67 | #............#.##...#..#...#.#. 68 | ......#....#.......#....#...... 69 | ..........#........#..#.#...... 70 | #..##.......#.........#..#..... 71 | .........#.....##........#.#..# 72 | ..#................#........... 73 | ....#..#........##.........#..# 74 | ###...#....##.#......##.......# 75 | .......#......##..#.......#.... 76 | .......###...#...#..........##. 77 | ................#.......#...... 78 | .#......##.##........#......... 79 | ....##.#.....##.......#........ 80 | ...........#...........#.....#. 81 | ..#........#..#.#...#.#........ 82 | #...............#...#.##.##.#.# 83 | ................#.......#...... 84 | .#..#......#........#.#........ 85 | ...##..#.......#.......#..#.... 86 | .#.....#.#....##..#........#... 87 | ........##......#..........#... 88 | .#.......#.......#...#..#...... 89 | .#..##.....#....#............#. 90 | ...#..........#....#........#.. 91 | ..#.#..#.......#.#.##.......... 92 | #........###.....#.#.......#.## 93 | .....#....##.............#.#..# 94 | ..##............#...##......... 95 | ...#.........#...........#..... 96 | ...#......#.#...#..###......... 97 | .............#...##............ 98 | .....##..##.####.#..#......#.#. 99 | .#...#.....#.....#.#.....#..... 100 | .........#.......###.....#..##. 101 | .##.#..#..........#.##.#.#..... 102 | .#...#...#.#.##......#..#...... 103 | .............#......#......#... 104 | #.....................#......#. 105 | ...#.....#.....#....#........#. 106 | ................##..#....#..#.. 107 | #.###...#.....................# 108 | ...#..#....#.......#.........#. 109 | ...........#..#..#...........#. 110 | .......#..#......#....#.#...... 111 | ..........#......#..#....#..... 112 | .#.#.....#...#.#...#...#.#....# 113 | .....#.......#............#...# 114 | #.#....#......#......#........# 115 | .#.#..#.........##...#......... 116 | #..###..#...................... 117 | ..#.#..#....................... 118 | .##.....#...#......#..#........ 119 | ...#...........#...#.......##.. 120 | ..#...........#........#....... 121 | ........#....#.....#.#......... 122 | ..........#...........#.....#.. 123 | ......#...#...##.#............. 124 | .#...#...##.................... 125 | ............###.........#...... 126 | .#.#...................#..#.... 127 | ....#.#...#.#........#.#....... 128 | ....#...#...........#.......#.# 129 | ...........#............#...##. 130 | .....####....#.#......#.#...... 131 | .##.............#............#. 132 | ......#.........#............## 133 | #.#....#...##....#.......#....# 134 | .....#.#....#..#..#...#..#.#..# 135 | .........................#..... 136 | ......#.#....###.......#....#.. 137 | .....................##.#...#.# 138 | ..#.....#.#.#...#...#.......... 139 | ........#..##........#...#...#. 140 | ..........#.#.##....#....##.... 141 | .............#..#.............. 142 | ..#.##..#.......#...#..#..##..# 143 | ..#..#....#.#..........#..#.... 144 | ..........#....#...#......#.... 145 | .##...#.......................# 146 | .#.....#....#..........#....... 147 | ...........#..#......##.....#.. 148 | ......###.#..##....#...#.##.... 149 | .......#..#.#....#............. 150 | ...#..#......##.........###.#.. 151 | ...........#............##...#. 152 | ...#...#...........##.....#.... 153 | ..................#............ 154 | .#.#.#...#..............#..##.. 155 | #.#....#........#.........#.##. 156 | #.#.#.......#.....#..........#. 157 | ...##.....##.#.....#........... 158 | .#....#..............##...##..# 159 | ........##..................... 160 | #..#..#.....###.............#.. 161 | .......#...........#........... 162 | .........#..................... 163 | .......#...#...#.....##........ 164 | ......#.........#........#..... 165 | ...#....##..#.####.#.......#.#. 166 | .....#..#......#........#.##..# 167 | .##....#......##......#...###.. 168 | ..###.#........##.#...#.......# 169 | ............#......##....#.#... 170 | .....#....##..##............##. 171 | ......##....#.#...#....#.#..#.# 172 | .......#.........#.#.....#.#... 173 | .......#.#....#................ 174 | .##...###..#.....#............# 175 | #.#......#.#..#..#.#...#..#..#. 176 | ..#.#.#.....#............#...## 177 | .##....###.........#..#........ 178 | .#..#.#..#.#....#.........##.#. 179 | ....#..#...##.##........#...... 180 | ........#.#....##....#....#.... 181 | .......#..#..#.#..............# 182 | #....#....#.....#....#......... 183 | .#.###...#....#.......#........ 184 | .........#.#....##....#...#.... 185 | ....#.............#.....##.##.. 186 | .....#.....#...##..#.#.##...##. 187 | .........#..#................## 188 | ...##..##......#.....#........# 189 | .#....#.....#.#......#..###.... 190 | #.....#..#..................... 191 | ....#.#...#.#.................# 192 | .....##..................#..... 193 | #....##...#.##..###...#........ 194 | ##.#.........#.......#....#.... 195 | .#.#.............##..#.##...... 196 | ...#.#..............#......#... 197 | .............#.........#.....#. 198 | #.......#........#......#.....# 199 | .....#..............#.##.#..... 200 | #......##...................#.. 201 | ##.#.....#..........#........#. 202 | #...........##...........#..... 203 | .#...#.....#..#..##....#....... 204 | .....#.........#....##.#....... 205 | #........#......#.............# 206 | .#..................####.#..... 207 | #...#......#....##...#.#..#..#. 208 | ............#.#............#... 209 | ............#........#.#..###.. 210 | .#..#..#..#.#.#.....#.#........ 211 | #.....#..#.#...#..#..#........# 212 | #................#....#..#..... 213 | ....#..#..#.#......#.#..#.....# 214 | .#..#.......#...##.#.#.....#..# 215 | #.....................#.......# 216 | .............#.......#...#..... 217 | ....#......#.........###.##.... 218 | ....#..#.......#.#........#.... 219 | ....#...#....#.#....#.......... 220 | ...#..#......#.............#... 221 | .......###.#.........#....#.#.. 222 | ..#.....##..................... 223 | .#.#...........#..##....#...... 224 | ..........##.#....#.#.......... 225 | ...........#.#..#.#..#.#....... 226 | ..........#..#...#.....##...... 227 | .....#.........#...#.#..#...... 228 | #.#................#..........# 229 | ...#.....##.#..#...#.##.......# 230 | .....##...........#............ 231 | .....#...#...#...#.#.....#..... 232 | ...........##.................. 233 | .........#................#.... 234 | ......#.....#.#...#.......#.... 235 | ...#...#........#...#...#.#.#.. 236 | ...............##..#....##...#. 237 | ...#.#...........##.......##..# 238 | ...........#............#...... 239 | .#....#.#.......##.#.#.#....... 240 | .....#.#..#.#.#................ 241 | .#............#...#.#.......... 242 | .....#.......#.#.......#.....#. 243 | #....#...........#...#....##... 244 | ..#...#..##.....#....#..#...... 245 | #.#.........#..#.#..#.#......#. 246 | ................#......##...... 247 | #........#..............#....#. 248 | ........#..#.#........#..#..#.. 249 | #..........#......#............ 250 | ..##.......#..#.......#....#... 251 | .#........#..#..#.#.......##... 252 | ................#.............. 253 | #.................#...........# 254 | ##..#...................#....## 255 | #..#....#.....#.#..#.#.#......# 256 | #................#.#.#...#..... 257 | .............#..#...#..##...#.# 258 | #..................#........... 259 | ..............#..#.....##.....# 260 | ..#...............#.#.......... 261 | .....#......#....#..#...#...... 262 | .#......#...##.....###.....#... 263 | ...##...##.##....#.#.#..#...... 264 | ....#.#.......#..##....#.##.... 265 | ...#.........#.#.....#...#...## 266 | .##.#.........##..#.##..#...... 267 | .#...#......#......#.........#. 268 | .............#................. 269 | ..........#..............#..... 270 | ##...........#...#...###....#.. 271 | ....#...............#.......... 272 | .......####.....#......#....... 273 | ........#..........#..#........ 274 | ..#.......#..#................. 275 | ......#.#..##...##....#........ 276 | .##...#........#...#....#...#.. 277 | .......................#....... 278 | .........##..#..#...#....##...# 279 | ..#..#...#.....#.........#..#.. 280 | .......#....#.........#...#..#. 281 | .............#................. 282 | .....##..#.....###....##.#..... 283 | ....#.#..#..#.#.....##....#..#. 284 | ......#..#..............#.##..# 285 | ..#..#......#.#.........#..#... 286 | ..........#.#..#....#.....#.... 287 | .....................#......... 288 | ...#.....#.......##..#.#....... 289 | .....#...#..........###....#.#. 290 | ......#.....##............#...# 291 | .......#..........#.#..#...#..# 292 | #...#..#...........#..##..#.... 293 | .#......#.......##.....#..#.... 294 | ...#..#....#.......##......#... 295 | ........#.......##...#.......#. 296 | .....#........#................ 297 | ......#........#....#.......... 298 | ...#....#....###.........#.#... 299 | ##..............#......#..#.#.. 300 | .........##....#........#..#.#. 301 | .......#.##.#........#........# 302 | .....###..#..#...........#....# 303 | .......#....##.......#.#...#... 304 | #..............#.#....#..#...#. 305 | #..#....#..#.#............#..#. 306 | .#...##.#..................#... 307 | ...#...............##.........# 308 | ###..............#.#..#.#.#.... 309 | .#......#.#.....##.......#..... 310 | ...#.................#.#....... 311 | .#...#....#...#..#......#...#.. 312 | ...##....#........#.#.#..#..... 313 | ..#.....#........#....#.#...... 314 | ...........#.#...#............. 315 | ......#.....#.....#.........#.. 316 | .#.##.###...#.##.......#....... 317 | .............#....#.......#.... 318 | ..............#...........#.... 319 | .............#..#.#.....#....#. 320 | .......#........##...##..##.... 321 | ..##...#............#..#......# 322 | .............#...##.....#...... 323 | .#...##..##.#.........#.##...#. 324 | -------------------------------------------------------------------------------- /src/main/resources/day05.txt: -------------------------------------------------------------------------------- 1 | BBFFFBBLLR 2 | BBFFFFFLRL 3 | BFBFFFBLRR 4 | FBBFFFFRLL 5 | FFBFFFBLRR 6 | BFBBBFFLLL 7 | BFBBBFFLRR 8 | FBBFBBFRLL 9 | BFFBFBBLLL 10 | BFBFBBFRRR 11 | FBFBFFBLLR 12 | FFFBBBFRLL 13 | BFBBFBBRRR 14 | FBFFBFBRRR 15 | BFFBFFFLLL 16 | FBBBFBFLRR 17 | BFBBFBFRLR 18 | BFFFFFBRRL 19 | BFFBFFFRLR 20 | FBBBBBFRLL 21 | BFBBFBBLRL 22 | BFFFBFBRLR 23 | FBBBBFBLLR 24 | BBFFFBFRRR 25 | BFFBBBFLRL 26 | BFBFBFFLLR 27 | FFFBBBFLLR 28 | BFBFFFFRRL 29 | FFFBBFBLLR 30 | FBFFFBFLRL 31 | FBBBFBBRLL 32 | FBBFBFFLLR 33 | FBFBBFFLLL 34 | FBBFFFFLLL 35 | BFBFFBFRRL 36 | FFBBBFBRLL 37 | BFFBBFFLLR 38 | BFBBBBBRLR 39 | BFFBFFFRLL 40 | FBBBBFFRRR 41 | FFBBBFFRRL 42 | BBFBFBBLRR 43 | BBFFFFFLLR 44 | FFBFBFBLRR 45 | FBBBBFFLLR 46 | BBFBFBBRLR 47 | FFBFFBFRLR 48 | BFBBFFFLRL 49 | FFBFBFFLLR 50 | FFBFBBFRRR 51 | BBFFFBFLLL 52 | BFFFBBFRLL 53 | FFBFBBFLRR 54 | FBBBFFFRLL 55 | FBBFBFBRLR 56 | BFFFFFBRLR 57 | BFBFBFBLRL 58 | FBBBBFBLRL 59 | BBFFFFBLRR 60 | FBBBFFFRRR 61 | FFBBFFBLRL 62 | FBFBFFFRRL 63 | FFBFBBFLLL 64 | BBFFFBBRLR 65 | FBFBFFBRRR 66 | BBFFBBFRLR 67 | BFBBBFBLLR 68 | BFFBFBBLLR 69 | FBBBFBBLRR 70 | FFBFBBFLRL 71 | BFBFFBBRLR 72 | BFBBBFFLRL 73 | BFFFFBBRLR 74 | BFBBBFBRRL 75 | BFBFBBBRRR 76 | FFBFFBBLRR 77 | FBFBBBBRRL 78 | FFBFFFBRLL 79 | FBFFFFBLLL 80 | FFBBBFBLRR 81 | BBFFBBFLLL 82 | BFFBFBBLRR 83 | FBBBFBBRRL 84 | FFBFFBFRRR 85 | BFBBFFBRLL 86 | FBFFBBBLRR 87 | FFBFFBFLLL 88 | FBFBFBFRRL 89 | BBFFFFFLRR 90 | FFBBFBFRLL 91 | BFBBFFFRLL 92 | FBBBBFFLLL 93 | BFFBFBBRRL 94 | FBFBBBFLRR 95 | FBBBBFFLRR 96 | FBFFBBFLLL 97 | BFFFBBFRRL 98 | BFBBBFBRLL 99 | BFBFBBFRLL 100 | FBFFFFBRLL 101 | BBFBFBBLLL 102 | FFBBBFBLLR 103 | BBFFBBBLLR 104 | FBBBBBBRRR 105 | BBFFBFFRLL 106 | FBBFFBBRRL 107 | FFBBBBFRRR 108 | FBFBBFBRRL 109 | BFFFBFFRLL 110 | BFBFBFFRLL 111 | FBFBFFBLRR 112 | BFBBFFFRRR 113 | BFBBBBBLLL 114 | BFBBFFFRLR 115 | FFBFBFBRLL 116 | FBFFBFBRRL 117 | FFFBBBFRLR 118 | BBFFFBFLLR 119 | FBFBBBBRLR 120 | FBFBBFFLRL 121 | FBBBBFBLRR 122 | FBFBBBBLLL 123 | BFBBFBBLRR 124 | FFBBFBFLRL 125 | FFBFBBFRLL 126 | BFFFBFBLRR 127 | FFBFFBBRRR 128 | FBFFFFFRLL 129 | BFFFBFFRRR 130 | BFFBBFBRLR 131 | BFBFBBBLLL 132 | BFFBBFBLLR 133 | BFFBBBFLLL 134 | BFFFBFFLRL 135 | FBBFBFFLLL 136 | FBBBBBFLRR 137 | FBFBFBBRRR 138 | BFBBBBFLLR 139 | FBFFBFBLLR 140 | BBFFBBBLLL 141 | BBFFBBBRLR 142 | FFBBBFFRRR 143 | BBFFFBFLRR 144 | FFFBBBBRRR 145 | FFBFBFBRRR 146 | FFFBBFFRLL 147 | FBFFBBFRLR 148 | BFFBBBBRRR 149 | FBFBFFBLLL 150 | BBFBFFBLRL 151 | FFBFFBFLLR 152 | BFFFBBBLRL 153 | FBFFBFFLRR 154 | FBFFBBBLLR 155 | FBBFBFFLRR 156 | BFFBFFFRRL 157 | FBBFBBBLLL 158 | BBFBFBFRRL 159 | FBFFFFBRLR 160 | BFBFBFBLRR 161 | BFFBFBBRLL 162 | BFBFBBFLRL 163 | FBBBBFFRLR 164 | BFFFBBFLLL 165 | BFBBBFBLLL 166 | FFBBBBFRRL 167 | FFBFFFFLLR 168 | FBFBFFBRLL 169 | BBFBFBFLRL 170 | FBBBBBBRLR 171 | BFBFFFBLLR 172 | BBFFBBFLRR 173 | BBFFBBBRRR 174 | FBFFFBFRLR 175 | FFBBFFBLLL 176 | BFFBFBFLLL 177 | FBFFFFFLRL 178 | BFFBBFFLRL 179 | FBBBBBBRRL 180 | BFFBFBBRLR 181 | FBFBFBFLLL 182 | BFFBFFFRRR 183 | BBFFFFBRRR 184 | BFFBBFFRRR 185 | FBBFBBBLRL 186 | FFBBFBBRLL 187 | FBFFBBFRLL 188 | BFBFFBBRRL 189 | FBBFFFBLRL 190 | BFBBFFBLRR 191 | BBFFBFBRLR 192 | FBFBFFBRLR 193 | BBFFBFBRRL 194 | FFBBFBBRLR 195 | BFBFBFFLRR 196 | BFFBFFFLRL 197 | FFBBBFBRRL 198 | FFBFFBBLRL 199 | FBBFBBBRLR 200 | FFFBBBBRLR 201 | FBBFFFBLLR 202 | FFBFBBBRRR 203 | FFBBBFBRRR 204 | BFFBFBFRLL 205 | BFBBBBFLLL 206 | BFBFFFFRLL 207 | FBBBBBFRLR 208 | BFFBFBFLRL 209 | FBFFBFFRRL 210 | BBFFBFFRRL 211 | BFFBFBBRRR 212 | FBFFFBBRRR 213 | FFBBFBFRRR 214 | BFBBBFBLRL 215 | FFBBBFFLLL 216 | BFFFBBBRRR 217 | BFFBBBBRLL 218 | BFBBBBBLRL 219 | FBFFFBBLLL 220 | FBFBBBFLLL 221 | FFBBBFFRLR 222 | FFBFFFFRLR 223 | FFBFFBFRLL 224 | BFBFBFFRRL 225 | BFBFFBBRRR 226 | FFFBBFFRRR 227 | BFFFBFBLLR 228 | FBFBFBFLRR 229 | BFBFFFFLLL 230 | FBBBFBBLLL 231 | FBBFBBFRLR 232 | FFBFBFFLRL 233 | FBFFBFFLLR 234 | BFBFBFBLLR 235 | FBBFFFFRLR 236 | FBFBFFBLRL 237 | BFFFBFFLLR 238 | BFBFBFBLLL 239 | BFBBFBFLRR 240 | BFFBBFFRLL 241 | BFFFBBFRRR 242 | BFBFFBBLLR 243 | FBBFBBBLRR 244 | FFBFFFBLRL 245 | BFFFBBBRLR 246 | BBFBFFBLLR 247 | BBFBFBFRLL 248 | FFFBBFBRRL 249 | BFFFFBBLRR 250 | BBFFFFFRRR 251 | BFBBFBBRRL 252 | BFFFFFFRLL 253 | BFFFFFFLLL 254 | FBFFBBBRLR 255 | BBFBFFBRRL 256 | BFFFBBFLRR 257 | FBBFBFBLLR 258 | FFBBBBBLLR 259 | FBFBBFFRLL 260 | BFBBFFFRRL 261 | FFBBBFBRLR 262 | FBBBFFFLRR 263 | FFBBBFFRLL 264 | FFBBBBBRLL 265 | BFFFBBBLLR 266 | FBBFFFFLLR 267 | BBFBFFBLRR 268 | FFBFBBFRRL 269 | BBFBFBBLRL 270 | BFBBBFBRRR 271 | FFBFFBBRLL 272 | FFBFBFFRRR 273 | FBFBBFBLRL 274 | BBFFFBBRRR 275 | BFFBBBBLRR 276 | BFBFBBFRLR 277 | FBBBBFBRRR 278 | FFBBFFBLRR 279 | FFFBBBFLLL 280 | BBFBFFFLLR 281 | FFBFFBFRRL 282 | BBFFFBFLRL 283 | BFBFFFFRRR 284 | BFFFFFFRRL 285 | FFBFFFFLRR 286 | BFBBBFBLRR 287 | FFFBBBBLLR 288 | BFFBBFFRLR 289 | BBFFFBFRLR 290 | BFFBFFBRLR 291 | FFBBFFFLLR 292 | FFBBFBFRRL 293 | FBFBBBBLRL 294 | FBBBFFBLLL 295 | FBBBBBBLRR 296 | FFBBFBBLRR 297 | FBBFBBFRRL 298 | FBBFFFFLRR 299 | FFBBFFBRLR 300 | FBFFFFBLRL 301 | FBFFBFFRLR 302 | BFBFFBFRRR 303 | FFBFFFFRLL 304 | BFBFFBBLRL 305 | FBFFFBFRRR 306 | BFFBBBFRLR 307 | BFFBBFBRRL 308 | BFBBBBFLRR 309 | FFBFBBBRLL 310 | FBFBBBFRLL 311 | BFBFFFFLRR 312 | BBFBFFFLLL 313 | BFFBBBBLRL 314 | FFBFBFBLLR 315 | FBBFFFBRLL 316 | BFFFFFBLLR 317 | FBFBBFFRRR 318 | FBFFBBFLRR 319 | BFFFFFBLLL 320 | FBFFFFFRRL 321 | FFBBBFBLLL 322 | FBBFFFFLRL 323 | BBFBFFBRRR 324 | FBFFBFBRLR 325 | FBBBFBFLLR 326 | BFFBBBBRRL 327 | BFFFBBFLLR 328 | BFFBFFBRLL 329 | FFBFBBBLLR 330 | FFBFBFFRLR 331 | BFFBFFBLRR 332 | BFBBBFFRRL 333 | BFFBBFBLRL 334 | FBFBFBFLRL 335 | BBFBFBBRLL 336 | FBFFFFBRRL 337 | FFBBBBBRRR 338 | BFBFFFBRRR 339 | FFBFFBFLRL 340 | BFFBBBFLRR 341 | FBFBBFBRLL 342 | BFBBBFFRRR 343 | BFFBFFFLRR 344 | BFBFFFFRLR 345 | FBBBFBFLRL 346 | FFFBBBFRRR 347 | FBFBBFFRRL 348 | BFFFBBFLRL 349 | FBBBBFBRLR 350 | FBBFBBFLLR 351 | FBFBBBBLRR 352 | FFBBBBBRRL 353 | FFBBFFFLLL 354 | FFBBFBBLLR 355 | BBFFFBFRLL 356 | BBFBFBBLLR 357 | FBBFBFBLLL 358 | FBFFBBFRRR 359 | FBBBFBBRRR 360 | BFBFBBFLLL 361 | FBFBFBBRRL 362 | BFBBFBFLRL 363 | BFBBFBBLLL 364 | FBBFBFFRLL 365 | BBFFFBBLLL 366 | FFBBFFFLRL 367 | BFFBFFFLLR 368 | BFFBBFBRRR 369 | BFFBFFBLLL 370 | BBFFBFBLRR 371 | FBFBFBBLRR 372 | BBFBFBFRLR 373 | BFFFFBFLLL 374 | FBBFBFFRLR 375 | FBFBFBBRLL 376 | BFFFFFBLRL 377 | BFBBFBBLLR 378 | BBFFBFFLLR 379 | BBFFBFBLRL 380 | BBFFBBBLRR 381 | FBFFBFBLRL 382 | BFFBBFBRLL 383 | BFFBBFFLRR 384 | FBBFFBFRRL 385 | BBFBFFBLLL 386 | BFBFBBBLRL 387 | FFBFFFBLLR 388 | FBBBFBFRLR 389 | BFFFFBFRRR 390 | BFBFBFBRRR 391 | FBBBBBFLLR 392 | BBFFBBFRRL 393 | BBFFFFFRLR 394 | FBFBFBBLLL 395 | BFFFFBFLRR 396 | BFFBBBFLLR 397 | FBFBBFBRRR 398 | BFBFBFFRLR 399 | FBFBFBFRLR 400 | BFBBFBFRRL 401 | FFBBFFBLLR 402 | FBBBBBFRRL 403 | BFBFFFBRRL 404 | BBFFBBBLRL 405 | FBBBFFFLRL 406 | BFFFBBBRRL 407 | FBBFFBBLRL 408 | FFBBBBBRLR 409 | BFBFBBBRLR 410 | FBFBFBBRLR 411 | FFBBBBBLRL 412 | FFBBFBFLLR 413 | FBFBFBFLLR 414 | FBFBBBBRLL 415 | FBFFFFFLLL 416 | BFFBFBFLLR 417 | BFBBBBBRRL 418 | FBBBBFFRLL 419 | BFBFFFBLLL 420 | FBFFBFBLRR 421 | FBFBBFBLLR 422 | FBBFFBFLRR 423 | BBFFFBBRRL 424 | FBBBFFBRLR 425 | BFFBBFFLLL 426 | FBFBBFFLRR 427 | FFBBBBFRLR 428 | FFBBBFFLRL 429 | FFBBFFFRRL 430 | BBFBFFFRRL 431 | FBFBFFFRLL 432 | BFBBBBFLRL 433 | FBFFFBFLLR 434 | FBFFBBBRLL 435 | FBBBFBBRLR 436 | BFBBBBBLLR 437 | BFBBFFBLLL 438 | BFBBFFFLLR 439 | FBBFBFBLRR 440 | BFFFBFFRRL 441 | FFBFFFFRRR 442 | FBFBFBBLLR 443 | FFBBBBFLLL 444 | FBFFFBFRRL 445 | FBBBFFBRRR 446 | BFBBFFFLRR 447 | BBFFFFBRLR 448 | FBBBFBFRLL 449 | FFBFFFBRLR 450 | FBFFFFBRRR 451 | FFBFBFFLLL 452 | BBFBFFBRLR 453 | BFFBFBFRLR 454 | FBBBBFBRLL 455 | FBFBFFFRRR 456 | BBFFBFFLRL 457 | BFBFBBBLLR 458 | FBBBBFFRRL 459 | FBFBFBFRRR 460 | FFBFBFBRRL 461 | FBFBBFBLRR 462 | FBBBFFBLRL 463 | BBFFFBBLRL 464 | FFBBFBFLRR 465 | BFFFFFFLLR 466 | BFBBBBBRLL 467 | BFBFBFBRLL 468 | BFBBFBFLLR 469 | FBFFFFFLRR 470 | BFFFBBBRLL 471 | FBBBBBBRLL 472 | BFBFBBBRRL 473 | FBFFBFBRLL 474 | FFFBBBBLRL 475 | BFBFFFBRLR 476 | FFBBBBFRLL 477 | FFBBFFBRLL 478 | BFFFBFBLLL 479 | BFFBFFBLLR 480 | BBFFFFFRRL 481 | BBFFBBFRRR 482 | BFBFFBFRLR 483 | FBFFBFFRLL 484 | FBBFBBBRRR 485 | BFFFFBFRRL 486 | BFFBFFBRRL 487 | BBFBFFFLRR 488 | BFBFBBFLLR 489 | FFBFFBBLLL 490 | FBFBFFFLRL 491 | FBFBFFFLLR 492 | BFBFBBFRRL 493 | FFBFFFFLLL 494 | BFFBFBBLRL 495 | FBFFFBBRLL 496 | FFFBBBBRRL 497 | FBFFBBFLRL 498 | FBFFFBBLLR 499 | FFBFBFFRLL 500 | FFBBBFFLLR 501 | BFBFFBBLLL 502 | BBFBFFBRLL 503 | BFFFFBFLLR 504 | BFFFFFFLRL 505 | BBFFBFFRLR 506 | FBBBFBFRRR 507 | FFFBBFBLLL 508 | FFBBFBBLLL 509 | BFFFFBFLRL 510 | BFBFBFFRRR 511 | BFBFFFFLLR 512 | BFFFBFBLRL 513 | FBBBBBBLLR 514 | BFFFFFFLRR 515 | FFBFBFBLRL 516 | BFFFFBBRRR 517 | BFBBFBBRLR 518 | BFBBFFBRRL 519 | FFBBBBBLLL 520 | FBFFFFBLLR 521 | FBBBFFBRLL 522 | FBBFBFBLRL 523 | BFBFFFBRLL 524 | FFBBFBBRRL 525 | BFBBFBFRLL 526 | FFBFFBBRRL 527 | FBBFBFFRRR 528 | BBFFFBBRLL 529 | BBFFBFBLLL 530 | FBFBFFFRLR 531 | FBFFFBBLRL 532 | FBFBBBFLRL 533 | BFFFFFFRLR 534 | FFFBBFFRRL 535 | FBFBBFFLLR 536 | BFFBFFBRRR 537 | FBBBFBFRRL 538 | BFBFFBFLRR 539 | BBFBFFFRLL 540 | BFFFFBFRLR 541 | FFBFBBBLLL 542 | FBBFFFBRLR 543 | BFFFFBBRRL 544 | BBFFBBBRLL 545 | BBFBFBFLRR 546 | BBFFBBBRRL 547 | FBFFBBBLLL 548 | BFBBFFFLLL 549 | FBBFBBBRLL 550 | BBFFBBFRLL 551 | BFFBFBFLRR 552 | FBFFBFFRRR 553 | FBBFFBFRRR 554 | BBFFBBFLRL 555 | BBFFBFFLRR 556 | FBBFFFBLRR 557 | FFBFBFFLRR 558 | BBFFBFFRRR 559 | BFBFBFFLRL 560 | FBFBBFBLLL 561 | BBFFBFFLLL 562 | BFBBBBFRRR 563 | BBFFBFBRLL 564 | FBFBBBFRRL 565 | BFBFFFBLRL 566 | FBBFFBBRLR 567 | FFBFFFBRRR 568 | BFBFBFBRRL 569 | BFFFBFBRLL 570 | FBFFFBBRLR 571 | FFBFFBFLRR 572 | BBFFBBFLLR 573 | BBFFFBBLRR 574 | BBFFFFBRLL 575 | BBFBFFFRLR 576 | FBFBFBFRLL 577 | FBBFFBFRLL 578 | FFFBBBFLRR 579 | BFFFBFBRRL 580 | BFFFFBBLRL 581 | BFFFFFBLRR 582 | BFFFFBFRLL 583 | FBBFBFFRRL 584 | BBFBFBFLLL 585 | FBFFBBBLRL 586 | FBBBFFBLRR 587 | FBBFFBBLRR 588 | FFFBBFBLRL 589 | BFFFBFFLRR 590 | FFBFFBBLLR 591 | BFBFBFBRLR 592 | BBFBFBFRRR 593 | BFFBFFBLRL 594 | FBFFBFFLLL 595 | FBFBFFFLRR 596 | FBBFBFBRRR 597 | BBFFBFBRRR 598 | FBBBBBBLLL 599 | FBBFBBFLLL 600 | FBBFFBFLLL 601 | FFBBBBFLLR 602 | FFBBBFFLRR 603 | FBFBFFFLLL 604 | FFBBBFBLRL 605 | FFFBBFBRLL 606 | BBFFFFBRRL 607 | FFFBBFBLRR 608 | BFBFBBBRLL 609 | FBFBBBFRLR 610 | FBBFFBBLLL 611 | FBFBBBFLLR 612 | FBFFBBFLLR 613 | BFBBBBBRRR 614 | FBBFFBFLLR 615 | FBFFFBBRRL 616 | BFBBBFFRLR 617 | BFBBBFFLLR 618 | FBFFFBBLRR 619 | FFBFBBBLRL 620 | BFFFBBBLLL 621 | FFBFFFBRRL 622 | BBFFFFFRLL 623 | FFFBBFBRLR 624 | FFFBBBBRLL 625 | FBBFBBFLRR 626 | FBBBBFBRRL 627 | BFBBBBBLRR 628 | BBFBFFFLRL 629 | BFBFBBFLRR 630 | BFBBFFBRLR 631 | FBFFFFFRLR 632 | FFBFFFBLLL 633 | FBBFBFBRLL 634 | BFBFFBBLRR 635 | FBBBBFBLLL 636 | FBBBFBFLLL 637 | FBFFFBFLLL 638 | BFFFFFBRRR 639 | FBBFFBFLRL 640 | BBFFBFBLLR 641 | FBBFBBBLLR 642 | FFBFFFFRRL 643 | FBBFFBBLLR 644 | BFFFFFBRLL 645 | FBFBBFFRLR 646 | FBBFFFBLLL 647 | BFFBBBFRRR 648 | BFFBBFBLRR 649 | FFBBBBBLRR 650 | FFBFFBBRLR 651 | FFBFFFFLRL 652 | FFBFBBBLRR 653 | BFBFFBFLRL 654 | FBFFBFFLRL 655 | FFBBFFFRLR 656 | BFBFBFFLLL 657 | FFBFBFBRLR 658 | FFBBFFBRRL 659 | FFBBFBFRLR 660 | FBBBFBBLLR 661 | FBFBBBBRRR 662 | FBBFFFFRRR 663 | FBFFBBBRRL 664 | BFBBBBFRLL 665 | FBBBBBFLRL 666 | FBBBBBBLRL 667 | FFBFBBFLLR 668 | BFBFFBFLLL 669 | BFFBBBBRLR 670 | FBFFFFFRRR 671 | FBFBBBBLLR 672 | BFBBBFBRLR 673 | BFFBBBFRRL 674 | BFFFBFFRLR 675 | BFBBBBFRRL 676 | BBFBFBFLLR 677 | BFFFBBBLRR 678 | FFBBFBBRRR 679 | FBFFFBFRLL 680 | FBBBFFFLLR 681 | BFBFFFFLRL 682 | FFBFBFFRRL 683 | BBFFFFBLRL 684 | BFFBBFBLLL 685 | BFFBBBBLLL 686 | FBBFFFFRRL 687 | FBBFBFFLRL 688 | BFFBFBFRRL 689 | FBFFBBFRRL 690 | FBBFFBBRRR 691 | FFFBBBBLRR 692 | FFBBFFBRRR 693 | FBBBFFFRRL 694 | FFBBFFFRLL 695 | FFFBBBFRRL 696 | FBFBFBBLRL 697 | BFFBBBFRLL 698 | FBBBBBFRRR 699 | FBBFBFBRRL 700 | BFFFFBBLLR 701 | FBFBFFBRRL 702 | BFBBFFBLRL 703 | BFBFFBBRLL 704 | BFBBBBFRLR 705 | FFBFBBFRLR 706 | FFBBFBBLRL 707 | FBBBFFFRLR 708 | BFBBBFFRLL 709 | FBBBFFFLLL 710 | BBFBFFFRRR 711 | BFBFBBBLRR 712 | FBFFBFBLLL 713 | FFFBBFBRRR 714 | BBFFFBFRRL 715 | FBFFFFBLRR 716 | BBFFFFBLLL 717 | BBFFFFFLLL 718 | FFBBFFFLRR 719 | BFFBFBFRRR 720 | BFFFBFBRRR 721 | FBBBFFBLLR 722 | BFBBFBFLLL 723 | FFBBBBFLRL 724 | FBBFFBFRLR 725 | BFFFFBBLLL 726 | FFBFBFBLLL 727 | FBBFFBBRLL 728 | FBBFFFBRRL 729 | FBFFBBBRRR 730 | BFFFBFFLLL 731 | FBBBBBFLLL 732 | BFFBBFFRRL 733 | FBBFBBBRRL 734 | BBFFFFBLLR 735 | FBFBBBFRRR 736 | FFBFBBBRRL 737 | FFBFBBBRLR 738 | FBBBFBBLRL 739 | FFFBBBBLLL 740 | BFBBFBBRLL 741 | FBBFBBFRRR 742 | BFFFFBBRLL 743 | BFFFBBFRLR 744 | FBBFBBFLRL 745 | BFBBFBFRRR 746 | FFBBBBFLRR 747 | FFFBBBFLRL 748 | FBFFFBFLRR 749 | FBBFFFBRRR 750 | BFBFFBFRLL 751 | FBFBBFBRLR 752 | BFBBFFBRRR 753 | FFBBFBFLLL 754 | FBFFFFFLLR 755 | BFBBFFBLLR 756 | FBBBBFFLRL 757 | FFFBBFFRLR 758 | BFBFFBFLLR 759 | FFBBFFFRRR 760 | FBBBFFBRRL 761 | BFFFFFFRRR 762 | -------------------------------------------------------------------------------- /src/main/resources/day08.txt: -------------------------------------------------------------------------------- 1 | acc +48 2 | acc -15 3 | jmp +510 4 | acc -16 5 | acc -9 6 | acc +10 7 | acc +45 8 | jmp +76 9 | acc +43 10 | acc -5 11 | acc +1 12 | jmp +306 13 | jmp +265 14 | jmp +506 15 | nop +48 16 | nop +596 17 | jmp +212 18 | acc +30 19 | jmp +311 20 | jmp +592 21 | acc +10 22 | jmp +1 23 | jmp +153 24 | acc +13 25 | nop +282 26 | jmp +482 27 | acc -12 28 | acc +22 29 | jmp +294 30 | acc -14 31 | acc +13 32 | nop +471 33 | acc +26 34 | jmp -13 35 | acc +11 36 | acc +23 37 | acc +9 38 | jmp +1 39 | jmp +158 40 | acc +20 41 | acc -3 42 | jmp +69 43 | jmp +546 44 | acc +14 45 | acc +25 46 | nop +488 47 | jmp +502 48 | acc +14 49 | acc -11 50 | acc +25 51 | acc +0 52 | jmp +527 53 | acc +45 54 | acc +35 55 | acc +2 56 | acc +33 57 | jmp +522 58 | acc +44 59 | acc +18 60 | acc +30 61 | jmp +429 62 | jmp +290 63 | jmp +36 64 | acc +36 65 | jmp +366 66 | acc +0 67 | acc +39 68 | acc -16 69 | jmp +160 70 | jmp -27 71 | acc -4 72 | acc -3 73 | acc +24 74 | acc +11 75 | jmp +321 76 | jmp +86 77 | acc +24 78 | jmp +113 79 | acc +28 80 | nop +73 81 | jmp +47 82 | jmp +165 83 | jmp +198 84 | acc -19 85 | acc -13 86 | jmp +297 87 | nop +175 88 | nop +328 89 | jmp +16 90 | acc -16 91 | acc -17 92 | acc -7 93 | acc +38 94 | jmp +409 95 | acc +27 96 | acc +38 97 | acc +2 98 | jmp -63 99 | jmp +145 100 | acc +18 101 | nop -74 102 | acc +39 103 | acc -13 104 | jmp -69 105 | acc +40 106 | acc +47 107 | jmp +16 108 | acc +9 109 | acc +13 110 | jmp +494 111 | acc +34 112 | acc +7 113 | jmp +303 114 | acc +0 115 | jmp +474 116 | acc +33 117 | acc +41 118 | acc +25 119 | acc +31 120 | jmp -49 121 | acc -17 122 | jmp +54 123 | jmp +172 124 | acc +30 125 | acc -13 126 | acc +13 127 | jmp +236 128 | acc +19 129 | jmp +15 130 | acc +24 131 | acc -17 132 | jmp +7 133 | acc +40 134 | acc -7 135 | acc -13 136 | jmp -59 137 | acc -2 138 | jmp +118 139 | acc +50 140 | acc +10 141 | acc +43 142 | jmp +41 143 | jmp +406 144 | nop +163 145 | acc +26 146 | acc +34 147 | jmp +426 148 | acc +0 149 | acc +18 150 | acc +0 151 | acc +1 152 | jmp -117 153 | acc +42 154 | jmp +51 155 | acc +21 156 | jmp +378 157 | jmp -73 158 | jmp +437 159 | jmp +475 160 | acc -10 161 | jmp +418 162 | jmp +211 163 | acc +15 164 | acc +27 165 | acc +32 166 | acc +9 167 | jmp +151 168 | acc -15 169 | acc +6 170 | jmp -88 171 | acc +14 172 | acc +15 173 | jmp +1 174 | acc +47 175 | jmp -36 176 | acc +42 177 | acc +34 178 | nop -39 179 | jmp +329 180 | acc +24 181 | acc +3 182 | jmp +418 183 | acc +10 184 | acc -19 185 | acc +23 186 | jmp +1 187 | jmp +326 188 | nop -49 189 | acc +19 190 | jmp +323 191 | jmp -182 192 | acc +14 193 | nop +164 194 | acc +47 195 | acc -8 196 | jmp +111 197 | acc +10 198 | nop +240 199 | acc +21 200 | jmp +100 201 | acc +19 202 | acc +32 203 | acc -5 204 | jmp +396 205 | acc -14 206 | acc -13 207 | jmp +18 208 | nop -11 209 | acc +40 210 | acc +27 211 | jmp +1 212 | jmp -7 213 | acc -8 214 | acc +14 215 | acc +29 216 | acc +22 217 | jmp +146 218 | nop +355 219 | jmp +322 220 | acc +3 221 | acc +17 222 | jmp +1 223 | jmp +258 224 | jmp +404 225 | acc -3 226 | acc +36 227 | jmp +204 228 | jmp -3 229 | acc -11 230 | acc +11 231 | jmp +310 232 | jmp +1 233 | jmp +308 234 | acc +11 235 | jmp +1 236 | acc +47 237 | acc -14 238 | jmp -81 239 | acc -16 240 | jmp +1 241 | acc +28 242 | acc +32 243 | jmp +157 244 | acc -13 245 | jmp +21 246 | jmp +312 247 | jmp +121 248 | jmp +135 249 | nop -5 250 | nop +6 251 | acc +23 252 | jmp -136 253 | acc +10 254 | acc +7 255 | jmp +63 256 | acc +25 257 | nop -214 258 | jmp +42 259 | acc +12 260 | acc +2 261 | jmp +1 262 | acc +16 263 | acc +47 264 | jmp -246 265 | jmp +42 266 | acc +10 267 | acc +11 268 | nop +344 269 | nop +197 270 | jmp +190 271 | jmp +201 272 | jmp -167 273 | acc +38 274 | nop -45 275 | acc +37 276 | acc +12 277 | jmp +1 278 | jmp -235 279 | acc +9 280 | jmp +254 281 | acc +33 282 | acc +11 283 | nop -11 284 | jmp -131 285 | nop +22 286 | acc +29 287 | jmp +1 288 | jmp +30 289 | jmp -121 290 | acc -8 291 | nop -115 292 | acc -16 293 | acc +15 294 | jmp +98 295 | acc +39 296 | jmp +53 297 | acc +0 298 | acc +5 299 | jmp +139 300 | acc -12 301 | acc -13 302 | jmp +50 303 | acc +47 304 | acc -18 305 | acc +8 306 | jmp -243 307 | acc +22 308 | jmp +188 309 | acc +5 310 | acc +46 311 | acc +25 312 | jmp +277 313 | acc -12 314 | jmp +250 315 | nop +116 316 | acc -19 317 | jmp -178 318 | acc -3 319 | acc +21 320 | nop -163 321 | jmp -77 322 | jmp -15 323 | acc -8 324 | acc -11 325 | jmp +129 326 | acc +32 327 | acc +46 328 | nop +88 329 | jmp -51 330 | jmp +27 331 | acc -11 332 | nop +116 333 | acc +31 334 | jmp -4 335 | acc +41 336 | jmp -315 337 | acc +10 338 | nop -76 339 | acc +25 340 | nop -127 341 | jmp -298 342 | acc +20 343 | acc +1 344 | acc -19 345 | jmp -125 346 | acc +9 347 | acc +40 348 | jmp +133 349 | nop -250 350 | jmp -116 351 | jmp -189 352 | acc +50 353 | jmp +78 354 | acc -3 355 | acc +37 356 | jmp -131 357 | nop -336 358 | acc +22 359 | acc +37 360 | jmp +94 361 | acc +43 362 | jmp -319 363 | jmp -328 364 | acc -18 365 | acc +0 366 | acc +33 367 | jmp -4 368 | acc +16 369 | jmp +213 370 | acc -12 371 | acc +23 372 | jmp -175 373 | acc -17 374 | acc -12 375 | nop -141 376 | nop +228 377 | jmp -244 378 | acc +11 379 | acc +12 380 | nop +220 381 | nop -184 382 | jmp +236 383 | acc +42 384 | acc +0 385 | acc +45 386 | acc +34 387 | jmp +213 388 | acc -18 389 | acc +18 390 | nop +26 391 | jmp +150 392 | nop -293 393 | nop -277 394 | jmp -380 395 | jmp -133 396 | acc -13 397 | jmp -108 398 | acc +39 399 | jmp +223 400 | acc +47 401 | acc +14 402 | acc +10 403 | jmp -90 404 | acc -19 405 | nop -387 406 | acc +24 407 | acc -19 408 | jmp -203 409 | acc +4 410 | jmp -132 411 | acc +31 412 | nop -255 413 | nop +187 414 | nop +40 415 | jmp +126 416 | acc -19 417 | acc -1 418 | acc -13 419 | jmp -147 420 | acc +0 421 | jmp -363 422 | acc -5 423 | acc -11 424 | acc +31 425 | acc +44 426 | jmp -177 427 | nop -406 428 | acc +29 429 | acc +34 430 | jmp -174 431 | acc +8 432 | acc -6 433 | nop -367 434 | acc -8 435 | jmp +183 436 | nop -147 437 | jmp +104 438 | acc -8 439 | nop +69 440 | acc -10 441 | acc -8 442 | jmp -384 443 | acc +20 444 | acc +39 445 | acc -16 446 | acc +2 447 | jmp -303 448 | acc -13 449 | jmp +100 450 | acc +14 451 | acc +22 452 | acc +27 453 | jmp -354 454 | acc +1 455 | acc +39 456 | acc -7 457 | jmp -346 458 | acc -10 459 | jmp -450 460 | nop -188 461 | jmp +5 462 | jmp +1 463 | nop -381 464 | acc +42 465 | jmp -102 466 | acc +13 467 | acc +11 468 | nop -224 469 | jmp -213 470 | acc +46 471 | jmp +57 472 | nop +140 473 | jmp +131 474 | acc +30 475 | acc +25 476 | acc -10 477 | acc -13 478 | jmp -78 479 | jmp -144 480 | jmp -185 481 | acc -17 482 | acc +36 483 | acc +38 484 | jmp +144 485 | nop -4 486 | acc +9 487 | acc +17 488 | acc +19 489 | jmp +90 490 | acc +11 491 | nop -380 492 | acc +17 493 | jmp -403 494 | acc -2 495 | jmp +94 496 | acc +32 497 | acc +45 498 | nop -249 499 | jmp -27 500 | acc +13 501 | nop -5 502 | jmp -439 503 | acc +32 504 | acc +5 505 | jmp -478 506 | acc +43 507 | jmp -98 508 | acc -18 509 | jmp -100 510 | acc +14 511 | acc -14 512 | jmp -329 513 | acc +46 514 | acc +5 515 | jmp -353 516 | acc -3 517 | acc +29 518 | acc +44 519 | jmp -88 520 | acc -11 521 | acc -14 522 | jmp -100 523 | nop -441 524 | acc +2 525 | acc +25 526 | acc +4 527 | jmp +7 528 | acc -17 529 | jmp +1 530 | nop -296 531 | acc +4 532 | jmp -132 533 | jmp -417 534 | nop -287 535 | acc +48 536 | nop -40 537 | acc -4 538 | jmp -146 539 | nop -521 540 | jmp -183 541 | acc -13 542 | acc +22 543 | jmp +15 544 | acc +21 545 | acc +22 546 | acc +27 547 | acc +34 548 | jmp -35 549 | acc -13 550 | nop -417 551 | acc +40 552 | jmp -114 553 | acc +4 554 | acc +20 555 | acc -1 556 | acc -9 557 | jmp -514 558 | acc +8 559 | acc -17 560 | acc +19 561 | jmp -130 562 | acc +11 563 | jmp -250 564 | nop +58 565 | acc +36 566 | acc -3 567 | acc -5 568 | jmp -120 569 | acc +11 570 | acc +50 571 | acc -18 572 | jmp -419 573 | jmp +1 574 | nop -446 575 | acc +22 576 | acc +28 577 | jmp -43 578 | jmp -289 579 | acc +1 580 | jmp -421 581 | jmp +14 582 | nop -62 583 | jmp -55 584 | jmp +1 585 | acc +5 586 | acc +26 587 | acc +0 588 | jmp -477 589 | acc +35 590 | acc -17 591 | acc +21 592 | jmp -200 593 | acc -2 594 | jmp -128 595 | jmp -253 596 | acc +28 597 | acc +47 598 | acc +27 599 | jmp -118 600 | acc +33 601 | jmp -228 602 | acc +41 603 | jmp -45 604 | acc +11 605 | acc -14 606 | jmp +1 607 | acc +35 608 | jmp -118 609 | acc +13 610 | acc +37 611 | jmp -108 612 | acc +44 613 | nop -523 614 | acc +45 615 | acc +39 616 | jmp +6 617 | jmp -582 618 | jmp -139 619 | acc -3 620 | jmp +1 621 | jmp -9 622 | acc +36 623 | acc +3 624 | acc +49 625 | jmp -562 626 | acc +14 627 | jmp -422 628 | acc +41 629 | acc +35 630 | jmp -582 631 | acc -11 632 | acc +0 633 | jmp -291 634 | acc -5 635 | acc -6 636 | acc +31 637 | acc -11 638 | jmp +1 639 | -------------------------------------------------------------------------------- /src/main/resources/day10.txt: -------------------------------------------------------------------------------- 1 | 111 2 | 56 3 | 160 4 | 128 5 | 25 6 | 182 7 | 131 8 | 174 9 | 87 10 | 52 11 | 23 12 | 30 13 | 93 14 | 157 15 | 36 16 | 155 17 | 183 18 | 167 19 | 130 20 | 50 21 | 71 22 | 98 23 | 42 24 | 129 25 | 18 26 | 13 27 | 99 28 | 146 29 | 81 30 | 184 31 | 1 32 | 51 33 | 137 34 | 8 35 | 9 36 | 43 37 | 115 38 | 121 39 | 171 40 | 77 41 | 97 42 | 149 43 | 83 44 | 89 45 | 2 46 | 38 47 | 139 48 | 152 49 | 29 50 | 180 51 | 10 52 | 165 53 | 114 54 | 75 55 | 82 56 | 104 57 | 108 58 | 156 59 | 96 60 | 150 61 | 105 62 | 44 63 | 100 64 | 69 65 | 72 66 | 143 67 | 32 68 | 172 69 | 84 70 | 161 71 | 118 72 | 47 73 | 17 74 | 177 75 | 7 76 | 61 77 | 4 78 | 103 79 | 66 80 | 76 81 | 138 82 | 53 83 | 88 84 | 122 85 | 22 86 | 123 87 | 37 88 | 90 89 | 134 90 | 41 91 | 64 92 | 127 93 | 166 94 | 173 95 | 168 96 | 58 97 | 26 98 | 24 99 | 33 100 | 151 101 | 57 102 | 181 103 | 31 104 | 124 105 | 140 106 | 3 107 | 19 108 | 16 109 | 80 110 | 164 111 | 70 112 | 65 113 | -------------------------------------------------------------------------------- /src/main/resources/day11.txt: -------------------------------------------------------------------------------- 1 | LLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLL.LLLLLLLLLLL.LLLLLLLLLLLLLL.LLLL.LLLL.LLLLLL 2 | LLLLL.LLLLLLLLLLLLLLLL.LLLLL.LLL.LLLLLLL.LLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLL.LLLL.LLLL.LLLL.LLLLLL 3 | LLLLL.LLLL.LLLL.LLLLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLL.LLLLLLLLLLL 4 | LLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLL.LLLL.LLLLLL 5 | LLLLL.LLLL.LLLL.LLLLLL.LLLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLLLLL.LLLL.LLLL.LLLLLL 6 | LLLLL.LLLL.LLLLLLLLLLL.LLLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLL.LLLL.LLLLLL 7 | LLLLLLLLLL.LLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLL.LLLL.LLLL.LLLL.LLLLLL 8 | LLLLLLLLLL.LLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLL.LLLL.LLLL.LLLL.LLLLLL 9 | L.L...L...LL.LL.......LL...LL.L...LL..LL..L.......LLLLL.....LL..LLLL.L....L..L...L.LL....LL...L 10 | LLLLL.LLLLL.LLLLLLLLLL.LLLLLLLLL.LLLLLLL.LLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLL.LLLL.LLLL.LLLL.LLLLLL 11 | LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLL.LL.LLLLLLLLL.LLLL.LLLL.LLLLLLLLLLL 12 | LLLLL.LLLL.LLLL.LLLLLL.LLLLLLLLL.LL.LLLLLLLLLL.LLLL.LLLLLLLLLLLLLLLL.LLLL.LLLL.LLLLLLLLL.LLLLLL 13 | LLLLLLLLLL.LLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLL.LLL.LL.LLLLLLLLL.LLLL.LLLL.LLLL.L.LLLL 14 | LLLLL.LLLL.LLLL.LLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLLLL.LLLLLLLLLLL.LLLLLLLLL.LLLL.LLLL.LLLLLLLLLLL 15 | LLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLL.LLLL.LLL.LL.LLLLLLLLLLLLLLLLLLL.LLLL.LLLLLL 16 | .L.....L.LL..LLL.L..L...L.LLL.L...L.L.L.L.....L..L.......L.LLL...L.......L.LLLL......L.L.L...LL 17 | LLLLLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLL..LLLLLL.LLLL.LLLL.L.LL.LLLLLLLLL.LLLLLL 18 | LLLLLLLLLL.LLLL.LLLLLL.LLLLLLLLL.LLLLLLLLLLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLLL 19 | LLLLL.LLLL.LLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLLLLL.LL.LLLLLLLLLLLLL.LLLLLLLLLLLLLL.LLLL.LLLL.LLLLLL 20 | LLLLL.LLLL.LLLL.LLLLLL.LLLLLLLLLLLLLLLLL.LLLLL.LLLL.LLLL.LLLLLL.LLLLLLLLLLLLLL.LLLL.LLLL.LLLLLL 21 | .L..LLL.L...LL.....LL......LL...L...LL...L.L..L....L.L.L.LL.L........L....LL......L..LL..LL.... 22 | LLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLL.LLLLLLL.LLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLLLLLLL 23 | LLLLLLLLLL.LLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLLLL.LLLLLLLLL.LLLLLLLLL.LLLL.LLLLLL 24 | LLLLL.LLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLL.LLLLL.LLL..LLLL.LLLLLL.LLLLLLLLLLL.LL.LLLL.LLLLLLLLLLL 25 | LLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLL.LLLL.LLLL..L.LLL.LLLLLLLLL.LLLL.LLLLLLLLLLLLLLLL 26 | LLLLLLLLLL.LLLL.LLLLLL.LLLLLL.LLLLLLLLLL.LLLLL.LLLL.LLLLLLLLLLL.LLLLLLLLLLLLLL.LLLL.LLLLLLLLLLL 27 | L.LLL.LLLLLLLLL.LLLLLL.LLLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLL.LLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLLLLL 28 | LLLL....L.......L..LLL...........L..L...LL..L.L.LLL...L.....LL..LL..L....L....L..LL..LL.L....L. 29 | LLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLL.L.LLLLLLLLLLLL.LLLLLL 30 | LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLL.LLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLL 31 | LLLLLLLLLLLLLLL.LLLLLL.LLLLLLLLL.LLLLLLL.LLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLL.LLLL.LLLLL.LLLLLLLLLL 32 | LLLLLLLLLL.LLLL.LLLLLL.LLLLLLLLL.LLLLLLLLLLLLL.LLLL.LLLL.LLLLLL..LLL.LLLL.LLLL.LLLL.LLLLLLLLLLL 33 | LLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLL.L.LLLL.LL.L.LL.LLLLLLLLLLLLL.LLLL.LLLL.LLLL.LLLLLL 34 | .LL........L.....L.L.L.......LL.L.L.......LLL.........L....LL........L.L..L......L.LL......L..L 35 | LLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLL.LLLL.LLLL.LLLL.LLLLLL 36 | LLLLL.LLLLLLLLL.LLLLLL.LLLLLLLLL.LLLLLLLLLLLLL.LLLL.LLLL.LLLLLL.LLLLLLLLLLLLLL.L.LLLLLLLLLLLLLL 37 | LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLL.LLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLLLLL 38 | LLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.L.LLLL.LLLLLL.LLLLLLLLL.LLLL.LLLLLLLLL.LLLLLL 39 | LLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLL.LLL..LLLLLL.LLLLLLLLL.LLLLLLLLL.LLLL.LLLLLL 40 | LLLLL.LLLL.LLLL.LLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLL.LL.L.LLLLLLLLLLLLLLLL.LLLL.LLLLLLLLL.LLLLLL 41 | .L..L...L........L.......L.L.LL.LLLL...LLL.L.L..L.L....L.................L.L.L.L....L...L...L.. 42 | LLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLL.LLLL.LLLLLL.LLLLLLLLLLLLLL.LLLL.LLLL.LLLLLL 43 | LLLLLLLLLL.LLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLL.LLLLLL.LLLLLLLLLLLLLL.LLLL.LLLL.LLLLLL 44 | LLLLL.LLLL.LLLL.LLLLLL.LLLLLLLLL.LLLLLLL.LLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLLLLLLL.LLLL.LLLL.LLLLLL 45 | LLLLL.LLLL.LLLL.LLLLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLL.LLLL.LLLLLL.LLLL 46 | LLLLL.LL.LLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLL.LLLL.LLLLLLLLLLLLLLLL.LLLL.LLLLLLLLL.LLLLLL 47 | LLLLL.LLLLLLLLL.LLLLLL.LLLLLLLLL.LLLLLLLLLLLLL.LLLL.LLLLLLLLLLL.LLLLLLLLLLLLLL.LLLL.LLLL.LLLLLL 48 | LLLL...LLL.......LL..L.L.L.L...L........LL..............L.L......L.......L..LL....L....LL...LL. 49 | LLLLL.LLLL.LLLL.LLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLL.LLLL.LLLLLL.L.LLLLLLL.LLLLLLLLL.LLLLLLLLLLL 50 | LLLLL.LLLL.LLLL.LLLLLL..LLLLLLLL.LLLLLLLLLLLLLLLLLL.LLLL.LLLLLL.LLLLLLLLL.LLLLLLL.L.LLLL.LLLLLL 51 | LLLLL.LLLL.LLLLLLLLLLL.LLLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLLLLLLL 52 | LLLLL.LLLL.LLLL.LLLLLL.LLLLLLLLLLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLLLLL.LLLLLLLLL.LLLLLL 53 | LLLLLLLLLL.LLLL.LLLLLL.LLLLLLLLL.LLLLLLLLLLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLL 54 | LLLLL.LLLL.LLLL.LLLLLL.LLLLLLLLLLLLLLLLL.LLLLL.LLLL.L.LL.LLLLLL.LLLLLLLLLLL.LL.LLLLLLLLL.LLL.LL 55 | LLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLL.LLLLLLLLLLL.LLLLLLLLL.LLLL.LLLLLLLLLLLLLLLL 56 | LLLLLLLLLL.LLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLLLLLLL.LLLLLLLLL.LLLL.LLLL.LLLL.LLLLLL 57 | LL.LL.LLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLL.LLLLLLLLL.LLLL.LLLLLL 58 | LLLL.L...LL.......LL..L.....L.LL..L....L.L..L.......L..L......LLLLL..L.L..L......L...L.L...L.L. 59 | LLLLL.LLL..LLLL.LLLLLL.LLLLL.LLL.LLLLL.L.LLLLL.LLLLLLLLL.LLLLLL.LLLLLLLLLLLLLL.LLLLLLLL..LLLLLL 60 | LLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLL.LLLLLL.LLLLLLLLL.LLLLLLLLL.LLLL.LLLLLL 61 | LLLLL.LLLL.LLLLLLLLLLL.LLLLLLLLL.LLLLLL.LLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLL.LLLL.LLLL.LLLLLLLLLLL 62 | LLLLLLLLLL.LLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLL.LLLLLL.LLLLLLLLLLLLLL.LLLL.LLLL.LLLLLL 63 | LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLL.LLLLL.LLLL.LLLLLLLLLLLL.LLLLLLLL.LLLL.LLLL.LLLL.LLLLLL 64 | L.L...............L..L.LLLL...L..L...LLL.......LLL.LL........L..LL..L..L...L.L.L.LL..LLLL.L.LL. 65 | LLLLLLLL.L.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLL.LLLL.LLLLLLLLL.LLLLLL 66 | LLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLLLL.LLLLLLLLLLL 67 | LLLLLLLLLLLLLLL.LLLLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLL.LLLL.LLLLLLLLLLL 68 | LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLL.LLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLL.LLLLLL 69 | LLLLL.LLLLLLLLL.LLLLLL.LLLLLLLLL.LLLLLLL.LLLLL.LLLL.LLLL.LLLLLL.LLLLLLLLL.LLLL.LLLLLLLLLLLLLLLL 70 | L.LLL.LLLL.LLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLL.LLLL.LLLL.LLLLLLLLLLL 71 | LLLLL.LLLL.LLLL.LLLLLL.LLLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLL.LLLLLL 72 | LLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLL.LLLL.LLLLLLLLLLLLL.LLLLLLL.LLLL.LLLL.LLLLLL 73 | .L..LL.L.L..L...L....L......LLL......L.LL..L....L.LLLL.LL.....L.L.LL.L.....L......L.LL......... 74 | LLLLL.LLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLL.LLLL..LLLL.LLLL.LLLLLL.LLLLLLLLL.LLLL.LLLLLLLLL.LLLLLL 75 | LLLLL.LLLL.LLLL.LLLLLL.LLLLLLLLL.LLLLLLL.LLLLL.LLLL.LLLLLLLLLLL.LLLLLLLLLLLLLL.LLLLLLLLL.LLLLLL 76 | LLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLL 77 | LLLLL.LLL..LLLL.LLLLLL.LLLLLLLLL.LLLLLLL.LLLLL.LLLL.LLLLLLLLLLL.LLLLLLLLL..LLL.LLLLLLLLLLLLLLLL 78 | .LLL......L.L.L......L.....LL......L.LLL.LLL..LL...L.L.......L..L.......L....L.....L.......LL.. 79 | LLLLL.LLLL.LLLL.LLLLLL.LLLLLLLLL.LLLLLLL.LLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLL.LLLL.LLLLLLLLL.LLLLLL 80 | LLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLL.LLLL.LLLL.LLLLLL.LLLLLLLLL.LLLL.LLLL.LLLL.LLLLLL 81 | LLLLLLLLLL.LLLL.LLLLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLL.LLLLLL.LLLLLLLLL.LLLL.LLLL.LLLL.LLLLLL 82 | LLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLL.LLLLLLLLL.LLLLLLLLLLLLLL.LLLLLL 83 | LLLLL.LLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLL.LLLL.LLLL.LLLL.LLLLLL 84 | LL...L...........L...L..L......LL...........L...L.LL..LL....L....LLL.LLLL....LLL...LL..L..L...L 85 | LLLLLLLLLLLLLLL.LLLLLL.LLLLLLLLL.LLLLLLLLLLLLL.LLLL.LLLL.LLLLLL.LLLLLLLLL.LLLL.LLLL.LLLL.LLLLLL 86 | LLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLL.LLLL.LLLLLL.LLLLLLLLL.LLLL.LLLL.LLLLLLLLLLL 87 | LLLLLLLLLL.LLLL.LLLLLL.LLL.LLLLLLLLLLLLL.LLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLL.LLLL.LLLL.LLLLLLLLLLL 88 | .LLLL.LLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLLLL.LLLL.LLLLLL 89 | LLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLL.LLLL.LLLL.LLLL.LLLLLL 90 | LLLLL.LLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLL 91 | LLLLL.LL.LLLLLLLLLLLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLLL.LLLLLLLLLLL.LLLLLLLL..LLLL.LLL..LLLLLLLLLLL 92 | .......L...LL.L.....L.L.....LLL.L.......L.....LL.......L..LLL.....L.LL.L..........LL........... 93 | LLLLL.LLLLLLLLL.LLLLLL.LLLLLLLLL.LLLLLLLLLLLLL.LLLLLL.LL.LL.LLL.LLLLLLLLLLLLLL.LLLL.LLLLLLLLLLL 94 | LLLLLLLLLL.LLLL.LLLLLL.LLLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLL.LLLL.LLLL.LLLL.LLLLLL 95 | LLLLL.LLLL.LLLLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLLL.LLLL.LLLLLL.LLLLLLLL..LLLLLLLLL.LLLL.LLLLLL 96 | LLLLL.LLLL.LLLL.LLLLLL.LLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLL.LLLLLL 97 | LLLLL.LLLL.LLLL.LLLLLL.LLLLLLLLL.LLLLLLL.LLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLL.LLLL.LLLL.LLLL.LLLLLL 98 | LLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLL -------------------------------------------------------------------------------- /src/main/resources/day12.txt: -------------------------------------------------------------------------------- 1 | N3 2 | F18 3 | L180 4 | F40 5 | N3 6 | R90 7 | S5 8 | R90 9 | N4 10 | F24 11 | R90 12 | E5 13 | F36 14 | R180 15 | W3 16 | W4 17 | F63 18 | N4 19 | W1 20 | N1 21 | E1 22 | L90 23 | W1 24 | N2 25 | E2 26 | S2 27 | F39 28 | W4 29 | S3 30 | F93 31 | N1 32 | F83 33 | S1 34 | R90 35 | W3 36 | R90 37 | W4 38 | L90 39 | F53 40 | S4 41 | F4 42 | L90 43 | W3 44 | F83 45 | L180 46 | W2 47 | L90 48 | W2 49 | L90 50 | W1 51 | N3 52 | F63 53 | R90 54 | N2 55 | N3 56 | E4 57 | F10 58 | S3 59 | E4 60 | R90 61 | F11 62 | L90 63 | R90 64 | S2 65 | W2 66 | F100 67 | W5 68 | R270 69 | F40 70 | S5 71 | L90 72 | E2 73 | L90 74 | E2 75 | L180 76 | N5 77 | F81 78 | N4 79 | E4 80 | L180 81 | F38 82 | W2 83 | F22 84 | W5 85 | N5 86 | E1 87 | N2 88 | W4 89 | N2 90 | F68 91 | N1 92 | F2 93 | S1 94 | F47 95 | W5 96 | F80 97 | N3 98 | E3 99 | S2 100 | L180 101 | F87 102 | L180 103 | E4 104 | L90 105 | E2 106 | S3 107 | L180 108 | E2 109 | L90 110 | W2 111 | N4 112 | F21 113 | S4 114 | W5 115 | F70 116 | F4 117 | N2 118 | F14 119 | E2 120 | S3 121 | R90 122 | W3 123 | N2 124 | E3 125 | S1 126 | F85 127 | R90 128 | E1 129 | F80 130 | L90 131 | F100 132 | R90 133 | W1 134 | R180 135 | S4 136 | F58 137 | L90 138 | N3 139 | R90 140 | E1 141 | F42 142 | E3 143 | F93 144 | S3 145 | R90 146 | W2 147 | N3 148 | L90 149 | W3 150 | W2 151 | N2 152 | W1 153 | S4 154 | R180 155 | N5 156 | R180 157 | F52 158 | N5 159 | F20 160 | L180 161 | E5 162 | R90 163 | W2 164 | S4 165 | E1 166 | S3 167 | F75 168 | R90 169 | F49 170 | L180 171 | N3 172 | F31 173 | S3 174 | E3 175 | S5 176 | L180 177 | N3 178 | E2 179 | R270 180 | W5 181 | N3 182 | W5 183 | N3 184 | L270 185 | F54 186 | R90 187 | W5 188 | F73 189 | S3 190 | W2 191 | R90 192 | N2 193 | R90 194 | S5 195 | R90 196 | W4 197 | S2 198 | L90 199 | F3 200 | S2 201 | R90 202 | F76 203 | S3 204 | F56 205 | L90 206 | F5 207 | N1 208 | R180 209 | E3 210 | N2 211 | F20 212 | E2 213 | L180 214 | F38 215 | R180 216 | W4 217 | R90 218 | S3 219 | N5 220 | E5 221 | F26 222 | S2 223 | L180 224 | E4 225 | R90 226 | F52 227 | N3 228 | L90 229 | N5 230 | E4 231 | F63 232 | L90 233 | F48 234 | W5 235 | F29 236 | N1 237 | E3 238 | L90 239 | N5 240 | L90 241 | S3 242 | F8 243 | N2 244 | R90 245 | E4 246 | S2 247 | E2 248 | F10 249 | W2 250 | L90 251 | N2 252 | R90 253 | F2 254 | E2 255 | N4 256 | R90 257 | F74 258 | W3 259 | W5 260 | S2 261 | R90 262 | N3 263 | L90 264 | E3 265 | F58 266 | N4 267 | E5 268 | S4 269 | E3 270 | F72 271 | L180 272 | E3 273 | S2 274 | L90 275 | W4 276 | S1 277 | F14 278 | W1 279 | N1 280 | E3 281 | W4 282 | L90 283 | N1 284 | F97 285 | R90 286 | N4 287 | E3 288 | F95 289 | F95 290 | L90 291 | S4 292 | F55 293 | R90 294 | W2 295 | N1 296 | R90 297 | F16 298 | L90 299 | S5 300 | F4 301 | R90 302 | F24 303 | S4 304 | E2 305 | R90 306 | W5 307 | E1 308 | L270 309 | F12 310 | L90 311 | F100 312 | W1 313 | S5 314 | W2 315 | S3 316 | F95 317 | L90 318 | F44 319 | N5 320 | F79 321 | S4 322 | R180 323 | E2 324 | S1 325 | F40 326 | R90 327 | W2 328 | R90 329 | F67 330 | S5 331 | F15 332 | L90 333 | N4 334 | L90 335 | S5 336 | E1 337 | R90 338 | N3 339 | W5 340 | N4 341 | L270 342 | F61 343 | L90 344 | E1 345 | L90 346 | E1 347 | F38 348 | E2 349 | F19 350 | W2 351 | L90 352 | S4 353 | R180 354 | W4 355 | F59 356 | N1 357 | F26 358 | N1 359 | W5 360 | F7 361 | N4 362 | F72 363 | E2 364 | R90 365 | F59 366 | N1 367 | F58 368 | N5 369 | F13 370 | N2 371 | F2 372 | S2 373 | W1 374 | F85 375 | R270 376 | S2 377 | F17 378 | R90 379 | F96 380 | S2 381 | L90 382 | E1 383 | N4 384 | F9 385 | R270 386 | F58 387 | N1 388 | L90 389 | W2 390 | S2 391 | F73 392 | W1 393 | S2 394 | F20 395 | E2 396 | S4 397 | F94 398 | L180 399 | F27 400 | S2 401 | F48 402 | N1 403 | L270 404 | S2 405 | F77 406 | E3 407 | F10 408 | W3 409 | L270 410 | S4 411 | F53 412 | F66 413 | E5 414 | S2 415 | F33 416 | S5 417 | L90 418 | W3 419 | S3 420 | E3 421 | R90 422 | E1 423 | F62 424 | S1 425 | L90 426 | S3 427 | E3 428 | N1 429 | S1 430 | E5 431 | S2 432 | F66 433 | N4 434 | N1 435 | W4 436 | F84 437 | R180 438 | F23 439 | F20 440 | E1 441 | S3 442 | R90 443 | E2 444 | F48 445 | F89 446 | L90 447 | F97 448 | R180 449 | N3 450 | F62 451 | L90 452 | N5 453 | F28 454 | W5 455 | N4 456 | L180 457 | N4 458 | W1 459 | N3 460 | L90 461 | F95 462 | N1 463 | W5 464 | R180 465 | N5 466 | F34 467 | S1 468 | W2 469 | N4 470 | F3 471 | S2 472 | E1 473 | R90 474 | E2 475 | F36 476 | S4 477 | E5 478 | F42 479 | W1 480 | L180 481 | S1 482 | F74 483 | F38 484 | N4 485 | R270 486 | N3 487 | W2 488 | S4 489 | L180 490 | F26 491 | S4 492 | F51 493 | R90 494 | F83 495 | R90 496 | F9 497 | S2 498 | W1 499 | F99 500 | S4 501 | W1 502 | F84 503 | W1 504 | R180 505 | F59 506 | W5 507 | R90 508 | F75 509 | S1 510 | F34 511 | E4 512 | N3 513 | L90 514 | F43 515 | W5 516 | N1 517 | R90 518 | F59 519 | W1 520 | N3 521 | W4 522 | S2 523 | F36 524 | N5 525 | W4 526 | E2 527 | F96 528 | R180 529 | F44 530 | R90 531 | F12 532 | E5 533 | F24 534 | W3 535 | F39 536 | S2 537 | L180 538 | W3 539 | W4 540 | F70 541 | N4 542 | E4 543 | F36 544 | E2 545 | N1 546 | F30 547 | L90 548 | S2 549 | F81 550 | R270 551 | R90 552 | F66 553 | W1 554 | L90 555 | W2 556 | F98 557 | S1 558 | E1 559 | L90 560 | E3 561 | N2 562 | F100 563 | W3 564 | N3 565 | R90 566 | F88 567 | E4 568 | L180 569 | F52 570 | L90 571 | E4 572 | F76 573 | W2 574 | L90 575 | E3 576 | F72 577 | S3 578 | L180 579 | F12 580 | F34 581 | E5 582 | F90 583 | S5 584 | W5 585 | E1 586 | N5 587 | L180 588 | E5 589 | F84 590 | E5 591 | E3 592 | L90 593 | E3 594 | F14 595 | L90 596 | W3 597 | L90 598 | S1 599 | L90 600 | W2 601 | F54 602 | R90 603 | S2 604 | F73 605 | S4 606 | E1 607 | S1 608 | F55 609 | E5 610 | N4 611 | R180 612 | L180 613 | N4 614 | R90 615 | F91 616 | L180 617 | F5 618 | E2 619 | N1 620 | W2 621 | F27 622 | W2 623 | S5 624 | R90 625 | S3 626 | F39 627 | S3 628 | W2 629 | F59 630 | F83 631 | W3 632 | E3 633 | E4 634 | L90 635 | S1 636 | R90 637 | E4 638 | F81 639 | E4 640 | R90 641 | W5 642 | F74 643 | W3 644 | E3 645 | F30 646 | L180 647 | S2 648 | E3 649 | F33 650 | S3 651 | R90 652 | F22 653 | S5 654 | F97 655 | S1 656 | E2 657 | F50 658 | E2 659 | F19 660 | E3 661 | L90 662 | L90 663 | S5 664 | W3 665 | F80 666 | F33 667 | E1 668 | R90 669 | N3 670 | L90 671 | F70 672 | L180 673 | W4 674 | N2 675 | R180 676 | S2 677 | F38 678 | S3 679 | F7 680 | R90 681 | E1 682 | N5 683 | F86 684 | W4 685 | F49 686 | W4 687 | F51 688 | S4 689 | F47 690 | R90 691 | W3 692 | R180 693 | R180 694 | W1 695 | F98 696 | S1 697 | W3 698 | S4 699 | L90 700 | F76 701 | E1 702 | F76 703 | R180 704 | S4 705 | R180 706 | W3 707 | F26 708 | N5 709 | F35 710 | S2 711 | F94 712 | F24 713 | N2 714 | F45 715 | E1 716 | L90 717 | F32 718 | S1 719 | R180 720 | F78 721 | F84 722 | L90 723 | N2 724 | F42 725 | R90 726 | F72 727 | S1 728 | E3 729 | N2 730 | W1 731 | F23 732 | E2 733 | F69 734 | L90 735 | F29 736 | R90 737 | S5 738 | W5 739 | L90 740 | W1 741 | S2 742 | E1 743 | F96 744 | S5 745 | R180 746 | F26 747 | S5 748 | W1 749 | S3 750 | F38 751 | S1 752 | E2 753 | S5 754 | W2 755 | S5 756 | F52 757 | L90 758 | F11 759 | E3 760 | R90 761 | E4 762 | F6 763 | L90 764 | R90 765 | W1 766 | R90 767 | E3 768 | F1 769 | E4 770 | N3 771 | E5 772 | R90 773 | N2 774 | R180 775 | W2 776 | N5 777 | F46 778 | N3 779 | E5 780 | F83 781 | R90 782 | F42 783 | S3 784 | R90 785 | N5 786 | F10 787 | -------------------------------------------------------------------------------- /src/main/resources/day13.txt: -------------------------------------------------------------------------------- 1 | 1003681 2 | 23,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,37,x,x,x,x,x,431,x,x,x,x,x,x,x,x,x,x,x,x,13,17,x,x,x,x,19,x,x,x,x,x,x,x,x,x,x,x,409,x,x,x,x,x,x,x,x,x,41,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,29 3 | -------------------------------------------------------------------------------- /src/main/resources/day15.txt: -------------------------------------------------------------------------------- 1 | 0,1,5,10,3,12,19 -------------------------------------------------------------------------------- /src/main/resources/day17.txt: -------------------------------------------------------------------------------- 1 | #.#.##.# 2 | #.####.# 3 | ...##... 4 | #####.## 5 | #....### 6 | ##..##.. 7 | #..####. 8 | #...#.#. 9 | -------------------------------------------------------------------------------- /src/main/resources/day21.txt: -------------------------------------------------------------------------------- 1 | jfvltdz txzv szzbr fcbsv klzdr xclff jqqbnzz flzmlbf crfxz jxrlzm xcfpc tvk kdbx zlhlq gfpnx ccvsl zfl skllln lxqbsc frgnkt mrnd smjhxg cmqjlb jxdbh tsbffm mtjlb czbhh gbbxhp snsnj lmvx pbztj glvv jkzxn nnfps hnvrfvm fddx nhhgb hdt jg hrnzq tmgfr vjcbtd nklc fmbqgs hcg gpgrb qrgvj znqbr pfdkkzp vmrf mbqpfm pccmj bph hmngm fcbvh vtqhqs zsjlp rdbdd gtjmd bskstb krxj rglbcpq svqz jczm frssvh nmxdsnc hjbs xkpm tsvfrt txr flmm tjrm jccqsxs bncfz vlpq ngl dvfqqz hqxdv xzrdx qdnh hbqhvk spbxz pnxzqgp kjcdgh ttmcq dlvdt (contains peanuts) 2 | bjqt frgnkt ctbmdg hbqhvk skllln spbxz frssvh rdbdd gpgrb nndr dvfqqz jlnrn tsvfrt jccqsxs jkzxn znqbr vlpq hcg gtjmd lmvx zck jnd vghkr fmfnh rlsqd vjcbtd kbszttf mdsg pfdkkzp stnb tjlz bqc gfpnx mfvxhv pdss tzglth mtpfk cnhbh thprs kvcc hnvrfvm klzdr xcfpc kdxvzqm (contains peanuts) 3 | pngs tjlz nmxdsnc qdnh pccmj mkz rdbdd mbqpfm ngl znqbr tzglth tlbj klzdr pgrc fddx mxmvt srxrn gtjmd vdgsz dxzzp zfsmv svcmg mzjvq txr jkzxn smjhxg dptl flmm xlcgr srpqk kdbx bctn hnvrfvm qkvrf kvcc qzqdq krdmn vlpq tmjltg kdxvzqm hdt thprs pfdkkzp nklc cmqjlb jrrgck gpgrb mdnchc gzngn qrgvj pznt pdss zjh crfxz krxj xcfpc svrvv ctbmdg spbxz (contains shellfish) 4 | xcfpc zfl cnhbh mdx tjlz pnxzqgp drzm glljh xsndjl hrnzq pdss zck kjcdgh pgrc bph gtjmd xmcsr ctgnz kbszttf gpgrb spbxz vtqhqs snsnj brjd znqbr mbqpfm crfxz blbfl rjds gdsk kdxvzqm mdnnfp mrnd mzjvq flzmlbf pznt pggzp txr vxx bncfz lzfmghs krxj pfdkkzp rtjxbbd (contains dairy, shellfish, fish) 5 | mdx glcfml jqkxx jccqsxs kvcc nndr kbszttf mfvxhv rjds tjrm spbxz gtjmd vtqhqs fmbqgs dxzzp snptbf hrnzq rtjxbbd tmgfr sckhr hsdnz xkpm txzv fgrmrqhp gxbs gfpnx mdnnfp kbtkrcf drzm tbptvzf dtqplpj vxx cmtq zsjlp gpgrb glvv qrgvj tmjltg hnvrfvm pbztj czbhh tvk cnhbh krdmn flzmlbf lblbm mrnd znqbr kdbx xcfpc nhhgb mdsg zck txr stnb hdt hjbs pfdkkzp skks klh zfl (contains dairy) 6 | skllln tvk srxrn snptbf cnhbh gbbxhp jczm spbxz pznt kbtkrcf fmbqgs tjlz frssvh pmhxl znqbr mtpfk fcbvh rdbdd xpmmdc vjcbtd cmqjlb jqqbnzz nnfps lblbm kdxvzqm qzqdq bjqt txzv qrgvj tmjltg mxfrnq hbqhvk gtjmd jlnrn kvcc hsdnz dfllfp mfvxhv mfcrq tgclx xlcgr glvv czbhh tsbffm hmnt xcfpc mkz cmtq gpgrb (contains soy) 7 | gtjmd zbj vdgsz stnb tsbffm tjlz pdss jqqbnzz nklc srxrn klh glljh ctbmdg dptl jczm pfdkkzp jfvltdz nhhgb glvv jccqsxs hsdnz bskstb brjd ctgnz rjds tjrm qrgvj zck spbxz zfl xbp mfcrq svrvv zsjlp bqc pbztj xsndjl bctn lblbm fmfnh kdxvzqm cdntx hjbs gnkr rtjxbbd hdt hcg vjcbtd hmnt skqbbj frgnkt znqbr klzdr tmjltg nndr hsdqb tgclx txzv hnnz mdx pngs jg snptbf czbhh cnhbh jrrgck jlnrn gpgrb mfvxhv mdnnfp sckhr pccmj gfpnx dxzzp tbptvzf (contains peanuts, soy, dairy) 8 | nkshjm pgmqs znqbr cdntx hsdnz kdxvzqm pmhxl tjlz nndr lzczv mtjlb jqkxx bjrbknjm pbztj nmpp mkz tbptvzf krxj bctn ctgnz qlzxbc hbqhvk mbqpfm dvfqqz gtjmd mfvxhv gdsk snptbf cmqjlb gpgrb jfvltdz vlpq zjh pggzp xkpm xpmmdc tgclx bqc spbxz kjcdgh lflzqr glvv stnb tjrm txzv qzqdq hjbs ccvsl jxdbh xcfpc bncfz flmm blbfl zbj rglbcpq srpqk tsvfrt fcbsv rtjxbbd bph tsbffm smjhxg tmjltg (contains shellfish) 9 | snsnj tmjltg lxqbsc czbhh txzv svqz krdmn tjlz jg bnrf nmxdsnc ndhx zck zjh skks rdbdd bnnt srpqk svrvv spbxz pdss cmqjlb vmrf crfxz gpgrb jdvtlsv sgh mkz pznt tgclx kdxvzqm jfvltdz ccvsl jlnrn gdsk pfdkkzp flzmlbf xcfpc jqkxx dptl hrnzq vghkr tmgfr glvv mfvxhv gtjmd fgrmrqhp mdnnfp klh glljh kdbx lzczv klzdr (contains nuts, fish) 10 | znqbr tsvfrt bjrbknjm kbtkrcf hsxp xsndjl jqkxx mrnd tjlz klzdr krxj gnzr nhhgb hqxdv mggk hsdqb zfl svqz hmngm ctbmdg tbptvzf bctn mdx gfpnx bskstb blbfl thprs sckhr lzfmghs rdbdd gbbxhp rglbcpq lmvx jkzxn lblbm bncfz ctgnz tjrm tlbj sndrzm tsbffm hdt spbxz jfvltdz gpgrb hrkf txzv ccvsl mtpfk vlpq pgmqs ttmcq pfdkkzp ndhx mdsg skllln xcfpc bph bdj (contains nuts, shellfish) 11 | vdgsz srpqk jccqsxs txzv gtjmd xzrdx jdvtlsv hcg hjbs tsbffm vlpq bctn fmbqgs krdmn crfxz gpgrb zjh skllln bjqt kdxvzqm mdnchc zfl svrvv zlhlq tzglth ccvsl frgnkt xpmmdc rtjxbbd dptl dlvdt kdbx xclff gbbxhp lxqbsc vmrf lmvx smjhxg skqbbj nndr jnd rlsqd xmcsr pfdkkzp hmnt jfvltdz gnzr znqbr ctbmdg svcmg flzmlbf tjlz tbptvzf bncfz vxx tmjltg xcfpc qlzxbc klh jg xbp mrnd pgrc qkvrf qdnh qzqdq vghkr zfsmv fddx dkzz fcbsv mggk (contains shellfish, soy, eggs) 12 | krxj kbszttf hnvrfvm mkz fjsgm nkshjm tjlz mfvxhv pccmj gnzr txzv flmm czbhh bnrf jccqsxs cnhbh gtjmd klh jg skllln hdt jrrgck nndr vtqhqs hrnzq dtqplpj blbfl glljh snptbf fddx spbxz pnxzqgp bjqt gnkr svqz dptl bncfz lhqxr pfdkkzp zsjlp srpqk dlvdt xcfpc dvfqqz zfl lmvx mzjvq thprs pngs sgh tmjltg tbptvzf vxx nmpp jdvtlsv hrkf rlsqd xzrdx mrnd skqbbj xclff szzbr srxrn vlpq nmxdsnc qkvrf hcg mfcrq fcbvh kbtkrcf mxmvt hjbs jfvltdz gpgrb (contains soy, shellfish) 13 | bnrf jrrgck xcfpc kdxvzqm lmvx xzrdx pfdkkzp crfxz gtjmd krxj qkvrf kdbx jdvtlsv mdnchc mbqpfm jfvltdz txzv vghkr jqkxx jxrlzm klzdr bnnt xpmmdc tsvfrt fcbvh xbp tlbj rglbcpq hdt vdgsz spbxz dxzzp hsdnz jg fgrmrqhp tmjltg jxdbh gjt mggk svrvv zbj mxmvt bncfz hsdqb qdnh hbqhvk kbszttf jkzxn dvfqqz tsbffm mrnd jnd hsxp zck tjlz gpgrb (contains nuts, soy, dairy) 14 | lmvx qzqdq mtpfk dkzz zck frssvh pbztj qlzxbc pccmj sckhr zfl dptl fddx mrnd gdsk mdnnfp hnvrfvm jfvltdz mtjlb lblbm spbxz hsdqb zbj krdmn lzfmghs pfdkkzp gzngn flmm hrnzq jqkxx znqbr jrrgck jkzxn svcs xcfpc mdsg fjsgm frgnkt rdbdd klh cmqjlb hrkf mxmvt hdt tzglth glcfml hbqhvk mkz bncfz pdss gtjmd jczm nrdv tjrm svrvv flzmlbf txzv pmhxl tjlz dvfqqz (contains peanuts, soy, nuts) 15 | mfvxhv pfdkkzp nrdv xcfpc znqbr zck gjt snsnj lmvx nhhgb fgrmrqhp bdj bnrf hrnzq lhqxr kdbx spbxz zfl glvv gpgrb vmrf hnvrfvm pccmj bqc fjsgm jnd xpmmdc hmnt bjqt mrnd jczm fcbvh tjlz hjbs frssvh gnkr pgmqs lxqbsc skqbbj hrkf frgnkt tbptvzf rglbcpq xbp sckhr txzv vjcbtd jqqbnzz mkz (contains peanuts) 16 | jczm gpgrb dfllfp tzglth txzv fmfnh jccqsxs zfl spbxz nhhgb cdntx txr kdxvzqm smjhxg fgrmrqhp qkvrf skqbbj kbszttf rjds snptbf cmqjlb szzbr glvv sckhr mbqpfm mxmvt gnzr pmhxl jqqbnzz bnrf frssvh bncfz znqbr dvfqqz mxfrnq hcg ttmcq kbtkrcf czbhh mdnchc hnnz xcfpc gbbxhp stnb pfdkkzp nrdv gtjmd zsjlp qzqdq flzmlbf vdgsz krdmn bjqt zjh kjcdgh sgh lblbm pdss hsdnz vxx skks mggk ctgnz xzrdx jqkxx klzdr fddx lflzqr svcmg xmcsr (contains nuts, shellfish) 17 | hsxp tjlz crfxz xcfpc pggzp spbxz skqbbj jkzxn tzglth svrvv mtjlb gtjmd hmnt jccqsxs vlpq tmjltg zfl gpgrb lxqbsc znqbr pfdkkzp mdnchc dlvdt gbbxhp hdt sgh rjds skks mkz hmngm vxx mzjvq cnhbh pgmqs lzfmghs qkvrf tsvfrt czbhh qrgvj hrnzq lflzqr dvfqqz xclff jxdbh pdss fcbvh (contains wheat, shellfish, eggs) 18 | jccqsxs rglbcpq pmhxl znqbr vdgsz jqkxx pngs txzv mdsg tvk cmtq dfllfp lhqxr fddx skllln dvfqqz crfxz lzczv brjd tlbj gfpnx gtjmd gxbs gnkr xmcsr dlvdt hsdnz bdj nklc zjh lzfmghs jqqbnzz pznt lflzqr bnrf cdntx tmjltg xcfpc lxqbsc tjlz mfcrq rlsqd kdbx vjcbtd dxzzp spbxz mkz pccmj hbqhvk nndr pfdkkzp fcbsv klzdr hdt svqz svrvv pbztj (contains shellfish) 19 | skks tzglth lmvx bph txr gpgrb klzdr txzv jnd svcmg xclff zsjlp jrrgck spbxz kjcdgh mdnchc kbtkrcf bqc bctn kbszttf dxzzp gtjmd mtjlb pfdkkzp hnvrfvm smjhxg gnkr pggzp vjcbtd lzfmghs vtqhqs tjlz fgrmrqhp svrvv fcbvh ttmcq skllln fjsgm xpmmdc xcfpc nkshjm crfxz lzczv zfl rtjxbbd hsxp cmtq snptbf skqbbj cdntx (contains nuts, peanuts, soy) 20 | xcfpc hrkf txr gxbs snptbf kbtkrcf jxrlzm mggk nmpp txzv vghkr mfcrq sckhr nrdv lflzqr xlcgr pfdkkzp hmnt fcbvh mkz glcfml znqbr cmtq spbxz crfxz gtjmd mdsg xzrdx skks stnb nkshjm zsjlp dptl fmbqgs kjcdgh jfvltdz blbfl vtqhqs lzfmghs hjbs hdt lxqbsc klzdr tjlz vxx pngs lmvx zck gdsk hsxp pccmj jrrgck fmfnh jqkxx fjsgm ccvsl jczm tlbj qkvrf smjhxg gjt jqqbnzz svqz rjds vlpq pmhxl qlzxbc pggzp lhqxr (contains wheat) 21 | bdj bph smjhxg pggzp svrvv dvfqqz pnxzqgp rglbcpq skks dlvdt pccmj tjlz hsdqb zbj qkvrf pmhxl fmfnh cmtq txzv ctbmdg vghkr cmqjlb gtjmd vjcbtd xpmmdc gzngn hrkf blbfl srxrn ctgnz rlsqd dxzzp fcbsv vxx zfsmv lblbm lmvx pgmqs tzglth bncfz mdx vtqhqs drzm jg jnd pfdkkzp xcfpc zfl zjh jfvltdz skllln spbxz znqbr mtpfk dfllfp mxmvt zck svcmg kbtkrcf xsndjl gjt kdbx klh nnfps (contains peanuts, wheat) 22 | jrrgck jfvltdz bjqt nndr znqbr xclff lzfmghs lxqbsc xbp dlvdt txzv tjrm ttmcq gtjmd rdbdd skqbbj dtqplpj kdbx mfcrq pggzp nhhgb tgclx pznt gnkr vghkr xcfpc klzdr krxj lzczv klh czbhh vtqhqs skllln rjds gbbxhp hsdnz bnnt qkvrf glvv bnrf tsbffm lblbm zlhlq dvfqqz bph jkzxn dkzz cnhbh tmgfr hsxp crfxz lhqxr ndhx ngl glcfml pfdkkzp mbqpfm ctgnz bdj spbxz brjd fcbvh gpgrb nklc smjhxg (contains dairy, peanuts, fish) 23 | ttmcq gbbxhp vxx cmtq fmbqgs nklc svqz znqbr hsxp hnvrfvm mtpfk pccmj pdss jczm mrnd zbj gtjmd klzdr thprs czbhh fddx blbfl tlbj fmfnh jdvtlsv txr rdbdd xcfpc glljh snsnj tjlz jqkxx tgclx gpgrb gnzr skllln nrdv qkvrf sgh kbtkrcf hdt pfdkkzp kdxvzqm bnnt jnd jg hqxdv spbxz flmm szzbr sckhr (contains nuts, dairy) 24 | svqz txzv gpgrb fcbvh gnzr tjlz drzm vmrf qkvrf dlvdt hsdqb hmnt spbxz tjrm mggk hnnz sckhr bjrbknjm jfvltdz xcfpc gtjmd zjh tvk srxrn mfcrq vjcbtd fcbsv xkpm gjt hbqhvk krdmn mdnchc zlhlq ndhx pfdkkzp mdnnfp xzrdx jxdbh gnkr zck pznt bncfz nmxdsnc hrnzq skqbbj mdx kdxvzqm snptbf hsdnz mdsg dxzzp rdbdd (contains shellfish, eggs, peanuts) 25 | dptl rlsqd tjlz mdsg pfdkkzp tzglth mxfrnq gzngn tmjltg mggk hmngm mdnchc nkshjm hnnz zlhlq cmtq vxx hnvrfvm sgh frssvh pdss mdnnfp xcfpc kbtkrcf qzqdq mrnd xbp nndr znqbr szzbr ctgnz spbxz ndhx svqz pbztj bdj smjhxg kbszttf gpgrb jkzxn hqxdv dtqplpj kdxvzqm crfxz cdntx mbqpfm hsxp dxzzp nnfps pgrc cnhbh fmbqgs pnxzqgp svrvv mdx klzdr zjh tsbffm srxrn glcfml rglbcpq hcg gtjmd glljh zck pngs jczm lxqbsc pccmj glvv (contains dairy, peanuts) 26 | znqbr hnvrfvm svrvv kbszttf bctn jccqsxs drzm rlsqd jlnrn srxrn rjds gjt skqbbj qrgvj kjcdgh vghkr svcmg gxbs xcfpc rtjxbbd zfl ndhx lzfmghs qdnh xkpm snsnj bqc lblbm dptl fcbvh gtjmd ccvsl txzv jfvltdz kdxvzqm mtpfk bph tjrm xpmmdc jqqbnzz cnhbh czbhh dtqplpj fgrmrqhp nmxdsnc gpgrb pggzp glcfml hrkf ttmcq mfcrq jczm zlhlq cmtq mdx txr vjcbtd mggk qzqdq skks svcs sndrzm bjqt hsxp tmgfr dkzz jg zck tjlz spbxz pnxzqgp klzdr mdsg zfsmv xbp (contains fish, wheat) 27 | vjcbtd jdvtlsv ccvsl krxj qlzxbc fmfnh zjh hcg jxrlzm spbxz txzv sgh flzmlbf hsdqb nhhgb srpqk xlcgr pggzp skqbbj dlvdt mdsg gzngn pmhxl jfvltdz dptl fgrmrqhp bjqt hsxp tvk gnzr xcfpc qkvrf gtjmd glljh bdj tmgfr jg pgrc hrnzq nnfps jlnrn svcmg zbj klzdr pccmj jqqbnzz gpgrb tmjltg mrnd hnvrfvm znqbr mbqpfm qzqdq snsnj kbtkrcf smjhxg qdnh hrkf mfvxhv srxrn tgclx tjlz fjsgm sndrzm jccqsxs xsndjl (contains eggs) 28 | ngl hjbs tsvfrt brjd zfl lflzqr jrrgck pbztj jxdbh srxrn mfvxhv thprs nkshjm tmgfr jqqbnzz rglbcpq drzm cdntx pggzp kdxvzqm mtpfk gpgrb klzdr vjcbtd mkz jnd kvcc znqbr qzqdq tgclx pdss bskstb skqbbj xkpm spbxz hsxp sgh bdj ccvsl gdsk svcs bqc lblbm gnkr gxbs tvk xpmmdc klh czbhh pccmj jxrlzm pnxzqgp pfdkkzp xzrdx fmfnh tjlz zlhlq mdnchc bctn dptl xcfpc snptbf rtjxbbd txzv bjqt mggk jqkxx flmm nklc cmtq (contains dairy) 29 | jxrlzm pnxzqgp rdbdd frgnkt znqbr gpgrb lblbm srxrn jfvltdz mrnd jkzxn kjcdgh skks bjrbknjm nmxdsnc zjh tjrm xlcgr kdxvzqm fmfnh jnd spbxz nndr zfl dvfqqz xcfpc tmgfr mfvxhv bdj nhhgb hsxp glljh dlvdt txzv vtqhqs zck nnfps gtjmd jrrgck jczm jlnrn drzm cmqjlb fddx xpmmdc hsdnz hqxdv qdnh vjcbtd dptl svcmg bnrf xbp qkvrf kbszttf pznt mfcrq stnb mzjvq pgrc xkpm fcbvh vdgsz mxmvt hjbs hnnz pmhxl tlbj hnvrfvm bncfz zfsmv xsndjl xmcsr bjqt vmrf tjlz bskstb mdx jxdbh gzngn ndhx vlpq (contains fish, wheat, nuts) 30 | ttmcq txr pmhxl frgnkt xbp gxbs zlhlq szzbr crfxz fmfnh smjhxg hmngm xclff glvv tmgfr thprs glcfml fjsgm tsvfrt znqbr spbxz svrvv nrdv lzfmghs tgclx jczm fgrmrqhp bctn mtpfk cdntx gtjmd fcbsv mkz rglbcpq mbqpfm rjds bph jfvltdz ngl zfl rdbdd tjlz gjt nmxdsnc hsdqb qrgvj gfpnx txzv hdt pfdkkzp tvk sckhr snptbf flmm vtqhqs lhqxr fcbvh hnnz mfvxhv nmpp bjrbknjm nkshjm fmbqgs svcs jqkxx gpgrb mtjlb zfsmv dlvdt pngs svqz hbqhvk hmnt ccvsl (contains peanuts, dairy, wheat) 31 | nmxdsnc txzv pggzp pznt cmqjlb hsdnz snsnj ndhx dlvdt ttmcq zbj xmcsr zlhlq flzmlbf tmjltg mdnchc qdnh pngs pmhxl cmtq skqbbj bph czbhh fmbqgs spbxz xclff drzm gdsk znqbr dfllfp tjlz zjh fcbvh pfdkkzp rjds glvv mkz nndr hbqhvk krdmn xcfpc skks mtpfk gtjmd rlsqd hrnzq svcs fcbsv lmvx ctbmdg frgnkt zfsmv sckhr (contains nuts, wheat, eggs) 32 | nrdv zlhlq mzjvq nnfps tmgfr fcbvh jccqsxs xcfpc cnhbh gpgrb brjd hnvrfvm tjlz xzrdx vmrf lmvx skllln zsjlp snsnj szzbr lxqbsc dvfqqz pdss spbxz zfsmv mggk gtjmd tgclx cmqjlb zck rjds hjbs gdsk mfvxhv thprs fcbsv lblbm srxrn jqkxx flmm jnd qdnh lzczv fjsgm xlcgr snptbf znqbr txzv stnb czbhh gnzr (contains wheat) 33 | vlpq svcs hqxdv mxfrnq zfl frssvh mggk kdbx ctbmdg tbptvzf zck xzrdx krdmn klh fcbsv znqbr sgh frgnkt lzfmghs cmtq xcfpc txzv rtjxbbd rjds fcbvh xclff pfdkkzp jccqsxs dvfqqz gtjmd hrkf hsdqb gnzr jqkxx lmvx flmm xlcgr mdsg tjlz jlnrn hnvrfvm hcg bdj lzczv gzngn fmbqgs spbxz bskstb jg nklc hdt gjt jrrgck skks srpqk ngl vxx (contains eggs, wheat) 34 | znqbr rdbdd jfvltdz gnzr mdx glcfml vtqhqs lblbm frssvh hsdnz jxdbh xsndjl pccmj kdxvzqm fgrmrqhp krdmn hnnz mtpfk gtjmd jccqsxs nklc vlpq svcs brjd xcfpc srxrn cdntx smjhxg pggzp fmfnh pdss nmxdsnc kbszttf xzrdx bnnt tvk fcbsv zfl mbqpfm xlcgr nnfps spbxz kdbx dlvdt gnkr tlbj vmrf hbqhvk mrnd dvfqqz tjlz gpgrb cnhbh hnvrfvm qrgvj snptbf tmjltg txzv mdnnfp nrdv jg xclff crfxz mdsg tsvfrt hdt dptl lflzqr hsdqb (contains shellfish) 35 | tjlz srxrn gpgrb blbfl dvfqqz nrdv fmfnh smjhxg jlnrn tvk hbqhvk bdj hsdqb klh qrgvj jczm spbxz jnd lxqbsc rglbcpq jxdbh fgrmrqhp zbj znqbr pfdkkzp pngs dkzz mbqpfm hmngm vjcbtd mrnd jfvltdz jccqsxs xmcsr mfvxhv bqc mdsg pgmqs stnb svcs xcfpc kvcc skqbbj zlhlq svcmg gtjmd glcfml dtqplpj bjrbknjm gdsk nnfps qdnh hrkf ngl mdnchc bncfz gnzr srpqk sgh gjt fcbsv hnvrfvm hmnt (contains nuts, dairy, peanuts) -------------------------------------------------------------------------------- /src/main/resources/day22.txt: -------------------------------------------------------------------------------- 1 | Player 1: 2 | 4 3 | 25 4 | 3 5 | 11 6 | 2 7 | 29 8 | 41 9 | 23 10 | 30 11 | 21 12 | 50 13 | 8 14 | 1 15 | 24 16 | 27 17 | 10 18 | 42 19 | 43 20 | 38 21 | 15 22 | 18 23 | 13 24 | 32 25 | 37 26 | 34 27 | 28 | Player 2: 29 | 12 30 | 6 31 | 36 32 | 35 33 | 40 34 | 47 35 | 31 36 | 9 37 | 46 38 | 49 39 | 19 40 | 16 41 | 5 42 | 26 43 | 39 44 | 48 45 | 7 46 | 44 47 | 45 48 | 20 49 | 17 50 | 14 51 | 33 52 | 28 53 | 22 54 | -------------------------------------------------------------------------------- /src/main/resources/day25.txt: -------------------------------------------------------------------------------- 1 | 13135480 2 | 8821721 3 | -------------------------------------------------------------------------------- /src/test/kotlin/com/ginsberg/advent2020/Day01Test.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import com.ginsberg.advent2020.Resources.resourceAsListOfInt 8 | import org.assertj.core.api.Assertions.assertThat 9 | import org.junit.jupiter.api.DisplayName 10 | import org.junit.jupiter.api.Nested 11 | import org.junit.jupiter.api.Test 12 | 13 | @DisplayName("Day 1") 14 | class Day01Test { 15 | 16 | // Arrange 17 | private val input = listOf(1721, 979, 366, 299, 675, 1456) 18 | 19 | @Nested 20 | @DisplayName("Part 1") 21 | inner class Part1 { 22 | @Test 23 | fun `Matches example`() { 24 | // Act 25 | val answer = Day01(input).solvePart1() 26 | 27 | // Assert 28 | assertThat(answer).isEqualTo(514_579) 29 | } 30 | 31 | @Test 32 | fun `Actual answer`() { 33 | // Act 34 | val answer = Day01(resourceAsListOfInt("day01.txt")).solvePart1() 35 | 36 | // Assert 37 | assertThat(answer).isEqualTo(181_044) 38 | } 39 | } 40 | 41 | @Nested 42 | @DisplayName("Part 2") 43 | inner class Part2 { 44 | @Test 45 | fun `Matches example`() { 46 | // Act 47 | val answer = Day01(input).solvePart2() 48 | 49 | // Assert 50 | assertThat(answer).isEqualTo(241_861_950) 51 | } 52 | 53 | @Test 54 | fun `Actual answer`() { 55 | // Act 56 | val answer = Day01(resourceAsListOfInt("day01.txt")).solvePart2() 57 | 58 | // Assert 59 | assertThat(answer).isEqualTo(82_660_352) 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/ginsberg/advent2020/Day02Test.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import com.ginsberg.advent2020.Resources.resourceAsList 8 | import org.assertj.core.api.Assertions.assertThat 9 | import org.junit.jupiter.api.DisplayName 10 | import org.junit.jupiter.api.Nested 11 | import org.junit.jupiter.api.Test 12 | 13 | @DisplayName("Day 2") 14 | class Day02Test { 15 | 16 | // Arrange 17 | private val input = listOf( 18 | "1-3 a: abcde", 19 | "1-3 b: cdefg", 20 | "2-9 c: ccccccccc" 21 | ) 22 | 23 | @Nested 24 | @DisplayName("Part 1") 25 | inner class Part1 { 26 | @Test 27 | fun `Matches example`() { 28 | // Act 29 | val answer = Day02(input).solvePart1() 30 | 31 | // Assert 32 | assertThat(answer).isEqualTo(2) 33 | } 34 | 35 | @Test 36 | fun `Actual answer`() { 37 | // Act 38 | val answer = Day02(resourceAsList("day02.txt")).solvePart1() 39 | 40 | // Assert 41 | assertThat(answer).isEqualTo(569) 42 | } 43 | } 44 | 45 | @Nested 46 | @DisplayName("Part 2") 47 | inner class Part2 { 48 | @Test 49 | fun `Matches example`() { 50 | // Act 51 | val answer = Day02(input).solvePart2() 52 | 53 | // Assert 54 | assertThat(answer).isEqualTo(1) 55 | } 56 | 57 | @Test 58 | fun `Actual answer`() { 59 | // Act 60 | val answer = Day02(resourceAsList("day02.txt")).solvePart2() 61 | 62 | // Assert 63 | assertThat(answer).isEqualTo(346) 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/ginsberg/advent2020/Day03Test.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import com.ginsberg.advent2020.Resources.resourceAsList 8 | import org.assertj.core.api.Assertions.assertThat 9 | import org.junit.jupiter.api.DisplayName 10 | import org.junit.jupiter.api.Nested 11 | import org.junit.jupiter.api.Test 12 | 13 | @DisplayName("Day 3") 14 | class Day03Test { 15 | 16 | // Arrange 17 | private val input = listOf( 18 | "..##.......", 19 | "#...#...#..", 20 | ".#....#..#.", 21 | "..#.#...#.#", 22 | ".#...##..#.", 23 | "..#.##.....", 24 | ".#.#.#....#", 25 | ".#........#", 26 | "#.##...#...", 27 | "#...##....#", 28 | ".#..#...#.#" 29 | ) 30 | 31 | @Nested 32 | @DisplayName("Part 1") 33 | inner class Part1 { 34 | @Test 35 | fun `Matches example`() { 36 | // Act 37 | val answer = Day03(input).solvePart1() 38 | 39 | // Assert 40 | assertThat(answer).isEqualTo(7) 41 | } 42 | 43 | @Test 44 | fun `Actual answer`() { 45 | // Act 46 | val answer = Day03(resourceAsList("day03.txt")).solvePart1() 47 | 48 | // Assert 49 | assertThat(answer).isEqualTo(167) 50 | } 51 | } 52 | 53 | @Nested 54 | @DisplayName("Part 2") 55 | inner class Part2 { 56 | @Test 57 | fun `Matches example`() { 58 | // Act 59 | val answer = Day03(input).solvePart2() 60 | 61 | // Assert 62 | assertThat(answer).isEqualTo(336L) 63 | } 64 | 65 | @Test 66 | fun `Actual answer`() { 67 | // Act 68 | val answer = Day03(resourceAsList("day03.txt")).solvePart2() 69 | 70 | // Assert 71 | assertThat(answer).isEqualTo(736_527_114L) 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/ginsberg/advent2020/Day04Test.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import com.ginsberg.advent2020.Resources.resourceAsText 8 | import org.assertj.core.api.Assertions.assertThat 9 | import org.junit.jupiter.api.DisplayName 10 | import org.junit.jupiter.api.Nested 11 | import org.junit.jupiter.api.Test 12 | 13 | @DisplayName("Day 4") 14 | class Day04Test { 15 | 16 | @Nested 17 | @DisplayName("Part 1") 18 | inner class Part1 { 19 | // Arrange 20 | private val input = """ 21 | ecl:gry pid:860033327 eyr:2020 hcl:#fffffd 22 | byr:1937 iyr:2017 cid:147 hgt:183cm 23 | 24 | iyr:2013 ecl:amb cid:350 eyr:2023 pid:028048884 25 | hcl:#cfa07d byr:1929 26 | 27 | hcl:#ae17e1 iyr:2013 28 | eyr:2024 29 | ecl:brn pid:760753108 byr:1931 30 | hgt:179cm 31 | 32 | hcl:#cfa07d eyr:2025 pid:166559648 33 | iyr:2011 ecl:brn hgt:59in 34 | """.trimIndent() 35 | 36 | @Test 37 | fun `Matches example`() { 38 | // Act 39 | val answer = Day04(input).solvePart1() 40 | 41 | // Assert 42 | assertThat(answer).isEqualTo(2) 43 | } 44 | 45 | @Test 46 | fun `Actual answer`() { 47 | // Act 48 | val answer = Day04(resourceAsText("day04.txt")).solvePart1() 49 | 50 | // Assert 51 | assertThat(answer).isEqualTo(233) 52 | } 53 | } 54 | 55 | @Nested 56 | @DisplayName("Part 2") 57 | inner class Part2 { 58 | // Arrange 59 | private val invalid = """ 60 | eyr:1972 cid:100 61 | hcl:#18171d ecl:amb hgt:170 pid:186cm iyr:2018 byr:1926 62 | 63 | iyr:2019 64 | hcl:#602927 eyr:1967 hgt:170cm 65 | ecl:grn pid:012533040 byr:1946 66 | 67 | hcl:dab227 iyr:2012 68 | ecl:brn hgt:182cm pid:021572410 eyr:2020 byr:1992 cid:277 69 | 70 | hgt:59cm ecl:zzz 71 | eyr:2038 hcl:74454a iyr:2023 72 | pid:3556412378 byr:2007 73 | """.trimIndent() 74 | 75 | // Arrange 76 | private val valid = """ 77 | pid:087499704 hgt:74in ecl:grn iyr:2012 eyr:2030 byr:1980 78 | hcl:#623a2f 79 | 80 | eyr:2029 ecl:blu cid:129 byr:1989 81 | iyr:2014 pid:896056539 hcl:#a97842 hgt:165cm 82 | 83 | hcl:#888785 84 | hgt:164cm byr:2001 iyr:2015 cid:88 85 | pid:545766238 ecl:hzl 86 | eyr:2022 87 | 88 | iyr:2010 hgt:158cm hcl:#b6652a ecl:blu byr:1944 eyr:2021 pid:093154719 89 | """.trimIndent() 90 | 91 | @Test 92 | fun `Matches example - all valid`() { 93 | // Act 94 | val answer = Day04(valid).solvePart2() 95 | 96 | // Assert 97 | assertThat(answer).isEqualTo(4) 98 | } 99 | 100 | @Test 101 | fun `Matches example - all invalid`() { 102 | // Act 103 | val answer = Day04(invalid).solvePart2() 104 | 105 | // Assert 106 | assertThat(answer).isEqualTo(0) 107 | } 108 | 109 | @Test 110 | fun `Actual answer`() { 111 | // Act 112 | val answer = Day04(resourceAsText("day04.txt")).solvePart2() 113 | 114 | // Assert 115 | assertThat(answer).isEqualTo(111) 116 | } 117 | } 118 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/ginsberg/advent2020/Day05Test.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import com.ginsberg.advent2020.Resources.resourceAsList 8 | import org.assertj.core.api.Assertions.assertThat 9 | import org.junit.jupiter.api.DisplayName 10 | import org.junit.jupiter.api.Nested 11 | import org.junit.jupiter.api.Test 12 | 13 | @DisplayName("Day 5") 14 | class Day05Test { 15 | 16 | 17 | @Nested 18 | @DisplayName("Part 1") 19 | inner class Part1 { 20 | // Arrange 21 | private val input = mapOf( 22 | "BFFFBBFRRR" to 567, 23 | "FFFBBBFRRR" to 119, 24 | "BBFFBBFRLL" to 820 25 | ) 26 | 27 | @Test 28 | fun `Matches examples`() { 29 | input.forEach { (key, expected) -> 30 | // Act 31 | val answer = Day05(listOf(key)).solvePart1() 32 | 33 | // Assert 34 | assertThat(answer).isEqualTo(expected) 35 | } 36 | } 37 | 38 | @Test 39 | fun `Actual answer`() { 40 | // Act 41 | val answer = Day05(resourceAsList("day05.txt")).solvePart1() 42 | 43 | // Assert 44 | assertThat(answer).isEqualTo(861) 45 | } 46 | } 47 | 48 | @Nested 49 | @DisplayName("Part 2") 50 | inner class Part2 { 51 | 52 | @Test 53 | fun `Actual answer`() { 54 | // Act 55 | val answer = Day05(resourceAsList("day05.txt")).solvePart2() 56 | 57 | // Assert 58 | assertThat(answer).isEqualTo(633) 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/test/kotlin/com/ginsberg/advent2020/Day06Test.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import com.ginsberg.advent2020.Resources.resourceAsText 8 | import org.assertj.core.api.Assertions.assertThat 9 | import org.junit.jupiter.api.DisplayName 10 | import org.junit.jupiter.api.Nested 11 | import org.junit.jupiter.api.Test 12 | 13 | @DisplayName("Day 6") 14 | class Day06Test { 15 | 16 | // Arrange 17 | private val input = """ 18 | abc 19 | 20 | a 21 | b 22 | c 23 | 24 | ab 25 | ac 26 | 27 | a 28 | a 29 | a 30 | a 31 | 32 | b 33 | """.trimIndent() 34 | 35 | @Nested 36 | @DisplayName("Part 1") 37 | inner class Part1 { 38 | @Test 39 | fun `Matches example`() { 40 | // Act 41 | val answer = Day06(input).solvePart1() 42 | 43 | // Assert 44 | assertThat(answer).isEqualTo(11) 45 | } 46 | 47 | @Test 48 | fun `Actual answer`() { 49 | // Act 50 | val answer = Day06(resourceAsText("day06.txt")).solvePart1() 51 | 52 | // Assert 53 | assertThat(answer).isEqualTo(6_551) 54 | } 55 | } 56 | 57 | @Nested 58 | @DisplayName("Part 2") 59 | inner class Part2 { 60 | @Test 61 | fun `Matches example`() { 62 | // Act 63 | val answer = Day06(input).solvePart2() 64 | 65 | // Assert 66 | assertThat(answer).isEqualTo(6) 67 | } 68 | 69 | @Test 70 | fun `Actual answer`() { 71 | // Act 72 | val answer = Day06(resourceAsText("day06.txt")).solvePart2() 73 | 74 | // Assert 75 | assertThat(answer).isEqualTo(3_358) 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/ginsberg/advent2020/Day07Test.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import com.ginsberg.advent2020.Resources.resourceAsList 8 | import org.assertj.core.api.Assertions.assertThat 9 | import org.junit.jupiter.api.DisplayName 10 | import org.junit.jupiter.api.Nested 11 | import org.junit.jupiter.api.Test 12 | 13 | @DisplayName("Day 7") 14 | class Day07Test { 15 | 16 | // Arrange 17 | private val input = listOf( 18 | "light red bags contain 1 bright white bag, 2 muted yellow bags.", 19 | "dark orange bags contain 3 bright white bags, 4 muted yellow bags.", 20 | "bright white bags contain 1 shiny gold bag.", 21 | "muted yellow bags contain 2 shiny gold bags, 9 faded blue bags.", 22 | "shiny gold bags contain 1 dark olive bag, 2 vibrant plum bags.", 23 | "dark olive bags contain 3 faded blue bags, 4 dotted black bags.", 24 | "vibrant plum bags contain 5 faded blue bags, 6 dotted black bags.", 25 | "faded blue bags contain no other bags.", 26 | "dotted black bags contain no other bags." 27 | ) 28 | 29 | @Nested 30 | @DisplayName("Part 1") 31 | inner class Part1 { 32 | @Test 33 | fun `Matches example`() { 34 | // Act 35 | val answer = Day07(input).solvePart1() 36 | 37 | // Assert 38 | assertThat(answer).isEqualTo(4) 39 | } 40 | 41 | @Test 42 | fun `Actual answer`() { 43 | // Act 44 | val answer = Day07(resourceAsList("day07.txt")).solvePart1() 45 | 46 | // Assert 47 | assertThat(answer).isEqualTo(101) 48 | } 49 | } 50 | 51 | @Nested 52 | @DisplayName("Part 2") 53 | inner class Part2 { 54 | @Test 55 | fun `Matches example 1`() { 56 | // Act 57 | val answer = Day07(input).solvePart2() 58 | 59 | // Assert 60 | assertThat(answer).isEqualTo(32) 61 | } 62 | 63 | @Test 64 | fun `Matches example 2`() { 65 | // Arrange 66 | val input = listOf( 67 | "shiny gold bags contain 2 dark red bags.", 68 | "dark red bags contain 2 dark orange bags.", 69 | "dark orange bags contain 2 dark yellow bags.", 70 | "dark yellow bags contain 2 dark green bags.", 71 | "dark green bags contain 2 dark blue bags.", 72 | "dark blue bags contain 2 dark violet bags.", 73 | "dark violet bags contain no other bags." 74 | ) 75 | 76 | // Act 77 | val answer = Day07(input).solvePart2() 78 | 79 | // Assert 80 | assertThat(answer).isEqualTo(126) 81 | } 82 | 83 | 84 | @Test 85 | fun `Actual answer`() { 86 | // Act 87 | val answer = Day07(resourceAsList("day07.txt")).solvePart2() 88 | 89 | // Assert 90 | assertThat(answer).isEqualTo(108_636) 91 | } 92 | } 93 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/ginsberg/advent2020/Day08Test.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import com.ginsberg.advent2020.Resources.resourceAsList 8 | import org.assertj.core.api.Assertions.assertThat 9 | import org.junit.jupiter.api.DisplayName 10 | import org.junit.jupiter.api.Nested 11 | import org.junit.jupiter.api.Test 12 | 13 | @DisplayName("Day 8") 14 | class Day08Test { 15 | 16 | // Arrange 17 | private val input = listOf( 18 | "nop +0", 19 | "acc +1", 20 | "jmp +4", 21 | "acc +3", 22 | "jmp -3", 23 | "acc -99", 24 | "acc +1", 25 | "jmp -4", 26 | "acc +6" 27 | ) 28 | 29 | @Nested 30 | @DisplayName("Part 1") 31 | inner class Part1 { 32 | @Test 33 | fun `Matches example`() { 34 | // Act 35 | val answer = Day08(input).solvePart1() 36 | 37 | // Assert 38 | assertThat(answer).isEqualTo(5) 39 | } 40 | 41 | @Test 42 | fun `Actual answer`() { 43 | // Act 44 | val answer = Day08(resourceAsList("day08.txt")).solvePart1() 45 | 46 | // Assert 47 | assertThat(answer).isEqualTo(1_134) 48 | } 49 | } 50 | 51 | @Nested 52 | @DisplayName("Part 2") 53 | inner class Part2 { 54 | @Test 55 | fun `Matches example`() { 56 | // Act 57 | val answer = Day08(input).solvePart2() 58 | 59 | // Assert 60 | assertThat(answer).isEqualTo(8) 61 | } 62 | 63 | @Test 64 | fun `Actual answer`() { 65 | // Act 66 | val answer = Day08(resourceAsList("day08.txt")).solvePart2() 67 | 68 | // Assert 69 | assertThat(answer).isEqualTo(1_205) 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/ginsberg/advent2020/Day09Test.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import com.ginsberg.advent2020.Resources.resourceAsListOfLong 8 | import org.assertj.core.api.Assertions.assertThat 9 | import org.junit.jupiter.api.DisplayName 10 | import org.junit.jupiter.api.Nested 11 | import org.junit.jupiter.api.Test 12 | 13 | @DisplayName("Day 9") 14 | class Day09Test { 15 | 16 | // Arrange 17 | private val input = listOf( 18 | 35, 20, 15, 25, 47, 40, 62, 55, 65, 95, 102, 19 | 117, 150, 182, 127, 219, 299, 277, 309, 576 20 | ).map { it.toLong() } 21 | 22 | @Nested 23 | @DisplayName("Part 1") 24 | inner class Part1 { 25 | @Test 26 | fun `Matches example`() { 27 | // Act 28 | val answer = Day09(input).solvePart1(5) 29 | 30 | // Assert 31 | assertThat(answer).isEqualTo(127) 32 | } 33 | 34 | @Test 35 | fun `Actual answer`() { 36 | // Act 37 | val answer = Day09(resourceAsListOfLong("day09.txt")).solvePart1() 38 | 39 | // Assert 40 | assertThat(answer).isEqualTo(1_721_308_972) 41 | } 42 | } 43 | 44 | @Nested 45 | @DisplayName("Part 2") 46 | inner class Part2 { 47 | @Test 48 | fun `Matches example`() { 49 | // Act 50 | val answer = Day09(input).solvePart2(5) 51 | 52 | // Assert 53 | assertThat(answer).isEqualTo(62) 54 | } 55 | 56 | @Test 57 | fun `Actual answer`() { 58 | // Act 59 | val answer = Day09(resourceAsListOfLong("day09.txt")).solvePart2() 60 | 61 | // Assert 62 | assertThat(answer).isEqualTo(209_694_133) 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/ginsberg/advent2020/Day10Test.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import com.ginsberg.advent2020.Resources.resourceAsListOfInt 8 | import org.assertj.core.api.Assertions.assertThat 9 | import org.junit.jupiter.api.DisplayName 10 | import org.junit.jupiter.api.Nested 11 | import org.junit.jupiter.api.Test 12 | 13 | @DisplayName("Day 10") 14 | class Day10Test { 15 | 16 | // Arrange 17 | private val input = listOf(16, 10, 15, 5, 1, 11, 7, 19, 6, 12, 4) 18 | 19 | @Nested 20 | @DisplayName("Part 1") 21 | inner class Part1 { 22 | @Test 23 | fun `Matches example`() { 24 | // Act 25 | val answer = Day10(input).solvePart1() 26 | 27 | // Assert 28 | assertThat(answer).isEqualTo(35) 29 | } 30 | 31 | @Test 32 | fun `Actual answer`() { 33 | // Act 34 | val answer = Day10(resourceAsListOfInt("day10.txt")).solvePart1() 35 | 36 | // Assert 37 | assertThat(answer).isEqualTo(2_812) 38 | } 39 | } 40 | 41 | @Nested 42 | @DisplayName("Part 2") 43 | inner class Part2 { 44 | @Test 45 | fun `Matches example`() { 46 | // Act 47 | val answer = Day10(input).solvePart2() 48 | 49 | // Assert 50 | assertThat(answer).isEqualTo(8) 51 | } 52 | 53 | @Test 54 | fun `Actual answer`() { 55 | // Act 56 | val answer = Day10(resourceAsListOfInt("day10.txt")).solvePart2() 57 | 58 | // Assert 59 | assertThat(answer).isEqualTo(386_869_246_296_064L) 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/ginsberg/advent2020/Day11Test.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import com.ginsberg.advent2020.Resources.resourceAsList 8 | import org.assertj.core.api.Assertions.assertThat 9 | import org.junit.jupiter.api.DisplayName 10 | import org.junit.jupiter.api.Nested 11 | import org.junit.jupiter.api.Test 12 | 13 | @DisplayName("Day 11") 14 | class Day11Test { 15 | 16 | // Arrange 17 | private val input = listOf( 18 | "L.LL.LL.LL", 19 | "LLLLLLL.LL", 20 | "L.L.L..L..", 21 | "LLLL.LL.LL", 22 | "L.LL.LL.LL", 23 | "L.LLLLL.LL", 24 | "..L.L.....", 25 | "LLLLLLLLLL", 26 | "L.LLLLLL.L", 27 | "L.LLLLL.LL" 28 | ) 29 | 30 | @Nested 31 | @DisplayName("Part 1") 32 | inner class Part1 { 33 | @Test 34 | fun `Matches example`() { 35 | // Act 36 | val answer = Day11(input).solvePart1() 37 | 38 | // Assert 39 | assertThat(answer).isEqualTo(37) 40 | } 41 | 42 | @Test 43 | fun `Actual answer`() { 44 | // Act 45 | val answer = Day11(resourceAsList("day11.txt")).solvePart1() 46 | 47 | // Assert 48 | assertThat(answer).isEqualTo(2_406) 49 | } 50 | } 51 | 52 | @Nested 53 | @DisplayName("Part 2") 54 | inner class Part2 { 55 | @Test 56 | fun `Matches example`() { 57 | // Act 58 | val answer = Day11(input).solvePart2() 59 | 60 | // Assert 61 | assertThat(answer).isEqualTo(26) 62 | } 63 | 64 | @Test 65 | fun `Actual answer`() { 66 | // Act 67 | val answer = Day11(resourceAsList("day11.txt")).solvePart2() 68 | 69 | // Assert 70 | assertThat(answer).isEqualTo(2_149) 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/ginsberg/advent2020/Day12Test.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import com.ginsberg.advent2020.Resources.resourceAsList 8 | import org.assertj.core.api.Assertions.assertThat 9 | import org.junit.jupiter.api.DisplayName 10 | import org.junit.jupiter.api.Nested 11 | import org.junit.jupiter.api.Test 12 | 13 | @DisplayName("Day 12") 14 | class Day12Test { 15 | 16 | // Arrange 17 | private val input = listOf( 18 | "F10", 19 | "N3", 20 | "F7", 21 | "R90", 22 | "F11" 23 | ) 24 | 25 | @Nested 26 | @DisplayName("Part 1") 27 | inner class Part1 { 28 | @Test 29 | fun `Matches example`() { 30 | // Act 31 | val answer = Day12(input).solvePart1() 32 | 33 | // Assert 34 | assertThat(answer).isEqualTo(25) 35 | } 36 | 37 | @Test 38 | fun `Actual answer`() { 39 | // Act 40 | val answer = Day12(resourceAsList("day12.txt")).solvePart1() 41 | 42 | // Assert 43 | assertThat(answer).isEqualTo(1_838) 44 | } 45 | } 46 | 47 | @Nested 48 | @DisplayName("Part 2") 49 | inner class Part2 { 50 | @Test 51 | fun `Matches example`() { 52 | // Act 53 | val answer = Day12(input).solvePart2() 54 | 55 | // Assert 56 | assertThat(answer).isEqualTo(286) 57 | } 58 | 59 | @Test 60 | fun `Actual answer`() { 61 | // Act 62 | val answer = Day12(resourceAsList("day12.txt")).solvePart2() 63 | 64 | // Assert 65 | assertThat(answer).isEqualTo(89_936) 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/ginsberg/advent2020/Day13Test.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import com.ginsberg.advent2020.Resources.resourceAsList 8 | import org.assertj.core.api.Assertions.assertThat 9 | import org.junit.jupiter.api.DisplayName 10 | import org.junit.jupiter.api.Nested 11 | import org.junit.jupiter.api.Test 12 | 13 | @DisplayName("Day 13") 14 | class Day13Test { 15 | 16 | // Arrange 17 | private val input = listOf( 18 | "939", 19 | "7,13,x,x,59,x,31,19" 20 | ) 21 | 22 | @Nested 23 | @DisplayName("Part 1") 24 | inner class Part1 { 25 | @Test 26 | fun `Matches example`() { 27 | // Act 28 | val answer = Day13(input).solvePart1() 29 | 30 | // Assert 31 | assertThat(answer).isEqualTo(295) 32 | } 33 | 34 | @Test 35 | fun `Actual answer`() { 36 | // Act 37 | val answer = Day13(resourceAsList("day13.txt")).solvePart1() 38 | 39 | // Assert 40 | assertThat(answer).isEqualTo(2_045) 41 | } 42 | } 43 | 44 | @Nested 45 | @DisplayName("Part 2") 46 | inner class Part2 { 47 | @Test 48 | fun `Matches example`() { 49 | // Act 50 | val answer = Day13(input).solvePart2() 51 | 52 | // Assert 53 | assertThat(answer).isEqualTo(1_068_781L) 54 | } 55 | 56 | @Test 57 | fun `Actual answer`() { 58 | // Act 59 | val answer = Day13(resourceAsList("day13.txt")).solvePart2() 60 | 61 | // Assert 62 | assertThat(answer).isEqualTo(402_251_700_208_309L) 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/ginsberg/advent2020/Day14Test.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import com.ginsberg.advent2020.Resources.resourceAsList 8 | import org.assertj.core.api.Assertions.assertThat 9 | import org.junit.jupiter.api.DisplayName 10 | import org.junit.jupiter.api.Nested 11 | import org.junit.jupiter.api.Test 12 | 13 | @DisplayName("Day 14") 14 | class Day14Test { 15 | 16 | // Arrange 17 | private val input = listOf( 18 | "mask = XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X", 19 | "mem[8] = 11", 20 | "mem[7] = 101", 21 | "mem[8] = 0" 22 | ) 23 | 24 | @Nested 25 | @DisplayName("Part 1") 26 | inner class Part1 { 27 | @Test 28 | fun `Matches example`() { 29 | // Act 30 | val answer = Day14(input).solvePart1() 31 | 32 | // Assert 33 | assertThat(answer).isEqualTo(165L) 34 | } 35 | 36 | @Test 37 | fun `Actual answer`() { 38 | // Act 39 | val answer = Day14(resourceAsList("day14.txt")).solvePart1() 40 | 41 | // Assert 42 | assertThat(answer).isEqualTo(15_403_588_588_538L) 43 | } 44 | } 45 | 46 | @Nested 47 | @DisplayName("Part 2") 48 | inner class Part2 { 49 | // Arrange 50 | private val input = listOf( 51 | "mask = 000000000000000000000000000000X1001X", 52 | "mem[42] = 100", 53 | "mask = 00000000000000000000000000000000X0XX", 54 | "mem[26] = 1" 55 | ) 56 | 57 | @Test 58 | fun `Matches example`() { 59 | // Act 60 | val answer = Day14(input).solvePart2() 61 | 62 | // Assert 63 | assertThat(answer).isEqualTo(208) 64 | } 65 | 66 | @Test 67 | fun `Actual answer`() { 68 | // Act 69 | val answer = Day14(resourceAsList("day14.txt")).solvePart2() 70 | 71 | // Assert 72 | assertThat(answer).isEqualTo(3_260_587_250_457L) 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/ginsberg/advent2020/Day15Test.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import com.ginsberg.advent2020.Resources.resourceAsString 8 | import org.assertj.core.api.Assertions.assertThat 9 | import org.junit.jupiter.api.DisplayName 10 | import org.junit.jupiter.api.Nested 11 | import org.junit.jupiter.api.Test 12 | 13 | @DisplayName("Day 15") 14 | class Day15Test { 15 | 16 | // Arrange 17 | private val input = "0,3,6" 18 | 19 | @Nested 20 | @DisplayName("Part 1") 21 | inner class Part1 { 22 | @Test 23 | fun `Matches example`() { 24 | // Act 25 | val answer = Day15(input).solve(2020) 26 | 27 | // Assert 28 | assertThat(answer).isEqualTo(436) 29 | } 30 | 31 | @Test 32 | fun `Actual answer`() { 33 | // Act 34 | val answer = Day15(resourceAsString("day15.txt")).solve(2020) 35 | 36 | // Assert 37 | assertThat(answer).isEqualTo(1_373) 38 | } 39 | } 40 | 41 | @Nested 42 | @DisplayName("Part 2") 43 | inner class Part2 { 44 | 45 | @Test 46 | fun `Actual answer`() { 47 | // Act 48 | val answer = Day15(resourceAsString("day15.txt")).solve(30_000_000) 49 | 50 | // Assert 51 | assertThat(answer).isEqualTo(112_458) 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/ginsberg/advent2020/Day16Test.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import com.ginsberg.advent2020.Resources.resourceAsList 8 | import org.assertj.core.api.Assertions.assertThat 9 | import org.junit.jupiter.api.DisplayName 10 | import org.junit.jupiter.api.Nested 11 | import org.junit.jupiter.api.Test 12 | 13 | @DisplayName("Day 16") 14 | class Day16Test { 15 | 16 | @Nested 17 | @DisplayName("Part 1") 18 | inner class Part1 { 19 | 20 | // Arrange 21 | private val input = 22 | """ 23 | class: 1-3 or 5-7 24 | row: 6-11 or 33-44 25 | seat: 13-40 or 45-50 26 | 27 | your ticket: 28 | 7,1,14 29 | 30 | nearby tickets: 31 | 7,3,47 32 | 40,4,50 33 | 55,2,20 34 | 38,6,12 35 | """.trimIndent().lines() 36 | 37 | @Test 38 | fun `Matches example`() { 39 | // Act 40 | val answer = Day16(input).solvePart1() 41 | 42 | // Assert 43 | assertThat(answer).isEqualTo(71) 44 | } 45 | 46 | @Test 47 | fun `Actual answer`() { 48 | // Act 49 | val answer = Day16(resourceAsList("day16.txt")).solvePart1() 50 | 51 | // Assert 52 | assertThat(answer).isEqualTo(21_978) 53 | } 54 | } 55 | 56 | @Nested 57 | @DisplayName("Part 2") 58 | inner class Part2 { 59 | 60 | // Arrange 61 | private val input = 62 | """ 63 | departure a: 0-1 or 4-19 64 | row: 0-5 or 8-19 65 | departure b: 0-13 or 16-19 66 | 67 | your ticket: 68 | 11,12,13 69 | 70 | nearby tickets: 71 | 3,9,18 72 | 15,1,5 73 | 5,14,9 74 | """.trimIndent().lines() 75 | 76 | @Test 77 | fun `Matches example`() { 78 | // Act 79 | val answer = Day16(input).solvePart2() 80 | 81 | // Assert 82 | assertThat(answer).isEqualTo(156) 83 | } 84 | 85 | @Test 86 | fun `Actual answer`() { 87 | // Act 88 | val answer = Day16(resourceAsList("day16.txt")).solvePart2() 89 | 90 | // Assert 91 | assertThat(answer).isEqualTo(1053686852011L) 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/ginsberg/advent2020/Day17Test.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import com.ginsberg.advent2020.Resources.resourceAsList 8 | import org.assertj.core.api.Assertions.assertThat 9 | import org.junit.jupiter.api.DisplayName 10 | import org.junit.jupiter.api.Nested 11 | import org.junit.jupiter.api.Test 12 | 13 | @DisplayName("Day 17") 14 | class Day17Test { 15 | 16 | // Arrange 17 | private val input = 18 | """ 19 | .#. 20 | ..# 21 | ### 22 | """.trimIndent().lines() 23 | 24 | @Nested 25 | @DisplayName("Part 1") 26 | inner class Part1 { 27 | 28 | @Test 29 | fun `Matches example`() { 30 | // Act 31 | val answer = Day17(input).solvePart1() 32 | 33 | // Assert 34 | assertThat(answer).isEqualTo(112) 35 | } 36 | 37 | @Test 38 | fun `Actual answer`() { 39 | // Act 40 | val answer = Day17(resourceAsList("day17.txt")).solvePart1() 41 | 42 | // Assert 43 | assertThat(answer).isEqualTo(380) 44 | } 45 | } 46 | 47 | @Nested 48 | @DisplayName("Part 2") 49 | inner class Part2 { 50 | 51 | @Test 52 | fun `Matches example`() { 53 | // Act 54 | val answer = Day17(input).solvePart2() 55 | 56 | // Assert 57 | assertThat(answer).isEqualTo(848) 58 | } 59 | 60 | @Test 61 | fun `Actual answer`() { 62 | // Act 63 | val answer = Day17(resourceAsList("day17.txt")).solvePart2() 64 | 65 | // Assert 66 | assertThat(answer).isEqualTo(2_332) 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/ginsberg/advent2020/Day18Test.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import com.ginsberg.advent2020.Resources.resourceAsList 8 | import org.assertj.core.api.Assertions.assertThat 9 | import org.junit.jupiter.api.DisplayName 10 | import org.junit.jupiter.api.Nested 11 | import org.junit.jupiter.api.Test 12 | 13 | @DisplayName("Day 18") 14 | class Day18Test { 15 | 16 | @Nested 17 | @DisplayName("Part 1") 18 | inner class Part1 { 19 | 20 | @Test 21 | fun `Matches example 1`() { 22 | // Act 23 | val answer = Day18(listOf("2 * 3 + (4 * 5)")).solvePart1() 24 | 25 | // Assert 26 | assertThat(answer).isEqualTo(26) 27 | } 28 | 29 | @Test 30 | fun `Matches example 2`() { 31 | // Act 32 | val answer = Day18(listOf("5 + (8 * 3 + 9 + 3 * 4 * 3)")).solvePart1() 33 | 34 | // Assert 35 | assertThat(answer).isEqualTo(437) 36 | } 37 | 38 | @Test 39 | fun `Matches example 3`() { 40 | // Act 41 | val answer = Day18(listOf("5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4))")).solvePart1() 42 | 43 | // Assert 44 | assertThat(answer).isEqualTo(12_240) 45 | } 46 | 47 | 48 | @Test 49 | fun `Matches example 4`() { 50 | // Act 51 | val answer = Day18(listOf("((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2")).solvePart1() 52 | 53 | // Assert 54 | assertThat(answer).isEqualTo(13_632) 55 | } 56 | 57 | @Test 58 | fun `Actual answer`() { 59 | // Act 60 | val answer = Day18(resourceAsList("day18.txt")).solvePart1() 61 | 62 | // Assert 63 | assertThat(answer).isEqualTo(1_451_467_526_514) 64 | } 65 | } 66 | 67 | @Nested 68 | @DisplayName("Part 2") 69 | inner class Part2 { 70 | 71 | @Test 72 | fun `Matches example 1`() { 73 | // Act 74 | val answer = Day18(listOf("2 * 3 + (4 * 5)")).solvePart2() 75 | 76 | // Assert 77 | assertThat(answer).isEqualTo(46) 78 | } 79 | 80 | @Test 81 | fun `Matches example 2`() { 82 | // Act 83 | val answer = Day18(listOf("5 + (8 * 3 + 9 + 3 * 4 * 3)")).solvePart2() 84 | 85 | // Assert 86 | assertThat(answer).isEqualTo(1_445) 87 | } 88 | 89 | @Test 90 | fun `Matches example 3`() { 91 | // Act 92 | val answer = Day18(listOf("5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4))")).solvePart2() 93 | 94 | // Assert 95 | assertThat(answer).isEqualTo(669_060) 96 | } 97 | 98 | 99 | @Test 100 | fun `Matches example 4`() { 101 | // Act 102 | val answer = Day18(listOf("((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2")).solvePart2() 103 | 104 | // Assert 105 | assertThat(answer).isEqualTo(23_340) 106 | } 107 | 108 | 109 | @Test 110 | fun `Actual answer`() { 111 | // Act 112 | val answer = Day18(resourceAsList("day18.txt")).solvePart2() 113 | 114 | // Assert 115 | assertThat(answer).isEqualTo(224_973_686_321_527) 116 | } 117 | } 118 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/ginsberg/advent2020/Day19Test.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import com.ginsberg.advent2020.Resources.resourceAsList 8 | import org.assertj.core.api.Assertions.assertThat 9 | import org.junit.jupiter.api.DisplayName 10 | import org.junit.jupiter.api.Nested 11 | import org.junit.jupiter.api.Test 12 | 13 | @DisplayName("Day 19") 14 | class Day19Test { 15 | 16 | // Arrange 17 | private val input = 18 | """ 19 | 42: 9 14 | 10 1 20 | 9: 14 27 | 1 26 21 | 10: 23 14 | 28 1 22 | 1: "a" 23 | 11: 42 31 24 | 5: 1 14 | 15 1 25 | 19: 14 1 | 14 14 26 | 12: 24 14 | 19 1 27 | 16: 15 1 | 14 14 28 | 31: 14 17 | 1 13 29 | 6: 14 14 | 1 14 30 | 2: 1 24 | 14 4 31 | 0: 8 11 32 | 13: 14 3 | 1 12 33 | 15: 1 | 14 34 | 17: 14 2 | 1 7 35 | 23: 25 1 | 22 14 36 | 28: 16 1 37 | 4: 1 1 38 | 20: 14 14 | 1 15 39 | 3: 5 14 | 16 1 40 | 27: 1 6 | 14 18 41 | 14: "b" 42 | 21: 14 1 | 1 14 43 | 25: 1 1 | 1 14 44 | 22: 14 14 45 | 8: 42 46 | 26: 14 22 | 1 20 47 | 18: 15 15 48 | 7: 14 5 | 1 21 49 | 24: 14 1 50 | 51 | abbbbbabbbaaaababbaabbbbabababbbabbbbbbabaaaa 52 | bbabbbbaabaabba 53 | babbbbaabbbbbabbbbbbaabaaabaaa 54 | aaabbbbbbaaaabaababaabababbabaaabbababababaaa 55 | bbbbbbbaaaabbbbaaabbabaaa 56 | bbbababbbbaaaaaaaabbababaaababaabab 57 | ababaaaaaabaaab 58 | ababaaaaabbbaba 59 | baabbaaaabbaaaababbaababb 60 | abbbbabbbbaaaababbbbbbaaaababb 61 | aaaaabbaabaaaaababaa 62 | aaaabbaaaabbaaa 63 | aaaabbaabbaaaaaaabbbabbbaaabbaabaaa 64 | babaaabbbaaabaababbaabababaaab 65 | aabbbbbaabbbaaaaaabbbbbababaaaaabbaaabba 66 | """.trimIndent().lines() 67 | 68 | @Nested 69 | @DisplayName("Part 1") 70 | inner class Part1 { 71 | 72 | 73 | @Test 74 | fun `Matches example`() { 75 | // Act 76 | val answer = Day19(input).solvePart1() 77 | 78 | // Assert 79 | assertThat(answer).isEqualTo(3) 80 | } 81 | 82 | @Test 83 | fun `Actual answer`() { 84 | // Act 85 | val answer = Day19(resourceAsList("day19.txt")).solvePart1() 86 | 87 | // Assert 88 | assertThat(answer).isEqualTo(285) 89 | } 90 | } 91 | 92 | @Nested 93 | @DisplayName("Part 2") 94 | inner class Part2 { 95 | 96 | @Test 97 | fun `Matches example`() { 98 | // Act 99 | val answer = Day19(input).solvePart2() 100 | 101 | // Assert 102 | assertThat(answer).isEqualTo(12) 103 | } 104 | 105 | @Test 106 | fun `Actual answer`() { 107 | // Act 108 | val answer = Day19(resourceAsList("day19.txt")).solvePart2() 109 | 110 | // Assert 111 | assertThat(answer).isEqualTo(412) 112 | } 113 | } 114 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/ginsberg/advent2020/Day20Test.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import com.ginsberg.advent2020.Resources.resourceAsText 8 | import org.assertj.core.api.Assertions.assertThat 9 | import org.junit.jupiter.api.DisplayName 10 | import org.junit.jupiter.api.Nested 11 | import org.junit.jupiter.api.Test 12 | 13 | @DisplayName("Day 20") 14 | class Day20Test { 15 | 16 | @Nested 17 | @DisplayName("Part 1") 18 | inner class Part1 { 19 | 20 | @Test 21 | fun `Matches example`() { 22 | // Act 23 | val answer = Day20(resourceAsText("day20_test.txt")).solvePart1() 24 | 25 | // Assert 26 | assertThat(answer).isEqualTo(20_899_048_083_289L) 27 | } 28 | 29 | @Test 30 | fun `Actual answer`() { 31 | // Act 32 | val answer = Day20(resourceAsText("day20.txt")).solvePart1() 33 | 34 | // Assert 35 | assertThat(answer).isEqualTo(51_214_443_014_783L) 36 | } 37 | } 38 | 39 | @Nested 40 | @DisplayName("Part 2") 41 | inner class Part2 { 42 | 43 | @Test 44 | fun `Matches example`() { 45 | // Act 46 | val answer = Day20(resourceAsText("day20_test.txt")).solvePart2() 47 | 48 | // Assert 49 | assertThat(answer).isEqualTo(273) 50 | } 51 | 52 | @Test 53 | fun `Actual answer`() { 54 | // Act 55 | val answer = Day20(resourceAsText("day20.txt")).solvePart2() 56 | 57 | // Assert 58 | assertThat(answer).isEqualTo(2_065) 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/ginsberg/advent2020/Day21Test.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import com.ginsberg.advent2020.Resources.resourceAsList 8 | import org.assertj.core.api.Assertions.assertThat 9 | import org.junit.jupiter.api.DisplayName 10 | import org.junit.jupiter.api.Nested 11 | import org.junit.jupiter.api.Test 12 | 13 | @DisplayName("Day 21") 14 | class Day21Test { 15 | 16 | // Arrange 17 | private val input = 18 | """ 19 | mxmxvkd kfcds sqjhc nhms (contains dairy, fish) 20 | trh fvjkl sbzzf mxmxvkd (contains dairy) 21 | sqjhc fvjkl (contains soy) 22 | sqjhc mxmxvkd sbzzf (contains fish) 23 | """.trimIndent().lines() 24 | 25 | @Nested 26 | @DisplayName("Part 1") 27 | inner class Part1 { 28 | 29 | @Test 30 | fun `Matches example`() { 31 | // Act 32 | val answer = Day21(input).solvePart1() 33 | 34 | // Assert 35 | assertThat(answer).isEqualTo(5) 36 | } 37 | 38 | @Test 39 | fun `Actual answer`() { 40 | // Act 41 | val answer = Day21(resourceAsList("day21.txt")).solvePart1() 42 | 43 | // Assert 44 | assertThat(answer).isEqualTo(1_913) 45 | } 46 | } 47 | 48 | @Nested 49 | @DisplayName("Part 2") 50 | inner class Part2 { 51 | 52 | @Test 53 | fun `Matches example`() { 54 | // Act 55 | val answer = Day21(input).solvePart2() 56 | 57 | // Assert 58 | assertThat(answer).isEqualTo("mxmxvkd,sqjhc,fvjkl") 59 | } 60 | 61 | @Test 62 | fun `Actual answer`() { 63 | // Act 64 | val answer = Day21(resourceAsList("day21.txt")).solvePart2() 65 | 66 | // Assert 67 | assertThat(answer).isEqualTo("gpgrb,tjlz,gtjmd,spbxz,pfdkkzp,xcfpc,txzv,znqbr") 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/ginsberg/advent2020/Day22Test.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import com.ginsberg.advent2020.Resources.resourceAsList 8 | import org.assertj.core.api.Assertions.assertThat 9 | import org.junit.jupiter.api.DisplayName 10 | import org.junit.jupiter.api.Nested 11 | import org.junit.jupiter.api.Test 12 | import org.junit.jupiter.api.assertTimeout 13 | import java.time.Duration 14 | 15 | @DisplayName("Day 22") 16 | class Day22Test { 17 | 18 | // Arrange 19 | private val input = 20 | """ 21 | Player 1: 22 | 9 23 | 2 24 | 6 25 | 3 26 | 1 27 | 28 | Player 2: 29 | 5 30 | 8 31 | 4 32 | 7 33 | 10 34 | """.trimIndent().lines() 35 | 36 | @Nested 37 | @DisplayName("Part 1") 38 | inner class Part1 { 39 | 40 | @Test 41 | fun `Matches example`() { 42 | // Act 43 | val answer = Day22(input).solvePart1() 44 | 45 | // Assert 46 | assertThat(answer).isEqualTo(306) 47 | } 48 | 49 | @Test 50 | fun `Actual answer`() { 51 | // Act 52 | val answer = Day22(resourceAsList("day22.txt")).solvePart1() 53 | 54 | // Assert 55 | assertThat(answer).isEqualTo(33_421) 56 | } 57 | } 58 | 59 | @Nested 60 | @DisplayName("Part 2") 61 | inner class Part2 { 62 | 63 | @Test 64 | fun `Matches example`() { 65 | // Act 66 | val answer = Day22(input).solvePart2() 67 | 68 | // Assert 69 | assertThat(answer).isEqualTo(291) 70 | } 71 | 72 | @Test 73 | fun `Infinite loop guard works`() { 74 | // Arrange 75 | val input = 76 | """ 77 | Player 1: 78 | 43 79 | 19 80 | 81 | Player 2: 82 | 2 83 | 29 84 | 14 85 | """.trimIndent().lines() 86 | 87 | // Act/Assert 88 | assertTimeout(Duration.ofSeconds(2)) { 89 | Day22(input).solvePart2() 90 | } 91 | } 92 | 93 | @Test 94 | fun `Actual answer`() { 95 | // Act 96 | val answer = Day22(resourceAsList("day22.txt")).solvePart2() 97 | 98 | // Assert 99 | assertThat(answer).isEqualTo(33_651) 100 | } 101 | } 102 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/ginsberg/advent2020/Day23Test.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import org.assertj.core.api.Assertions.assertThat 8 | import org.junit.jupiter.api.DisplayName 9 | import org.junit.jupiter.api.Nested 10 | import org.junit.jupiter.api.Test 11 | 12 | @DisplayName("Day 23") 13 | class Day23Test { 14 | 15 | @Nested 16 | @DisplayName("Part 1") 17 | inner class Part1 { 18 | 19 | @Test 20 | fun `Matches example - 10 moves`() { 21 | // Act 22 | val answer = Day23("389125467").solvePart1(10) 23 | 24 | // Assert 25 | assertThat(answer).isEqualTo("92658374") 26 | } 27 | 28 | @Test 29 | fun `Matches example - 100 moves`() { 30 | // Act 31 | val answer = Day23("389125467").solvePart1(100) 32 | 33 | // Assert 34 | assertThat(answer).isEqualTo("67384529") 35 | } 36 | 37 | @Test 38 | fun `Actual answer`() { 39 | // Act 40 | val answer = Day23("219748365").solvePart1(100) 41 | 42 | // Assert 43 | assertThat(answer).isEqualTo("35827964") 44 | } 45 | } 46 | 47 | @Nested 48 | @DisplayName("Part 2") 49 | inner class Part2 { 50 | 51 | @Test 52 | fun `Matches example`() { 53 | // Act 54 | val answer = Day23("389125467").solvePart2(10_000_000) 55 | 56 | // Assert 57 | assertThat(answer).isEqualTo(149245887792) 58 | } 59 | 60 | @Test 61 | fun `Actual answer`() { 62 | // Act 63 | val answer = Day23("219748365").solvePart2(10_000_000) 64 | 65 | // Assert 66 | assertThat(answer).isEqualTo(540_3610_688L) 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/ginsberg/advent2020/Day24Test.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import com.ginsberg.advent2020.Resources.resourceAsList 8 | import org.assertj.core.api.Assertions.assertThat 9 | import org.junit.jupiter.api.DisplayName 10 | import org.junit.jupiter.api.Nested 11 | import org.junit.jupiter.api.Test 12 | 13 | @DisplayName("Day 24") 14 | class Day24Test { 15 | 16 | // Arrange 17 | private val input = 18 | """ 19 | sesenwnenenewseeswwswswwnenewsewsw 20 | neeenesenwnwwswnenewnwwsewnenwseswesw 21 | seswneswswsenwwnwse 22 | nwnwneseeswswnenewneswwnewseswneseene 23 | swweswneswnenwsewnwneneseenw 24 | eesenwseswswnenwswnwnwsewwnwsene 25 | sewnenenenesenwsewnenwwwse 26 | wenwwweseeeweswwwnwwe 27 | wsweesenenewnwwnwsenewsenwwsesesenwne 28 | neeswseenwwswnwswswnw 29 | nenwswwsewswnenenewsenwsenwnesesenew 30 | enewnwewneswsewnwswenweswnenwsenwsw 31 | sweneswneswneneenwnewenewwneswswnese 32 | swwesenesewenwneswnwwneseswwne 33 | enesenwswwswneneswsenwnewswseenwsese 34 | wnwnesenesenenwwnenwsewesewsesesew 35 | nenewswnwewswnenesenwnesewesw 36 | eneswnwswnwsenenwnwnwwseeswneewsenese 37 | neswnwewnwnwseenwseesewsenwsweewe 38 | wseweeenwnesenwwwswnew 39 | """.trimIndent().lines() 40 | 41 | @Nested 42 | @DisplayName("Part 1") 43 | inner class Part1 { 44 | 45 | @Test 46 | fun `Matches example`() { 47 | // Act 48 | val answer = Day24(input).solvePart1() 49 | 50 | // Assert 51 | assertThat(answer).isEqualTo(10) 52 | } 53 | 54 | @Test 55 | fun `Actual answer`() { 56 | // Act 57 | val answer = Day24(resourceAsList("day24.txt")).solvePart1() 58 | 59 | // Assert 60 | assertThat(answer).isEqualTo(450) 61 | } 62 | } 63 | 64 | @Nested 65 | @DisplayName("Part 2") 66 | inner class Part2 { 67 | 68 | @Test 69 | fun `Matches example`() { 70 | // Act 71 | val answer = Day24(input).solvePart2() 72 | 73 | // Assert 74 | assertThat(answer).isEqualTo(2_208) 75 | } 76 | 77 | @Test 78 | fun `Actual answer`() { 79 | // Act 80 | val answer = Day24(resourceAsList("day24.txt")).solvePart2() 81 | 82 | // Assert 83 | assertThat(answer).isEqualTo(4_059) 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/ginsberg/advent2020/Day25Test.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | package com.ginsberg.advent2020 6 | 7 | import com.ginsberg.advent2020.Resources.resourceAsList 8 | import org.assertj.core.api.Assertions.assertThat 9 | import org.junit.jupiter.api.DisplayName 10 | import org.junit.jupiter.api.Nested 11 | import org.junit.jupiter.api.Test 12 | 13 | @DisplayName("Day 25") 14 | class Day25Test { 15 | 16 | // Arrange 17 | private val input = 18 | """ 19 | 5764801 20 | 17807724 21 | """.trimIndent().lines() 22 | 23 | @Nested 24 | @DisplayName("Part 1") 25 | inner class Part1 { 26 | 27 | @Test 28 | fun `Matches example`() { 29 | // Act 30 | val answer = Day25(input).solvePart1() 31 | 32 | // Assert 33 | assertThat(answer).isEqualTo(14897079L) 34 | } 35 | 36 | @Test 37 | fun `Actual answer`() { 38 | // Act 39 | val answer = Day25(resourceAsList("day25.txt")).solvePart1() 40 | 41 | // Assert 42 | assertThat(answer).isEqualTo(8329514L) 43 | } 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/ginsberg/advent2020/ResourcesTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 by Todd Ginsberg 3 | */ 4 | 5 | @file:Suppress("RedundantInnerClassModifier", "RedundantInnerClassModifier") 6 | 7 | package com.ginsberg.advent2020 8 | 9 | import com.ginsberg.advent2020.Resources.resourceAsList 10 | import com.ginsberg.advent2020.Resources.resourceAsListOfInt 11 | import com.ginsberg.advent2020.Resources.resourceAsListOfLong 12 | import com.ginsberg.advent2020.Resources.resourceAsString 13 | import com.ginsberg.advent2020.Resources.resourceAsText 14 | import org.assertj.core.api.Assertions.assertThat 15 | import org.assertj.core.api.Assertions.assertThatThrownBy 16 | import org.junit.jupiter.api.Nested 17 | import org.junit.jupiter.api.Test 18 | 19 | class ResourcesTest { 20 | 21 | @Nested 22 | inner class ResourceAsStringTests { 23 | @Test 24 | fun `concatenates lines without delimiter`() { 25 | assertThat(resourceAsString("read_file_test_1.txt")) 26 | .isEqualTo("123") 27 | } 28 | 29 | @Test 30 | fun `concatenates lines with delimiter`() { 31 | assertThat(resourceAsString(fileName = "read_file_test_1.txt", delimiter = ":::")) 32 | .isEqualTo("1:::2:::3") 33 | } 34 | 35 | @Test 36 | fun `throws exception when file does not exist`() { 37 | assertThatThrownBy { 38 | resourceAsString("this_does_not_exist.txt", delimiter = "???") 39 | }.isInstanceOf(IllegalArgumentException::class.java) 40 | } 41 | } 42 | 43 | @Nested 44 | inner class ResourceAsTextTests { 45 | @Test 46 | fun `reads file as-is into one String`() { 47 | assertThat(resourceAsText("read_file_test_1.txt")) 48 | .isEqualTo(""" 49 | 1 50 | 2 51 | 3 52 | """.trimIndent()) 53 | } 54 | } 55 | 56 | @Nested 57 | inner class ResourceAsListTests { 58 | @Test 59 | fun `reads lines`() { 60 | assertThat(resourceAsList("read_file_test_1.txt")) 61 | .hasSize(3) 62 | .containsExactly("1", "2", "3") 63 | } 64 | 65 | @Test 66 | fun `reads lines as Ints`() { 67 | assertThat(resourceAsListOfInt("read_file_test_1.txt")) 68 | .hasSize(3) 69 | .containsExactly(1, 2, 3) 70 | } 71 | 72 | @Test 73 | fun `reads lines as Longs`() { 74 | assertThat(resourceAsListOfLong("read_file_test_1.txt")) 75 | .hasSize(3) 76 | .containsExactly(1L, 2L, 3L) 77 | } 78 | 79 | @Test 80 | fun `throws exception when file does not exist`() { 81 | assertThatThrownBy { 82 | resourceAsList("this_does_not_exist.txt") 83 | }.isInstanceOf(IllegalArgumentException::class.java) 84 | } 85 | } 86 | 87 | } -------------------------------------------------------------------------------- /src/test/resources/day20_test.txt: -------------------------------------------------------------------------------- 1 | Tile 2311: 2 | ..##.#..#. 3 | ##..#..... 4 | #...##..#. 5 | ####.#...# 6 | ##.##.###. 7 | ##...#.### 8 | .#.#.#..## 9 | ..#....#.. 10 | ###...#.#. 11 | ..###..### 12 | 13 | Tile 1951: 14 | #.##...##. 15 | #.####...# 16 | .....#..## 17 | #...###### 18 | .##.#....# 19 | .###.##### 20 | ###.##.##. 21 | .###....#. 22 | ..#.#..#.# 23 | #...##.#.. 24 | 25 | Tile 1171: 26 | ####...##. 27 | #..##.#..# 28 | ##.#..#.#. 29 | .###.####. 30 | ..###.#### 31 | .##....##. 32 | .#...####. 33 | #.##.####. 34 | ####..#... 35 | .....##... 36 | 37 | Tile 1427: 38 | ###.##.#.. 39 | .#..#.##.. 40 | .#.##.#..# 41 | #.#.#.##.# 42 | ....#...## 43 | ...##..##. 44 | ...#.##### 45 | .#.####.#. 46 | ..#..###.# 47 | ..##.#..#. 48 | 49 | Tile 1489: 50 | ##.#.#.... 51 | ..##...#.. 52 | .##..##... 53 | ..#...#... 54 | #####...#. 55 | #..#.#.#.# 56 | ...#.#.#.. 57 | ##.#...##. 58 | ..##.##.## 59 | ###.##.#.. 60 | 61 | Tile 2473: 62 | #....####. 63 | #..#.##... 64 | #.##..#... 65 | ######.#.# 66 | .#...#.#.# 67 | .######### 68 | .###.#..#. 69 | ########.# 70 | ##...##.#. 71 | ..###.#.#. 72 | 73 | Tile 2971: 74 | ..#.#....# 75 | #...###... 76 | #.#.###... 77 | ##.##..#.. 78 | .#####..## 79 | .#..####.# 80 | #..#.#..#. 81 | ..####.### 82 | ..#.#.###. 83 | ...#.#.#.# 84 | 85 | Tile 2729: 86 | ...#.#.#.# 87 | ####.#.... 88 | ..#.#..... 89 | ....#..#.# 90 | .##..##.#. 91 | .#.####... 92 | ####.#.#.. 93 | ##.####... 94 | ##..#.##.. 95 | #.##...##. 96 | 97 | Tile 3079: 98 | #.#.#####. 99 | .#..###### 100 | ..#....... 101 | ######.... 102 | ####.#..#. 103 | .#...#.##. 104 | #.#####.## 105 | ..#.###... 106 | ..#....... 107 | ..#.###... -------------------------------------------------------------------------------- /src/test/resources/read_file_test_1.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 --------------------------------------------------------------------------------