Compare commits

..

32 Commits

Author SHA1 Message Date
f9930694ec [CLEANUP] Cleaned up day 16 2023-01-29 21:36:26 +01:00
9c2793324a [TASK] Completed Day 18 2023-01-29 21:36:15 +01:00
5424772424 [TASK] Solved Day 17 pt 1 2022-12-20 00:23:48 +01:00
c14277a2f3 [TASK] Solved day 16 but it's extremely slow 2022-12-19 17:06:02 +01:00
25c4b6617b [TASK] Day 16 part 1 2022-12-19 15:26:56 +01:00
8345fa1c24 [WIP] Working on day 16p1, but the current solution is way to slow 2022-12-18 00:08:03 +01:00
b01edf2db0 [TASK] Solved day 15 part 2 (but it's not very fast yet) 2022-12-17 23:09:36 +01:00
2171307f5f [TASK] Day 15 pt 1 2022-12-17 17:40:02 +01:00
56cc1a53f3 [WIP] Added a comment with ideas on how I could optimize day 14 2022-12-16 12:30:01 +01:00
e6331778f2 [TASK] Solved Day 14 2022-12-16 12:26:51 +01:00
e2386f7f92 [TASK] Solved day 13 2022-12-13 22:17:25 +01:00
dd05abd1a5 [TASK] Solved day 12 2022-12-13 00:06:03 +01:00
6518483461 [CLEANUP] Day 11 code optimization & cleanup
(but it's still quite slow)
2022-12-12 09:12:52 +01:00
33027001d2 [TASK] Solved Day 11 2022-12-12 08:55:01 +01:00
e33875103f [CLEANUP] Removed duplicate code in Day 10 2022-12-11 20:08:48 +01:00
afa80765cf [TASK] Solved Day 10 2022-12-11 16:17:45 +01:00
563cddce78 [TASK] Solved Day 9 2022-12-11 14:52:15 +01:00
ae90aad6dc [TASK] Implemented Day 8 2022-12-11 12:17:43 +01:00
f6132bbf24 [TASK] Optimized Day 7: removed directory names 2022-12-10 16:53:36 +01:00
8754356dbc [TASK] Solved Day 7 2022-12-10 16:30:05 +01:00
a284052dcd [WIP] Day 7 2022-12-07 19:19:46 +01:00
983ebde050 [CLEANUP] Removed slower solutions 2022-12-06 16:26:02 +01:00
8f6c8ee5c7 [TASK] Implemented day 6 2022-12-06 15:54:19 +01:00
a6a2cd3093 [TWEAK] Performance improvement by dropping the need for a hashmap and using the stack indices directly 2022-12-05 20:43:19 +01:00
324d5ab02b [TASK] Implemented day 5 2022-12-05 20:26:50 +01:00
08a0576ac3 [CLEANUP] Cleaned up the code for day 4 2022-12-04 19:01:05 +01:00
1e189fb333 [TASK] Solved Day 4 2022-12-04 18:57:43 +01:00
0b0032267e [TWEAK] Small improvements to the benchmark output 2022-12-04 13:27:28 +01:00
6adca06f04 [TASK] Implemented Day 3 2022-12-04 13:15:32 +01:00
5a3968d50e [CLEANUP] re-ordered some of the code 2022-12-02 21:21:07 +01:00
78a905f9de [TASK] Extended the benchmarking tools, to give information about which parts take time etc 2022-12-02 19:03:05 +01:00
b9c24407a3 [TASK] Solved Day 2 2022-12-02 19:02:43 +01:00
69 changed files with 14570 additions and 76 deletions

View File

@@ -0,0 +1,19 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Run-aoc2022-bench-dayX" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="command" value="run --package advent-of-code-2022-rust --bin advent-of-code-2022-rust --release -- -d 15 -b 10" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<option name="channel" value="DEFAULT" />
<option name="requiredFeatures" value="true" />
<option name="allFeatures" value="false" />
<option name="emulateTerminal" value="false" />
<option name="withSudo" value="false" />
<option name="buildTarget" value="REMOTE" />
<option name="backtrace" value="NO" />
<envs />
<option name="isRedirectInput" value="false" />
<option name="redirectInputPath" value="" />
<method v="2">
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
</method>
</configuration>
</component>

View File

@@ -1,6 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Run-aoc2022-bench" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="command" value="run --package advent-of-code-2022-rust --bin advent-of-code-2022-rust --release -- -b" />
<option name="command" value="run --package advent-of-code-2022-rust --bin advent-of-code-2022-rust --release -- -b 100" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<option name="channel" value="DEFAULT" />
<option name="requiredFeatures" value="true" />

19
.run/run-day-12.run.xml Normal file
View File

@@ -0,0 +1,19 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="run-day-12" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="command" value="run --package advent-of-code-2022-rust --bin advent-of-code-2022-rust -- -d 12" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<option name="channel" value="DEFAULT" />
<option name="requiredFeatures" value="true" />
<option name="allFeatures" value="false" />
<option name="emulateTerminal" value="false" />
<option name="withSudo" value="false" />
<option name="buildTarget" value="REMOTE" />
<option name="backtrace" value="SHORT" />
<envs />
<option name="isRedirectInput" value="false" />
<option name="redirectInputPath" value="" />
<method v="2">
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
</method>
</configuration>
</component>

19
.run/run-day-13.run.xml Normal file
View File

@@ -0,0 +1,19 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="run-day-13" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="command" value="run --package advent-of-code-2022-rust --bin advent-of-code-2022-rust -- -d 13" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<option name="channel" value="DEFAULT" />
<option name="requiredFeatures" value="true" />
<option name="allFeatures" value="false" />
<option name="emulateTerminal" value="false" />
<option name="withSudo" value="false" />
<option name="buildTarget" value="REMOTE" />
<option name="backtrace" value="SHORT" />
<envs />
<option name="isRedirectInput" value="false" />
<option name="redirectInputPath" value="" />
<method v="2">
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
</method>
</configuration>
</component>

19
.run/run-day-15.run.xml Normal file
View File

@@ -0,0 +1,19 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="run-day-15" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="command" value="run --package advent-of-code-2022-rust --bin advent-of-code-2022-rust -- -d 15" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<option name="channel" value="DEFAULT" />
<option name="requiredFeatures" value="true" />
<option name="allFeatures" value="false" />
<option name="emulateTerminal" value="false" />
<option name="withSudo" value="false" />
<option name="buildTarget" value="REMOTE" />
<option name="backtrace" value="SHORT" />
<envs />
<option name="isRedirectInput" value="false" />
<option name="redirectInputPath" value="" />
<method v="2">
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
</method>
</configuration>
</component>

19
.run/run-day-16.run.xml Normal file
View File

@@ -0,0 +1,19 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="run-day-16" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="command" value="run --package advent-of-code-2022-rust --bin advent-of-code-2022-rust --release -- -d 16" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<option name="channel" value="DEFAULT" />
<option name="requiredFeatures" value="true" />
<option name="allFeatures" value="false" />
<option name="emulateTerminal" value="false" />
<option name="withSudo" value="false" />
<option name="buildTarget" value="REMOTE" />
<option name="backtrace" value="SHORT" />
<envs />
<option name="isRedirectInput" value="false" />
<option name="redirectInputPath" value="" />
<method v="2">
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
</method>
</configuration>
</component>

19
.run/run-day-3.run.xml Normal file
View File

@@ -0,0 +1,19 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="run-day-3" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="command" value="run --package advent-of-code-2022-rust --bin advent-of-code-2022-rust -- -d 3" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<option name="channel" value="DEFAULT" />
<option name="requiredFeatures" value="true" />
<option name="allFeatures" value="false" />
<option name="emulateTerminal" value="false" />
<option name="withSudo" value="false" />
<option name="buildTarget" value="REMOTE" />
<option name="backtrace" value="SHORT" />
<envs />
<option name="isRedirectInput" value="false" />
<option name="redirectInputPath" value="" />
<method v="2">
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
</method>
</configuration>
</component>

19
.run/run-day-5.run.xml Normal file
View File

@@ -0,0 +1,19 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="run-day-5" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="command" value="run --package advent-of-code-2022-rust --bin advent-of-code-2022-rust -- -d 5" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<option name="channel" value="DEFAULT" />
<option name="requiredFeatures" value="true" />
<option name="allFeatures" value="false" />
<option name="emulateTerminal" value="false" />
<option name="withSudo" value="false" />
<option name="buildTarget" value="REMOTE" />
<option name="backtrace" value="SHORT" />
<envs />
<option name="isRedirectInput" value="false" />
<option name="redirectInputPath" value="" />
<method v="2">
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
</method>
</configuration>
</component>

19
.run/run-day-6.run.xml Normal file
View File

@@ -0,0 +1,19 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="run-day-6" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="command" value="run --package advent-of-code-2022-rust --bin advent-of-code-2022-rust -- -d 6" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<option name="channel" value="DEFAULT" />
<option name="requiredFeatures" value="true" />
<option name="allFeatures" value="false" />
<option name="emulateTerminal" value="false" />
<option name="withSudo" value="false" />
<option name="buildTarget" value="REMOTE" />
<option name="backtrace" value="SHORT" />
<envs />
<option name="isRedirectInput" value="false" />
<option name="redirectInputPath" value="" />
<method v="2">
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
</method>
</configuration>
</component>

45
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,45 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug executable 'advent-of-code-2022-rust'",
"cargo": {
"args": [
"build",
"--bin=advent-of-code-2022-rust",
"--package=advent-of-code-2022-rust"
],
"filter": {
"name": "advent-of-code-2022-rust",
"kind": "bin"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in executable 'advent-of-code-2022-rust'",
"cargo": {
"args": [
"test",
"--no-run",
"--bin=advent-of-code-2022-rust",
"--package=advent-of-code-2022-rust"
],
"filter": {
"name": "advent-of-code-2022-rust",
"kind": "bin"
}
},
"args": [],
"cwd": "${workspaceFolder}"
}
]
}

97
Cargo.lock generated
View File

@@ -7,7 +7,10 @@ name = "advent-of-code-2022-rust"
version = "0.1.0"
dependencies = [
"lazy_static",
"nohash-hasher",
"num",
"regex",
"rustc-hash",
]
[[package]]
@@ -19,6 +22,12 @@ dependencies = [
"memchr",
]
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "lazy_static"
version = "1.4.0"
@@ -31,6 +40,88 @@ version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "nohash-hasher"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
[[package]]
name = "num"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606"
dependencies = [
"num-bigint",
"num-complex",
"num-integer",
"num-iter",
"num-rational",
"num-traits",
]
[[package]]
name = "num-bigint"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-complex"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ae39348c8bc5fbd7f40c727a9925f03517afd2ab27d46702108b6a7e5414c19"
dependencies = [
"num-traits",
]
[[package]]
name = "num-integer"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-iter"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
dependencies = [
"autocfg",
"num-bigint",
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
dependencies = [
"autocfg",
]
[[package]]
name = "regex"
version = "1.7.0"
@@ -47,3 +138,9 @@ name = "regex-syntax"
version = "0.6.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"

View File

@@ -9,3 +9,6 @@ edition = "2021"
[dependencies]
regex = "1"
lazy_static = "1.4.0"
rustc-hash = "1.1.0"
nohash-hasher = "0.2.0"
num = "0.4.0"

139
input/day10.txt Normal file
View File

@@ -0,0 +1,139 @@
addx 1
noop
noop
noop
addx 5
addx 5
noop
noop
addx 9
addx -5
addx 1
addx 4
noop
noop
noop
addx 6
addx -1
noop
addx 5
addx -2
addx 7
noop
addx 3
addx -2
addx -38
noop
noop
addx 32
addx -22
noop
addx 2
addx 3
noop
addx 2
addx -2
addx 7
addx -2
noop
addx 3
addx 2
addx 5
addx 2
addx -5
addx 10
noop
addx 3
noop
addx -38
addx 1
addx 27
noop
addx -20
noop
addx 2
addx 27
noop
addx -22
noop
noop
noop
noop
addx 3
addx 5
addx 2
addx -11
addx 16
addx -2
addx -17
addx 24
noop
noop
addx 1
addx -38
addx 15
addx 10
addx -15
noop
addx 2
addx 26
noop
addx -21
addx 19
addx -33
addx 19
noop
addx -6
addx 9
addx 3
addx 4
addx -21
addx 4
addx 20
noop
addx 3
addx -38
addx 28
addx -21
addx 9
addx -8
addx 2
addx 5
addx 2
addx -9
addx 14
addx -2
addx -5
addx 12
addx 3
addx -2
addx 2
addx 7
noop
noop
addx -27
addx 28
addx -36
noop
addx 1
addx 5
addx -1
noop
addx 6
addx -1
addx 5
addx 5
noop
noop
addx -2
addx 20
addx -10
addx -3
addx 1
addx 3
addx 2
addx 4
addx 3
noop
addx -30
noop

146
input/day10_example.txt Normal file
View File

@@ -0,0 +1,146 @@
addx 15
addx -11
addx 6
addx -3
addx 5
addx -1
addx -8
addx 13
addx 4
noop
addx -1
addx 5
addx -1
addx 5
addx -1
addx 5
addx -1
addx 5
addx -1
addx -35
addx 1
addx 24
addx -19
addx 1
addx 16
addx -11
noop
noop
addx 21
addx -15
noop
noop
addx -3
addx 9
addx 1
addx -3
addx 8
addx 1
addx 5
noop
noop
noop
noop
noop
addx -36
noop
addx 1
addx 7
noop
noop
noop
addx 2
addx 6
noop
noop
noop
noop
noop
addx 1
noop
noop
addx 7
addx 1
noop
addx -13
addx 13
addx 7
noop
addx 1
addx -33
noop
noop
noop
addx 2
noop
noop
noop
addx 8
noop
addx -1
addx 2
addx 1
noop
addx 17
addx -9
addx 1
addx 1
addx -3
addx 11
noop
noop
addx 1
noop
addx 1
noop
noop
addx -13
addx -19
addx 1
addx 3
addx 26
addx -30
addx 12
addx -1
addx 3
addx 1
noop
noop
noop
addx -9
addx 18
addx 1
addx 2
noop
noop
addx 9
noop
noop
noop
addx -1
addx 2
addx -37
addx 1
addx 3
noop
addx 15
addx -21
addx 22
addx -6
addx 1
noop
addx 2
addx 1
noop
addx -10
noop
noop
addx 20
addx 1
addx 2
addx 2
addx -6
addx -11
noop
noop
noop

55
input/day11.txt Normal file
View File

@@ -0,0 +1,55 @@
Monkey 0:
Starting items: 61
Operation: new = old * 11
Test: divisible by 5
If true: throw to monkey 7
If false: throw to monkey 4
Monkey 1:
Starting items: 76, 92, 53, 93, 79, 86, 81
Operation: new = old + 4
Test: divisible by 2
If true: throw to monkey 2
If false: throw to monkey 6
Monkey 2:
Starting items: 91, 99
Operation: new = old * 19
Test: divisible by 13
If true: throw to monkey 5
If false: throw to monkey 0
Monkey 3:
Starting items: 58, 67, 66
Operation: new = old * old
Test: divisible by 7
If true: throw to monkey 6
If false: throw to monkey 1
Monkey 4:
Starting items: 94, 54, 62, 73
Operation: new = old + 1
Test: divisible by 19
If true: throw to monkey 3
If false: throw to monkey 7
Monkey 5:
Starting items: 59, 95, 51, 58, 58
Operation: new = old + 3
Test: divisible by 11
If true: throw to monkey 0
If false: throw to monkey 4
Monkey 6:
Starting items: 87, 69, 92, 56, 91, 93, 88, 73
Operation: new = old + 8
Test: divisible by 3
If true: throw to monkey 5
If false: throw to monkey 2
Monkey 7:
Starting items: 71, 57, 86, 67, 96, 95
Operation: new = old + 7
Test: divisible by 17
If true: throw to monkey 3
If false: throw to monkey 1

27
input/day11_example.txt Normal file
View File

@@ -0,0 +1,27 @@
Monkey 0:
Starting items: 79, 98
Operation: new = old * 19
Test: divisible by 23
If true: throw to monkey 2
If false: throw to monkey 3
Monkey 1:
Starting items: 54, 65, 75, 74
Operation: new = old + 6
Test: divisible by 19
If true: throw to monkey 2
If false: throw to monkey 0
Monkey 2:
Starting items: 79, 60, 97
Operation: new = old * old
Test: divisible by 13
If true: throw to monkey 1
If false: throw to monkey 3
Monkey 3:
Starting items: 74
Operation: new = old + 3
Test: divisible by 17
If true: throw to monkey 0
If false: throw to monkey 1

41
input/day12.txt Normal file
View File

@@ -0,0 +1,41 @@
abccccaaaaaaacccaaaaaaaccccccccccccccccccccccccccccccccccaaaa
abcccccaaaaaacccaaaaaaaaaaccccccccccccccccccccccccccccccaaaaa
abccaaaaaaaaccaaaaaaaaaaaaaccccccccccccccccccccccccccccaaaaaa
abccaaaaaaaaaaaaaaaaaaaaaaacccccccccaaaccccacccccccccccaaacaa
abaccaaaaaaaaaaaaaaaaaacacacccccccccaaacccaaaccccccccccccccaa
abaccccaaaaaaaaaaaaaaaacccccccccccccaaaaaaaaaccccccccccccccaa
abaccccaacccccccccaaaaaacccccccccccccaaaaaaaacccccccccccccccc
abcccccaaaacccccccaaaaaaccccccccijjjjjjaaaaaccccccaaccaaccccc
abccccccaaaaacccccaaaacccccccciiijjjjjjjjjkkkkkkccaaaaaaccccc
abcccccaaaaacccccccccccccccccciiiirrrjjjjjkkkkkkkkaaaaaaccccc
abcccccaaaaaccccccccccccccccciiiirrrrrrjjjkkkkkkkkkaaaaaccccc
abaaccacaaaaacccccccccccccccciiiqrrrrrrrrrrssssskkkkaaaaacccc
abaaaaacaaccccccccccccccccccciiiqqrtuurrrrrsssssskklaaaaacccc
abaaaaacccccccccccaaccccccccciiqqqttuuuurrssusssslllaaccccccc
abaaaaaccccccccaaaaccccccccciiiqqqttuuuuuuuuuuusslllaaccccccc
abaaaaaacccccccaaaaaaccccccciiiqqqttxxxuuuuuuuusslllccccccccc
abaaaaaaccccaaccaaaaacccccchhiiqqtttxxxxuyyyyvvsslllccccccccc
abaaacacccccaacaaaaaccccccchhhqqqqttxxxxxyyyyvvsslllccccccccc
abaaacccccccaaaaaaaacccccchhhqqqqtttxxxxxyyyvvssqlllccccccccc
abacccccaaaaaaaaaaccaaacchhhpqqqtttxxxxxyyyyvvqqqlllccccccccc
SbaaacaaaaaaaaaaaacaaaaahhhhppttttxxEzzzzyyvvvqqqqlllcccccccc
abaaaaaaacaaaaaacccaaaaahhhppptttxxxxxyyyyyyyvvqqqlllcccccccc
abaaaaaaccaaaaaaaccaaaaahhhppptttxxxxywyyyyyyvvvqqqmmcccccccc
abaaaaaaacaaaaaaacccaaaahhhpppsssxxwwwyyyyyyvvvvqqqmmmccccccc
abaaaaaaaaaaaaaaacccaacahhhpppssssssswyyywwvvvvvqqqmmmccccccc
abaaaaaaaacacaaaacccccccgggppppsssssswwywwwwvvvqqqqmmmccccccc
abcaaacaaaccccaaaccccccccgggppppppssswwwwwrrrrrqqqmmmmccccccc
abcaaacccccccccccccccccccgggggpppoosswwwwwrrrrrqqmmmmddcccccc
abccaacccccccccccccccccccccgggggoooosswwwrrrnnnmmmmmddddccccc
abccccccccccccccccccccccccccgggggooossrrrrrnnnnnmmmddddaccccc
abaccccaacccccccccccccccccccccgggfoossrrrrnnnnndddddddaaacccc
abaccaaaaaaccccccccccccccccccccgffooorrrrnnnneeddddddaaaacccc
abaccaaaaaacccccccccccccccccccccfffooooonnnneeeddddaaaacccccc
abacccaaaaaccccccccaaccaaaccccccffffoooonnneeeeccaaaaaacccccc
abcccaaaaacccccccccaaccaaaaccccccffffoooneeeeeaccccccaacccccc
abaccaaaaaccccccccaaaacaaaaccccccafffffeeeeeaaacccccccccccccc
abacccccccccccccccaaaacaaacccccccccffffeeeecccccccccccccccaac
abaaaacccccccaaaaaaaaaaaaaacccccccccfffeeeccccccccccccccccaaa
abaaaacccccccaaaaaaaaaaaaaaccccccccccccaacccccccccccccccccaaa
abaacccccccccaaaaaaaaaaaaaaccccccccccccaacccccccccccccccaaaaa
abaaaccccccccccaaaaaaaaccccccccccccccccccccccccccccccccaaaaaa

5
input/day12_example.txt Normal file
View File

@@ -0,0 +1,5 @@
Sabqponm
abcryxxl
accszExk
acctuvwj
abdefghi

449
input/day13.txt Normal file
View File

@@ -0,0 +1,449 @@
[[[[]]],[[[1,2,7,3,10],10,8,4,10]],[1,3,[],6,0]]
[[[[9,3,5],[5,9,1,2,9],8],[[],9]]]
[[],[6,[],[[6,8,9],4]],[[[10,6,2],[10,8,4],8],3,[2,5,1,1],1,[]],[10,[[2],4,5,[3,6],10]],[5]]
[[6,[[4],3],4,5],[],[[[0,5,2],9,5],[9,2,10],9],[[[10],5,2,[3,7,10,7,3]],3,[[],3,9,7,6],[[0,9,9],2,[10,0,2],[9,3,6,0,4]]],[3,7,[9,9,[],[10],[3]],[10,6,[5,8],[4],[3]]]]
[[4],[6,9,[[2,8,3],[8,0,5,2]],3,[10]],[[6,3,9,9],[1,9]]]
[[[]],[[10,[9,7,3],6,5]]]
[[],[],[[[0],8],[],[4,4,9],8],[[8,1,6]]]
[[[3],[[4,8],[],7],10,[0,[9,2,1,3,4],4,0,3]],[[],9,5,[]],[1,[[3,10,8,5,0],6,5],[],9],[1,[]],[]]
[[[[3,4],0],8]]
[[[]],[],[10],[[],1,1,0],[0,[[7,9,6,0],[0,9],[7,0,7,8,8]]]]
[[[[0,2,9,10],[1,8,4],6,8,[8,0,5,0]],[[9,5],2,7],1,8],[6,[3,3,[5,5],2,3],1,6,[[7],8,[1,0],8]]]
[[10],[[],3,[4,[],3]],[[[0,4,1,5,10]],[0,5,9,10,[6,4,1,6,4]],7,[10,[3,1,6,5],3,5,2],[7]],[[6,7,8,[9,10,5,5],9],6,[7],[4,[5,10,0,4,10]]],[3]]
[[],[[],2],[0,8]]
[[6,[],3,[9,7,9,[8,0],[9,5,10,8]]],[[[3,4,1,3],6,7,[7,0,7,7,5],5]],[10],[6,0,[6,7,[7,3,10,1],[1,9,8],[0,0]],[9]]]
[[3,3],[5],[1,4],[[7],[[6,4,5,2],4],2,4]]
[[8,[0,1],[1,[1,2,8,7,7],0,3,6],[10,4,[3]]],[9,3,5,9],[[5,8,[0],6,[]],2],[3,[0,10],1,[[1],2,[8,5,6,1],[7,0,9,9,9],[8,1,1,4,7]],[[8,2,3,2,10],[1,6,6],7,3]]]
[[8,[3,8,1,[],[3,5,10,7]],[4],[[],[9,3]]],[[1,[2,1,7,8],6],[[9,9,10],[5,10,5,1,1],[7,10,10,1,3]]],[8,[[10,4,0,3],[3]],[9,[],7,[7,8,2],[]],10]]
[[4,[[10,8,3,2],[6]],7,[9,[3,9]],[]],[]]
[[9,10,1,[6,8,8],2],[9,10],[[[3,9,8,1],[2,9,9,4]],[[9,10,2]]]]
[[[2],6],[5,6,[[4,2],[0,0],[3,3,5,4],10],[1]],[[],9],[],[5,[[6,0,4,8,5],4]]]
[[[[0,2,6],[2],[9],[9,10,2]],6,[[]],[[8,9,3],[2]],[[5,9,10],[3],[0,3,1],8,[10,10]]]]
[[8,9,[3,[],[1,9,8,7]],4,10],[[],6]]
[[6],[9,[],6,[[3,8,4],[5,4,9,0],2],9],[[[1,1,2,8]],[4,[7],[2,7,9,9,0],5],[],4,8]]
[[8,6,[],6]]
[[[10],[10],7],[],[[[0,0,2,3,0]],[[8,8,8]],[0,[2,7,0,2],5],2,[[],10,10,6]],[],[[[10,9],[8,8,2,4],1,[7,0,9]],7]]
[[1,[[9,10,6,7],[2,10,1],0,[4],3],4],[[[9,3,0],1,6,[7,10],[8,9,5]],[9,[2,10,3],9],6,[2]],[],[4,[8,[],[0,6,3],[5,3,3]],6,[]],[]]
[[1,[[3,6,8,3,1],0,[6],5,5]],[1,7],[]]
[[7]]
[[3,10,2,[3,[],3,[7,7,10,9]]],[5,[],0],[6,8,4,4],[2,4,1,[10,[10,8,4],8,[10,2,1,5],9]],[]]
[[5,[[1,3],[4,6],[4,6,6,3],4],[[2,10,6],[10,6,1],[2,2]],1],[[[],[9,9,4,7],[4],9,[6,1,9,5,5]],5]]
[[],[10,10,9],[[0,[1]]],[0,10]]
[[],[9,9,[[7,5,4,3]],0],[[9,9]]]
[[[3,2,[3,2],[4,2,2,4,0],1],10,3,[[2,0,1,9],5,4],[]],[]]
[[],[7,[]],[],[]]
[[[8,6],[],9,9],[3,10,[]]]
[[],[[9],8,10],[[9,[6,3,4],[0,2]],[10,[0,2,8],[0,0],3],9,6],[[9,[2],7,8,7],[[6],4,[9,0,1,2],[2,5]],2,4],[[[]]]]
[[[0]],[[[10,7,5,4],5,[],1]],[5],[]]
[[],[[8],[4,[4,7],1,[7,0,4,9]],3],[[[9],[0,3,2,8]],7,[5],8],[[[5,0,9,4],9,[1,6,5]],7,[8,1,[4],[]],[]],[2,3,[[5,0,4],5,4],[4]]]
[[3,[1,10,9],[1,[]],[6,10],1],[[],5,8,7,[[2,6,3,9]]],[7,[[],[3,8,1,9,2]],2,[[4,0],[],5]]]
[[1]]
[[],[7,7,[[5],0,1,10]],[[[],[4,6,8,9,9],6,6],9,7,[8,5,[0,4],[7,9,6]],[8,[7,9,4],[8,2,8],[]]],[8,7,8,6,[]]]
[[[],[[10,6,2,0],[],4],7,[]]]
[[9,[],[[],[1,7,5,2],[1,7]]],[[5,10,8,[10,9],9],[6,5],4,0,[[9,7,0]]],[10,5],[]]
[[6,[[],3],[[9,6,5],0],9,1],[10]]
[[[],0,9,[[10,5],[1]],[1,7,[9,10],[8,7,1],[9,0,9,4,6]]],[[],[2,1,0,7,[]],[0,3,5,[9,3,1,9]],8,[[1,1,7,3,3]]]]
[[[0,1,10],[[6,6,4,0]]],[],[7],[[7,[],[8]],5,[[8,5]]]]
[[8,[]],[]]
[[[6,[1,7,2,0]],1],[0],[1,[[9],[9,2,1,6,8],2]]]
[[[8],2,4]]
[[],[0,4,[],2,10],[9,[3,8]],[[9,10],[[3,5,4,7,2],[9,6,6,0,6],[1,5,6],[9,4,4,1,9],[2,0,5]],[8],0]]
[[0,8,[],10],[],[[1],[]],[],[10,[7,[],2,[],0],5,5,10]]
[[],[[],[2,0]],[1,[[9]],1],[9,4,[],1],[2,10]]
[[[[8],[2,8,5,3],[7]],[10],8,1],[],[[1,[8,1],[6,4]],3,1,5,[7,[2,1,3,3],[0,0,9],[3,5,0]]],[10,[[10,2,10,0],[8,8,0,8,7],7],3,[6]],[[[7,2],[4,5]],[]]]
[[[[8,2,8,7,4]]],[5,7],[]]
[[[10],[[0,4,4],1,[9,2],[9,0,9,1,10],10],[0,2,3,[6,1]]],[2,7,9,2]]
[[],[[7],10,3,[[0,10]]],[[8,9,[]]],[[7,[0,2,0,10],[8,6,1,9],[6,3,9]]],[8]]
[[[[],[4],[10,10,4,6,0],6,[9,10,9,0]],1,5,3],[1,10,[2,2,2,[1,6],0],[],[[]]],[],[1]]
[[[[5,8],[],7,[10],1]],[8],[4,[[5],[1,1,4,8],[],1,[]],[[1,3,0,1],[5,3,10,10,2]],1],[[[]],[1,6,8,[6,2]],[[6,10,6,7],[],[2],5],[5,[5,8,3,0],[8],3]],[4,[10],0,[10,8,[8,4,10,4],2]]]
[[],[[7]],[]]
[[2,5],[[6,4,[10,7,5,5]]],[[1,0,[0,7,8,6,4]],[[9,10,0,10,8],[8,6,6,8]]]]
[[[],[0],[9,9,[],0]],[[6,[],7],[6,[],1,[8],9],10,[9],[3,[8,6,5,8,8]]],[3,2,[5,1,0,9],[],[0,[10,4,10,5,8],[2],[],0]]]
[[6,3,[]],[7,[[7,5,8,8],4,5,1,[8,2,2,7]],8,[[6,9],1,[0,1,5],10,6]],[[],9,2,[],5],[1,[[],9,[0,4,1],[8,7,8,0,1],5]]]
[[[9],[[1,9],[0,1,9],[8,0,5,8,9]],[8,5,[8,8,0],7,[3,2]]],[[9,4,[7,5,1,8],[4,0,9],3],4,[[],[],3,[]],0,7],[6,[8,5]],[[[1,6,4],5],[],9,5]]
[[3,6,8],[6,[4,[]],0,2],[[[1,8,8,10],[4,3,6],4],9]]
[10,10,8,6]
[10,10,8,6,5]
[[8,10,8],[8,[[]],8,[[10,9,3,7,4],[1,5,0],[]],9],[8,1,[],[],[[8,1],[10,10,2,1],1,[7,5]]],[[4],3]]
[[],[[4,[4,9],[],8,2],6,[4,[3],1,0],2,6],[6,[2,3,5],[[]],[[7,1],[9,0,6,3,8]],[]]]
[[],[[[0]],[3],9,[8]],[[0,[8,4,4,6,9],6]]]
[[0,[10,6],8,[9,[6,0],5]]]
[[[[10]],3]]
[[[2,[10,0,5],[7],[5,5,1,4,3],[1,4]],0,10],[5,[[10,9,8,3,6],2],2],[[8],5],[9,6,2,[4,4,4],2]]
[[[5,[],1,2]]]
[[0,[[1]]],[6,[10,6,1],8,[8]]]
[[5,[]]]
[[2,[[2,6,3,8],1,4],[[7]],[[],8,[7,8],3,[10]]],[[[4,2],7],[0,[],4,[1,4],[3,9,2,1]],[[9,2],1,[9],[]],7],[]]
[[[2,[7,4,5,6,2],5,[5,7,3,6]],0,5,0],[[[2,5,9],[6,10,9],0,7],4,[7],10],[10,10,6,[10,4],6],[9,3,0,[[3,9,6],1]]]
[[[],[10,1,[5,6,5,5],[2,1],[9,6,5,7,9]]],[6,[[],[],9],[],[],9],[7,[5,[4,6,10,5,8],[8,6,0],5]]]
[[0,0,[[8,1,4,5],[7,1,6,1,7],[8,0],[9],1],[1,3],[[4,7]]],[[2,[7,0]],4,9,[]],[[[3],[1,9,2,10,3],[5],5,[2,5,4]],[10],[]],[],[1,9]]
[[[],[8]],[[],[3,2]],[10,4,8,[7],[[7,4],2,10,[9,5]]],[4],[[[],8,4],3,[],4]]
[[[[6,5],1,[3],[3],[]],9],[0,[[5,3,4,7,1],[3]],10,[4,[4]],[9,0,6]],[[[],7,[]],[10,5,[]]]]
[[5,5,[[4,10,4,3],0,9,2,9]]]
[[],[[9,4],8,7,8,6],[10,[[6],[10,4,3,9,5]],6],[[[5]],[6,[7,4,4,2,5],[4,5],5],2,[[6,0,7,9],[6],[2,5,5,2,8]],[10,2,2,4,[]]]]
[[6,[3],9],[[7],8],[[[2,1]],[[]]],[[],4,2,3]]
[[10,[0],[[6,10,1],[2,9],[10,3,3,6,3],10,0],4,[]]]
[[[[],10,[4],[6,1,4]],7,[]],[8],[[[],[0,3,3,3,8],[],10]]]
[[9,0,9],[],[[]],[4,[],[[5,1,0],[6,7,1],9,[4],8]]]
[[],[[],2,[]],[[[4,8,6,3],5,[6,9,5,0,10]],[[9,8,3],[5,1,1],4,[3,8,2],10],[],5]]
[[],[[],2,[3,[9,10,3,3],[6,6]],10],[0,[[0,9],0,1,[1,10,2,10]],8]]
[[4,1,3,10,[[6],[],[0,10],9,10]]]
[[[],10,9,7,[]]]
[[[]],[4,[[10,1,7,5,0],[10,3,7,10,10]]],[8,3,[6,0,6,[10]],[8,2]],[[[10],6,1,5],6]]
[[[[4,4,8]],6,2,[[5,8,0,1,7]],[]],[3],[[[0],9,7],[[6],9,[1,10],[4,0,3,8,6]],[[],4,[6],4,[4,0,6,7,3]],1]]
[[[]],[[4,[3,0,2,10],[10]],[[1,7]],[]],[6,6]]
[[2],[9],[[2,6,[]],[],6,[5,8,8,[5],[]]],[[[0,2,9,10]],0,[6,[10,6,3,4,10],[8,5,6],6,3]]]
[[[],7],[4],[8,2,[1,3,7,7],[],[[7,7,3,5],3,[0,7],[]]],[[10,[8,8,10]],[8],[[5,0,8,10],8,10]],[[[0],[0,5,9],[2,4,8,1,1]],[[8,9,10,6,7]],1,0,[0,6,[6,1,7,3]]]]
[[[[],5,[],8,2]]]
[[7,[[],0,[2,0,2,9]]],[],[],[9,[],7,5]]
[[],[],[],[[[8,1,6],[],8,9],[9,8,[8,10,0,3],[4]],6,[[2,1,3],[5,10,3,0],4],[[8,8,10],[0,7,4]]],[[[8,5]],1,1,7]]
[[],[[[2,0,6,4],[1,0,2,0,6],[1,3,4],[8,5],0]],[0,[[0,5,1,3],[2],0,6],[]],[[[8,2],[3],9,[9,0]],[1,[],9],[1],[6,4,[0,5,9,8],[4,9,8],3],[[1,4,3,5],1,[6,10,6],5,2]]]
[[[[6,6]],[7,[1,1,3,4],5]],[10,10,6,0,[[6],[7],4,9,1]],[3,9],[3,10,10,[1,[4,5,5],6,[3,3,10]]]]
[[[6,6,9,[3,8,3]],9,10,5]]
[[6,4],[5,[[2,3,5,9,9],4,[9,6,0,9,1],[4,9]],2,[],10]]
[[],[]]
[[],[],[],[]]
[[[],[[6],6,[4,2,6,3,10],5,7]]]
[[[[10]],2,7],[[[1,9,1,3],[6,3,6],[6,0,4,4,3]],[3],8,[0]],[],[[10,9,[9,5,0,7,3],9,[4,3,9]],[6]]]
[[[10],3,9],[[[0]],4,0]]
[[6,[[3,5],10]],[[[8,5,8,6],10],[[7,3],6,[3,7,2,5,5],[9,2,8,1],0]],[[[]]]]
[[[],6],[[1]],[],[],[[[2,1,0,1,3],[4,6],10,2]]]
[[[[3,1],[]],10,0,6],[],[[3],9,[],2],[9,[3]],[4,1,[[9,0],9,8,3],2]]
[[9]]
[[9,9]]
[[8,[7],[[10,8,6],[1],10,[5]]],[0,[7,8,8,[10,6,2]],[9,[6]]],[],[[4,2,0,[4,9,5]],2,7,[],6],[]]
[[[8,2,[6,8,3,6,7],[2,10],[]],8,[7,[]]],[5,9,2,8,9],[],[5,[6,[5,3]],[]],[]]
[[[10,8,1,8,[]]]]
[[],[[[2,4,7,10],10],6,[],5]]
[[5,[1,0],1,5,4],[[2],[[10,5,6,9],10,3,1]],[2,9]]
[[[2,[1,1,5]],[[],[7,0,10],[1,7],[6,10]],9,[[1],[],[5,0,5,3,8],[6,7,3]]]]
[[[[4,0,5,1],2,[1,5,6],8],3,2,[[3,0,0,4],[2,4],7,[0,9,10]],1],[],[[[3,2]]],[10],[[[7,10,0,4,6],[1,10,3],7],0,[[0,1,9,6,1]],[4,1,3]]]
[[[7,6],6,[8,4,[],[],[8]],8],[[8,0],[0,6,[]],[[8,4],4]],[9,2,3,9,[[],[2,2,5,6],[10,9]]]]
[[10,6,8],[7,5,0,[[],[6],3,2]]]
[[4,6],[0,10],[],[4,7,[[3,10],0,7,[2,10,4,2,9]],[[3],[9,0]]]]
[[[],[[],[2,5,8]],7,[[10],[0,0,7]],[1,6]]]
[[],[],[2,4,[9,[],[4,9,6,0,6],[6,2]]],[[9,[],[3,4,9,1]],10,[[6,5,3,6,2],[],[7,8,2],[7,8]]]]
[[3],[[[]],0,[[],[0,3,9],5],7,0],[5],[[2],[[9,5,7,2,10],[0,7],9,[4,3]],2]]
[[9,[5,6,[],[1,5,4,7,9]],[]],[[[],9,4,[3,5,2]],1,8,6,[2,[]]],[[[8,5,4],[10,0,7],1,2,[7,3,5,0,6]]]]
[[[[0,1,6],[8]],0,[]],[[10,[0,5]]],[0,0,[[1],2,9,[]],[]],[[[1],[],[2]],[[7,5,7],9,7,[6,1,4,7]],[[7]],[7,0,4,6]],[9,7,2,[],[]]]
[[4,3]]
[[[8,0,5,6,[7,10,10,0,4]],[[7,9,6,3],5],8],[7,5,6,4],[]]
[[[8]]]
[[[[7,2,4,2],1]]]
[[],[6,[5,[],5,7,[0,3,6]],[3,[9,1,6,0,8],7,7,5],0,[[3,3,5,0],[8,4]]],[[[5,6,3,8]],9,10,5]]
[[7],[],[[6,[],4]]]
[[[]],[[[10],10],10,[[10,8,4,1],[4,3,6,4,8],9]]]
[[1,7,[10,6,9,[0,7],8],7]]
[[8,[[4],[4,4,5,3],2,10,2]],[0,[5,10,[]],5,[[8],[],[7,8,10],5]]]
[[[9,5,0,[5],9]],[[5,[],[10,8,2,10,5]],[6,0,[6,7,3],[],[]],[[6,1],2,[2,9,5]],6,[4,[9,7,2,6,0],[1,3],[0,1,1,0],0]]]
[[[[6,5,3,2]],5,10,1,7],[],[5,5,[[6,3],[3,5],1],5]]
[[8,[[9,2,9],[3,4,3],5,[7,8],[8]],9,7,[[6,3,10,1,3],[9],[2,4,0,9]]],[[[8,1],9,5,[3]]],[7,[[10,2,6,3],[6,10,5,6],[4,7,2,4,7],[]],[4,6,1]],[[]]]
[[[[6,9,8],[],[],[7,3,6,2,0]],[9,[7,2,10],3,2],[[4,5],[2],[2,7,5,1,2]],7,[10,[3,1,6]]],[10,[[5,0,9],[5,1]]],[7,[[],[6,0]],10,3,9],[],[[[],9],10,2,2,[]]]
[[[9,9,[9,3,2,9]],[],0,[4,[10,7],[5],[8,3],5],9],[],[0,1]]
[[[[10],[6],[]],3,[[2,7,9,1,4],[6,9,5,3],[7,3,7,0,1]]]]
[[],[[[6,4],0,[8,8,8,0]],1]]
[[5,6,[7],0],[9,10,9,[]],[[4],2,0]]
[[[6,[7,2,10,6,0],8,[],[9,1,3,2,5]],3,[9,4,[0,1],[3,7,7],[6,0,2,7,8]],[[4,5,6],7,1,[9,7,8]],[[0,5,3],[3,1],6]],[1]]
[[[[10,5,5,1,2],6,10,[9]],0,4,[0],[8,3,1,1]],[7,7],[[5,[],[4,7,4,8,5],[9],0],7,8],[10,[[7,3,1,1],1,7,[],[4,9,2,2,6]],[[9,9,5],[4,0]]]]
[[[[],3,[0,10,2,10]]],[2],[[[9,6,9,0,10],6],[10,[2],1,10],[[9,3,4,7],10,[4,2,10,9,2],0],[]]]
[[]]
[]
[[],[[3,[0]],[4,0,3,[8]],9,[]],[6,[[6],2,[6,5,6,10],2],[2,4,[8,10]]],[2]]
[[7,[8,[7,5,4,6]]],[],[9,6,[[6,7],9,[3,5,10,6,9],[5,3,4,2,5]]],[[[3,10,0,7,10],[2,2,5,1,4],4],10,7]]
[[[[9,5,0,10],[1,4,7,10,6],6],2,[3]],[[],7],[],[9,10,[],[5,[9],[],[2,5],8]],[7,[9,[7,5,4,4,9],1]]]
[[[[8,5,8],[9,4,10],[]],7,[0,6,8,[10,3,5]]]]
[[],[9,[[9,3,10,2,1],5,[6,7,1,8],[8,8,8]],[[0,8,8],[],[3,8,0,10]],2,[2,[6,6,0,10,4]]],[7,[[4,0],[10,9,8,6]],[5],[5,10]]]
[[[8,[7,1],3,[],[9,8]],[8,[]],[[1,4],[4,1,8,5],5]]]
[[[[0,2],[10],0,[]]],[[1],[3,5,[],2]]]
[[[10,[9],1],[[],9,8],6],[0],[[7,1,10,3,[6,0,9]]],[[2]]]
[[1],[],[0,5,3,[10,10,7,[3,8,3]]],[[10,[9,6,3,7,0],4,3,7],3,[6,[4,2,3,6],[5,9,3],[7,1,9,10,8],[8,4,1]]],[]]
[[[[6,9,4,10,3]]],[9,[4],[[1,8,5,4],[4],[5,2,3,8],[],[2,3,8,9]],[7,8,3,[]]]]
[[6,8],[7]]
[[[[0,6,2,7,6],[0]],7,[[2,4],[3],[6,2,6,8,9],[4,7,1,10,8],[8,6]],7],[8,2,[[0,6,0,4],7],8,6],[2,6,[3],7],[[0,[3,6],0],[],4,2]]
[[3],[],[],[9,6,[0,8,[2,2,4,8],0,[5,2,7,4,8]]],[[5],[[],0,[6,0],9,7],2]]
[[3]]
[[10,[[9,0,0],0,9,8],5,6],[[7,[10,1]]],[6,4,6,[2,10],[[10],[10,7],3,[0]]]]
[[[10,[6,4,1],3,5],3,4,[9]],[[[7],[],3,[9,7,4],[]],[6,2,7,[9,4,10,10,1],4],[],4],[[0],[0],[[10,5,0,5],[],[6,7,3,6,1]],[[7,5],[],1],[]]]
[[0]]
[[0],[],[[4,[7,1,4],8],9,4,[[2],[6]],3],[5],[[],2,[[1],4,6,[10,9,1,0],10],2,[]]]
[[1,[0]]]
[[[6,[4],[7,8]],[3,0,7,1,0],10,8],[[]]]
[[[1],10],[7,4,3],[4,[[2,1]],[10],[[1,5,9,1,8],[3,2,5,9],[9,7,7,5,8],[5,2,8]]],[[],[9,[2,5,5,7,2],2],8]]
[[[1,[0,7,7,10,4],7],[[],4],[10,[2,5,0],[9,9,7,2,7],[1,9]],9,[]],[8,[[],[]],[7,3,10]]]
[[[[],[10,0,10,9,3]],[1,[10]],[9,[8,2,7],6,[1,9,1]],4,10],[[[]],0,4,1],[[[],0],[[3]]]]
[[5],[3,6,[[7,10,6]],0],[],[10,[[4,7,4,1],[8,9,9],[5,4,6,6,7]],[9,[1,7,10,4,1],0,[],7],1,7]]
[[2,[[]],3,[[2,8,9,4,5]],[5,10,5,[7],5]],[2,[0,5],[4],9,[[],9,2,8,[7,6]]],[[4,[7,6,10,2,7],[0],7],8,[]]]
[[],[[[0],3,[1]],[5,6,[7,0,7,3],10,10],[4,5,[],10,6],[[6,0,8],[1,0,10,2],[10,3,1],0,[]],[[2,6],[4]]],[[],[[6]],8],[]]
[[0],[[[2,4,5,1,3],6],0,3],[5,8,[[3,5,0,9]],7,2],[10,[7,[10,3,2],10,[5]]],[3,9,6,[],[[9,3,1,1],6]]]
[[10],[4,[9,[9,6,2,5],4]],[2,[[9],[0,9,6,4],[2,5,1,1],2,3],1],[[8,[6]]],[10,6,[0,[1,1,10,8,2],8],[2,[4,7,10,10,5],10,2],[0,9,[3],[4,1,3,9,3]]]]
[[2,4],[1,6],[],[[5,[6,0,0]],6,6]]
[[[0,[7,4,8,5],[9,2,10,3]],10,[[9]],0,[7]],[[[10,6,7],2,10,[9,0,9]],[[3,6,2],[9,6],5],6,7,[10,3,[2]]],[3]]
[[[[2,7,2,7]],9,2,7,[[10,4],[10]]]]
[[],[8,5,[],[5,[10,9,3]],1]]
[[4,8],[[[7,3,6,8,7],[0]],10,[7],0,[9,8,[5,9,8,7],2]],[7,8],[[],5,6,[4],[]],[[[8,6,10],5],[]]]
[[[0,2,[9,10],5],[1,[1],[6,4,4,2],[],[8]],[0,[9,6,9,9,7],6],[[],8],0],[3,10,[[7,6,0],[5],10],3,[9,3,[0,10,3,9]]],[1,[2],[],[6,5]]]
[[0],[3],[[[8,10,5,3,1]],4,3,9]]
[[[3,[]],[[],1],[4,9,9],3],[4,6,[8],9],[[[1,1,10,3,5],0,10,[3]],3,8,[]],[7]]
[[2],[]]
[[8,[[9,6,4],[4,7,3,6],[2,4,4,9,8]],[9,4,6,6,[1,8,5,9,1]],2,7],[2,[2,[0],10],[]]]
[[5],[[[9],[9,0,10],1],10,5,8],[5,4,4,4,10],[7,0,[[2,1],1],[3]],[]]
[[6,[5,[],[6,0],[4,1,10],6],6,[]]]
[[[0,5]],[]]
[[9,10,[2,[],1,8],5],[0,[],7,3,[]]]
[[1,[[],5,1],9,[[3],[],2,10,[5,7,10]]],[4,[10,[5]],[9,9,[6,1,8],0,[3,8,4,9]],7],[[4,[0,6]],[0],[[8,10,8,7],[5],[4],[5,3],0]],[2,3,[9,[1,7,5],[5,0,2],[]],[[3,8],9,9,[0,1,7]],10],[]]
[[[[2,9,7,8,1],7,[1],3,[]],5,8],[7]]
[[5],[[],[0,[9,3,9,4],7,[9,0]],5,[0,8,1,[4,3,7],6],5],[0,10,8,8]]
[[[],[1,[10,5,9,6,9]],3],[2,[[8,7],0,[10,10,9,8,5]],9],[0,[]]]
[[[],[6],[[3,4,6,9,3]]]]
[[[[7,8,5,9],[4],0],[[6,5,1]],4],[],[9,[[2,7,7,0],[10,5,0]],[[4,2,6,3],0,[8,3,3,10,4],6,10],[[],5,[8,9,0]]],[4,[[5,4,10],[6,3,1,3],[],[3,9]],[[1,9,2,7],2,3,7,1],[[4,10,5,1],8,[1,5,8,7,5]]],[[10,3,[],[]],5,9,0,[[4],[0,8,4],[4],[8,7]]]]
[[[4,[2],[9,10]]],[[[4,9],7]],[2],[[1,[6,0,10,6],0]]]
[[],[7,[],10],[[8,0],[]]]
[[],[4,4,10,4],[4,1,[4,[4,8,8,2],5,[2,6,1,6],10]]]
[[[6],0,0,[7,[5,3],[],3,1],10]]
[[[2,9,[5,1,6,4,10],10,8]],[[0,[10,9,1]]],[]]
[[[[8,9,8,8,9]],5,7,8]]
[[],[[],3,3],[6,[1,1,[9,4,9,1],[4,10]],[[7,6,6],[0,5,10,4],1,6,9]],[],[[[1,4,9,10]],[[8,5,5,6],1,8,[9,7,9,0,6]],0]]
[[9,8,10,[7]],[[6,[],4]],[[],[8,[5,4,7],[5,1,3],[9],[8,9]],[10,[5,8]]],[4]]
[[[4,[0,7,9,1,9]],4,[8,[8,9,1,9,9],[3,9],2],[],[1,9]],[[0,[1,4,1]]]]
[[[[0,10,0,5]],[0,1,[7,5,4]],[[6,3,8,1],7,9],2],[0,[[5,3],6,[0,1],[8,7,9,10,6],0]]]
[[[0,[4,8]],[8],[[],7,[9,7,3,4,6],2,[9]]]]
[[],[[],1,7],[[],[[4]]],[[3,8],[],9,[[4,1,9],5,[8,5,5,3,2]]]]
[[[5,[4,4,9,1]],5,[8,4,2,10,[1,7,1,8]],6,[[4,8,7],[7,5,2,10,0],5,[3,10,7,7,8],[4,3,2,3]]]]
[[[],[1,[5,1,4],[3,2,4]],7]]
[[[[6,2,4,0,1],0,5]],[[6],7,[8,5,[10,5,6,1,4],[9,6,7]]],[7],[[[2,7,1,4,10],[6,3,5],6,3,[3,5,0,1]],[3,5,4,9,1],3],[[[],10,[10,9,7,1,6],[9,2,8,7]]]]
[[[[6],[4,1],[]],[6,10,10,[4,9,0,6],[0,5,8]]],[],[5,3,2,7,[5,[7,10,10,7],7]],[]]
[[],[],[0,[[]]]]
[[[1,4,1,0]],[8,4],[3,5],[1,[1,[8,9,10,7],6,[]],[5,3,[4,7,1],8],[[7,8,3,5],4,[3,10,4,3],[2,6],6],3],[[[6,2,6],8,0]]]
[[5],[[4,10,[3],0],6,2,[4,2,[4,9,5,4]]],[4],[6,10,10,2,[]],[6,[1],5]]
[[],[10]]
[[8,[],8,2],[],[[5,[9,3,7,7]],1,[9,2,2,5,[6,4,8,5,0]],[[],[6,0,5,2,7],[9]],2],[]]
[[],[3,[0],9],[4,10],[[[8,7,4],[5,2]],[3],[[9,6,8,2]]]]
[[7,[[0,3],2,[10,5],[2],1],9],[2,3,[[3,3,0],7,3,[4,5]]],[3,[],[[10],7,8,[]],[[3,9],1,[1,6],0,8],[[]]],[],[]]
[[4,[],0],[[6,2,[7,5,10],[7,6],4],10,0],[4],[]]
[[1],[[[2],7],10,[9,[7,7,0,8]]]]
[[4,[2]],[[5,6,[10,10,9,9],[0]],7,[1,[],5,[4,0]],[],[]],[5,[4],[[0,9,3],[6,1,6,1,8],3,[7,4,3,3,8]],[[8,1,0,10]]],[1,[5,2,3]]]
[[5,[[5,8],[],[8],0],6],[]]
[[4,5,[4,4,1,8,[6,2,3,4,5]],8,4],[[0,[6,3],10,9,5],[[8,1,7],3,7,[10,4,4,0],7],[10],[[8],[4,9]],[[9,5],[8,10,9],7,[8,0]]],[4,0,[],2]]
[[6,[8,[]],[]],[[],4,[]],[],[[5,[3,7,5]],[9,[0,4,0]],[1],[5,[10],[2,4,9,0,6],0,[5,10,7]],[[2,10],3,[5,10],4]],[[],[1,2,[9,0,9,7,10]],9]]
[[],[[4]],[[[5,3],5,[1]]],[10,[10,[7,10,9,7,0]],[],7]]
[[7],[5,[[],[3,10,0],[5,5,0,10,5]],8,[[6]]],[5],[[],9,0,7,[0]],[[2,7,3],3,6]]
[[[],10],[0,2,1,[[]],[6,4]],[[10,[2]],[7],[2,5,[]],[[],[0,0,5]]],[10],[]]
[[[[9,8,4,2,5],3],[[1,7,8,0],0,4,4,6],[[6],7,9,[]],[[],[4,6,2,0,6],9,0,[0]],[[7],9,9,[0,4,4,3]]],[],[[5,[],0,[]],7,[[4,9,6,7,6],[],[10,4],2],8],[[[2,4,3]],4,8,5],[9,8,0,9,5]]
[[2,1,[[4,3,9,0],9,3,3,[2,5,8]]],[[[8,5,3,3,1],9,[0]]],[[],[[],9,2],[[1,8,9,1],0,10,[6,1]],9,10],[[[3,3,4,9],5],[4,[]],[0,0,6],5],[1]]
[[2,[2,5,[9]],[1,[8,7,2,5,2],[7],[],[6,3,2,4,1]],9,8],[6]]
[[[[0,3,4,5,5],[8,10],4,4],7,[1,1,[],[5],[]],3],[5],[],[],[0,10]]
[[],[1,2],[]]
[[[10,[7,2,10,7],10,4],[[9,9,5],9,[9,1,0,0,6],9,4]],[[],10]]
[[6,10,[6],10,[]],[[[6]],[],0],[8,7]]
[[7,[8,[6,4]],10,[6,8,0,[],3],[[6,5],[9,7],[1,7],[6,5],9]]]
[[[[1,9],5]],[[],[[10],[0]],[[8,1,10],2,[1,9,2],[]],[[5,10,3]]]]
[[[[1,8],[2,9,10,1,8],9],4,5,10],[5],[8,9,10,[7,0,[9,9,0,10,5],4]],[[]]]
[[[0,2,5,0,2],6,2,4],[],[0,[9,1,0,[1],1],[]],[0,[[1],8,3,[1,7,0,10],2]],[3,5]]
[[0,[[4],[7,0,10]],3],[],[1,7,[],3]]
[[[[5],[6]],7,[7]],[[3,2,9,[0,8],6],[[5,5,6,7],[4,4,6,0,8],8,[10,4,0,3]],[8,[3,3,3,4,6]],[[6],[8,4,4,8,2],[3,3],4,6]],[[3],[7,[10,1,0,7],6]],[[9,[]],[9]]]
[[0,6,4,8],[],[1,[3,[9,8,5,2],[0,3,0,9,9],3],6,[[1,4],[],0,[0,9]],[1,6]],[8,[1,4,6],[[2,10,6,7,8],[8,6],4]],[7,8]]
[[],[8,[6,[10,3,9,0]]],[[0,[8]]],[3]]
[[9,3,[3,8,8,[8]],[[],8],[2,[6,5,8,5,0]]],[],[[0],2],[[3,[2]],[2],7,4],[]]
[[[4,5,[9,1,5]],[[2,2],2,[],3,10],8],[[[]],2,2],[10,[[10,8,1,10,1],10,1,10,[8,10]],[[4,5],4,[9,7,7,1],[0,10],[1,7,9,5]]],[8,5],[5,[4,0]]]
[[8,7,[[4,1,5,6,10],9,[4]],[7],3],[3,4,[[],3],0]]
[9,3,6,10,8]
[9,3,6,10]
[[3,[[6,8,8],10,0,0],9],[4,2,0,[2,[6],[9,8,2,7,2],6,[]],[[1,7,8,4,7]]],[],[],[10,9,[[0,4],[6,4]]]]
[[7,8,[]],[6,[[6,5,2,9,10],5,8]]]
[[1,[1,[],[],[]]],[[10,[5,3,8,0],[4,5,4,0],[1,0],1],[[6,0,9,10,6],[5,3,4,6,5]],0,[6,[3,10],0,[10],9],[[2,0],[5],[6,2,5,8],10]],[[1,[2,9]]]]
[[[9],[1],2],[],[[],10,[[8]]]]
[[9,[],[],[8,7,[7,6,5,5,2]]]]
[[8,3],[],[[[10],[9,5,1]],[],2,0,[5]]]
[[9,8,2],[]]
[[8,[[2,10],[8,1,0,3],[9],7],[[2],3,0,5,8],2],[[[4,4],8],0,8,9,6]]
[[[]]]
[[],[[10,[],[6,7,8,5,10]],4],[[],4,8,[]],[[5,3],1,2]]
[[[6],[1,7,4,6],[3],[[],3,[],7],[5]],[3,8,0],[[[7]],[8,[7,2,7],[6,10],[1],[10,3]]],[3],[]]
[[5,[[7,0,3,10],[3,9],[0],[0,0,9,3],[1,5,1]],0,2],[],[[8,[10],4,4,[9,2,8,3]],10,5],[[[6,5],[2],[2,9,4]],9],[[8,[4,1,6],5,[4,8]],[],7,[],5]]
[[3,6],[[[10,2,7]],5,[[3],[10,9,8],3,[6,7,4,10]],4,[7,[9,10,4]]],[2,5],[2],[]]
[[9,[3,[8,5]],3,3],[[10,0]],[],[6,10,2]]
[[2,[[8,10],[3,2],5,10],5,2],[[3,1,9,7]],[0,9],[[[10]],[0,[6,3]],[5,[]],7],[7,6,[8,[3,1,0]],[0,[6],[1]],6]]
[[[[8,0,6,5],2],4,[[4,10],9],0,[2]]]
[[[[0,8]],9,[[6,2,9],8],1,2]]
[[[7,[]],[]],[],[],[[[],[9],[8,7,0,3,1]],4,[[],[1,5]]],[1,[2,[7],9,[9,7,6,2,5],0],4,[[6,9],10,2,[2,8,1,5,7]]]]
[[4,5,0,10],[[5],[5,1,[1,5,1,10],5],7,[]],[],[[[7,1,9,6]],4,0]]
[[7,5,7,10,[4,5,6,[],[9,8,2,5]]]]
[[],[[9,[],[7]],5,7],[3,10],[3,[4,[6,2]],8,8],[7,3,[[3,1,2]],[9,[1,4,10,4,2],2,9]]]
[[8,6,[]],[[2,8,[10,3,4,7],[7,7,2,6,6]],[[1]],[[3,3]],[[10,2,6,7],3,[1,2],0]]]
[[[[8,9,7,7,7],10],4],[5,[],2,7],[[[9,0,9,7],10,[3],0],[[7,3,6],5,[2],8,[4,5,6]],1,[9]]]
[[[[7,5],9],0],[1,[[8,3]],2,4,[[8,9,8]]],[[3,[2,2,1,5,4],[7,0],[9]],4,[[8],[7,9,10],[9,0,0,4],3,3],[6,1,4]],[[2,5,[2,10,7,0],4,2],[]],[8,[[7,5,3,5],[2,10,6,5,2]],[0,0,[],1]]]
[[[4,[]],8,[],4],[[2,[6,6,9,3,4],1],7,9,[[2,9,5,0]],5],[[1,[4,8,4],[6,7,9,9],8,9],2,6],[[],0]]
[[6,[6,[7,6],4,[4,8,10]],[],[6,[7,5,1,3,0]],[6]],[0,6,[[5,8,8],0],7],[[[2,3],7],0,5,4,6]]
[[[[8,4],0,5],[],7,6],[4,[],5,6],[1],[4]]
[[6,[1,[],[4,4,0],0],4,[1,0,5,0],8],[],[[7]],[],[[],9,5,3]]
[[[3,9,[7,0],[]],[],[]],[8,8,10,[[2,3,6,6,2]]],[],[[[6,6,1]],[[2],9],[4,8,5],[4,9,5,[4,9]]],[9,[[3],[2,6]]]]
[[[5,8,4,3,3],1]]
[[],[[6,[1],3],4,[0,[2,8],4]],[[0,[7],[],0,[0]]],[[[5,3]],[[],2],5,10],[[[2,4,4,9],[7]],[9],7]]
[[6,[6,[5,2,10,10],7,6],9],[8,6,10,[5,[4],[7,4,3]],[[6,8,8,6],[7]]],[[8,5]]]
[[9],[]]
[[],[],[[[1,1],0]],[[[10,6]],[[3,10],[10,0],4,7,[2,5,9,1,5]],[[6],8,7,[1,5,5,3],2],[6,[3],8,[1,0,7,8,8]],[[6,0],[],10,1]],[5]]
[[3,0]]
[[[[7,10],[7,9,1,6,6],[0,0,1],[4],7],6,2,1,3],[[5,8,[6,3,6,6,2]]],[4,[[1,4,5],[8,7,1],[9,7],7],[5,6],[[10,9,4],7,0,10,[2,0,1,9]],8]]
[[[],2,[[6,4,8,2,1],9,6,[4,10,6,7],[8,8,5,1]]]]
[[[],[[5]],4,0],[5]]
[[1,2,[2,1,[8,6,9,5]]],[],[[],[[1,10],4,[4],9,[4,10,6,8]],[5,[6,0]],4,9],[0,[[3,4],[5,0,10,9,4],0],[],[7,5,3],[7,[5],[]]],[8,6,7,[[5,4,6,2,9],[9],[],[6,2,1,4,10],4],[[3,8,3,2],[7,3,10,8],7]]]
[[10,[6,8],2,[[],2,10]],[]]
[[1,[8,[],10,[10,2,8,8,3]],[],0],[],[1]]
[[4,[[4,9]],[4,[],3]],[4,[0,6],7,[7,8,0,5]],[[8,5,[],3,[]],1,[[10],10]],[[2],2],[[1,4],7,8]]
[[8],[[4],[]],[[[3,2,1],[9,4,8],10],2]]
[[[[4,5,9],4,5,[4,8,9,8,8],9],[8,7]],[8,10,10]]
[[[[4,8,2,7],9,6,6],[4],[[6,9,4,4],8],0,[0,10,9]],[],[9]]
[[4,10],[1,1,2,[]],[1,[8,[]],[9,[]],[],5],[],[8,[],0,5,10]]
[[3,6,2,[[0,4,8,6,2],[1,10,1,5]],8],[[[2,4,9]],10,7,[5,1]],[[[1,7,9,7,7],3,3,10,1],[[3,5,0],2,[7,5]],4,[[9,7,10,6,2],[7,6,10,9,0],[7],5]]]
[[[6,9,[5,3,2,7]],[0,1,2,2],1,[6,[],1]],[[8,4],[[4,4,4,0,0],[9],[2],3,[8,3,1]]],[2,[]],[8,[]],[1,[[0]],4,5,[[3],10,[1,4,2]]]]
[[[]],[1,7,9,9,[7,8]],[],[[[2],10],2,1,[[2,4,10],[10,6],3,9],9]]
[[0,2,10],[[],3],[[[0,2,6,5],[5,4,4]],[],[],[],4],[[1,[2],8,[7,8,0,3,7]],7,7,1,[2,[8,3,1],[],[7,8,2,7]]]]

23
input/day13_example.txt Normal file
View File

@@ -0,0 +1,23 @@
[1,1,3,1,1]
[1,1,5,1,1]
[[1],[2,3,4]]
[[1],4]
[9]
[[8,7,6]]
[[4,4],4,4]
[[4,4],4,4,4]
[7,7,7,7]
[7,7,7]
[]
[3]
[[[]]]
[[]]
[1,[2,[3,[4,[5,6,7]]]],8,9]
[1,[2,[3,[4,[5,6,0]]]],8,9]

112
input/day14.txt Normal file
View File

@@ -0,0 +1,112 @@
481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
465,117 -> 465,120 -> 464,120 -> 464,123 -> 476,123 -> 476,120 -> 471,120 -> 471,117
451,104 -> 451,103 -> 451,104 -> 453,104 -> 453,97 -> 453,104 -> 455,104 -> 455,100 -> 455,104
501,15 -> 506,15
481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
474,73 -> 474,74 -> 486,74 -> 486,73
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54
491,29 -> 495,29
491,17 -> 496,17
474,36 -> 474,38 -> 468,38 -> 468,41 -> 482,41 -> 482,38 -> 478,38 -> 478,36
454,107 -> 454,110 -> 450,110 -> 450,114 -> 467,114 -> 467,110 -> 459,110 -> 459,107
462,84 -> 462,87 -> 455,87 -> 455,91 -> 469,91 -> 469,87 -> 466,87 -> 466,84
462,84 -> 462,87 -> 455,87 -> 455,91 -> 469,91 -> 469,87 -> 466,87 -> 466,84
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
477,33 -> 482,33 -> 482,32
485,29 -> 489,29
481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54
485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
465,117 -> 465,120 -> 464,120 -> 464,123 -> 476,123 -> 476,120 -> 471,120 -> 471,117
462,84 -> 462,87 -> 455,87 -> 455,91 -> 469,91 -> 469,87 -> 466,87 -> 466,84
481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54
474,36 -> 474,38 -> 468,38 -> 468,41 -> 482,41 -> 482,38 -> 478,38 -> 478,36
485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
477,59 -> 477,60 -> 495,60
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54
465,117 -> 465,120 -> 464,120 -> 464,123 -> 476,123 -> 476,120 -> 471,120 -> 471,117
465,117 -> 465,120 -> 464,120 -> 464,123 -> 476,123 -> 476,120 -> 471,120 -> 471,117
465,117 -> 465,120 -> 464,120 -> 464,123 -> 476,123 -> 476,120 -> 471,120 -> 471,117
451,104 -> 451,103 -> 451,104 -> 453,104 -> 453,97 -> 453,104 -> 455,104 -> 455,100 -> 455,104
477,140 -> 488,140
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
485,23 -> 489,23
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
497,65 -> 502,65
488,26 -> 492,26
451,104 -> 451,103 -> 451,104 -> 453,104 -> 453,97 -> 453,104 -> 455,104 -> 455,100 -> 455,104
479,29 -> 483,29
474,36 -> 474,38 -> 468,38 -> 468,41 -> 482,41 -> 482,38 -> 478,38 -> 478,36
454,107 -> 454,110 -> 450,110 -> 450,114 -> 467,114 -> 467,110 -> 459,110 -> 459,107
485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
454,107 -> 454,110 -> 450,110 -> 450,114 -> 467,114 -> 467,110 -> 459,110 -> 459,107
474,36 -> 474,38 -> 468,38 -> 468,41 -> 482,41 -> 482,38 -> 478,38 -> 478,36
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
498,17 -> 503,17
485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
474,36 -> 474,38 -> 468,38 -> 468,41 -> 482,41 -> 482,38 -> 478,38 -> 478,36
485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
488,20 -> 492,20
494,67 -> 499,67
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
462,84 -> 462,87 -> 455,87 -> 455,91 -> 469,91 -> 469,87 -> 466,87 -> 466,84
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
454,107 -> 454,110 -> 450,110 -> 450,114 -> 467,114 -> 467,110 -> 459,110 -> 459,107
485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
505,17 -> 510,17
487,67 -> 492,67
451,104 -> 451,103 -> 451,104 -> 453,104 -> 453,97 -> 453,104 -> 455,104 -> 455,100 -> 455,104
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
474,36 -> 474,38 -> 468,38 -> 468,41 -> 482,41 -> 482,38 -> 478,38 -> 478,36
490,65 -> 495,65
485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
478,81 -> 483,81
501,67 -> 506,67
484,69 -> 489,69
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
454,107 -> 454,110 -> 450,110 -> 450,114 -> 467,114 -> 467,110 -> 459,110 -> 459,107
462,84 -> 462,87 -> 455,87 -> 455,91 -> 469,91 -> 469,87 -> 466,87 -> 466,84
485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
497,29 -> 501,29
493,63 -> 498,63
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
494,26 -> 498,26
481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54
477,59 -> 477,60 -> 495,60
470,77 -> 475,77
451,104 -> 451,103 -> 451,104 -> 453,104 -> 453,97 -> 453,104 -> 455,104 -> 455,100 -> 455,104
497,13 -> 502,13
451,104 -> 451,103 -> 451,104 -> 453,104 -> 453,97 -> 453,104 -> 455,104 -> 455,100 -> 455,104
505,69 -> 510,69
474,73 -> 474,74 -> 486,74 -> 486,73
474,73 -> 474,74 -> 486,74 -> 486,73
467,79 -> 472,79
482,26 -> 486,26
465,117 -> 465,120 -> 464,120 -> 464,123 -> 476,123 -> 476,120 -> 471,120 -> 471,117
451,104 -> 451,103 -> 451,104 -> 453,104 -> 453,97 -> 453,104 -> 455,104 -> 455,100 -> 455,104
465,117 -> 465,120 -> 464,120 -> 464,123 -> 476,123 -> 476,120 -> 471,120 -> 471,117
454,107 -> 454,110 -> 450,110 -> 450,114 -> 467,114 -> 467,110 -> 459,110 -> 459,107
491,69 -> 496,69
474,36 -> 474,38 -> 468,38 -> 468,41 -> 482,41 -> 482,38 -> 478,38 -> 478,36
498,69 -> 503,69
464,81 -> 469,81
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
462,84 -> 462,87 -> 455,87 -> 455,91 -> 469,91 -> 469,87 -> 466,87 -> 466,84
491,23 -> 495,23
471,81 -> 476,81
477,33 -> 482,33 -> 482,32
451,104 -> 451,103 -> 451,104 -> 453,104 -> 453,97 -> 453,104 -> 455,104 -> 455,100 -> 455,104
485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
462,84 -> 462,87 -> 455,87 -> 455,91 -> 469,91 -> 469,87 -> 466,87 -> 466,84
481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
454,107 -> 454,110 -> 450,110 -> 450,114 -> 467,114 -> 467,110 -> 459,110 -> 459,107
494,15 -> 499,15
474,79 -> 479,79

2
input/day14_example.txt Normal file
View File

@@ -0,0 +1,2 @@
498,4 -> 498,6 -> 496,6
503,4 -> 502,4 -> 502,9 -> 494,9

31
input/day15.txt Normal file
View File

@@ -0,0 +1,31 @@
Sensor at x=3923513, y=2770279: closest beacon is at x=3866712, y=2438950
Sensor at x=675683, y=3223762: closest beacon is at x=-224297, y=2997209
Sensor at x=129453, y=2652332: closest beacon is at x=92656, y=2629486
Sensor at x=3906125, y=2154618: closest beacon is at x=3866712, y=2438950
Sensor at x=65723, y=902062: closest beacon is at x=92656, y=2629486
Sensor at x=3137156, y=2876347: closest beacon is at x=2907507, y=3100765
Sensor at x=32848, y=2676435: closest beacon is at x=92656, y=2629486
Sensor at x=3272472, y=3445147: closest beacon is at x=2907507, y=3100765
Sensor at x=2926008, y=128948: closest beacon is at x=3089364, y=-501737
Sensor at x=2975, y=2769838: closest beacon is at x=92656, y=2629486
Sensor at x=3540455, y=2469135: closest beacon is at x=3866712, y=2438950
Sensor at x=3674809, y=2062166: closest beacon is at x=3719980, y=2000000
Sensor at x=3693706, y=2027384: closest beacon is at x=3719980, y=2000000
Sensor at x=3869683, y=2291983: closest beacon is at x=3866712, y=2438950
Sensor at x=2666499, y=2796436: closest beacon is at x=2650643, y=2489479
Sensor at x=492, y=2601991: closest beacon is at x=92656, y=2629486
Sensor at x=2710282, y=3892347: closest beacon is at x=2907507, y=3100765
Sensor at x=28974, y=3971342: closest beacon is at x=-224297, y=2997209
Sensor at x=3990214, y=2399722: closest beacon is at x=3866712, y=2438950
Sensor at x=3853352, y=1009020: closest beacon is at x=3719980, y=2000000
Sensor at x=1231833, y=3999338: closest beacon is at x=1313797, y=4674300
Sensor at x=2083669, y=875035: closest beacon is at x=1369276, y=-160751
Sensor at x=1317274, y=2146819: closest beacon is at x=2650643, y=2489479
Sensor at x=3712875, y=2018770: closest beacon is at x=3719980, y=2000000
Sensor at x=963055, y=23644: closest beacon is at x=1369276, y=-160751
Sensor at x=3671967, y=64054: closest beacon is at x=3089364, y=-501737
Sensor at x=3109065, y=2222392: closest beacon is at x=2650643, y=2489479
Sensor at x=3218890, y=1517419: closest beacon is at x=3719980, y=2000000
Sensor at x=3856777, y=3987650: closest beacon is at x=4166706, y=3171774
Sensor at x=1912696, y=3392788: closest beacon is at x=2907507, y=3100765
Sensor at x=3597620, y=3100104: closest beacon is at x=4166706, y=3171774

14
input/day15_example.txt Normal file
View File

@@ -0,0 +1,14 @@
Sensor at x=2, y=18: closest beacon is at x=-2, y=15
Sensor at x=9, y=16: closest beacon is at x=10, y=16
Sensor at x=13, y=2: closest beacon is at x=15, y=3
Sensor at x=12, y=14: closest beacon is at x=10, y=16
Sensor at x=10, y=20: closest beacon is at x=10, y=16
Sensor at x=14, y=17: closest beacon is at x=10, y=16
Sensor at x=8, y=7: closest beacon is at x=2, y=10
Sensor at x=2, y=0: closest beacon is at x=2, y=10
Sensor at x=0, y=11: closest beacon is at x=2, y=10
Sensor at x=20, y=14: closest beacon is at x=25, y=17
Sensor at x=17, y=20: closest beacon is at x=21, y=22
Sensor at x=16, y=7: closest beacon is at x=15, y=3
Sensor at x=14, y=3: closest beacon is at x=15, y=3
Sensor at x=20, y=1: closest beacon is at x=15, y=3

59
input/day16.txt Normal file
View File

@@ -0,0 +1,59 @@
Valve FY has flow rate=0; tunnels lead to valves TG, CD
Valve EK has flow rate=12; tunnels lead to valves JE, VE, PJ, CS, IX
Valve NU has flow rate=0; tunnels lead to valves FG, HJ
Valve AY has flow rate=0; tunnels lead to valves EG, KR
Valve DH has flow rate=0; tunnels lead to valves FX, VW
Valve IX has flow rate=0; tunnels lead to valves VW, EK
Valve DZ has flow rate=0; tunnels lead to valves HT, FG
Valve YE has flow rate=0; tunnels lead to valves CI, MS
Valve OO has flow rate=0; tunnels lead to valves FX, CS
Valve SB has flow rate=0; tunnels lead to valves RR, AP
Valve HT has flow rate=4; tunnels lead to valves DZ, GA, CI, DE, JS
Valve MS has flow rate=11; tunnels lead to valves PJ, WG, CA, YE
Valve CD has flow rate=0; tunnels lead to valves UW, FY
Valve IZ has flow rate=0; tunnels lead to valves XF, AP
Valve JE has flow rate=0; tunnels lead to valves EK, TQ
Valve DN has flow rate=0; tunnels lead to valves KR, VE
Valve VW has flow rate=13; tunnels lead to valves DH, IX
Valve UH has flow rate=0; tunnels lead to valves MN, TQ
Valve TB has flow rate=0; tunnels lead to valves AP, BJ
Valve XT has flow rate=0; tunnels lead to valves TQ, UW
Valve RR has flow rate=0; tunnels lead to valves FG, SB
Valve BJ has flow rate=0; tunnels lead to valves TB, AA
Valve DE has flow rate=0; tunnels lead to valves HT, WI
Valve MT has flow rate=0; tunnels lead to valves EW, FG
Valve HJ has flow rate=0; tunnels lead to valves KS, NU
Valve WI has flow rate=3; tunnels lead to valves XF, DX, DE, EW
Valve KI has flow rate=0; tunnels lead to valves GW, TQ
Valve JS has flow rate=0; tunnels lead to valves UW, HT
Valve XF has flow rate=0; tunnels lead to valves WI, IZ
Valve VE has flow rate=0; tunnels lead to valves DN, EK
Valve CI has flow rate=0; tunnels lead to valves YE, HT
Valve GW has flow rate=0; tunnels lead to valves EG, KI
Valve TQ has flow rate=14; tunnels lead to valves WG, KI, JE, UH, XT
Valve AA has flow rate=0; tunnels lead to valves BJ, CF, DX, RB, AQ
Valve EW has flow rate=0; tunnels lead to valves MT, WI
Valve UW has flow rate=6; tunnels lead to valves XT, CD, NZ, JS
Valve MN has flow rate=0; tunnels lead to valves KR, UH
Valve FG has flow rate=8; tunnels lead to valves NU, RR, MT, MK, DZ
Valve RB has flow rate=0; tunnels lead to valves NZ, AA
Valve AQ has flow rate=0; tunnels lead to valves AA, MK
Valve WG has flow rate=0; tunnels lead to valves TQ, MS
Valve YW has flow rate=0; tunnels lead to valves CA, KR
Valve CA has flow rate=0; tunnels lead to valves YW, MS
Valve PJ has flow rate=0; tunnels lead to valves MS, EK
Valve EG has flow rate=23; tunnels lead to valves AY, GW
Valve NC has flow rate=0; tunnels lead to valves TG, KS
Valve WY has flow rate=16; tunnel leads to valve VQ
Valve AP has flow rate=7; tunnels lead to valves IZ, VQ, TB, SB
Valve CF has flow rate=0; tunnels lead to valves GA, AA
Valve FX has flow rate=20; tunnels lead to valves DH, OO
Valve NZ has flow rate=0; tunnels lead to valves RB, UW
Valve KS has flow rate=19; tunnels lead to valves NC, HJ
Valve VQ has flow rate=0; tunnels lead to valves WY, AP
Valve TG has flow rate=17; tunnels lead to valves NC, FY
Valve GA has flow rate=0; tunnels lead to valves CF, HT
Valve CS has flow rate=0; tunnels lead to valves OO, EK
Valve MK has flow rate=0; tunnels lead to valves AQ, FG
Valve KR has flow rate=18; tunnels lead to valves MN, DN, YW, AY
Valve DX has flow rate=0; tunnels lead to valves AA, WI

10
input/day16_example.txt Normal file
View File

@@ -0,0 +1,10 @@
Valve AA has flow rate=0; tunnels lead to valves DD, II, BB
Valve BB has flow rate=13; tunnels lead to valves CC, AA
Valve CC has flow rate=2; tunnels lead to valves DD, BB
Valve DD has flow rate=20; tunnels lead to valves CC, AA, EE
Valve EE has flow rate=3; tunnels lead to valves FF, DD
Valve FF has flow rate=0; tunnels lead to valves EE, GG
Valve GG has flow rate=0; tunnels lead to valves FF, HH
Valve HH has flow rate=22; tunnel leads to valve GG
Valve II has flow rate=0; tunnels lead to valves AA, JJ
Valve JJ has flow rate=21; tunnel leads to valve II

1
input/day17.txt Normal file

File diff suppressed because one or more lines are too long

1
input/day17_example.txt Normal file
View File

@@ -0,0 +1 @@
>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>

2881
input/day18.txt Normal file

File diff suppressed because it is too large Load Diff

13
input/day18_example.txt Normal file
View File

@@ -0,0 +1,13 @@
2,2,2
1,2,2
3,2,2
2,1,2
2,3,2
2,2,1
2,2,3
2,2,4
2,2,6
1,2,5
3,2,5
2,1,5
2,3,5

2500
input/day2.txt Normal file

File diff suppressed because it is too large Load Diff

3
input/day2_example.txt Normal file
View File

@@ -0,0 +1,3 @@
A Y
B X
C Z

300
input/day3.txt Normal file
View File

@@ -0,0 +1,300 @@
BzRmmzZHzVBzgVQmZLPtqqffPqWqJmPLlL
hpvvTDcrCjhpcrvcGGhfLHMlLtMCqflNlWPJlJ
hGjhncHhGnhbTHczBBZVVSbRwgSgRV
rWVQjPQQjGRWNSrWrPjcptwBpqqJBtJBBcZgMdtq
zzmmpzfTCFpTlMlJJwBgMlqMBt
TvLszpbhhTLmsnRQPDQGWDWRvQSR
zGzvLlGlQHLGBQZlhBWhdjRdmdWRcjPj
fTJNfTfNSRWPhjdjfj
pbsbVVnpSnbVTprnbqqrzvLLgQlGLPLHll
ZCCCsWvNvmsCsCmZLZmgMLRpQMhwQRpQRfphfprpTfpM
tlncPjzlndctbzcPPBcjwDphwrfGGDffbDRpDTGG
cdqnddwzqjNVWVLZZLZq
DTLbDbRrlQbwhhNrmmfwdt
zzMJMzjCjJJjvLjMPJpcgPpzfhHdfqWcqddwtwfqdttcNtdN
pJCzVpCvDZBLsVRQ
STzBBbJzRRBZBRTqCCsfZLtNNLClCsfh
jsQnnQjjHcvQFrcPwCmtLCNlvDfftfff
sGFscMQQMMpqzqbMbd
QlNDWGsjQjgQllWQsbtzqTJczTJcbFmmFJJP
MhLrhgLVndRmzJFzVqqJqP
pSLnMdwhwdRZRSwhLZwLhdGWQjlsgWjNQWWSvgBsWDlj
THjSRFSddTjdBTcPLcVVvVBw
GzWnWfndWfznDfsnsBsPVwVwPPLL
zNflzJWqqzQDdSStHNZNpFFtbj
FSzDmsFSFlDlBzqVjqHHjHHpVgHLbp
rTrTtTQQntRQnQJQgggHZttVgHLBLhZL
WTJJRRQCRRJTRdBCRdvRNDFSWFMPmDlPPSsNPSzS
WQldlMtMVQgVMQHnDGbHGGnRnQmD
rqcZPrCFjmHlbGjZ
zSScchqwchBzTzFzhhSlcCwNtdVWWJgsVdMtWNgNVWTJTd
lMZqjMWllrTTspjprWWSSwgWNSVNDmWGVwFwgN
cdCCdLHcnndHJnmCRntLBnRzDvFNtNDVzgSgwDgFNVzFVv
BRLcCCJCmJdcRhfjPPZphrlrPqlZ
GdGqcrrZGDrvDJJqJHcBvmFFgmFMMgMgBtMLTssLmF
NbPVPDlljPmTmsTj
VfQDhflCCRWdcrQwJvvnJv
RLcWgLCqqPQLcqZwzHgwmmrmmtgwTw
DhbhNrMpnJSDJwVTHmmTVnTTVj
lrsvblMDlcWcfQPQ
PVldlphHwGwJJGdjZZWsRbbsGsNWrWQbNbQR
SqcDvTmDLtfmSmtqppfqzTgTQBrRQsbCFWbNNFQFBBrRbLNb
MgtmTgtfpqVlnVddZMwV
BdmfmPBPSbSNdGSdvWrwcZrccZPPcZnH
jzzLsjsMRlQQVHwswvvZrCHrrT
VqhzVFzplFlpLwpMphLRQQVRmSqgbdGtNJBmNSmgGbtggSgt
DHVpNZjdZjFZWVFHpvFvzmlRzPnlfznFRz
lrTBTsBwwMbrrwLPPfwGmGzvRf
scrtMhMCtJBBBclbHdHttWZWDSqDSjHj
wzqsPmqsbsfqBwPMNRMMZcZmFFNtZM
CgCnhlvvLJgcRFNNBdCpWM
QnQrVgHSvVHjbjTGBbbTHb
HdrVrdqFDdZVmHgRmDRFHMnTdTssMGnLnPJLbPTbCs
SczlScjwcNzplNzQSSfjwQSrTGGsbTsnTCnGTMCMLMGGbN
wQlfjrhfhQFHqZhRZRtD
RsfJDGJvzPNcjpddSWJWMd
LLCbBCwCrCmVVnrmhQFmbVhdcdlWpjZzSpMdWSpcWczSBj
rrLCbTwnHTvzvNGT
wPhPhbCqqSCrtJDlqvlrJr
RVVZddLFRZZcQLvJJtzptlgPJp
TVQRZGVncFdTGWZdCNShHhfPNwwsWPwb
dzLVzPSgrgDDDCMSMLLPwFmdTTcsvmwNwjNsHcFF
nWBGntQfGNGBflWBBqlpRQGbWFvjwsbsFswbvTHjjbmHTc
tBNJBnGBflQnDPJrPhDgrPVg
VtWztWtqpqzWpWzqjNRjNpWTmrrmrSbnmJwSJwnMPrCSJVwM
sDHsBDhBdsBZGcHvLHDLhhCSnRSwCJMZrPbmnMbJSCSR
ccLRhgsLBdRsdHNTFFNNgqTglqzF
hztlmDhPhgPlPNNgmZMCbmwwQjcwjjwMjVCd
RSJRrRqnqQJFqvnTGrHCcHHCCHHbHHMcMvdM
qGJsnQTRsStsftPlhPNl
BFFBLPRCwsLwhlPlRmhcGGrbmmGjfNTTnp
VJMVpzgqggJnrjmjNcMjmT
VqdSZtQgZvtdzqHqHtVZdVQpCDWWFdwlRPDpWPPBCswlWD
fCWCsjPzcbzwRSzVTzhhDLqvdg
TmJtrNJrBLSLJqgS
ptNTQFHrZlnpFPwsWMbRjCpcjR
nJmQNCmbmlllmbClbfMLjMFqbGBsdLFq
ZcgTWcTnMqqMTBqF
tPgctSnPctZZgDWzZgQHwNmHlhlmzlQhlJlw
ZpTCwpffdslvgShCBhqhRz
FDMPnNFNmBPzvRPRBg
nNgMrnnDGjDmJMmnFdZTTsdsrZrslcwcQr
pTmczpCldcdDDnPttpvWSqbpJf
jgjRZMGHhGLgQrjvPWzPJgJvzStbbq
LGNLLNBBzcDFCBwwFC
nJTTqnrNvTzNMzzNfqrTPrJnwpwPpZpsHccZVsBRpcVHwpcp
bgDhgbghLWmFmStctVpZtBCVCCpfZp
LLSgLGSjggFGbSSbmMnrvqvzjfzTNrJrqM
RRpDmmPMTjwfGmJQgQ
WsNscdnvvdVZFVnnrZbjjflwljlbzfGFjQjq
NnLZsNnrrVVVcvdBLTPCPCRMwhPMBMPhCt
lbVvzngGJnVbJHpHtHNPpdSQvc
TsMBswFZsWMWBZMNwPtNNtRNHcNpSQ
CcZCTrZDsjZTsTsshWhrWrTnfgbLDfJzVVLVVlgfnzfVGV
JzTTRtJRZWmWjrMHCT
DDFGlLGcGlSSSLsFGBspPBmNMBHMghmWNmWjWCmWtH
nSSpnbsGlLDnpPsSSspFtVvffRQdVzqvvbqdfVQwRz
sMhzszlHHDsWbthHDqsbJjpLNtmjVJmVLLVLVLBp
nrTPrGwfPLdprzJzdL
wgPQcTGGzgccwCgnRwgRChFhlWSDqWWQMWhssSsMQl
NSNmwtpSpCpvMphCsr
PHcRGPLJMrsvzsqG
QHjbnRMcfbPbQZmlZgZlgBBQ
cPRPbhQjbQRdtPQdLqLHqzFZjCFCqLjC
mmfsnnwrfvwrfSNZFzHHLDCFNlLlqDlN
wsmrwswwGTffMrBnmQttJtcMZQQtPJPbZc
MvBPDDRRdnnvHPCHZLHZsFLL
rmJcbVqbcjWwWjQHLzTZFTHSzFrpsz
cmwllVqqGJbVVVmmqbQcmgRnRvGhGfgDRDZBBBvRdd
nMvMhMnvhnbTZWSSZgHmGJDFmmNDzBmbNmdGBN
rCsPLRCssRjrLLsrLlwRVrcNJQfDQfdBmmfNBGJNzmDPfB
CRjCpLltgtJgJJWq
jshCzJpjzTPpmCWvSlpfwHfSWglf
LQMMNMnHtDtLVRvwwgRWlldgWD
qHVrQNHVMFQtrrBBQMBcrrZsZbzCZhbbJZJsmmsmFPTC
JZQZnsQNMqTngZqJBVfBfPPVBNrwvfPw
SSmDstFjpDpCszDjcLLhrPVlGlrGGVBwrvwVPt
FSssFcLjFjbmFFCzjLcFLRDnMJnTHRnZZTdWqZZWnMnRnZ
GbHRHpldwGMpWhHpCMBlCbRdVSLhnqJLSrDPLPPLPDqVDrhh
gvjWWQvgZFtQFFNqLnVnDnSJzzztDD
ZccccfTsffHdWWdRWwsw
ClCtbHMlnnPPlszV
gSDWSLgWQWQJJNWqgtQjPsnfcdVcLVdVdzfzVzff
WQgqtFQgDgQSFqJhqhSJvNDRrZMZHwHMCbZhTpZbGHMTMG
pZJZlCQtHFhPfdNfCh
zcmLSVczwcMcLDNFHdLPhPWH
szvVVnBmnTGQtHTQ
RVVCNDlNGzlGZqHGHWqWhGqQwH
ZFLFTmpLvvmSqsbb
TrfpBfJpJMlnnNfNZD
qHHlDClHhltMqQsHDhHslGznwdTnzzwDGSdfnwGnwG
mZRNcNcLLPNPBFFbbPmLmbZFSCVfJJTVndVfSwnRzznfTwCS
CcCWFbbBLCWtgWgHjghqvv
TjbzlnlFmfqCFFVVCRWr
PhMcLpPDtMLpwPDvLPJbMhSgVCGqggVqQgCqCgCgSWvv
btbZbNZhJDJJhDtwtsTTTmBzzBBmlNlmHj
FqhjWtqlqmmsnFPTCvMCQMTTCjQd
pfffRfLpgrgGgzrNVzzpGVzRCdMCPJbwwcVMbQPCJVMVdbww
DGGDZRGrHggzSsFQnnWShmtH
vtHVVMMrvVMVrSHvLgvlHcZFCnRCZcccZtRRZfJFCJ
rdDjGsdTQDcNZfdncCRR
rBDsTwBbjbmbbQswswPhqVmmSvpVhlvvqMhHhh
vGBLrqMNvqSLBvvrNbllLHfwStWWtFttccjtRtjtcj
MhCDJmhMDzmcRRcjzWfztH
ZQDmDhVVCQbBVdVNMvvv
ptCtCzhWPWptnhVzzpGZbZTjTjVjFGjVFgVl
fQswRRffmRqZlgrqqFjjSgGg
HwsQDNNsDsmRLLHmffsfvHptBnhtzCvhWpZWBdhnMdCh
RlHzzTqczBPfbnvcpB
wVtNwpSZstppwwMsZhsdnLvnbtBBmbnLFFdnmF
WNQJMVWsZWwGJWhhSNrQzlgHrDCgQRHpCHrl
RrZWpJZRrZpdTGstlchLGGlLMd
NqjDPCQPnQCSvtMzSLhhjM
nQVQDDDDfwBwNCVCNVFNpWpgJgrRTmLTmTmgRTWF
SHMcrMHpcjGcjSrMMbvSvvSvwFTLJwJNtFGFWJNtDLFTLfWN
zqRnPfzQCRzqsmRPzznhszzLtLwQwwFTgWWLDLgWFTwTNQ
qVPZmRZhsCZPhZlRCqRRRCbfpccMBjvMVjdHjjMjSvdf
VVQdHwBZLVltlddtBczhrzvGcWWFRwgsFG
TDTTTqqTSSqjqnmTmPqPPmTmGhRszvsrzsjRsccgzrRzgWGF
DpJPqpWqHbZpllpt
cCSCFsnnZFnscDtNdJFJtJtdmb
VgBqBsqRrHtNdzmNrt
BGLLVVjRBsqPBfsGwPsMfSSZCSfTZTZQpSphfS
plCHCHlgglHHGpNbtngNrDvBDpfQDBQfZDfWZVrr
mTmMLhRfwhsLPQvQZDMZQBQWMB
cwsssmqRTFFfFgtbCtGl
LQPPrCPnMZwqtRMn
cWTSlJWlcplJdDTdGdpDlGcGgqmtwwZtqRrNRRmRdNZqmgNq
GSJcJSjsjTpsvWGWBHLLvVVBBBrFrzVz
NVPCSPMNDSNFVSWCsJJJmpGmZZGLLcpZLHGGtsHt
fwzlBBqghqvzqqlDrHbpHjZHmGZbLZrHLb
dnBgnDqQvwRnSnnFMFMP
BCbPsFFwCRHmDSBmWnvDDj
phhZVzdpVfQZphhZpRhSVnjmrcvvnrWtDrvWDS
TfQJMfLphMhJdfdzpQJRTPbwHHNlgbGwsTGgCP
ttWLlnnvnNnBBtlTqWlpvpndQdZsQQFssFDdsRFdVdRNFQ
jSgrScrbGZSGrrCGsFVMssFsPPFcDDMV
bzSmJbfCZCbzLwllflwqtvvw
zmFTJwFLPmzLztmjDzTJwfNrdFNrFppBSNRGNGdbrpBR
gqlhWQgsZMsvqMlMMvsvqsNlLbcdppbrRpdbbcSrrbbr
vssCgVgCsggZQZCgsnsqWgWvfJPDLwffwTPPmzTnjTPmPmwJ
SpcRTPQLBLWpNNzjmmwwwRrR
tGlfvGhfnbDlbqlChnfFMrwsmwNssTMHMHjFwv
ZlhtCtffCdWcZWZVVT
jTTCcWHWJNgCGTzTmnzrmnGn
BwRRbFvtvvQmJJFMpMJr
ZBBwLvqbBZsRsbVsZSqbcZdJjHHjhfPCJfJfHhgc
VrnDSvvrLrfTdTLGfdRp
zcJzmcFcHGfdGmWTVd
tHsMhwPVctccHFHFcbSDbbPjnNbBnbvBQB
QttWQwLTnLnWTtnffnLQSBFVjNvBjBFNgMdCsVWsjv
pDqcmmRPHqgVBddjvN
DcclzbcbPbJLnNTfnw
plRcpsZDGlGZvWvMCNcLtttq
SrfrwSjSVrSjwbmSrHzmHJCQQPQzqttNNQJMzJtqMW
wSHVnfHfWwwHWFVfSnfgmmRsslFZZDBBGZsZsDTdGRTp
qSFQSgQNgQBrBHHcrW
VTmjVJLTwlTmwTVmsMJMVlJmPvcbvvbCBbGBPjGvBbBGWcbb
DnJTZwmnZRhnpqNdWt
dTVHjZLLZDVCfVHtLDDjQbscjWbSJMJPjsbWWb
FnqrnmzzFllmsWwtsFtQMMFc
lmqzzzngGmlNNBqGllzlBNRvptHHpTCHpDLpgDZdgvHvDD
sdRZQbCfZTSTdlfTZCffccWPHPPcPPwLwctRnLWn
BBJDzFVgCDrCJrqDJJhqJVVMLPHwcctFwcWHHGLcwGwGHnWc
ghpJgqqjCZbQdZpd
tbcpzbHSszcHBgqHGZgJJJhhww
jfvdvRTffQQrrFCRFTnGwJRqNRZVpJGZLZggLh
nQTjTnMndlTdQFMvnrClCnpzmzDtbbmBbcPSzzlmmtzP
BqBqTCSTcqHsJHHM
WWPGVPLtzVgWtjWPGzVjzVGcbDhPsRbDcsbJwNRswRDRss
VQfWjfLFGWLjdFfVzTZZpJTpnmlTrSQlBl
jLNsZjqSHCsGdsmpsm
MvnVFzWMwMVWzfnVDwfBMfnnrCtdtPmPlRrdrJCJrtPDrrPD
zznfFWwMfMfFMwVTMQFnQjhjgjSZhCNbLSTcHHgbbC
GGtssttVmvnnGNMQrrVzgwVrCWMz
FdhfhhcCDhHLfzclZMcrwcQMZM
HHqqCBhHSSpdmjGqmGjtjtjj
bbQLtGMQQtQRQtrDtGprrrbCqwplZhhqSqmdwvdzqqqhSmpS
FsJjJBfnsJcFcFfjVPjWBzldqhqnlZZZzzhmnSvSnm
JPcFfFWjFHJVVsVjPVscsDlLNRHGDbLRMRCDNrCGbG
JdMdlMRJnTwdvcjv
CDLHbNSzzLFgHvnTjrswBNBTNT
QgbvzSFQmZQPQQRW
NTBrNzrpjjjCwGbB
FRbQlcvFvcRQQlRsMlRRRZjwCqMwjmjwJZdLJmjCZC
cVPPQcvlWDNhrbPz
VdbVtbbZJdtJVVdDVZmTLqqTSQvNLjjDShhvSG
zplpnBnFpnrrlghGNpLNqHvqvjNj
cWncllnlPFWzcMwtWWtsVLVRmJWCds
ShLSTnZnTSttTSbLQdfSZTMwcDHwwcHnJvDHnlnlclMM
NmPMsssRrVwjDclHJwwR
gNNMWGzNmqGdtfZTbGGb
sWNNlRHnmJtmntJt
brbbBTbbFbCbqqGgBTrCfmQVVZfSSQQSVtJZSrVZ
bbFqvbDvvGGLGbCCtBGDLbLlcPNHhhccPNcdPPchlsdR
DCFvDvnCnNfMBmMMslDZML
SQQQJHwpSgJSJHQWSWHqJWWbmcBBBLLTsmhhTcZbMhmlshcb
RJRgpJHssgwSQHRqsQPGGjjtNCrrFvvnFjjPrP
mThmsgjzTPjMpcvtWP
GNNBVqVGNZbbNbNqqZQVNVNbWcpdtMCcpCtMWCdCPpQccmpp
VSmNrmmbBfZVlsrssrLTRhRhTn
TdmCvLDCpTRNTdFbbWnnSWCfhjbbzn
GrrMsPVGcQHBGMbhjjSgWfHHDbjb
BPBVqqrQPsQqwrrmmmJdRLDDqFRplT
fpDDJljDlCfDTjprjrfbddWthCSCtdPPQFhSSSWW
HsLZgMGbgBBsNzMvGbdVtVQzFRQSthhFPdtP
sMBmGBmbNvLHGMnrDppTcJmcjpqljf
ptSpSJQqpbNGGDDhcMWrlNHcZZWWls
zRLRRRjvvgjHMMsMpWpc
vmCPLCgwvwdnCzmvLbpTbVQqJJPbJPpTVq
TJCfhhJVFffrJJQQllNWcvWhwvWD
GPSGjjpLslBbpLpLqqqPDvdwvwvNzQWGzDDNdzGN
msbRjbpPqsRpHnlZrmJlnVHT
GGfFsCCTvGDsfTTrhsCMMzptZJMdpdgtrpdMcV
LBlwBHPSqjwwlVggHpnMZcVHMt
ZlZZlBbRPGGTGfmRsD
CtCjbVvzQQZTWVdd
MlSqWlmsmGBSHJHTDFHZ
pcqsmsplwsqclwRtRWgtRnPPvb
zCrzCrsdjrhGDCFqGDjRRPtpWfQQcpfQZcCZPp
VSVwVMgLHHLTwMDTMMVnbWPRZQRcRQPptWnpbZcb
MNBBBlSMvLVwTlVTFdNdhNhFsqsGDrzm
rBLWTwTThWwVVDTwHBsZZWppvpGtpptppmRvFFFMFMfL
qPPNCCbqcbcNqbqQjjJQqzjRpptmlpMGmMlJtftmtFHpMt
QnCgzzQbbQqPcPQnncbdQdnVTwDssZgrShBTVgZZsBSDHT
PFGJFqnfqmPgFJQPWdbLdpDRhbphWjDm
rclNHvcrzCNwrWRprjdMMMph
wsZHwZNvRRQsQqBV
LqlGCPlPLTCPqqQlpqLlWfBfWgcHNRJRfWNsncGH
VVtdwVtDDdVmhrdwSBmjbdzNHgfgJnNnsSnHsNffHgRsgR
wVzhbjmDbDrwjdbztFDDthMCvqPppZQBQLZQTqTvFTvZ
BnQnQFwRmRwmwdBSFDFnmSDVLCJTCTppVVmGLVTCLcgVpC
ZlWvhvZjNrbNvqjNhlfPfqjCGHrsspggTpVLpsJCpcJVgg
vPzNvqjWhqFzGSnRGMDG
wZnMZzzZZchDRtVsqtCtwV
WmWpWWmPPWrmrmBmWrTlTFPNVqVCRSDCQHcqVTtTqsSDSTSD
PrppdFlWWlfrWmpWFffrdcGjJJGggnnhZGdLLgGGndvz
FShHNmNhRhNJmBnQBQJrmP
VTgzDTjwfffwzDvwlcczzVSJbQlBQSWBWCnPJPbJWWbC
tzSVtzvSvGSRZqqFMNtpRR
hPZhGDZpnCGtDhznjmLmdJffdNzJ
glwsSrQwBvLdgLzdcj
QsRbHllzzlHwHlBszWlTBFbpDPMhbPDVGpGFpPtFPp
SRjStRDctgDSBzLvPvNrDhmPLr
QqTHGTPJmmHmhNmH
TGQZsTqFnQZCJTPsnJnZQMjVRBVtcVRSVRBlwccSCtBS
bbsNsvsvnNPTRRllbblLqhtQCqQSLCGGHSqHNC
wFpzFgqVzqVJWFDwqJDmSBBmHBHhShLQhCGSBCGH
MJVpFMqgwMqRRbZsMbZMrP
PPdDhvNDQdmgQPZmQVHHtHGGWVGbffWGvs
MMLCTRRLlLclTLRMRLCwMLHWVctbVVHWWWFfVjVGsFWW
MRSMMlpTJRqClBCRqBDnzqgQPnqgznZPZqbP
MrMNPNNpjvdprWtrpMsthqBfqlnfqcGhVBqFRcnqFG
QbDgSSQbgSDDmDVmlqSCRllRcFqnqfBl
QVJbVmwwDQbzVTgbppNJNMWNjNNPrdpM
WwJJNbtHfpLpVgZZPVFhZh
vmmqlDvRvRfqBSrlzmmMjRBhcVhQVZhVghCQQQQTcTrPTP
jSqMmqRzMDDjvqlBqsBMBmmwGNJwJnwLNfbGwddswnJtJH
RLgRmRggbvbzzPmmRNmzsQWFtSGNtwSNQnntFwnnCw
pDBrBHpHhlldphHBHhJVFSLnWWFJttCtQSttSS
hfHrpphHBppfTvmzgMmbLbgf

6
input/day3_example.txt Normal file
View File

@@ -0,0 +1,6 @@
vJrwpWtwJgWrhcsFMMfFFhFp
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
PmmdzqPrVvPwwTWBwg
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
ttgJtRGJQctTZtZT
CrZsJsPPZsGzwwsLwLmpwMDw

1000
input/day4.txt Normal file

File diff suppressed because it is too large Load Diff

6
input/day4_example.txt Normal file
View File

@@ -0,0 +1,6 @@
2-4,6-8
2-3,4-5
5-7,7-9
2-8,3-7
6-6,4-6
2-6,4-8

513
input/day5.txt Normal file
View File

@@ -0,0 +1,513 @@
[H] [Z] [J]
[L] [W] [B] [G] [R]
[R] [G] [S] [J] [H] [Q]
[F] [N] [T] [J] [P] [R] [F]
[B] [C] [M] [R] [Q] [F] [G] [P]
[C] [D] [F] [D] [D] [D] [T] [M] [G]
[J] [C] [J] [J] [C] [L] [Z] [V] [B]
[M] [Z] [H] [P] [N] [W] [P] [L] [C]
1 2 3 4 5 6 7 8 9
move 3 from 2 to 1
move 8 from 6 to 4
move 4 from 8 to 2
move 3 from 1 to 9
move 1 from 2 to 4
move 3 from 7 to 5
move 3 from 9 to 2
move 3 from 3 to 5
move 1 from 5 to 1
move 5 from 1 to 8
move 2 from 1 to 8
move 3 from 7 to 3
move 1 from 8 to 9
move 6 from 9 to 8
move 3 from 8 to 7
move 7 from 8 to 9
move 2 from 5 to 9
move 2 from 2 to 9
move 3 from 3 to 7
move 2 from 8 to 3
move 7 from 4 to 8
move 3 from 4 to 1
move 4 from 8 to 6
move 4 from 6 to 1
move 8 from 1 to 2
move 1 from 1 to 4
move 3 from 5 to 1
move 8 from 9 to 8
move 4 from 3 to 1
move 5 from 5 to 3
move 2 from 7 to 1
move 1 from 7 to 4
move 1 from 7 to 2
move 3 from 3 to 5
move 3 from 9 to 1
move 9 from 8 to 1
move 2 from 9 to 7
move 1 from 8 to 5
move 4 from 5 to 3
move 1 from 3 to 4
move 1 from 9 to 6
move 1 from 6 to 9
move 7 from 4 to 9
move 1 from 7 to 3
move 1 from 8 to 2
move 8 from 2 to 1
move 4 from 3 to 5
move 2 from 9 to 6
move 2 from 6 to 2
move 2 from 4 to 9
move 8 from 9 to 2
move 3 from 7 to 9
move 1 from 3 to 5
move 2 from 3 to 8
move 9 from 2 to 1
move 1 from 8 to 7
move 4 from 2 to 9
move 4 from 5 to 6
move 1 from 8 to 9
move 27 from 1 to 2
move 1 from 6 to 4
move 3 from 6 to 4
move 7 from 9 to 8
move 4 from 4 to 1
move 9 from 2 to 6
move 2 from 1 to 9
move 6 from 1 to 3
move 1 from 5 to 3
move 3 from 3 to 5
move 3 from 5 to 3
move 3 from 3 to 1
move 4 from 6 to 7
move 3 from 9 to 2
move 1 from 6 to 4
move 4 from 3 to 5
move 3 from 6 to 5
move 1 from 6 to 2
move 15 from 2 to 3
move 5 from 5 to 9
move 13 from 3 to 9
move 2 from 5 to 7
move 1 from 4 to 2
move 3 from 3 to 7
move 11 from 2 to 7
move 7 from 9 to 5
move 3 from 5 to 7
move 6 from 8 to 9
move 4 from 1 to 2
move 6 from 1 to 6
move 3 from 5 to 1
move 1 from 8 to 2
move 4 from 2 to 9
move 1 from 5 to 7
move 6 from 7 to 6
move 18 from 7 to 5
move 1 from 7 to 1
move 8 from 9 to 5
move 1 from 2 to 6
move 15 from 5 to 6
move 6 from 5 to 3
move 4 from 3 to 6
move 26 from 6 to 5
move 2 from 1 to 7
move 4 from 5 to 9
move 8 from 5 to 7
move 3 from 7 to 9
move 14 from 9 to 8
move 7 from 5 to 2
move 4 from 2 to 1
move 5 from 1 to 9
move 12 from 5 to 3
move 5 from 8 to 5
move 14 from 3 to 2
move 1 from 5 to 2
move 10 from 2 to 6
move 7 from 9 to 6
move 6 from 8 to 6
move 1 from 2 to 7
move 2 from 9 to 7
move 2 from 8 to 6
move 6 from 2 to 7
move 1 from 1 to 8
move 15 from 6 to 2
move 1 from 6 to 9
move 1 from 5 to 9
move 1 from 9 to 6
move 2 from 2 to 4
move 3 from 9 to 5
move 5 from 5 to 3
move 3 from 3 to 6
move 6 from 2 to 7
move 1 from 5 to 9
move 8 from 6 to 9
move 2 from 6 to 7
move 3 from 2 to 4
move 9 from 6 to 7
move 17 from 7 to 5
move 1 from 8 to 4
move 7 from 9 to 3
move 12 from 5 to 8
move 3 from 5 to 2
move 4 from 7 to 8
move 2 from 5 to 7
move 1 from 7 to 9
move 8 from 3 to 7
move 17 from 7 to 5
move 3 from 2 to 5
move 1 from 3 to 6
move 10 from 5 to 4
move 5 from 2 to 7
move 1 from 4 to 2
move 3 from 9 to 8
move 7 from 7 to 2
move 5 from 5 to 1
move 14 from 4 to 9
move 3 from 9 to 8
move 1 from 6 to 9
move 2 from 1 to 4
move 2 from 8 to 5
move 16 from 8 to 6
move 1 from 6 to 2
move 11 from 9 to 2
move 2 from 7 to 5
move 1 from 1 to 6
move 11 from 2 to 9
move 4 from 2 to 8
move 9 from 5 to 3
move 1 from 4 to 2
move 2 from 1 to 8
move 1 from 2 to 9
move 2 from 4 to 3
move 8 from 6 to 9
move 16 from 9 to 3
move 16 from 3 to 2
move 17 from 2 to 6
move 1 from 9 to 3
move 1 from 2 to 5
move 1 from 9 to 4
move 3 from 2 to 8
move 1 from 9 to 1
move 1 from 9 to 6
move 7 from 3 to 1
move 5 from 3 to 5
move 3 from 8 to 3
move 2 from 3 to 4
move 6 from 8 to 4
move 7 from 6 to 4
move 3 from 6 to 7
move 3 from 8 to 9
move 3 from 5 to 2
move 3 from 1 to 3
move 1 from 4 to 8
move 3 from 5 to 1
move 13 from 4 to 7
move 14 from 6 to 7
move 6 from 1 to 9
move 3 from 9 to 6
move 1 from 8 to 7
move 1 from 8 to 7
move 20 from 7 to 3
move 1 from 8 to 9
move 1 from 1 to 9
move 1 from 1 to 5
move 1 from 4 to 6
move 14 from 3 to 9
move 1 from 2 to 6
move 3 from 7 to 6
move 6 from 3 to 2
move 1 from 3 to 8
move 2 from 7 to 3
move 7 from 6 to 3
move 12 from 3 to 1
move 1 from 8 to 2
move 1 from 4 to 9
move 1 from 5 to 6
move 1 from 6 to 4
move 1 from 4 to 2
move 2 from 2 to 3
move 16 from 9 to 7
move 3 from 6 to 7
move 6 from 9 to 4
move 4 from 4 to 7
move 6 from 1 to 8
move 2 from 3 to 6
move 3 from 1 to 9
move 3 from 2 to 3
move 3 from 3 to 8
move 5 from 2 to 8
move 2 from 7 to 8
move 3 from 1 to 5
move 1 from 4 to 3
move 2 from 9 to 8
move 1 from 6 to 8
move 2 from 9 to 1
move 15 from 7 to 1
move 1 from 6 to 5
move 10 from 1 to 5
move 1 from 4 to 1
move 2 from 1 to 6
move 9 from 7 to 8
move 27 from 8 to 3
move 1 from 6 to 1
move 1 from 8 to 5
move 5 from 5 to 6
move 12 from 3 to 1
move 3 from 7 to 1
move 7 from 5 to 1
move 1 from 6 to 4
move 3 from 6 to 9
move 1 from 4 to 2
move 2 from 6 to 5
move 1 from 7 to 6
move 1 from 9 to 2
move 2 from 5 to 6
move 2 from 6 to 5
move 3 from 1 to 3
move 19 from 3 to 1
move 2 from 2 to 9
move 42 from 1 to 7
move 4 from 9 to 7
move 1 from 6 to 8
move 1 from 8 to 5
move 2 from 1 to 9
move 3 from 5 to 7
move 27 from 7 to 4
move 1 from 1 to 4
move 3 from 9 to 2
move 18 from 4 to 9
move 2 from 5 to 3
move 1 from 7 to 1
move 2 from 3 to 4
move 8 from 7 to 5
move 15 from 9 to 3
move 1 from 9 to 7
move 3 from 7 to 2
move 2 from 7 to 2
move 2 from 5 to 3
move 1 from 1 to 5
move 1 from 9 to 1
move 1 from 3 to 1
move 1 from 4 to 3
move 8 from 7 to 3
move 8 from 2 to 4
move 1 from 9 to 6
move 23 from 3 to 9
move 1 from 9 to 6
move 2 from 6 to 8
move 1 from 8 to 6
move 1 from 5 to 3
move 7 from 4 to 8
move 7 from 5 to 7
move 2 from 8 to 3
move 1 from 1 to 8
move 3 from 7 to 4
move 5 from 4 to 3
move 1 from 1 to 8
move 3 from 3 to 1
move 8 from 9 to 7
move 3 from 8 to 4
move 1 from 6 to 2
move 5 from 8 to 7
move 6 from 3 to 1
move 1 from 2 to 9
move 7 from 7 to 9
move 4 from 1 to 9
move 2 from 4 to 2
move 1 from 4 to 9
move 1 from 1 to 6
move 8 from 4 to 8
move 4 from 1 to 5
move 3 from 5 to 2
move 2 from 2 to 5
move 2 from 5 to 6
move 1 from 3 to 7
move 2 from 6 to 4
move 1 from 5 to 7
move 1 from 6 to 9
move 1 from 4 to 1
move 6 from 9 to 2
move 8 from 9 to 7
move 4 from 7 to 3
move 4 from 8 to 3
move 3 from 8 to 3
move 8 from 3 to 5
move 1 from 1 to 7
move 11 from 9 to 7
move 5 from 2 to 7
move 1 from 8 to 1
move 3 from 2 to 3
move 1 from 1 to 4
move 1 from 2 to 5
move 20 from 7 to 8
move 7 from 7 to 9
move 4 from 4 to 7
move 3 from 9 to 4
move 5 from 7 to 4
move 7 from 4 to 7
move 4 from 9 to 2
move 1 from 4 to 3
move 4 from 3 to 5
move 2 from 5 to 8
move 4 from 5 to 2
move 5 from 2 to 6
move 2 from 6 to 3
move 22 from 8 to 5
move 13 from 7 to 9
move 11 from 9 to 3
move 2 from 6 to 8
move 7 from 3 to 1
move 18 from 5 to 2
move 1 from 6 to 4
move 1 from 4 to 9
move 2 from 8 to 5
move 2 from 9 to 1
move 9 from 3 to 1
move 4 from 5 to 6
move 2 from 6 to 7
move 3 from 9 to 5
move 10 from 5 to 8
move 6 from 8 to 7
move 3 from 8 to 1
move 6 from 2 to 3
move 1 from 9 to 6
move 5 from 3 to 4
move 4 from 1 to 4
move 17 from 1 to 5
move 12 from 2 to 7
move 1 from 3 to 6
move 16 from 5 to 8
move 3 from 5 to 6
move 9 from 8 to 3
move 8 from 8 to 4
move 7 from 4 to 1
move 5 from 1 to 4
move 4 from 3 to 7
move 14 from 7 to 3
move 6 from 4 to 8
move 9 from 7 to 4
move 5 from 6 to 1
move 1 from 7 to 1
move 1 from 6 to 7
move 16 from 4 to 5
move 1 from 4 to 2
move 1 from 7 to 5
move 2 from 1 to 7
move 2 from 7 to 4
move 4 from 1 to 6
move 13 from 5 to 6
move 5 from 6 to 3
move 22 from 3 to 2
move 1 from 4 to 7
move 4 from 5 to 4
move 1 from 7 to 6
move 5 from 8 to 5
move 2 from 3 to 1
move 13 from 6 to 1
move 6 from 1 to 4
move 1 from 8 to 1
move 6 from 1 to 4
move 1 from 5 to 4
move 7 from 4 to 7
move 3 from 1 to 5
move 2 from 5 to 7
move 5 from 5 to 1
move 8 from 7 to 4
move 1 from 6 to 4
move 1 from 7 to 4
move 9 from 2 to 7
move 8 from 7 to 6
move 5 from 6 to 4
move 1 from 7 to 4
move 2 from 4 to 9
move 2 from 6 to 1
move 8 from 2 to 6
move 9 from 1 to 8
move 9 from 6 to 2
move 1 from 1 to 8
move 6 from 8 to 4
move 2 from 9 to 7
move 2 from 7 to 9
move 15 from 2 to 8
move 18 from 4 to 2
move 14 from 4 to 5
move 10 from 2 to 4
move 9 from 2 to 6
move 1 from 9 to 3
move 1 from 3 to 1
move 6 from 5 to 8
move 3 from 4 to 9
move 2 from 2 to 1
move 1 from 1 to 6
move 3 from 9 to 7
move 22 from 8 to 6
move 1 from 8 to 9
move 2 from 1 to 5
move 5 from 5 to 4
move 2 from 5 to 8
move 2 from 8 to 7
move 1 from 9 to 7
move 1 from 5 to 8
move 1 from 9 to 8
move 15 from 6 to 4
move 2 from 5 to 2
move 11 from 4 to 6
move 5 from 4 to 1
move 5 from 4 to 2
move 2 from 1 to 5
move 6 from 2 to 8
move 11 from 6 to 3
move 12 from 6 to 8
move 1 from 3 to 9
move 3 from 3 to 2
move 6 from 4 to 2
move 2 from 5 to 8
move 5 from 7 to 2
move 11 from 8 to 4
move 1 from 7 to 4
move 1 from 9 to 6
move 7 from 2 to 1
move 3 from 6 to 5
move 2 from 5 to 3
move 1 from 5 to 9
move 3 from 4 to 9
move 4 from 9 to 1
move 4 from 3 to 6
move 3 from 4 to 8
move 3 from 8 to 9
move 2 from 8 to 2
move 9 from 8 to 7
move 2 from 3 to 1
move 2 from 3 to 2
move 1 from 3 to 6
move 2 from 9 to 1
move 8 from 7 to 5
move 7 from 2 to 7
move 2 from 8 to 9
move 4 from 6 to 5
move 13 from 1 to 5
move 4 from 1 to 8
move 3 from 9 to 3
move 12 from 5 to 9
move 3 from 8 to 9
move 1 from 8 to 4
move 3 from 2 to 7
move 3 from 3 to 7
move 1 from 9 to 2
move 4 from 6 to 4
move 6 from 5 to 6
move 2 from 7 to 3
move 2 from 2 to 1
move 5 from 6 to 5
move 1 from 1 to 7
move 9 from 5 to 4
move 10 from 9 to 6
move 1 from 2 to 6
move 12 from 7 to 6
move 1 from 7 to 4
move 23 from 6 to 1
move 10 from 4 to 3
move 16 from 1 to 5
move 5 from 1 to 2
move 6 from 3 to 7
move 5 from 4 to 8

9
input/day5_example.txt Normal file
View File

@@ -0,0 +1,9 @@
[D]
[N] [C]
[Z] [M] [P]
1 2 3
move 1 from 2 to 1
move 3 from 1 to 3
move 2 from 2 to 1
move 1 from 1 to 2

1
input/day6.txt Normal file
View File

@@ -0,0 +1 @@
qzbzwwghwhwdhdqhhbhfbfsstggdsssgzgdzzdbbbzmbzzvlldppjnjlltwtsszwswgssjnsjnnfqfzqqjzjfjmfmwfmfhfnnmdnmnllbzzlbzlzflldzdbzbsbdddpgdppzhphhjjtccjgcgrgjgcjgjjsbjbffsgsqqrsqqgppgmgcmmrdrqdqbqmmctchcgcdgdwdwcdcjcfjccmpmlpllqqpmpllhfhchppwwdmdhdphpvprrhwhgwwlrwlwggwlwqqnmqnqrrbbzdzwddqzznllzwlljsscqqtlltppqspswsttlrttnvvvwllfslsjsfjssnqnbbbvgvlltjtltjljmljjfgfbggcbgbmbjjvwjvjgvgzvvzddrjdddrwrlrlgldlhlwwcddbsbbtwwcssrnndvvsbsnbsbmbnmngnpgpphfhzhshllltqtppnrrzpzrpzzrttmbmssbrbmbsmsnspnsncscwwmjwmwdmwmrmvmqvqvjqvvnrrtntwwwwsrwrnwnrwwwlslrlhrllvpvhppdpprrgzrgzggqmqgmgvghhsmhhjljfflrflfrlrzzbjjqmmmcncddvhhzjjqzzjfzzbssjqqtsqtqccmttdhttmwtmtffspplhlrhrdhhhpghgrhrchhmgmqgqlglssvnnwrrrrqqbmmpgmpmdmmljlflzzjttqntqqcnqccrvcczffclffmvfvwvmvnvsvnvffczzljzztdtztcztctbtppmrprqprpbbhlhphphhvppvdvmddvcctvvjbvvpmpbpnpllvclvlqlwqqpcpffdwdsdttzftfddbrrgsrgsgvgpgjpggfvgfvvtqtnnscssmnnfqnnblnnjlnlbbjrrmmpgmgnnqbbcjbcjbbmjjljsjrsjrsrwrgwgpgqgccqppfdpdssffgdgwddcvdvzzpttjlttmwwhnnlntncttfvfwvvwrvrwwlhlwlvwvzvpvfpvvsbslblrlssjddwhwfhwffqjfjzfjfmfrrvsrrlbrrdfdmdwmddpnpfnpfnfppczpprzprpvpjjtltptvvrgvvsttflfvfqqhnnbmnbmmpsptpdpttrbbhjbbdnntppbsbmssgccfdfflppbcpbblclrlhrhttffvqqvvnpnmpnnrbnnhqnqrrwvwrrbvbffcvctcjcwwmzmvvtdvtvbtblbvlbvlvdvdrdsrdrprllnzznzhhcjjsgglfglgrlrwwfcfzfjzfztfztzggffjftjffcbfbhhwfwnnbssrpsppmllszstztwwgbwgbgtbgggztgztzwtztbbrffznndhdmmqggssjfssrgssbnsndnqnvqvqvjqvqttlctltvlttrzrqrrdprddpqqvppvddgmdddpldllnvvjdjcjdjvvznzqqbgqbgbpbnbvvdjvvsnndsdjjjhnhggrnnrvrvlvqllqhhsbhssvvlhlssgqgmqqcscpsspsrpsrpspvvdmvdvwwcjwwvhwvvmzvzvfvccfzczjccscbcrcjrrrsgrsspnsntsnnrnwwhdwwzhzbbwgwcgglvlttqrttvrrgprrljlddnttqrqffgdfgdgzzhghthhmdmsmtsshhsfhhgzgvzgzwzffvlffzjjrttsdddbldljlvjvjttwdwzzrbblwbbgmbmgmbggbdbsbqqwzzgnzgzczpzfztftbtwbtbsttrwrfrssbrrdqdjqdqppdsswrwttmgmllqbqnnpspjjzjjmbbsddgjgbjggqqlgqgmgdmmwcmwcmwwsddvgvpphmhqmmlvlpvlpltllphhcshhrsrgsgzssspjspplgghvvwhwgwssbhshvvscshhbccbtcbcvvmnndsdwwbzbffhmmbppfjppbsblbtlltggzczdczdzjdjpjtppwdwlwqwnwjnnvttmcmzzqccvfcvvmrmzmwmhmttgdgmsrlddnbgqfbbmrpdglpbtdqpmctzjrffvvqnltcqlfddwqhvjpzhczzwhsmjtrpgsdtqlcqsljsjzqwhcfwttgghsjqhzqlgjzgrtgttwblpprbppcpzsbntrwwmvfvbmjjrjwjqcjhnstmvwzrbnjpzznnctrtllzhtwttntjqwjnfspzccqpjlzbncgbjjjztbgfmzflzsqflflcrfhtlsgbdfdbtwwqfdrqhzmmqdqthwzwqqqzddfvbwhnqwqtgwhtzlqqpwhcjhglcmmncvfcmqdwnzzmjbflwjrcjzwcblftzrpdcjzcmtzccjbsqmcnfmbsmrvlhswnmrqdczvvzzcnffgljdbtlvjgrqttcjhjmcdllnvhcdpztqghfgvjcqmqvmdwhcgrtwpjlmjfbqmnjnbvvjczcwfcrhcgzmsvmjlplcpghnqtpzddnwtmrwmqwbttsnlngszfbnslqvlbzbfzqnjpdvcdpmjpmmjhvzwwgzfjfqwbqwrznhsdpjgsvzlsrtlmhjrfnwrmljlqzwnfnsmqtzfsldwrgmbrrvcmmmdmwflwnvpwsrrstmffwbtwqmjzdnzbwmqfrfdgsmhzhprdsgsqtljqhtdqmvnzlwhrrqqftbvnhmjnzvmbdqpjhzjnszgcfptfcmthpfcvfvdmwdswzfgwjblglfbpfvvwrmnzlcvtgqbcrhfqlffrznnhbtbwdwdldthbhdsqvnghpqdlvpfmzhjbtdhfmrdzpghtppmvddnphcnnczvznwzrvtcwvpslhrhmhzbzqtjqjvdpwncjbqdnwwpnfblqtqdwwqncbvtsncfhgncrprvhvzppwjfpdmtdrmtfcqdmdhwzrhpnrvspfbzhsvlpwzgrrhnrllhmpcdfcqdhcnphlffpbfmbsznmvfdgshbsjcjjvhqqfpmjgpdpcrglbqdrnqmftqtnwcsgqzdwntfplsnlhdbdmcgwfldzzgmzjsdnldbnlnhjqhpmnsljsbhrglhjbbrmlhrmjnvzhnlvnfpdzfzwwdpzwhnqhlbqhrgfmvzpctdvscqbgznzdsvvvvcjnmbzlvsptslmqnggqjcmgvtgbnrzlmzqzmtdfvhjqqcpvbngmngjvrtcfvsmbvthvhmdcfhthmnjcvsvmsbwsjtmrwshspcsmnhvzqvglntngbmgtdngbvvcjrznpdmmsssljnnqjwwfzgwtlfqqpsqghjgrghldrcdmcqvqdjsfrfrnlnvltpfjhmcclwbsdcbmvmlnwltztfggzmrtnsczwvqgpqtwffmphprgrmjlnftlgqjvrngbcndlmrblmvcjsdhdcmtgsztjttpbgcznfcgdwfwdnqmrrjgdgrgshjfjqrbsjdhblvrqhlfphnbdslrjszcnpfhhwrfhhdvqbjpsmzznzbtbsgcggtctfbsrscvzlplfhlwjlrmzhbwjqhffdhrwcdctwvttwqzbdtrhdhdvtgvdbzjtqvdgbpwtzqqqnljztgpbjjcrgdgmrrsfvngcdbgzvcfpdppbgfrmmdnqdvtlwwglmghjwfjjrwjfnwgwdplbmlfljhsmshwvvvtdnvfcbbwplwnvzfcjwgsrrlctpsrhprttcjgcmfsjggfvbbljsbjtzplvjdwnwgsgvvntjwdwdqbwmtnnlgdcmfcccnwnrjlqtznjhdzwfpbzhjdmwwpcmffcwsnpfhmgqgwwnvpmqvrdfhlqtghrrbggdmtvpqgqsspmchnrqnrmqlddnspcdrwqpvclhrvjtzhpvthpltwqqbrdfjtnwncwrmdqszdpmmdzmjwjvqnfszvbchfdvwzhtrfgfhfmgwprdpqgmbfntsqztvqmtjvgbsjvzsbhfznbbzrstqbrrmqdjcztmfpnwbmvtccmvlhtvmgfdzcchbccrzznscbdwrdtnpslvcqmgrrvwhnjgjdpvbfgsdtdcmhpnwfwnnntqjqnwzfwnhsrjbhtqtlncvsnhgvtntfwldqfzztcdctsscfdmtnmdqgqgwmtqhlmswtqrvqbchdwtjsdlqjvfjdtmzlvrzwvfprzvjzrrfn

1
input/day6_example.txt Normal file
View File

@@ -0,0 +1 @@
mjqjpqmgbljsphdztnvjfqwrcgsmlb

1
input/day6_example2.txt Normal file
View File

@@ -0,0 +1 @@
bvwbjplbgvbhsrlpgdmjqwftvncz

1
input/day6_example3.txt Normal file
View File

@@ -0,0 +1 @@
nppdvjthqldpwncqszvftbrmjlhg

1089
input/day7.txt Normal file

File diff suppressed because it is too large Load Diff

23
input/day7_example.txt Normal file
View File

@@ -0,0 +1,23 @@
$ cd /
$ ls
dir a
14848514 b.txt
8504156 c.dat
dir d
$ cd a
$ ls
dir e
29116 f
2557 g
62596 h.lst
$ cd e
$ ls
584 i
$ cd ..
$ cd ..
$ cd d
$ ls
4060174 j
8033020 d.log
5626152 d.ext
7214296 k

99
input/day8.txt Normal file
View File

@@ -0,0 +1,99 @@
131102031022411233124153000402524132243245422402002121234345453535321113450535302430144220243210033
210030011133442111442145434004231353202400601331445042106230540242340014332243105022302133441101011
201302044230110302341330012044051130055046354663404014033243655520410125432425532024143403330032232
210303103204034020151134514120046162664361356330261302226530654326452225134535222440444443410101130
021310332113230035544033314213544254421233042151226601345516101654005025035545035333140023212102212
220140301231432453044535532323066560244052510442522465306425021511260132313424322110345422300411332
103013240142011245425311001542145655516105003352455141424412415222100145355043202120423034202120403
314103304322445325255534650156565303510461206034672755654106425161056213552330050310445352323213402
243430113305332145305400366156126611120357766767667531265661631510215134106224240155532142014202020
344044011305120500223111213354316112154646744635155132374774442641061323024416155344101304242413014
210001340311202411013214565026366577746364242672331436164352252445110000414212215202321411504422400
001030344254033552521244445311464542617442572153467545366653342426676363026234406640015310103000111
123004351234415456501532136126535464236513321263256111263236363424471316560661104630322511135024314
243444301010130503501065440067414335615573435151661324666436573133444251763541254166141130405531401
301333054435342646553265615125271561444757162666247563564724434377461174733226461663122454115301022
313333115034033032461152521554721624436564356545874583322623147632365263427634464233444421123452114
434441324240044110131332722354256132333522657745624745724323263635746316535120231124164652542245541
020013043025261604606066777717675561448878622688884553346728286853164272251311263510330645452212040
225405401530036646635664123763243188844858643328244728344354343287813231363771264361344552214134043
444013205241103641532477643143435563484567276423226466226434857664377176552653732212146514023430325
235444033555452351644577725572733823223422438445886848336238372267477767173715122521014452405344110
022222500504231055646646534633724257646568684735488756288737857786232268232655151633323530463425151
412102254551210100735562467375656382325864659764674335534465738553284326347575542675435335613154320
202304233522424114651647265763556544532358373769578879369385574555386666783363244334360301665155255
400235422666401262236327746826382638573848989589958764697958946664233887757677777164614616200413302
413211350405512664175712772346875822558798479568486643787487763573785465875336133314155235265153544
412112650043523364626154522655787734369585968849884958638795656846722736645822544573361050432101002
040151232015244534675233447267274466883354564933934639355395374945757347634723116764261154205631025
053511566106055552733487866435428673379594867554589579573759867856436754328455243315565403452366550
402441261342655261311663778728277373873487457867467678497684746937764462833722831553364205512206541
401560462601374333165687778774966694644847875679669694796453568554383377242683474675113640166014002
245431640441276372256235534578677594558499466595957658548574676357557473852362834636123725105611001
140325466637452621767678632447835458776865576466546548894776445753494487385328422645157221103664133
253440020224216474125727543697395446885846849486744757588954688447585337348374328857266123303626032
522360463154354425644334277863647479565896696996775849896649575745746557964548536537415577142552050
402351634474624167474857559553949899894799879644496759587555549787974996993634823833353424316316042
414140006077774645384224689955449865767867876647679668857949995687773539976755288762714471242526254
032242255462211412258653836566746764685477947565799869886769647489953985859547537844111624535631156
241646435225236526565228495485878686676559956669957869665758947786478934645637286347261114426145563
512215356337536722737525437473645894558456658976958699776986594778559569864962457825216143344215016
322625244746336257345525895486859454957989669585766859958667775649875866654855238722721513671212305
044600535247217686848675385837958687859856856865869679556868995579875763985654342678317263541605554
430320424173321746345287493633447589689698796959599858768985856685945573454358785585284454656334025
232026013361136674773333583555589876467998965697988698997966777468454666855894285223681327425505166
354332536226232536453676489538955896788985786767799998876886965757444485955456462568453444425456521
016154147271566788586769489946847647867857556667888797775895768988576579978395627453672756147414326
463454162462563733454784956555887864475857986666689767978699985965647598648778424456255355723655466
021001072567511684363734454496747746785559778677966778897776558954997794766634668356686124441524525
234605435156344755776859794859864756797769876888968689787579998559856654953446748662382433262116262
030666223611312438477278595797684446757958596668696976678757986797965899875556377876865147373650335
245046541536764737224694794369857786796969878968689968797958865856864988656773724353268427134461620
265066622261247542566375373496969757789659688887789988798956868878668565665794723743572475263161166
422245453144736877586299945587888888767997586686876996879786788998867747683776448657845662361505315
210351625547722865278485967857788659769765586689699988976775596895984657648869967252632246417436621
141004614422116428487735355858968995455599988699767679796595755979678769336598642342483777532511004
533362561377622426377686383498446767487997987976886899988585956569875694463399574483265564264622314
456163507723454276868637866355647859456998677889778989889969998954684957667483346372863274465245646
030644251421316636263479555487765499846688669798677798668968599994746869757876565775844144255106462
510135336311735337436764935399965949469956999767696876898578576969547984463869253278467243311543030
466524526117724766584368696865578944888566858759789698699778689456856774865884337672615767136523254
254110631463762333865539645936466585858655857657659586556989585456479575455563845762632676471423233
562434653773762262468663566995359545869887797866957588766855659579865834576343438465353323754454240
112066240641477224475587449447989749648974898785555767886979489566644938356955638286634724441631625
330443313353347713822865768695549469777556759786896565758769775757475566378642426537546311412140051
040065350247621726448577745444446666557767548565886798996759654466566755698345662584625446342463260
330536625076531353825376746548345995946649894668956867559446757474398638639624464682343654214032311
530251120326432762683357643388548466489576697998869899549584977659746869733837538723573545213461105
255356015316555756432734833639785737748988987965669458947565666746847669548847254811135737404226043
454354550123557227257454326863468487794448666674495859497588676766356646553276336612337324063553462
144340525160235512164242786385886753536996894579865659848488534457479379684556654637432614663443613
305316054035171372138527636345993984687638579458566486795488343446895753373444445772513544116215313
543055400456632262131666826787874497775946535566897457748984377394483964377555447341647525602315351
412546632444321676125286364645444448636496473746537653585847369856994564666782226566264742530022340
044233444612165527122563533685825959374668734768758953663536843946435452847223172365277563546141540
340030454102343151253211647666557354334348799955649644348678747758347287426221514313112316663165454
011020051334501654522762446268866586389746656669789443696677886848328248582411315534364123146250501
305413453334030464614216442476475733478966457359966737766476988846463467574624373625606065562242335
034215112203016427473135421577622448726677469646375339565639944867546662453345521671403262325021214
132210543140531252452317342463454885388566728556533533877354846446665578244115675240031664244524501
201140051634662646614612354714626525722377445426842485568735384726362363654642742661135663265002510
025011353243541235316415314133578633558245363633567643474723462264656821637416273202656565602515322
121540314222665224011553176734444466578255884322834667368468238484254776573264467333645106223352155
233134314541654641520531771126551528746557387438726348653238283875537147555615754035502132555444301
424510000505066600303343337525732714723283556468834467558232644677477536766533666404266150255104242
041433452552331436330125237255465337374884372735358382327855756643676341445255435062065033314033212
141025211241314363206626056633223121353133645783244374622462256271457773212200625560321421020100213
224101010422251643133220616233621223532466525114754865347141165612135423157400060111225313054434032
004040052225144131342364656025377722754756627621767354111575442445436452322335541156250421012350243
043322120521041516241540153402233524371432721521521276133447761312616332565246332656140342120501432
200232013354533102134562014146621725413251577715376671261144475237357064044430050234040121014304202
011420212054031401033241133121106532344212712314572323662643147467661343340045361122545415103011124
102223410325432324313243446514164004156475643254444557477323147134144354265066260422110450012141414
031411112311321035125554420606413626050373327654774373667767140605036115333551650220414205214132024
210204032200320524351051665115025502044361230251377575706601164652440120455165201034431244211004301
331131223444034015143142430503454436431142412165246111316106164251614223504203533022310134023423343
120300034332102045152234220042512653414152606411234665213124345325420542210314454221024423343223220
200230420442302210441134513143532363040132120013505235035543064245636124512505054404233133430423011
000202411243122420140310501035333204626352325031215630345206242502134153000033354044334042221310101
111301302244231442013332415144033330063530643146335532313306033656410450441505505240142210004121122

5
input/day8_example.txt Normal file
View File

@@ -0,0 +1,5 @@
30373
25512
65332
33549
35390

2000
input/day9.txt Normal file

File diff suppressed because it is too large Load Diff

8
input/day9_example.txt Normal file
View File

@@ -0,0 +1,8 @@
R 4
U 4
L 3
D 1
R 4
D 1
L 5
R 2

8
input/day9_example2.txt Normal file
View File

@@ -0,0 +1,8 @@
R 5
U 8
L 8
D 3
R 17
D 10
L 25
U 20

96
src/day10.rs Normal file
View File

@@ -0,0 +1,96 @@
use crate::day_solver::DaySolver;
use super::util;
pub struct Day10 {
instructions: Vec<Instruction>
}
impl Day10 {
pub fn create() -> Self {
// let lines = util::read_file("input/day10_example.txt");
let lines = util::read_file("input/day10.txt");
// Put the input into the day struct
return Day10 {
instructions: lines.iter()
.map(|s| {
if s == "noop" {
Instruction::Noop
} else if s.starts_with("addx") {
Instruction::Addx(s.split_whitespace().last().unwrap().parse::<i32>().unwrap())
} else {
panic!("Unknown instruction {}", s)
}
})
.collect(),
}
}
fn execute<F>(&self, mut cycle_fun: F) where F: FnMut(&i32, &i32) {
let mut x: i32 = 1;
let mut cycle = 1;
for instr in &self.instructions {
for _ in 0..instr.cycles() {
cycle_fun(&cycle, &x);
cycle += 1;
}
if let Instruction::Addx(addx) = instr {
x += addx;
}
}
}
}
impl DaySolver for Day10 {
fn solve_part1(&mut self) -> String {
let mut interesting_cycle_sum = 0;
self.execute(|cycle, x| {
if (cycle + 20) % 40 == 0 {
// println!("{} * {} = {}", x, cycle, x * cycle);
interesting_cycle_sum += x * cycle;
}
});
return interesting_cycle_sum.to_string();
}
fn solve_part2(&mut self) -> String {
let mut res = String::from("\n");
self.execute(|cycle, x| {
if x.abs_diff((cycle - 1) % 40) <= 1 {
res += "#";
} else {
res += "."
}
if cycle % 40 == 0 {
res += "\n";
}
});
return res;
}
}
#[derive(Debug, Clone)]
enum Instruction {
Noop,
Addx(i32)
}
impl Instruction {
fn cycles(&self) -> u8 {
match self {
Self::Addx(_) => 2,
_ => 1
}
}
}

176
src/day11.rs Normal file
View File

@@ -0,0 +1,176 @@
use crate::day_solver::DaySolver;
use super::util;
pub struct Day11 {
monkeys: Vec<Monkey>
}
impl Day11 {
pub fn create() -> Self {
// let lines = util::read_file("input/day11_example.txt");
let lines = util::read_file("input/day11.txt");
let mut lines_it = lines.iter();
let mut monkeys = Vec::new();
while let Some(line) = lines_it.next() {
if line.starts_with("Monkey") {
// Let's parse the whole monkey
let start_items_line = lines_it.next().unwrap();
assert!(start_items_line.starts_with(" Starting items: "));
let items: Vec<u64> = (&start_items_line[" Starting items: ".len()..])
.split(", ").filter_map(|s| s.parse::<u64>().ok()).collect();
let operation_line = lines_it.next().unwrap();
assert!(operation_line.starts_with(" Operation: new = "));
let mut operation_split = (&operation_line[" Operation: new = ".len()..]).split_whitespace();
let operation = Operation {
arg1: OperationVar::parse(operation_split.next().unwrap()),
op: operation_split.next().unwrap().chars().next().unwrap(),
arg2: OperationVar::parse(operation_split.next().unwrap())
};
let test_line = lines_it.next().unwrap();
assert!(test_line.starts_with(" Test: divisible by "));
let check_divisor = (&test_line[" Test: divisible by ".len()..]).parse::<u64>().unwrap();
let if_true_line = lines_it.next().unwrap();
assert!(if_true_line.starts_with(" If true: throw to monkey "));
let if_true_throw_to_monkey = (&if_true_line[" If true: throw to monkey ".len()..]).parse::<usize>().unwrap();
let if_false_line = lines_it.next().unwrap();
assert!(if_false_line.starts_with(" If false: throw to monkey "));
let if_false_throw_to_monkey = (&if_false_line[" If false: throw to monkey ".len()..]).parse::<usize>().unwrap();
monkeys.push(Monkey {
items,
operation,
test: MonkeyTest { check_divisor, if_true_throw_to_monkey, if_false_throw_to_monkey }
})
}
}
// Put the input into the day struct
return Day11 {
monkeys
}
}
fn play_monkey_game_and_calculate_monkey_business<F>(&mut self, rounds: u32, mut worry_level_modifier: F) -> u64
where F: FnMut(&u64, &Monkey) -> u64 {
let mut monkey_items: Vec<Vec<u64>> = self.monkeys.iter()
.map(|m| m.items.to_owned()).collect();
let mut monkey_inspection_counts: Vec<usize> = vec![0; self.monkeys.len()];
for _round in 0..rounds {
let mut monkey_id = 0;
for monkey in &self.monkeys {
for i in 0..monkey_items[monkey_id].len() {
let item = &monkey_items[monkey_id][i];
let item_worry_level = worry_level_modifier(item, monkey);
if item_worry_level % monkey.test.check_divisor == 0 {
monkey_items[monkey.test.if_true_throw_to_monkey].push(item_worry_level);
} else {
monkey_items[monkey.test.if_false_throw_to_monkey].push(item_worry_level);
}
}
monkey_inspection_counts[monkey_id] += monkey_items[monkey_id].len();
monkey_items[monkey_id].clear();
monkey_id += 1;
}
// println!("After round {}, monkey items: ", _round);
// for (i, monkey_items) in monkey_items.iter().enumerate() {
// println!("Monkey {}: {:?}", i, monkey_items);
// }
}
monkey_inspection_counts.sort_by_cached_key(|k| usize::MAX - k);
monkey_inspection_counts[0] as u64 * monkey_inspection_counts[1] as u64
}
}
impl DaySolver for Day11 {
fn solve_part1(&mut self) -> String {
let monkey_business = self.play_monkey_game_and_calculate_monkey_business(20,
|item, monkey| (monkey.operation.execute(item)) / 3);
return monkey_business.to_string();
}
fn solve_part2(&mut self) -> String {
let normalizer = self.monkeys.iter().map(|m| m.test.check_divisor)
.reduce(|a, b| a * b).unwrap();
let monkey_business = self.play_monkey_game_and_calculate_monkey_business(10000,
|item, monkey| monkey.operation.execute(item) % normalizer);
return monkey_business.to_string();
}
}
#[derive(Debug, Clone)]
struct Monkey {
items: Vec<u64>,
operation: Operation,
test: MonkeyTest
}
#[derive(Debug, Clone)]
struct Operation {
op: char,
arg1: OperationVar,
arg2: OperationVar
}
#[derive(Debug, Clone)]
enum OperationVar {
Old,
Num(u64)
}
impl OperationVar {
fn concrete<'a>(&'a self, old: &'a u64) -> &'a u64 {
match self {
OperationVar::Old => old,
OperationVar::Num(x) => x
}
}
fn parse(str: &str) -> Self {
if str == "old" {
OperationVar::Old
} else {
OperationVar::Num(str.parse().unwrap())
}
}
}
impl Operation {
fn execute(&self, old: &u64) -> u64 {
let arg1 = self.arg1.concrete(old);
let arg2 = self.arg2.concrete(old);
match self.op {
'*' => arg1 * arg2,
'+' => arg1 + arg2,
_ => panic!("Unsupported operation: {}", self.op)
}
}
}
#[derive(Debug, Clone)]
struct MonkeyTest {
check_divisor: u64,
if_true_throw_to_monkey: usize,
if_false_throw_to_monkey: usize
}

113
src/day12.rs Normal file
View File

@@ -0,0 +1,113 @@
use crate::day_solver::DaySolver;
use crate::util::Grid;
use super::util;
pub struct Day12 {
map: Grid<u8>,
start: (usize, usize),
end: (usize, usize)
}
impl Day12 {
pub fn create() -> Self {
// let lines = util::read_file("input/day12_example.txt");
let lines = util::read_file("input/day12.txt");
let map_1d = lines.join("");
let width = lines[0].len();
let s_idx = map_1d.find("S").unwrap();
let e_idx = map_1d.find("E").unwrap();
// Put the input into the day struct
return Day12 {
map: Grid {
width,
data: map_1d.chars().map(|c| match c {
'S' => 0u8,
'E' => 'z' as u8 - 'a' as u8,
_ => c as u8 - 'a' as u8
})
.collect()
},
start: (s_idx % width, s_idx / width),
end: (e_idx % width, e_idx / width)
}
}
fn can_reach(&self, from: &u8, to: &u8) -> bool {
to < from || to - from <= 1
}
fn try_add_path_to_neighbor(&self, cur_pos: usize, target_pos: usize, dists: &mut Vec<usize>, positions_to_check: &mut Vec<usize>, prev_idx: &mut Vec<Option<usize>>) {
let cur_dist = dists[cur_pos];
let cur_height = self.map.data[cur_pos];
if self.can_reach(&cur_height, &self.map.data[target_pos]) && dists[target_pos] > cur_dist + 1 {
dists[target_pos] = cur_dist + 1;
positions_to_check.push(target_pos);
prev_idx[target_pos] = Some(cur_pos);
}
}
fn calculate_distance_to_end(&self, starting_positions: Vec<usize>) -> usize {
let mut dists = vec![usize::MAX; self.map.data.len()];
let mut prev_idx: Vec<Option<usize>> = vec![None; self.map.data.len()];
for start_idx in &starting_positions {
dists[*start_idx] = 0;
}
let mut positions_to_check = starting_positions.to_owned();
while !positions_to_check.is_empty() {
positions_to_check.sort_by_key(|p| usize::MAX - dists[*p]);
let cur_pos = positions_to_check.pop().unwrap();
// Check for each neighbor, if it's accessible, and if moving from here to the neighbor is shorter
// move up
if cur_pos >= self.map.width {
let up_pos = cur_pos - self.map.width;
self.try_add_path_to_neighbor(cur_pos, up_pos, &mut dists, &mut positions_to_check, &mut prev_idx);
}
// move down
if cur_pos + self.map.width < self.map.data.len() {
let down_pos = cur_pos +self.map.width;
self.try_add_path_to_neighbor(cur_pos, down_pos, &mut dists, &mut positions_to_check, &mut prev_idx);
}
// move left
if cur_pos % self.map.width > 0 {
let left_pos = cur_pos - 1;
self.try_add_path_to_neighbor(cur_pos, left_pos, &mut dists, &mut positions_to_check, &mut prev_idx);
}
// move right
if cur_pos % self.map.width < self.map.width - 1 {
let right_pos = cur_pos + 1;
self.try_add_path_to_neighbor(cur_pos, right_pos, &mut dists, &mut positions_to_check, &mut prev_idx);
}
}
// println!("{:?}", dists);
let end_idx = self.end.0 + self.end.1 * self.map.width;
return dists[end_idx]
}
}
impl DaySolver for Day12 {
fn solve_part1(&mut self) -> String {
let start_idx = self.start.0 + self.start.1 * self.map.width;
self.calculate_distance_to_end(vec![start_idx]).to_string()
}
fn solve_part2(&mut self) -> String {
self.calculate_distance_to_end(self.map.data.iter().enumerate().filter_map(|(i, x)| if x == &0 { Some(i) } else { None }).collect()).to_string()
}
}

145
src/day13.rs Normal file
View File

@@ -0,0 +1,145 @@
use std::cmp::Ordering;
use crate::day_solver::DaySolver;
use super::util;
pub struct Day13 {
packet_pairs: Vec<(Packet, Packet)>
}
impl Day13 {
pub fn create() -> Self {
// let lines = util::read_file("input/day13_example.txt");
let lines = util::read_file("input/day13.txt");
let mut line_iter = lines.iter();
let mut packet_pairs = Vec::new();
while let Some(line) = line_iter.next() {
if line.is_empty() {
continue
}
let left = Packet::parse(line);
let right = Packet::parse(line_iter.next().unwrap());
// println!("left: {:?}, right: {:?}", left, right);
packet_pairs.push((left, right));
}
// println!("{:?}", packet_pairs);
// Put the input into the day struct
return Day13 {
packet_pairs
}
}
fn compare(left: &Packet, right: &Packet) -> Ordering {
if let Packet::Num(n_left) = left {
if let Packet::Num(n_right) = right {
if n_left != n_right {
return if n_left < n_right { Ordering::Less } else { Ordering::Greater };
}
} else {
// The right value is a vec-packet, so we need to act like the left value is as well:
return Self::compare(&Packet::Vec(vec![Packet::Num(n_left.to_owned())]), right);
}
} else if let Packet::Vec(vec_left) = left {
// Left is a vec-packet
if let Packet::Vec(vec_right) = right {
for i in 0..vec_left.len().min(vec_right.len()) {
let comp = Self::compare(&vec_left[i], &vec_right[i]);
if comp != Ordering::Equal {
return comp
}
}
if vec_left.len() != vec_right.len() {
return if vec_left.len() < vec_right.len() { Ordering::Less } else { Ordering::Greater };
}
} else if let Packet::Num(n_right) = right {
// The left value is a vec-packet, so we need to act like the right value is as well:
return Self::compare(left, &Packet::Vec(vec![Packet::Num(n_right.to_owned())]));
}
}
return Ordering::Equal;
}
}
impl DaySolver for Day13 {
fn solve_part1(&mut self) -> String {
self.packet_pairs.iter().enumerate()
.filter_map(|(i, p)| {
let comp = Day13::compare(&p.0, &p.1);
// println!("{:?} vs {:?} is {:?}", p.0, p.1, comp);
if comp == Ordering::Less { Some(i + 1) } else { None }
})
.sum::<usize>().to_string()
}
fn solve_part2(&mut self) -> String {
let mut full_vec: Vec<Packet> = self.packet_pairs.iter()
.flat_map(|p| vec![p.0.to_owned(), p.1.to_owned()].into_iter())
.collect();
let div_packet1 = Packet::parse("[[2]]");
full_vec.push(div_packet1.to_owned());
let div_packet2 = Packet::parse("[[6]]");
full_vec.push(div_packet2.to_owned());
full_vec.sort_by(|l, r| Day13::compare(l, r));
full_vec.iter().enumerate()
.filter_map(|(i, p)| if p == &div_packet1 || p == &div_packet2 { Some(i + 1) } else { None })
.reduce(|a, b| a * b)
.unwrap()
.to_string()
}
}
#[derive(Debug, Clone, PartialEq)]
enum Packet {
Num(u8),
Vec(Vec<Packet>)
}
impl Packet {
fn parse(str: &str) -> Packet {
let (p, _) = Self::parse_internal(str);
p
}
fn parse_internal(str: &str) -> (Packet, usize) {
if str.chars().next() == Some('[') {
if str.starts_with("[]") {
// We're dealing with an empty vec:
(Packet::Vec(Vec::new()), 2)
} else {
// We're dealing with a vec
let mut idx = 0;
let mut vec_content = Vec::new();
loop {
idx += 1;
let (p, i) = Packet::parse_internal(&str[idx..]);
vec_content.push(p);
idx += i;
if str.chars().nth(idx) != Some(',') {
break;
}
};
assert_eq!(str.chars().nth(idx), Some(']'), "Vec not ending: {} at idx {}", str, idx);
(Packet::Vec(vec_content), idx + 1)
}
} else {
// We should be dealing with a number
let n_str = str.chars().take_while(|c| c.is_numeric()).collect::<String>();
let n = n_str.parse::<u8>().expect(format!("Vec is not a number: {}", str).as_str());
(Packet::Num(n), n_str.len())
}
}
}

171
src/day14.rs Normal file
View File

@@ -0,0 +1,171 @@
use std::fmt::{Display, Formatter};
use crate::{day_solver::DaySolver, util::{Coord, Grid}};
use super::util;
pub struct Day14 {
platforms: Vec<Platform>
}
const STARTING_COORD: Coord<usize> = Coord { x: 500, y: 0};
impl Day14 {
pub fn create() -> Self {
// let lines = util::read_file("input/day14_example.txt");
let lines = util::read_file("input/day14.txt");
// Put the input into the day struct
return Day14 {
platforms: lines.iter().map(|l|
Platform {
coords: l.split(" -> ")
.map(|c| {
let mut c_split = c.split(",");
Coord {
x: c_split.next().unwrap().parse::<u16>().unwrap(),
y: c_split.next().unwrap().parse::<u16>().unwrap(),
}
}).collect::<Vec<Coord<u16>>>()
}).collect()
}
}
fn try_move_to(sand_coord: &mut Coord<usize>, target_x: &usize, target_y: &usize, grid: &Grid<Cell>) -> Option<bool> {
match grid.get(target_x, target_y) {
Cell::Empty => {
sand_coord.x = target_x.to_owned();
sand_coord.y = target_y.to_owned();
Some(true)
},
_ => None
}
}
fn build_grid(&self) -> Grid<Cell> {
// println!("{:?}", self.platforms);
// Build a grid from the platforms:
let max_y = self.platforms.iter().map(|p| p.coords.iter().map(|c| c.y).max().unwrap()).max().unwrap() as usize;
let mut grid = Grid {
data: vec![Cell::Empty; 1000 * (max_y + 3)],
width: 1000
};
// Add the platforms to the grid
for platform in &self.platforms {
let mut coord_iter = platform.coords.iter();
let mut from = coord_iter.next().unwrap();
while let Some(to) = coord_iter.next() {
// println!("Adding wall from {:?} to {:?}", from, to);
for y in from.y.min(to.y)..(to.y.max(from.y) + 1) {
for x in from.x.min(to.x)..(to.x.max(from.x) + 1) {
// println!("Adding {},{}", x, y);
grid.set(&(x as usize), &(y as usize), Cell::Wall);
}
}
from = to;
}
}
// grid.print_range(495, 505, 0, max_y + 3);
grid
}
fn simulate_sand(&self, grid: &mut Grid<Cell>) -> SimulationResult {
// TODO test optimization ideas:
// 1. Store a stack of the path the sand took. When executing the next one, go up the stack and use the position
// that is found as the starting point for the current grain of sand
// 2. Just store the previous position of the sand before it came to rest, and start the siulation from there.
// 3. Use an quadtree for a represenation of the sand
let grid_height = grid.height();
let mut sand_coord = STARTING_COORD.clone();
loop {
let target_x = sand_coord.x;
let target_y = sand_coord.y + 1;
if target_y >= grid_height {
// Falling into the abyss!!
return SimulationResult::FellOff
}
if Day14::try_move_to(&mut sand_coord, &target_x, &target_y, &grid)
.or_else(|| Day14::try_move_to(&mut sand_coord, &(target_x - 1), &target_y, &grid))
.or_else(|| Day14::try_move_to(&mut sand_coord, &(target_x + 1), &target_y, &grid)) == None {
// If we didn't find any option, the sand stops moving:
grid.set(&sand_coord.x, &sand_coord.y, Cell::Sand);
return SimulationResult::EndedAt(sand_coord);
}
// println!("Sand is at {:?}", sand_coord)
}
}
}
impl DaySolver for Day14 {
fn solve_part1(&mut self) -> String {
let mut grid = self.build_grid();
// Let's drop some sand
let mut counter = 0;
loop {
if self.simulate_sand(&mut grid) == SimulationResult::FellOff {
return counter.to_string();
}
counter += 1;
// grid.print_range(495, 505, 0, 10);
}
}
fn solve_part2(&mut self) -> String {
let mut grid = self.build_grid();
grid.set_row(grid.height() - 1, Cell::Wall);
// Let's drop some sand
let mut counter = 0;
loop {
self.simulate_sand(&mut grid);
counter += 1;
if grid.get(&STARTING_COORD.x, &STARTING_COORD.y) == &Cell::Sand {
return counter.to_string()
}
// grid.print_range(495, 505, 0, 10);
}
}
}
#[derive(Debug)]
struct Platform {
coords: Vec<Coord<u16>>
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Cell {
Empty, Wall, Sand
}
impl Display for Cell {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Cell::Empty => ".",
Cell::Wall => "#",
Cell::Sand => "o"
}
)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
enum SimulationResult {
FellOff,
EndedAt(Coord<usize>)
}

166
src/day15.rs Normal file
View File

@@ -0,0 +1,166 @@
use std::collections::HashSet;
use regex::Regex;
use crate::{day_solver::DaySolver, util::Coord};
use super::util;
pub struct Day15 {
beacon_scanners: Vec<BeaconSensor>
}
impl Day15 {
pub fn create() -> Self {
// let lines = util::read_file("input/day15_example.txt");
let lines = util::read_file("input/day15.txt");
// Lines look like:
// "Sensor at x=2, y=18: closest beacon is at x=-2, y=15"
let re = Regex::new(r"Sensor at x=(-?\d+), y=(-?\d+): closest beacon is at x=(-?\d+), y=(-?\d+)").unwrap();
// Put the input into the day struct
return Day15 {
beacon_scanners: lines.iter().map(|s| {
let cap = re.captures_iter(s).next().unwrap();
BeaconSensor::new(
Coord { x: cap[1].parse::<i32>().unwrap(), y: cap[2].parse::<i32>().unwrap() },
Coord { x: cap[3].parse::<i32>().unwrap(), y: cap[4].parse::<i32>().unwrap() }
)
}).collect()
}
}
fn find_ranges_without_beacons_at_y(&mut self, y: i32) -> Vec<Range> {
self.beacon_scanners.iter().filter_map(|bs| {
let dist_to_check_y = bs.sensor.y.abs_diff(y) as i32;
let coverage_width = bs.distance - dist_to_check_y;
// println!("Sensor at {},{} sees beacon {},{} at distance {}, and distance {} to check_y. So it covers {} cells",
// bs.sensor.x, bs.sensor.y, bs.closest_beacon.x, bs.closest_beacon.y, sensor_dist, dist_to_check_y, coverage_width);
if coverage_width < 0 {
None
} else {
// println!("Adding");
Some(Range {
min: bs.sensor.x - coverage_width,
max: bs.sensor.x + coverage_width
})
}
}).collect()
}
fn merge_overlapping_ranges(ranges_covered: &mut Vec<Range>) -> Vec<Range> {
// Now we need to merge all overlapping ranges into one, so we don't count any double ones:
// Note: there can be no beacons inside the sensor ranges, because if there were, the sensor
// would pick up that one and have a smaller range
ranges_covered.sort_by_key(|r| r.min);
// println!("Ranges covered: {:?}", ranges_covered);
let mut merged_ranges: Vec<Range> = Vec::new();
let mut ranges_covered_iter = ranges_covered.iter();
let mut current_range = ranges_covered_iter.next().unwrap().clone();
while let Some(next_range) = ranges_covered_iter.next() {
if current_range.overlaps(next_range) {
current_range.max = next_range.max.max(current_range.max);
} else {
// New range!
merged_ranges.push(current_range);
current_range = next_range.clone();
}
}
merged_ranges.push(current_range);
merged_ranges
}
}
impl DaySolver for Day15 {
fn solve_part1(&mut self) -> String {
// print!("{:?}", self.beacon_scanners);
// If we sort the beacon scanner by their x-coordinate, range-merging will be faster later on in the process
self.beacon_scanners.sort_by_key(|bs| bs.sensor.x);
let check_y = if self.beacon_scanners.len() < 20 { 10 } else { 2_000_000 };
let mut ranges_covered = self.find_ranges_without_beacons_at_y(check_y);
if ranges_covered.is_empty() {
return 0.to_string();
}
// println!("Ranges covered: {:?}", ranges_covered);
let merged_ranges = Self::merge_overlapping_ranges(&mut ranges_covered);
let beacons_on_check_y = self.beacon_scanners.iter()
.filter(|bs| bs.closest_beacon.y == check_y)
.map(|bs| bs.closest_beacon.x)
.filter(|x| merged_ranges.iter().any(|r| r.in_range(&x)))
.collect::<HashSet<i32>>();
// println!("Merged ranges: {:?}", merged_ranges);
return (merged_ranges.iter().map(|r| r.max - r.min + 1).sum::<i32>() - beacons_on_check_y.len() as i32).to_string();
}
fn solve_part2(&mut self) -> String {
// println!("{:?}", self.beacon_scanners.iter().filter(|bs| bs.distance > 2_000_000).collect::<Vec<&BeaconSensor>>());
let check_until = if self.beacon_scanners.len() < 20 { 20 } else { 4_000_000 };
let target_range = Range { min: 0, max: check_until };
for y in 0..(check_until+1) {
let ranges_covered = Self::merge_overlapping_ranges(&mut self.find_ranges_without_beacons_at_y(y));
if !ranges_covered.iter().any(|r| r.covers(&target_range)) {
// println!("Found solution at y={}", y);
let x = ranges_covered.iter()
.filter(|r| r.max < check_until && r.max >= 0)
.next()
.unwrap().max + 1;
return (4000000i64 * x as i64 + y as i64).to_string();
}
}
panic!("Couldn't find the answer :(")
}
}
#[derive(Debug, Clone)]
struct BeaconSensor {
sensor: Coord<i32>,
closest_beacon: Coord<i32>,
distance: i32
}
impl BeaconSensor {
fn new(sensor: Coord<i32>, closest_beacon: Coord<i32>) -> Self {
BeaconSensor {
sensor, closest_beacon,
distance: sensor.manhattan_dist(&closest_beacon)
}
}
}
#[derive(Debug, Clone)]
struct Range {
min: i32,
max: i32
}
impl Range {
pub fn overlaps(&self, other: &Range) -> bool {
self.min <= other.max && self.max >= other.min
}
pub fn covers(&self, other: &Range) -> bool {
self.min <= other.min && self.max >= other.max
}
pub fn in_range(&self, x: &i32) -> bool {
self.min.le(&x) && self.max.ge(&x)
}
}

301
src/day16.rs Normal file
View File

@@ -0,0 +1,301 @@
use std::collections::HashMap;
use crate::day16::ValveStep::{MoveTo, OpenValve};
use crate::day_solver::DaySolver;
use super::util;
pub struct Day16 {
valves: Vec<Valve>,
initial_valve_idx: usize,
// valve_names: Vec<String>
}
impl Day16 {
pub fn create() -> Self {
// let lines = util::read_file("input/day16_example.txt");
let lines = util::read_file("input/day16.txt");
// We first map all the valve names to indexes for performance reasons:
let valve_names = lines.iter()
.map(|s| s.split_whitespace().nth(1).unwrap().to_string())
.collect::<Vec<String>>();
// Put the input into the day struct
return Day16 {
valves: lines.iter().enumerate().map(|(_, s)| {
let mut s_split = s.split(';');
let flow_rate = s_split.next().unwrap().split("rate=").nth(1).unwrap().parse::<u32>().unwrap();
let connections = s_split.next().unwrap()["tunnels lead to valves ".len()..].trim().split(", ")
.map(|n| valve_names.iter().position(|nn| n.eq(nn)).unwrap())
.collect();
Valve {
// id: i,
flow_rate, connections
}
}).collect(),
initial_valve_idx: valve_names.iter().position(|n| n == "AA").unwrap(),
// valve_names
}
}
fn set_open(valve_idx: &usize, cur_open_valves_mask: &u64) -> u64 {
cur_open_valves_mask.clone() | (1u64 << valve_idx)
}
fn is_open(valve_idx: &usize, open_valves_mask: &u64) -> bool {
open_valves_mask & (1u64 << valve_idx) != 0
}
// fn is_closed(valve_idx: &usize, open_valves_mask: &u64) -> bool {
// !Self::is_open(valve_idx, open_valves_mask)
// }
//
// fn calc_flow_rate(&self, open_valves_mask: &u64) -> u32 {
// let mut res = 0;
// for i in 0..self.valves.len() {
// if Self::is_open(&i, open_valves_mask) {
// res += self.valves[i].flow_rate
// }
// }
// res
// }
fn should_valve_be_opened(&self, valve_idx: &usize, open_valves_mask: &u64) -> bool {
if Self::is_open(valve_idx, open_valves_mask) { false }
else if let Some(valve) = self.valves.get(*valve_idx) {
valve.flow_rate > 0
} else { false }
}
fn find_best_option_pt2(&self, valve_state: ValveStatePt2, cur_flow_rate: u32, cache: &mut HashMap<ValveStatePt2, BestOptionPt2>) -> BestOptionPt2 {
if valve_state.minutes_left == 0 {
return BestOptionPt2 {
// my_step: ValveStep::None,
// elephant_step: ValveStep::None,
total_flow: 0,
// cur_flow: cur_flow_rate
}
}
if let Some(res) = cache.get(&valve_state) {
return res.to_owned();
}
let mut my_options = Vec::new();
let mut elephant_options = Vec::new();
if self.should_valve_be_opened(&valve_state.my_position, &valve_state.open_valves_mask) {
// One option is to open the valve at the current position
my_options.push(OpenValve(valve_state.my_position));
}
if valve_state.my_position != valve_state.elephant_position && self.should_valve_be_opened(&valve_state.elephant_position, &valve_state.open_valves_mask) {
elephant_options.push(OpenValve(valve_state.elephant_position));
}
// We try and move to an adjacent valve, see if we can be more useful there
let my_valve = &self.valves[valve_state.my_position];
for connection in my_valve.connections.iter() {
my_options.push(MoveTo(connection.to_owned()))
}
let elephant_valve = &self.valves[valve_state.elephant_position];
for connection in elephant_valve.connections.iter() {
elephant_options.push(MoveTo(connection.to_owned()))
}
// Now we try all combinations of my and elephants options:
let mut best: u32 = 0;
// let mut my_best_step = None;
// let mut elephant_best_step = None;
let next_minutes_left = valve_state.minutes_left - 1;
for my_option in my_options {
let mut my_next_position = valve_state.my_position;
let mut next_valve_mask_for_me = valve_state.open_valves_mask;
let mut next_flow_rate_for_me = cur_flow_rate;
match my_option {
MoveTo(idx) => my_next_position = idx,
OpenValve(idx) => {
next_valve_mask_for_me = Self::set_open(&idx, &next_valve_mask_for_me);
next_flow_rate_for_me += self.valves[idx].flow_rate
}
}
for elephant_option in &elephant_options {
let mut next_valve_mask = next_valve_mask_for_me;
let mut next_flow_rate = next_flow_rate_for_me;
let mut elephant_next_position = valve_state.elephant_position;
match elephant_option {
MoveTo(idx) => elephant_next_position = *idx,
OpenValve(idx) => {
next_valve_mask = Self::set_open(idx, &next_valve_mask);
next_flow_rate += self.valves[*idx].flow_rate
}
}
let res = self.find_best_option_pt2(ValveStatePt2::new(my_next_position, elephant_next_position, next_valve_mask, next_minutes_left), next_flow_rate, cache);
if best == 0 || res.total_flow > best {
best = res.total_flow;
// my_best_step = Some(my_option);
// elephant_best_step = Some(elephant_option.to_owned());
}
}
}
let res = BestOptionPt2 {
// my_step: my_best_step.unwrap(),
// elephant_step: elephant_best_step.unwrap(),
// cur_flow: cur_flow_rate,
total_flow: best + cur_flow_rate
};
cache.insert(valve_state, res.to_owned());
res
}
fn find_best_option(&self, valve_state: ValveState, cur_flow_rate: u32, cache: &mut HashMap<ValveState, BestOptionResult>) -> Option<BestOptionResult> {
if valve_state.minutes_left == 0 { return None }
if let Some(res) = cache.get(&valve_state) {
return Some(res.clone());
}
let cur_valve = &self.valves.get(valve_state.my_position).unwrap();
let mut best_step_option: Option<ValveStep> = None;
let mut best_step_result_option: Option<BestOptionResult> = None;
if self.should_valve_be_opened(&valve_state.my_position, &valve_state.open_valves_mask) {
// One option is to open the valve at the current position
let new_open_valves_mask = Self::set_open(&valve_state.my_position, &valve_state.open_valves_mask);
best_step_result_option = self.find_best_option(ValveState::new(valve_state.my_position, new_open_valves_mask, valve_state.minutes_left - 1), cur_flow_rate + cur_valve.flow_rate, cache);
best_step_option = Some(OpenValve(valve_state.my_position));
}
// We try and move to an adjacent valve, see if we can be more useful there
for connection in cur_valve.connections.iter().rev() {
let next_step_result = self.find_best_option(ValveState::new(connection.to_owned(), valve_state.open_valves_mask, valve_state.minutes_left - 1), cur_flow_rate, cache);
if best_step_result_option.is_none() || next_step_result.as_ref().unwrap().total_flow > best_step_result_option.as_ref().unwrap().total_flow {
best_step_result_option = next_step_result;
best_step_option = Some(MoveTo(connection.to_owned()));
}
}
let Some(best_step) = best_step_option else { panic!("Couldn't find a good step?") };
let mut flow_per_step = Vec::with_capacity(valve_state.minutes_left as usize);
flow_per_step.push(cur_flow_rate);
let mut steps = Vec::with_capacity(valve_state.minutes_left as usize);
steps.push(best_step);
let mut best_next_flow = 0;
if let Some(best_step_result) = best_step_result_option {
flow_per_step.extend(best_step_result.flow_per_step.iter());
steps.extend(best_step_result.steps.iter());
best_next_flow = best_step_result.total_flow;
}
let step_result = BestOptionResult {
total_flow: best_next_flow + cur_flow_rate,
flow_per_step,
steps,
};
cache.insert(valve_state, step_result.clone());
Some(step_result)
}
}
impl DaySolver for Day16 {
fn solve_part1(&mut self) -> String {
let mut cache= HashMap::new();
// let example_flows = [0, 0, 0, 20, 20, 20, 33, 33, 33, 33, 54, 54, 54, 54, 54, 54, 54, 54, 76, 76, 76, 76, 79, 79, 79, 81, 81, 81, 81, 81, 81];
// let mut prev_best: u32 = 0;
// let mut example_running_total = 0;
// for i in 1..31u32 {
// let Some(best) = self.find_best_option(ValveState::new(self.initial_valve_idx, 0, i), 0, &mut cache) else { panic!("Not best!")};
// let cur_example_flow = example_flows[i as usize];
// example_running_total += cur_example_flow;
// println!("Best in {} minutes is {}, so I guess the flow is {}, while example flow is {} (example running total {})", i, best.total_flow, best.total_flow - prev_best, cur_example_flow, example_running_total);
// prev_best = best.total_flow;
// }
let best = self.find_best_option(ValveState::new(self.initial_valve_idx, 0, 30), 0, &mut cache).unwrap();
// for i in 0..best.steps.len() {
// println!("Step {}", i + 1);
// match best.steps[i] {
// ValveStep::OpenValve(v) => println!("Opening valve {}", self.valve_names[v]),
// ValveStep::MoveTo(v ) => println!("Moving to valve {}", self.valve_names[v])
// }
// println!("The flow is now {}\n", best.flow_per_step[i]);
// }
best.total_flow.to_string()
}
fn solve_part2(&mut self) -> String {
let mut cache= HashMap::new();
let best = self.find_best_option_pt2(ValveStatePt2::new(self.initial_valve_idx, self.initial_valve_idx, 0, 26), 0, &mut cache);
best.total_flow.to_string()
}
}
#[derive(Debug, Clone)]
struct Valve {
// id: usize,
flow_rate: u32,
connections: Vec<usize>
}
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
struct ValveState {
my_position: usize,
open_valves_mask: u64,
minutes_left: u32
}
impl ValveState {
fn new(cur_valve_idx: usize, open_valves_mask: u64, minutes_left: u32) -> Self{
ValveState { my_position: cur_valve_idx, open_valves_mask, minutes_left }
}
}
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
struct ValveStatePt2 {
my_position: usize,
elephant_position: usize,
open_valves_mask: u64,
minutes_left: u32
}
#[derive(Debug, Clone, Copy)]
struct BestOptionPt2 {
// my_step: ValveStep,
// elephant_step: ValveStep,
total_flow: u32,
// cur_flow: u32
}
impl ValveStatePt2 {
fn new(my_position: usize, elephant_position: usize, open_valves_mask: u64, minutes_left: u32) -> Self{
ValveStatePt2 { my_position, elephant_position, open_valves_mask, minutes_left }
}
}
#[derive(Debug, Clone)]
struct BestOptionResult {
steps: Vec<ValveStep>,
flow_per_step: Vec<u32>,
total_flow: u32
}
#[derive(Debug, Clone, Copy, PartialEq)]
enum ValveStep {
OpenValve(usize),
MoveTo(usize),
}

148
src/day17.rs Normal file
View File

@@ -0,0 +1,148 @@
use std::fmt::{Display, Formatter};
use lazy_static::lazy_static;
use crate::day_solver::DaySolver;
use crate::util::{Coord, Grid};
use super::util;
pub struct Day17 {
jet_pattern: Vec<char>
}
impl Day17 {
pub fn create() -> Self {
// let lines = util::read_file("input/day17_example.txt");
let lines = util::read_file("input/day17.txt");
// Put the input into the day struct
return Day17 {
jet_pattern: lines.first().unwrap().chars().collect()
}
}
fn rock_can_occupy_pos(&self, rock: &Grid<bool>, pos: &Coord<usize>, grid: &Grid<CaveCell>) -> bool {
if rock.width + pos.x > grid.width {
return false;
}
for y in 0..rock.height() {
for x in 0..rock.width {
if rock.get(&x, &y) == &true && grid.get(&(x + pos.x), &(pos.y + y)) == &CaveCell::Rock {
return false
}
}
}
return true;
}
}
impl DaySolver for Day17 {
fn solve_part1(&mut self) -> String {
let mut cave = Grid {
data: vec![CaveCell::Empty; 7 * 2022 * 4],
width: 7
};
let mut cur_spawn_height = 3;
let mut jet_iter = self.jet_pattern.iter().cycle();
for i in 0..2022 {
// Spawn the rock
let Some(rock) = ROCK_SHAPES.get(i % ROCK_SHAPES.len()) else { panic!("Can't find rock {}", i % ROCK_SHAPES.len())};
// The rock_pos is the bottom-left corner of the rock
let mut rock_pos = Coord::new(2, cur_spawn_height);
loop {
match jet_iter.next() {
Some('>') => {
let next_pos = Coord::new(rock_pos.x + 1, rock_pos.y);
if self.rock_can_occupy_pos(rock, &next_pos, &cave) {
rock_pos = next_pos;
}
}
Some('<') => {
if rock_pos.x > 0 {
let next_pos = Coord::new(rock_pos.x - 1, rock_pos.y);
if self.rock_can_occupy_pos(rock, &next_pos, &cave) {
rock_pos = next_pos;
}
}
}
m => { panic!("Unknown rock movement: {}...", m.unwrap_or(&'?')); }
}
// Now we move the rock down
if rock_pos.y == 0 {
break;
}
let next_pos = Coord::new(rock_pos.x, rock_pos.y - 1);
if self.rock_can_occupy_pos(rock, &next_pos, &cave) {
rock_pos = next_pos;
} else {
break;
}
}
// place the rock
for y in 0..rock.height() {
for x in 0..rock.width {
if rock.get(&x, &y) == &true {
cave.set(&(rock_pos.x + x), &(rock_pos.y + y), CaveCell::Rock);
}
}
}
cur_spawn_height = cur_spawn_height.max(rock_pos.y + rock.height() + 3);
}
cave.print_range(0, 7, 0, 40);
return (cur_spawn_height-3).to_string();
}
fn solve_part2(&mut self) -> String {
return 0.to_string();
}
}
lazy_static! {
static ref ROCK_SHAPES: Vec<Grid<bool>> = vec![
Grid { data: vec![
true, true, true, true],
width: 4},
Grid { data: vec![
false, true, false,
true, true, true,
false, true, false],
width: 3},
Grid {data: vec![
true, true, true,
false, false, true,
false, false, true,
], width: 3},
Grid { data: vec![
true,
true,
true,
true], width: 1},
Grid { data: vec![
true, true,
true, true],
width: 2 },
];
}
#[derive(Debug, Clone, Copy, PartialEq)]
enum CaveCell {
Rock, Empty
}
impl Display for CaveCell {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
CaveCell::Rock => write!(f, "#"),
CaveCell::Empty => write!(f, ".")
}
}
}

