├── .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 |
4 |
5 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/copyright/Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
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 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
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 | []()
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
--------------------------------------------------------------------------------