Compare commits

..

14 Commits

34 changed files with 5426 additions and 59 deletions

View File

@@ -1,6 +1,6 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="Run-aoc2022-bench-dayX" type="CargoCommandRunConfiguration" factoryName="Cargo Command"> <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 4 -b 1000" /> <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="workingDirectory" value="file://$PROJECT_DIR$" />
<option name="channel" value="DEFAULT" /> <option name="channel" value="DEFAULT" />
<option name="requiredFeatures" value="true" /> <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>

83
Cargo.lock generated
View File

@@ -8,6 +8,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"lazy_static", "lazy_static",
"nohash-hasher", "nohash-hasher",
"num",
"regex", "regex",
"rustc-hash", "rustc-hash",
] ]
@@ -21,6 +22,12 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.4.0" version = "1.4.0"
@@ -39,6 +46,82 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" 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]] [[package]]
name = "regex" name = "regex"
version = "1.7.0" version = "1.7.0"

View File

@@ -11,3 +11,4 @@ regex = "1"
lazy_static = "1.4.0" lazy_static = "1.4.0"
rustc-hash = "1.1.0" rustc-hash = "1.1.0"
nohash-hasher = "0.2.0" nohash-hasher = "0.2.0"
num = "0.4.0"

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

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,63 +1,10 @@
use std::{fmt::{Debug, Display}}; use std::fmt::Debug;
use crate::day_solver::DaySolver; use crate::day_solver::DaySolver;
use crate::util::Grid;
use super::util; use super::util;
#[derive(Debug, Clone)]
pub struct Grid<T> {
width: usize,
data: Vec<T>
}
impl<T: Clone + Sized> Grid<T> {
#[allow(dead_code)]
fn set_row(&mut self, x: usize, v: T) {
// let range = &mut self.data[x * self.width..(x+1) * self.width];
for i in self.width * x..self.width * (x + 1) {
self.data[i] = v.to_owned();
}
}
#[allow(dead_code)]
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();
}
}
fn idx(&self, x: &usize, y: &usize) -> usize {
y * self.width + x
}
fn height(&self) -> usize {
self.data.len() / self.width
}
fn get(&self, x: &usize, y: &usize) -> &T {
let idx = self.idx(x, y);
&self.data[idx]
}
}
impl <T: Display + Clone + Sized> Grid<T> {
#[allow(dead_code)]
fn print(&self) {
for y in 0..self.height() {
for x in 0..self.width {
print!("{}", self.get(&x, &y))
}
println!();
}
}
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Day8 { pub struct Day8 {
grid: Grid<u8> grid: Grid<u8>

View File

@@ -1,3 +1,5 @@
extern crate core;
use std::time::Instant; use std::time::Instant;
use crate::day1::Day1; use crate::day1::Day1;
use crate::day2::Day2; use crate::day2::Day2;
@@ -9,6 +11,14 @@ use crate::day7::Day7;
use crate::day8::Day8; use crate::day8::Day8;
use crate::day9::Day9; use crate::day9::Day9;
use crate::day10::Day10; 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; use crate::day_solver::DaySolver;
mod util; mod util;
@@ -23,8 +33,16 @@ mod day7;
mod day8; mod day8;
mod day9; mod day9;
mod day10; mod day10;
mod day11;
mod day12;
mod day13;
mod day14;
mod day15;
mod day16;
mod day17;
mod day18;
const MAX_DAY: u8 = 9; const MAX_DAY: u8 = 17;
const DEFAULT_BENCHMARK_AMOUNT: u32 = 100; const DEFAULT_BENCHMARK_AMOUNT: u32 = 100;
fn main() { fn main() {
@@ -98,6 +116,14 @@ fn build_day_solver(day: u8) -> Option<Box<dyn DaySolver>> {
8 => Some(Box::new(Day8::create())), 8 => Some(Box::new(Day8::create())),
9 => Some(Box::new(Day9::create())), 9 => Some(Box::new(Day9::create())),
10 => Some(Box::new(Day10::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 _ => None
} }
} }

View File

@@ -1,5 +1,8 @@
use std::fmt::Display;
use std::fs; use std::fs;
use num::Integer;
pub fn read_file(filename: &str) -> Vec<String> { pub fn read_file(filename: &str) -> Vec<String> {
let contents = fs::read_to_string(filename) let contents = fs::read_to_string(filename)
@@ -11,3 +14,85 @@ pub fn read_file(filename: &str) -> Vec<String> {
res 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))
}
}