205
src/day18.rs Normal file
View File

@@ -0,0 +1,205 @@
use std::collections::{HashSet};
use crate::day18::VoxelState::{Air, Unknown};
use crate::day_solver::DaySolver;
use super::util;
pub struct Day18 {
voxels: HashSet<Vec3>
}
impl Day18 {
pub fn create() -> Self {
// let lines = util::read_file("input/day18_example.txt");
let lines = util::read_file("input/day18.txt");
let voxels = lines.iter().map(|l| {
let mut c_iter = l.split(",").map(|c| c.parse().unwrap());
Vec3 {
x: c_iter.next().unwrap(),
y: c_iter.next().unwrap(),
z: c_iter.next().unwrap()
}
}).collect::<HashSet<Vec3>>();
// Put the input into the day struct
return Day18 { voxels }
}
}
impl DaySolver for Day18 {
fn solve_part1(&mut self) -> String {
let mut sides = 0;
for voxel in &self.voxels {
// We just scan all sides if there are voxels there
if !self.voxels.contains(&voxel.moved(-1, 0, 0)) { sides += 1 };
if !self.voxels.contains(&voxel.moved(1, 0, 0)) { sides += 1 };
if !self.voxels.contains(&voxel.moved(0, -1, 0)) { sides += 1 };
if !self.voxels.contains(&voxel.moved(0, 1, 0)) { sides += 1 };
if !self.voxels.contains(&voxel.moved(0, 0, -1)) { sides += 1 };
if !self.voxels.contains(&voxel.moved(0, 0, 1)) { sides += 1 };
}
return sides.to_string();
}
fn solve_part2(&mut self) -> String {
// We need to find the cubes that can't be reached
let x_min = self.voxels.iter().map(|v| v.x).min().unwrap();
let x_max = self.voxels.iter().map(|v| v.x).max().unwrap();
let y_min = self.voxels.iter().map(|v| v.y).min().unwrap();
let y_max = self.voxels.iter().map(|v| v.y).max().unwrap();
let z_min = self.voxels.iter().map(|v| v.z).min().unwrap();
let z_max = self.voxels.iter().map(|v| v.z).max().unwrap();
let width = (x_max + 1 - x_min) as usize;
let height = (y_max + 1 - y_min) as usize;
let depth = (z_max + 1 - z_min) as usize;
let mut grid = Grid3D {
data: vec![Unknown; width * depth * height],
width,
height,
depth,
offset: Vec3 { x: x_min, y: y_min, z: z_min },
max: Vec3{ x: x_max, y: y_max, z: z_max}
};
for vox in &self.voxels {
grid.set(&vox.x, &vox.y, &vox.z, VoxelState::Rock);
}
let mut queue = Vec::new();
// Now we mark all voxels on the edge as air (if they're not rock)
for x in grid.offset.x..grid.max.x+1 {
for y in grid.offset.y..grid.max.y+1 {
queue_if_unknown(&mut grid, &mut queue, &x, &y, &z_min);
queue_if_unknown(&mut grid, &mut queue, &x, &y, &z_max);
}
for z in grid.offset.z..grid.max.z+1 {
queue_if_unknown(&mut grid, &mut queue, &x, &y_min, &z);
queue_if_unknown(&mut grid, &mut queue, &x, &y_max, &z);
}
}
for z in z_min..z_max + 1 {
for y in y_min..y_max + 1 {
queue_if_unknown(&mut grid, &mut queue, &x_min, &y, &z);
queue_if_unknown(&mut grid, &mut queue, &x_max, &y, &z);
}
}
// We search one extra cube around the actual grid, so that the search doesn't get blocked
// by rocks hitting the outer edge:
queue.push(grid.offset.moved(-1, 0, 0));
while let Some(pos) = queue.pop() {
// If we got here, it means that "pos" is in air, and we need to check if the neighbors are as well
try_pos(&mut grid, &mut queue, &pos, 1, 0, 0);
try_pos(&mut grid, &mut queue, &pos, -1, 0, 0);
try_pos(&mut grid, &mut queue, &pos, 0, 1, 0);
try_pos(&mut grid, &mut queue, &pos, 0, -1, 0);
try_pos(&mut grid, &mut queue, &pos, 0, 0, 1);
try_pos(&mut grid, &mut queue, &pos, 0, 0, -1);
}
// and finally, we do the same check (basically) as in pt 1:
let mut sides = 0;
for voxel in &self.voxels {
// We just scan all sides if there are voxels there
if grid.get(&(voxel.x + 1), &voxel.y, &voxel.z) == &Air { sides += 1 };
if grid.get(&(voxel.x - 1), &voxel.y, &voxel.z) == &Air { sides += 1 };
if grid.get(&voxel.x, &(voxel.y + 1), &voxel.z) == &Air { sides += 1 };
if grid.get(&voxel.x, &(voxel.y - 1), &voxel.z) == &Air { sides += 1 };
if grid.get(&voxel.x, &voxel.y, &(voxel.z + 1)) == &Air { sides += 1 };
if grid.get(&voxel.x, &voxel.y, &(voxel.z - 1)) == &Air { sides += 1 };
}
// println!("{:?}", grid.data);
// return grid.data.iter().filter(|v| v == &&Unknown).count().to_string();
sides.to_string()
}
}
fn try_pos(grid: &mut Grid3D, queue: &mut Vec<Vec3>, pos: &Vec3, offset_x: i32, offset_y: i32, offset_z: i32) {
let x = pos.x + offset_x;
let y = pos.y + offset_y;
let z = pos.z + offset_z;
queue_if_unknown(grid, queue, &x, &y, &z);
}
fn queue_if_unknown(grid: &mut Grid3D, queue: &mut Vec<Vec3>, x: &i32, y: &i32, z: &i32) {
if grid.get(x, y, z) == &Unknown {
grid.set(x, y, z, Air);
queue.push(Vec3::new(*x, *y, *z))
}
}
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
struct Vec3 {
x: i32,
y: i32,
z: i32
}
impl Vec3 {
fn moved(&self, x: i32, y: i32, z: i32) -> Vec3 {
Vec3 {
x: self.x + x,
y: self.y + y,
z: self.z + z
}
}
fn new(x: i32, y: i32, z: i32) -> Vec3 {
return Vec3 {
x, y, z
}
}
}
#[derive(Debug, PartialEq, Eq)]
struct Grid3D {
data: Vec<VoxelState>,
width: usize,
height: usize,
depth: usize,
offset: Vec3,
max: Vec3
}
impl Grid3D {
fn set(&mut self, x: &i32, y: &i32, z: &i32, value: VoxelState) {
if x < &self.offset.x || y < &self.offset.y || z < &self.offset.z {
panic!("Invalid position to update the grid: ({}, {}, {})", x, y, z);
}
let coord = self.grid_coord(&x, &y, &z);
self.data[coord] = value;
}
fn get(&self, x: &i32, y: &i32, z: &i32) -> &VoxelState {
if x < &self.offset.x || y < &self.offset.y || z < &self.offset.z ||
x > &self.max.x || y > &self.max.y || z > &self.max.z {
&VoxelState::Air
} else {
&self.data[self.grid_coord(x, y, z)]
}
}
fn grid_coord(&self, x: &i32, y: &i32, z: &i32) -> usize {
(x - self.offset.x) as usize + ((y - self.offset.y) as usize * self.width) + ((z - self.offset.z) as usize * self.width * self.height)
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
enum VoxelState {
Air, Rock, Unknown
}

View File

@@ -1,20 +1,100 @@
use std::cmp::Reverse;
use crate::day_solver::DaySolver;
use super::util;
const ROCK: u8 = 0;
const PAPER: u8 = 1;
const SCISSORS: u8 = 2;
#[derive(Copy, Clone, PartialEq, Debug)]
struct RockPaperScissorsGame {
elf: char,
you: char
}
impl RockPaperScissorsGame {
fn elf_choice(&self) -> u8 {
return (self.elf as u8) - ('A' as u8);
}
fn you_choice_part1(&self) -> u8 {
return (self.you as u8) - ('X' as u8);
}
fn choice_score(choice: u8) -> u64 {
return (choice + 1) as u64;
}
fn calc_score_part1(&self) -> u64 {
return RockPaperScissorsGame::calc_score(self.you_choice_part1(), self.elf_choice());
}
fn calc_score(you_choice:u8, elf_choice: u8) -> u64 {
let choice_score = RockPaperScissorsGame::choice_score(you_choice);
return if you_choice == elf_choice {
// tie
choice_score + 3
} else if (you_choice == ROCK && elf_choice == SCISSORS) ||
(you_choice == PAPER && elf_choice == ROCK) ||
(you_choice == SCISSORS && elf_choice == PAPER)
{
// you win
choice_score + 6
} else {
// you lose
choice_score
}
}
fn calc_score_part2(&self) -> u64 {
let you_choice = if self.you == 'X' {
// We need to lose
match self.elf_choice() {
ROCK => SCISSORS,
PAPER => ROCK,
SCISSORS => PAPER,
_ => panic!("Invalid choice: {}", self.elf_choice())
}
} else if self.you == 'Y' {
// We need a tie
self.elf_choice()
} else {
// We need to win
match self.elf_choice() {
ROCK => PAPER,
PAPER => SCISSORS,
SCISSORS => ROCK,
_ => panic!("Invalid choice: {}", self.elf_choice())
}
};
return RockPaperScissorsGame::calc_score(you_choice, self.elf_choice());
}
}
pub struct Day2 {
games: Vec<RockPaperScissorsGame>
}
impl Day2 {
pub fn create() -> Self {
// let lines = util::read_file("input/dayX_example.txt");
let lines = util::read_file("input/dayX.txt");
// let lines = util::read_file("input/day2_example.txt");
let lines = util::read_file("input/day2.txt");
// Put the input into the day struct
return Day2 {}
return Day2 {
games: lines.iter().map(|s|
RockPaperScissorsGame {
elf: s.chars().next().unwrap(),
you: s.chars().nth(2).unwrap() })
.collect()
}
}
}
@@ -22,10 +102,11 @@ impl DaySolver for Day2 {
fn solve_part1(&mut self) -> String {
return 0.to_string();
return self.games.iter().map(|g| g.calc_score_part1()).sum::<u64>().to_string()
}
fn solve_part2(&mut self) -> String {
return 0.to_string();
return self.games.iter().map(|g| g.calc_score_part2()).sum::<u64>().to_string()
}
}

127
src/day3.rs Normal file
View File

@@ -0,0 +1,127 @@
use crate::day_solver::DaySolver;
use std::fmt;
use std::fmt::Formatter;
use super::util;
struct Bag {
left: Vec<char>,
right: Vec<char>,
}
impl fmt::Display for Bag {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
"{} and {}",
self.left.iter().cloned().collect::<String>(),
self.right.iter().cloned().collect::<String>()
)
}
}
const POW_MASK: [u64; 6] = [
0xAAAAAAAAAAAAAAAAu64,
0xCCCCCCCCCCCCCCCCu64,
0xF0F0F0F0F0F0F0F0u64,
0xFF00FF00FF00FF00u64,
0xFFFF0000FFFF0000u64,
0xFFFFFFFF00000000u64,
];
impl Bag {
fn priority(c: char) -> u8 {
return if c >= 'a' && c <= 'z' {
c as u8 - 'a' as u8 + 1
} else {
c as u8 - 'A' as u8 + 27
};
}
fn find_duplicate_priority(&self) -> u8 {
let left_mask = Bag::build_mask(&self.left, 0);
let right_mask = Bag::build_mask(&self.right, 0);
return Bag::match_masks(left_mask, right_mask);
}
fn build_full_mask(&self) -> u64 {
return Bag::build_mask(&self.right, Bag::build_mask(&self.left, 0));
}
fn build_mask(chars: &Vec<char>, initial: u64) -> u64 {
let mut mask = initial;
for c in chars {
mask = mask | (1 << Bag::priority(c.to_owned()));
}
mask
}
fn match_masks(mask1: u64, mask2: u64) -> u8 {
Bag::find_set_bit(mask1 & mask2)
}
fn find_set_bit(v: u64) -> u8 {
let mut r: u8 = 0;
let mut i: u8 = 0;
for m in POW_MASK {
if v & m != 0 {
r |= 1 << i;
}
i += 1;
}
// println!("log2 {} = {}", v, r);
r
}
}
pub struct Day3 {
bags: Vec<Bag>,
}
impl Day3 {
pub fn create() -> Self {
// let lines = util::read_file("input/day3_example.txt");
let lines = util::read_file("input/day3.txt");
// Put the input into the day struct
return Day3 {
bags: lines
.iter()
.map(|s| {
let (left_str, right_str) = s.split_at(s.len() / 2);
assert_eq!(left_str.len(), right_str.len());
Bag {
left: left_str.chars().collect(),
right: right_str.chars().collect(),
}
})
.collect(),
};
}
}
impl DaySolver for Day3 {
fn solve_part1(&mut self) -> String {
self.bags
.iter()
.map(|b| b.find_duplicate_priority() as u64)
.sum::<u64>()
.to_string()
}
fn solve_part2(&mut self) -> String {
return self
.bags
.chunks(3)
.map(|bags| {
Bag::find_set_bit(
bags[0].build_full_mask()
& bags[1].build_full_mask()
& bags[2].build_full_mask(),
) as u64
})
.sum::<u64>()
.to_string();
}
}

63
src/day4.rs Normal file
View File

@@ -0,0 +1,63 @@
use crate::day_solver::DaySolver;
use super::util;
struct Range {
start: u8,
end: u8
}
struct ElfPair {
range1: Range,
range2: Range
}
pub struct Day4 {
elfs: Vec<ElfPair>
}
impl Day4 {
pub fn create() -> Self {
// let lines = util::read_file("input/day4_example.txt");
let lines = util::read_file("input/day4.txt");
return Day4 {
elfs: lines.iter().map(|s| {
let mut split = s.split(",");
ElfPair {
range1: Day4::parse_range(split.next().unwrap()),
range2: Day4::parse_range(split.next().unwrap())
}
})
.collect()
}
}
fn parse_range(str: &str) -> Range {
let mut res = str.split('-');
Range {
start: res.next().unwrap().parse::<u8>().unwrap(),
end: res.next().unwrap().parse::<u8>().unwrap()
}
}
}
impl DaySolver for Day4 {
fn solve_part1(&mut self) -> String {
return self.elfs.iter()
.filter(|e|
(e.range1.start >= e.range2.start && e.range1.end <= e.range2.end) ||
(e.range2.start >= e.range1.start && e.range2.end <= e.range1.end))
.count()
.to_string()
}
fn solve_part2(&mut self) -> String {
return self.elfs.iter()
.filter(|e| e.range1.start <= e.range2.end && e.range1.end >= e.range2.start)
.count()
.to_string()
}
}

123
src/day5.rs Normal file
View File

@@ -0,0 +1,123 @@
use crate::day_solver::DaySolver;
use super::util;
#[derive(Debug, Copy, Clone)]
struct StackInstruction {
amount: u8,
from: u8,
to: u8
}
impl StackInstruction {
fn parse(str: &str) -> StackInstruction {
let mut split = str.split_whitespace()
.filter(|s| s.chars().all(|c| c.is_numeric()));
return StackInstruction {
amount: split.next().unwrap().parse().unwrap(),
from: split.next().unwrap().parse().unwrap(),
to: split.next().unwrap().parse().unwrap()
}
}
}
#[derive(Debug, Clone)]
pub struct Day5 {
stacks: Vec<Vec<char>>,
instructions: Vec<StackInstruction>
}
impl Day5 {
fn execute_instruction_part1(&mut self, instr: &StackInstruction) {
for _ in 0..instr.amount {
let moving_crate = self.stacks[instr.from as usize].pop().unwrap();
self.stacks[instr.to as usize].push(moving_crate);
}
}
fn execute_instructions_part1(&self) -> Day5 {
let mut updated_day = self.clone();
for instr in &self.instructions {
updated_day.execute_instruction_part1(instr);
}
updated_day
}
fn execute_instruction_part2(&mut self, instr: &StackInstruction) {
// TODO prevent copying into a Vec here (we don't need a heap allocation...)
let from_stack = &self.stacks[instr.from as usize];
let from_stack_remaining = from_stack.len() - instr.amount as usize;
let to_move: Vec<char> = from_stack.iter().skip(from_stack_remaining).cloned().collect();
self.stacks[instr.to as usize].extend(to_move);
self.stacks[instr.from as usize].truncate(from_stack_remaining);
}
fn execute_instructions_part2(&self) -> Day5 {
let mut updated_day = self.clone();
for instr in &self.instructions {
updated_day.execute_instruction_part2(instr);
}
updated_day
}
}
impl Day5 {
pub fn create() -> Self {
// let lines = util::read_file("input/day5_example.txt");
let lines = util::read_file("input/day5.txt");
// Put the input into the day struct
let mut line_split = lines.split(|s| s.is_empty());
let stack_lines = line_split.next().unwrap();
let instruction_lines = line_split.next().unwrap();
let stack_id_line = stack_lines.last().unwrap();
let stack_id_strs: Vec<&str> = stack_id_line.split_whitespace().collect();
let mut stack_id_idxs = Vec::new();
let mut last_idx = 0;
for stack_id_str in &stack_id_strs {
let stack_id_idx = stack_id_line[last_idx..].find(stack_id_str).unwrap();
stack_id_idxs.push(last_idx + stack_id_idx);
last_idx = stack_id_idx + 1;
}
let stack_ids: Vec<u8> = stack_id_strs.iter().map(|s| s.parse::<u8>().unwrap()).collect();
let mut stacks: Vec<Vec<char>> = vec![Vec::with_capacity(stack_lines.len() - 1);
stack_ids.iter().max().unwrap().to_owned() as usize + 1];
for stack_line in stack_lines.iter().rev().skip(1) {
stack_id_idxs.iter().enumerate()
.for_each(|(i, stack_id_idx)| if let Some(c) = stack_line.chars()
.nth(stack_id_idx.to_owned())
.filter(|c| !c.is_whitespace()) {
stacks[stack_ids[i] as usize].push(c)
})
}
return Day5 {
stacks,
instructions: instruction_lines.iter().map(|s| StackInstruction::parse(s)).collect()
};
}
}
impl DaySolver for Day5 {
fn solve_part1(&mut self) -> String {
let updated_day = self.execute_instructions_part1();
return updated_day.stacks.iter().filter_map(|s| s.last())
.cloned()
.collect::<String>()
}
fn solve_part2(&mut self) -> String {
let updated_day = self.execute_instructions_part2();
return updated_day.stacks.iter().filter_map(|s| s.last())
.cloned()
.collect::<String>()
}
}

54
src/day6.rs Normal file
View File

@@ -0,0 +1,54 @@
use crate::day_solver::DaySolver;
use super::util;
pub struct Day6 {
data: Vec<char>
}
impl Day6 {
pub fn create() -> Self {
// let lines = util::read_file("input/day6_example.txt");
// let lines = util::read_file("input/day6_example2.txt");
// let lines = util::read_file("input/day6_example3.txt");
let lines = util::read_file("input/day6.txt");
// Put the input into the day struct
return Day6 {
data: lines.first().unwrap().chars().collect()
}
}
const A_CHAR: usize = 'a' as usize;
fn are_unique(chars: &[char]) -> bool {
let mut x: u32 = 0;
for c in chars {
x = x | 1 << (c.to_owned() as usize - Day6::A_CHAR)
}
return x.count_ones() == chars.len() as u32;
}
fn find_unique_chain(&self, len: usize) -> Option<usize> {
for i in (len-1)..self.data.len() {
if Day6::are_unique(&self.data[i-(len - 1)..i+1]) {
return Some(i);
}
}
return None
}
}
impl DaySolver for Day6 {
fn solve_part1(&mut self) -> String {
return self.find_unique_chain(4).map_or("-".to_string(), |n| (n+1).to_string());
}
fn solve_part2(&mut self) -> String {
return self.find_unique_chain(14).map_or("-".to_string(), |n| (n+1).to_string());
}
}

147
src/day7.rs Normal file
View File

@@ -0,0 +1,147 @@
use crate::day_solver::DaySolver;
use super::util;
#[derive(Debug)]
enum FileSystemEntry {
File {
size: usize
},
Directory
}
#[derive(Debug)]
enum Command {
LS { result: Vec<FileSystemEntry> },
CD { target: String }
}
pub struct Day7 {
commands: Vec<Command>
}
impl Day7 {
pub fn create() -> Self {
// let lines = util::read_file("input/day7_example.txt");
let lines = util::read_file("input/day7.txt");
let mut lines_iter = lines.iter().peekable();
let mut commands = Vec::new();
while let Some(line) = lines_iter.next() {
if line == "$ ls" {
let mut result = Vec::new();
while let Some(result_line) = lines_iter.peek() {
if !result_line.starts_with("$") {
if result_line.starts_with("dir") {
result.push(FileSystemEntry::Directory)
} else {
let mut result_split = result_line.split_whitespace();
result.push(FileSystemEntry::File {
size: result_split.next().unwrap().parse::<usize>().unwrap()
});
}
lines_iter.next();
} else {
break;
}
}
commands.push(Command::LS {
result
});
} else if line.starts_with("$ cd") {
commands.push(Command::CD {
target: line.chars().skip(5).collect()
});
}
}
// println!("{:?}", commands);
// Put the input into the day struct
return Day7 {
commands
}
}
fn calculate_dir_sizes(&self) -> Vec<usize> {
let mut size_stack: Vec<usize> = Vec::new();
size_stack.push(0);
let mut dir_sizes: Vec<usize> = Vec::new();
for command in &self.commands {
// In the first pass, we only count files directly under it, then in the final pass we also include children.
match command {
Command::CD { target } => {
if target == ".." {
Day7::move_up_dir(&mut dir_sizes, &mut size_stack);
} else if target == "/" {
Day7::move_to_root(&mut dir_sizes, &mut size_stack);
} else {
size_stack.push(0);
}
}
Command::LS { result } => {
let file_size: usize = result.iter()
.map(|f| if let FileSystemEntry::File { size } = f { size.to_owned() } else { 0usize })
.sum();
Day7::increment_last(&mut size_stack, file_size);
}
}
}
Day7::move_to_root(&mut dir_sizes, &mut size_stack);
let root_size: usize = size_stack.last().unwrap().to_owned();
dir_sizes.push(root_size);
dir_sizes
}
fn move_to_root(dir_sizes: &mut Vec<usize>, size_stack: &mut Vec<usize>) {
// Note that the size stack must always have at least one entry left (for the root)
while size_stack.len() > 1 {
Day7::move_up_dir(dir_sizes, size_stack);
}
}
fn move_up_dir(dir_sizes: &mut Vec<usize>, size_stack: &mut Vec<usize>) {
// If we leave the directory, we should have collected all sizes of subdirs
dir_sizes.push(size_stack.last().unwrap().to_owned());
// We also need to add the child size to the size of the "parent"
if let Some(child_size) = size_stack.pop() {
Day7::increment_last(size_stack, child_size);
} else {
panic!("I kind of expected to always have a child size?");
}
}
fn increment_last(size_stack: &mut Vec<usize>, size: usize) {
if let Some(last) = size_stack.last_mut() {
*last += size;
}
}
}
impl DaySolver for Day7 {
fn solve_part1(&mut self) -> String {
let dir_sizes = self.calculate_dir_sizes();
return dir_sizes.iter()
.filter(|size| size <= &&100000usize)
.sum::<usize>().to_string();
}
fn solve_part2(&mut self) -> String {
let dir_sizes = self.calculate_dir_sizes();
let root_size = dir_sizes.last().unwrap();
let min_delete_size = 30_000_000usize - (70_000_000usize - root_size);
return dir_sizes.iter()
.filter(|s| s > &&min_delete_size)
.min().unwrap().to_string();
}
}

148
src/day8.rs Normal file
View File

@@ -0,0 +1,148 @@
use std::fmt::Debug;
use crate::day_solver::DaySolver;
use crate::util::Grid;
use super::util;
#[derive(Debug, Clone)]
pub struct Day8 {
grid: Grid<u8>
}
impl Day8 {
pub fn create() -> Self {
// let lines = util::read_file("input/day8_example.txt");
let lines = util::read_file("input/day8.txt");
// Put the input into the day struct
let grid = Grid {
width: lines.first().unwrap().len(),
data: lines.join("").chars().map(|c| c.to_digit(10).unwrap() as u8).collect()
};
// println!("{:?}", grid);
return Day8 {
grid
}
}
fn calc_required_heights_for_x_range<R>(&self, y: usize, required_heights: &mut Grid<u8>, range: R)
where R: IntoIterator<Item = usize> {
let mut min_required_height = 0;
for x in range {
self.update_required_heights(x, y, required_heights, &mut min_required_height);
if min_required_height >= 10 { break }
}
}
fn calc_required_heights_for_y_range<R>(&self, x: usize, required_heights: &mut Grid<u8>, range: R)
where R: IntoIterator<Item = usize> {
let mut min_required_height = 0;
for y in range {
self.update_required_heights(x, y, required_heights, &mut min_required_height);
if min_required_height >= 10 { break }
}
}
fn update_required_heights(&self, x: usize, y: usize, required_heights: &mut Grid<u8>, min_required_height: &mut u8) {
let idx = self.grid.idx(&x, &y);
if required_heights.data[idx] >= *min_required_height {
required_heights.data[idx] = *min_required_height
}
let tree_height = self.grid.data[idx];
if tree_height + 1 > *min_required_height {
*min_required_height = tree_height + 1;
}
}
fn calc_viewing_dist_x<R>(&self, cur_height: &u8, x_range: R, y: &usize) -> usize
where R: IntoIterator<Item = usize> {
let mut count = 0;
for x in x_range {
count += 1;
if self.grid.get(&x, &y) >= cur_height {
break;
}
}
count
}
fn calc_viewing_dist_y<R>(&self, cur_height: &u8, x: &usize, y_range: R) -> usize
where R: IntoIterator<Item = usize> {
let mut count = 0;
for y in y_range {
count += 1;
if self.grid.get(&x, &y) >= &cur_height {
break;
}
}
count
}
}
impl DaySolver for Day8 {
fn solve_part1(&mut self) -> String {
let mut required_heights: Grid<u8> = Grid {
width: self.grid.width,
data: vec![10u8; self.grid.data.len()]
};
// First, we go over the rows, scanning them left-to-right
for y in 0..self.grid.height() {
self.calc_required_heights_for_x_range(y, &mut required_heights, 0..self.grid.width);
// println!("After y = {} L2R", y);
// required_heights.print();
self.calc_required_heights_for_x_range(y, &mut required_heights, (0..self.grid.width).rev());
// println!("After y = {} R2L", y);
// required_heights.print();
}
for x in 0..self.grid.width {
self.calc_required_heights_for_y_range(x, &mut required_heights, 0..self.grid.height());
self.calc_required_heights_for_y_range(x, &mut required_heights, (0..self.grid.height()).rev());
}
// required_heights.print();
let mut visible_trees = 0;
for i in 0..required_heights.data.len() {
if self.grid.data[i] >= required_heights.data[i] {
visible_trees += 1;
}
}
return visible_trees.to_string();
}
fn solve_part2(&mut self) -> String {
// Note that we skip the edges; since one of the distances is 0, the scenic score will also be 0
let mut max_scenic_score = 0;
for y in 1..self.grid.height() - 1 {
for x in 1..self.grid.width - 1 {
let cur_height = self.grid.get(&x, &y);
let right_view = self.calc_viewing_dist_x(cur_height, x+1..self.grid.width, &y);
let left_view = self.calc_viewing_dist_x(cur_height, (0..x).rev(), &y);
let up_view = self.calc_viewing_dist_y(cur_height, &x, y + 1..self.grid.height());
let down_view = self.calc_viewing_dist_y(cur_height, &x, (0..y).rev());
let scenic_score = left_view * right_view * up_view * down_view;
if scenic_score > max_scenic_score {
max_scenic_score = scenic_score;
}
}
}
return max_scenic_score.to_string();
}
}

155
src/day9.rs Normal file
View File

@@ -0,0 +1,155 @@
use std::collections::HashSet;
use crate::day_solver::DaySolver;
use super::util;
pub struct Day9 {
commands: Vec<Command>
}
impl Day9 {
pub fn create() -> Self {
// let lines = util::read_file("input/day9_example.txt");
// let lines = util::read_file(/"input/day9_example2.txt");
let lines = util::read_file("input/day9.txt");
// Put the input into the day struct
return Day9 {
commands: lines.iter()
.map(|s| {
let mut split = s.split_whitespace();
Command {
direction: split.next().unwrap().chars().next().unwrap(),
steps: split.next().unwrap().parse().unwrap()
}
})
.collect()
}
}
}
impl DaySolver for Day9 {
fn solve_part1(&mut self) -> String {
let mut head = Vec2 { x: 0, y: 0 };
let mut tail = Vec2 { x: 0, y: 0 };
let mut tail_positions: HashSet<Vec2> = HashSet::new();
tail_positions.insert(tail.to_owned());
for command in &self.commands {
for _ in 0..command.steps {
head.move_into_direction(&command.direction);
if !tail.is_adjacent(&head) {
tail.move_towards(&head);
tail_positions.insert(tail.to_owned());
}
}
}
return tail_positions.len().to_string();
}
fn solve_part2(&mut self) -> String {
let mut knot_positions = vec![Vec2 { x: 0, y: 0 }; 9];
let mut head = Vec2 { x: 0, y: 0 };
let mut tail_positions: HashSet<Vec2> = HashSet::new();
tail_positions.insert(knot_positions.last().unwrap().to_owned());
for command in &self.commands {
for _ in 0..command.steps {
head.move_into_direction(&command.direction);
let mut connected_knot = &head;
for knot in &mut knot_positions {
if !knot.is_adjacent(connected_knot) {
knot.move_towards(connected_knot);
}
connected_knot = knot;
}
tail_positions.insert(knot_positions.last().unwrap().to_owned());
}
// println!("After step {} {}", command.direction, command.steps);
// draw_rope(&head, &knot_positions);
}
return tail_positions.len().to_string();
}
}
#[derive(Debug, Clone)]
struct Command {
direction: char,
steps: i32
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
struct Vec2 {
x: i32,
y: i32
}
impl Vec2 {
fn is_adjacent(&self, other: &Vec2) -> bool {
self.x.abs_diff(other.x) <= 1 && self.y.abs_diff(other.y) <= 1
}
fn move_into_direction(&mut self, direction: &char) {
match direction {
'U' => self.y += 1,
'D' => self.y -= 1,
'L' => self.x -= 1,
'R' => self.x += 1,
_ => panic!("Unknown direction: {}", direction)
}
}
fn move_towards(&mut self, target: &Vec2) {
if target.x > self.x {
self.x += 1;
} else if target.x < self.x {
self.x -= 1;
}
if target.y > self.y {
self.y += 1;
} else if target.y < self.y {
self.y -= 1;
}
}
}
#[allow(dead_code)]
fn draw_rope(head: &Vec2, knot_positions: &Vec<Vec2>) {
let min_x = 0.min(head.x.min(knot_positions.iter().map(|k| k.x).min().unwrap()));
let max_x = head.x.max(knot_positions.iter().map(|k| k.x).max().unwrap());
let min_y = 0.min(head.y.min(knot_positions.iter().map(|k| k.y).min().unwrap()));
let max_y = head.y.max(knot_positions.iter().map(|k| k.y).max().unwrap());
for y in (min_y..max_y+1).rev() {
for x in min_x..max_x+1 {
if head.x == x && head.y == y {
print!("H")
} else if let Some(k) = knot_positions.iter().enumerate()
.find_map(|(i, k)| if k.x == x && k.y == y { Some(i)} else { None }) {
if k == knot_positions.len() - 1 {
print!("T");
} else {
print!("{}", k + 1);
}
} else if x == 0 && y == 0 {
print!("s");
} else {
print!(".");
}
}
println!()
}
}

View File

@@ -8,11 +8,11 @@ pub struct DayX {
impl DayX {
pub fn create() -> Self {
// let lines = util::read_file("input/dayX_example.txt");
let lines = util::read_file("input/dayX.txt");
let lines = util::read_file("input/dayX_example.txt");
// let lines = util::read_file("input/dayX.txt");
// Put the input into the day struct
return Day2 {}
return DayX {}
}
}

View File

@@ -1,46 +1,50 @@
extern crate core;
use std::time::Instant;
use crate::day1::Day1;
use crate::day2::Day2;
use crate::day3::Day3;
use crate::day4::Day4;
use crate::day5::Day5;
use crate::day6::Day6;
use crate::day7::Day7;
use crate::day8::Day8;
use crate::day9::Day9;
use crate::day10::Day10;
use crate::day11::Day11;
use crate::day12::Day12;
use crate::day13::Day13;
use crate::day14::Day14;
use crate::day15::Day15;
use crate::day16::Day16;
use crate::day17::Day17;
use crate::day18::Day18;
use crate::day_solver::DaySolver;
#[macro_use] extern crate lazy_static;
mod util;
mod day1;
mod day_solver;
mod day2;
mod day3;
mod day4;
mod day5;
mod day6;
mod day7;
mod day8;
mod day9;
mod day10;
mod day11;
mod day12;
mod day13;
mod day14;
mod day15;
mod day16;
mod day17;
mod day18;
const MAX_DAY: u8 = 17;
const DEFAULT_BENCHMARK_AMOUNT: u32 = 100;
const MAX_DAY: u8 = 1;
const BENCHMARK_AMOUNT: u32 = 100;
fn build_day_solver(day: u8) -> Option<Box<dyn DaySolver>> {
match day {
1 => Some(Box::new(Day1::create())),
2 => Some(Box::new(Day2::create())),
_ => None
}
}
fn solve(day: u8, silent: bool) {
let solver = build_day_solver(day);
match solver {
Some(mut s) => {
let part1 = s.solve_part1();
if !silent {
println!("Day {} Part 1: {}", day, part1);
}
let part2 = s.solve_part2();
if !silent {
println!("Day {} Part 1: {}", day, part2);
}
},
None => println!("This day is not yet implemented")
}
}
fn main() {
let args: Vec<String> = std::env::args().collect();
@@ -49,49 +53,156 @@ fn main() {
let single_day = day_arg_idx.is_some();
let day = if single_day { args[day_arg_idx.unwrap() + 1].parse::<u8>().unwrap() } else { 0 };
let benchmark = args.contains(&String::from("--bench")) || args.contains(&String::from("-b"));
let benchmark_arg_idx_option = args.iter().position(|a| a == "--bench").or(
args.iter().position(|a| a == "-b"));
let mut bench_results: Vec<u128> = Vec::new();
let benchmark = benchmark_arg_idx_option.is_some();
let bench_amount: u32 = if let Some(benchmark_arg_idx) = benchmark_arg_idx_option {
args.get(benchmark_arg_idx + 1)
.map_or(DEFAULT_BENCHMARK_AMOUNT, |r| r.parse::<u32>().unwrap_or(DEFAULT_BENCHMARK_AMOUNT))
} else {
DEFAULT_BENCHMARK_AMOUNT
};
let mut bench_results: Vec<AocBenchResult> = Vec::new();
// This is essentially the warmup for the benchmark:
run_once(single_day, day, false, &mut bench_results);
let first_run_time = bench_results[0];
let first_run_bench = bench_results[0].to_owned();
let (_, total_time) = bench(||
if benchmark {
// Ignore the warmup run in the rest of the benchmark:
bench_results.clear();
for _ in 0..BENCHMARK_AMOUNT {
run_once(single_day, day, true,&mut bench_results);
}
}
let avg_runtime: u128 = bench_results.iter().sum::<u128>() / (bench_results.len() as u128);
for _ in 0..bench_amount {
run_once(single_day, day, true, &mut bench_results);
}
});
println!("Executed {} rounds; Execution took {} μs {}", BENCHMARK_AMOUNT, avg_runtime, if benchmark { "on average" } else { "" });
if benchmark {
bench_results.sort();
println!("Min: {} μs, Max: {} μs, Median: {} μs",
bench_results[0],
bench_results[bench_results.len() - 1],
bench_results[bench_results.len() / 2]
);
println!("First time took {} μs", first_run_time);
println!("Executed {} rounds in {:.3} s ({} μs, or {} μs on average per round)", bench_results.len(), total_time as f64 / 1000000f64, total_time, total_time / bench_amount as u128);
print_bench_result(&bench_results, |b| b.total, "Execution");
print_bench_result(&bench_results, |b| b.init, "Initialization");
print_bench_result(&bench_results, |b| b.part1, "Part 1");
print_bench_result(&bench_results, |b| b.part2, "Part 2");
print_bench_result(&bench_results, |b| b.part1 + b.part2, "Part 1 & 2 together");
println!("First time took {} μs (init {} μs, part 1: {} μs, part 2: {} μs)", first_run_bench.total, first_run_bench.init, first_run_bench.part1, first_run_bench.part2);
} else {
println!("Execution took {} μs (init {} μs, part 1: {} μs, part 2: {} μs)", first_run_bench.total, first_run_bench.init, first_run_bench.part1, first_run_bench.part2);
}
}
fn run_once(single_day: bool, day: u8, silent: bool, bench_results: &mut Vec<u128>) {
#[derive(Copy, Clone)]
struct AocBenchResult {
init: u128,
part1: u128,
part2: u128,
total: u128
}
fn build_day_solver(day: u8) -> Option<Box<dyn DaySolver>> {
match day {
1 => Some(Box::new(Day1::create())),
2 => Some(Box::new(Day2::create())),
3 => Some(Box::new(Day3::create())),
4 => Some(Box::new(Day4::create())),
5 => Some(Box::new(Day5::create())),
6 => Some(Box::new(Day6::create())),
7 => Some(Box::new(Day7::create())),
8 => Some(Box::new(Day8::create())),
9 => Some(Box::new(Day9::create())),
10 => Some(Box::new(Day10::create())),
11 => Some(Box::new(Day11::create())),
12 => Some(Box::new(Day12::create())),
13 => Some(Box::new(Day13::create())),
14 => Some(Box::new(Day14::create())),
15 => Some(Box::new(Day15::create())),
16 => Some(Box::new(Day16::create())),
17 => Some(Box::new(Day17::create())),
18 => Some(Box::new(Day18::create())),
_ => None
}
}
fn solve(day: u8, silent: bool) -> AocBenchResult {
let now = Instant::now();
if single_day {
solve(day, silent);
} else {
solve_all(silent);
let (solver, init_time) = bench(|| build_day_solver(day));
let part1_time: u128;
let part2_time: u128;
match solver {
Some(mut s) => {
let(part1, pt1_time) = bench(|| s.solve_part1());
part1_time = pt1_time;
if !silent {
println!("Day {} Part 1: {}", day, part1);
}
bench_results.push(now.elapsed().as_micros());
let (part2, pt2_time) = bench(|| s.solve_part2());
part2_time = pt2_time;
if !silent {
println!("Day {} Part 2: {}", day, part2);
}
},
None => panic!("This day is not yet implemented")
}
return AocBenchResult{
init: init_time,
part1: part1_time,
part2: part2_time,
total: now.elapsed().as_micros()
}
}
fn solve_all(silent: bool) {
for day in 1..(MAX_DAY + 1) {
solve(day, silent);
}
fn print_bench_result<F>(bench_results: &Vec<AocBenchResult>, f: F, bench_part_description: &str)
where
F: FnMut(&AocBenchResult) -> u128 {
let mut benches: Vec<u128> = bench_results.iter().map(f).collect();
benches.sort();
let avg_runtime: u128 = benches.iter().sum::<u128>() / (bench_results.len() as u128);
println!("{} took {} μs {} (Min: {} μs, Max: {} μs, Median: {} μs)", bench_part_description, avg_runtime, if bench_results.len() > 1 { "on average"} else {""},
benches[0], benches[benches.len() - 1], benches[benches.len() / 2])
}
fn run_once(single_day: bool, day: u8, silent: bool, bench_results: &mut Vec<AocBenchResult>) {
let bench_result = if single_day {
solve(day, silent)
} else {
solve_all(silent)
};
bench_results.push(bench_result);
}
fn solve_all(silent: bool) -> AocBenchResult {
let mut bench_results = Vec::new();
for day in 1..(MAX_DAY + 1) {
bench_results.push(solve(day, silent));
}
return AocBenchResult {
init: bench_results.iter().map(|t| t.init).sum(),
part1: bench_results.iter().map(|t| t.part1).sum(),
part2: bench_results.iter().map(|t| t.part2).sum(),
total: bench_results.iter().map(|t| t.total).sum(),
}
}
fn bench<F, K>(mut f: F) -> (K, u128)
where F: FnMut() -> K {
let now = Instant::now();
let res = f();
(res, now.elapsed().as_micros())
}

View File

@@ -1,5 +1,8 @@
use std::fmt::Display;
use std::fs;
use num::Integer;
pub fn read_file(filename: &str) -> Vec<String> {
let contents = fs::read_to_string(filename)
@@ -11,3 +14,85 @@ pub fn read_file(filename: &str) -> Vec<String> {
res
}
#[derive(Debug, Clone)]
pub struct Grid<T> {
pub(crate) width: usize,
pub(crate) data: Vec<T>
}
impl<T: Clone + Sized> Grid<T> {
#[allow(dead_code)]
pub fn set_row(&mut self, y: usize, v: T) {
// let range = &mut self.data[x * self.width..(x+1) * self.width];
for i in self.width * y..self.width * (y + 1) {
self.data[i] = v.to_owned();
}
}
#[allow(dead_code)]
pub fn set_col(&mut self, x: usize, v: T) {
for y in 0..self.height() {
let idx = self.idx(&x, &y);
self.data[idx] = v.to_owned();
}
}
pub(crate) fn idx(&self, x: &usize, y: &usize) -> usize {
y * self.width + x
}
pub(crate) fn height(&self) -> usize {
self.data.len() / self.width
}
pub(crate) fn get(&self, x: &usize, y: &usize) -> &T {
let idx = self.idx(x, y);
&self.data[idx]
}
pub fn set(&mut self, x: &usize, y: &usize, v: T) {
let idx = self.idx(x, y);
self.data[idx] = v;
}
}
impl <T: Display + Clone + Sized> Grid<T> {
#[allow(dead_code)]
pub fn print(&self) {
self.print_range(0, self.width, 0, self.height());
}
#[allow(dead_code)]
pub fn print_range(&self, from_x: usize, to_x: usize, from_y: usize, to_y: usize) {
for y in from_y.max(0)..to_y.min(self.height()) {
for x in from_x.max(0)..to_x.min(self.width) {
print!("{}", self.get(&x, &y))
}
println!();
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Coord<T> where T: Sized {
pub x: T,
pub y: T
}
impl<T> Coord<T> where T: Sized {
pub(crate) fn new(x: T, y: T) -> Self {
Coord { x, y }
}
}
impl <T> Coord<T> where T: Integer + Copy {
pub fn manhattan_dist(&self, other: &Coord<T>) -> T {
self.x.max(other.x).sub(self.x.min(other.x)) + self.y.max(other.y).sub(self.y.min(other.y))
}
}