Compare commits

...

242 Commits

Author SHA1 Message Date
68d1803e8f feat: solve part two 2025-12-21 09:26:50 +01:00
a39f261ba9 test: add unit test for part two 2025-12-21 09:13:08 +01:00
0c77a62ab4 feat: solve part one 2025-12-21 09:12:16 +01:00
60ee8c0307 test: add unit test for part one 2025-12-21 09:05:19 +01:00
dfe08db759 chore: add 2022D4 dataset 2025-12-21 09:04:00 +01:00
081f4ea295 feat: register fourth day 2025-12-21 09:03:50 +01:00
34be9e0847 feat: solve part two using exhaustive search 2025-12-20 09:25:03 +01:00
6ea67eac0c test: add unit test for part two 2025-12-20 09:18:32 +01:00
bb366fbe17 refactor: extract reactPolymer to reuse it in PartTwo 2025-12-20 09:18:17 +01:00
681b7bae16 feat: solve part one 2025-12-20 09:15:52 +01:00
c8ded5c42d test: add unit test for part one 2025-12-20 09:12:51 +01:00
b37f1ec366 chore: add 20218D5 dataset 2025-12-20 09:08:46 +01:00
40e2e329e0 feat: register fifth day 2025-12-20 09:08:34 +01:00
fa5bf2e85b feat: refactor some code and solve part two 2025-12-14 10:14:18 +01:00
ea1b57b17e test: add unit test for part two 2025-12-14 10:10:30 +01:00
174671e6f5 feat: use min() and get rid of Reindeer struct 2025-12-14 10:02:57 +01:00
40bcf3052f test: add unit test for part one 2025-12-14 10:00:17 +01:00
1e634b7ee9 feat: implement partone in CalculateMaxDistance to make the test relevant 2025-12-14 10:00:11 +01:00
6e625dcf06 feat: register fourteenth day 2025-12-14 09:52:39 +01:00
141216920d chore: add 2015D14 dataset 2025-12-14 09:52:25 +01:00
b685e81c58 feat: solve part two 2025-12-12 18:35:11 +01:00
1adc10ea88 test: add test for part two 2025-12-12 18:35:05 +01:00
db7c31cb39 feat: solve part one using direct byte comparaison and efficient hex extraction 2025-12-12 18:30:25 +01:00
1ad1da1309 chore: add 2016D5 dataset 2025-12-12 18:30:07 +01:00
228392fe83 feat: register fifth day 2025-12-12 18:29:50 +01:00
4837cbf290 test: add unit test for part one 2025-12-12 18:29:20 +01:00
8503cee52b test: add unit test for part two 2025-12-10 18:41:25 +01:00
b16b052115 feat: solve part one using brute-force 2025-12-10 16:51:57 +01:00
bc76283458 test: add unit test for part one 2025-12-10 06:11:04 +01:00
9d2a087801 feat: register tenth day 2025-12-10 06:10:57 +01:00
0bd3b6dc69 chore: add 2025D10 dataset 2025-12-10 06:10:50 +01:00
da81f67b7f feat: solve part two 2025-12-09 20:59:57 +01:00
caa7da5a7d test: add reverse unit test for part two 2025-12-09 20:59:46 +01:00
eebe707ef9 feat: solve part one 2025-12-09 20:40:59 +01:00
8960dcb072 test: add unit test for part one 2025-12-09 20:14:22 +01:00
99eb0fbaa8 chore: 2016D4 dataset 2025-12-09 20:14:16 +01:00
a739425209 feat: register fourth day 2025-12-09 20:14:11 +01:00
af306eb73c feat: solve part two 2025-12-09 19:24:30 +01:00
cdbc3f3b16 feat: solve part one 2025-12-09 19:22:12 +01:00
ed445a8be7 test: add unit test for both parts 2025-12-09 19:21:59 +01:00
8bbf6662b1 chore: add 2016D3 input 2025-12-09 19:21:51 +01:00
b60c971d50 feat: register third day 2025-12-09 19:21:44 +01:00
5dab84eeb3 feat: solve part two 2025-12-09 14:40:37 +01:00
2283b62503 clean: oneliner for compute and check 2025-12-09 07:10:30 +01:00
ccf50c12c9 test: add unit test for part two 2025-12-09 06:45:39 +01:00
f25d7511aa feat: solve part one 2025-12-09 06:33:16 +01:00
243ccf3da9 test: unit test for part one 2025-12-09 06:14:02 +01:00
aedf9cd06d chore: day 9 input 2025-12-09 06:05:48 +01:00
c053c905ad feat: register ninth day 2025-12-09 06:05:42 +01:00
7dff40745c feat: solve part two using keypad with 10+ for letter and 0 for inexisting keys 2025-12-08 22:52:28 +01:00
0e8563b216 test: add printing unit test for part two (as it returns string) 2025-12-08 22:39:11 +01:00
6720bbabc1 feat: solve part one building the code digit by digit 2025-12-08 22:34:59 +01:00
6035989da4 test: add unit test for part one 2025-12-08 22:26:25 +01:00
dc16893777 chore: add 2016D2 dataset 2025-12-08 22:26:15 +01:00
fdfad57cee feat: register second day 2025-12-08 22:26:01 +01:00
9cf00b290f feat: solve part two using same logic and injecting me :) 2025-12-08 22:17:11 +01:00
47072a4982 feat: extract shared functions and solve part two 2025-12-08 22:01:31 +01:00
62748990cb test: unit test for part two 2025-12-08 21:55:29 +01:00
42c69d44e5 feat: solve part one 2025-12-08 21:51:40 +01:00
c6eb51a395 comment: no test for part two 2025-12-08 21:45:42 +01:00
6777696df6 test: add unit test for part one 2025-12-08 21:45:27 +01:00
a8e244f9ab feat: register third day 2025-12-08 21:43:39 +01:00
911f9bfe7b chore: add 2022D3 dataset 2025-12-08 21:43:15 +01:00
24a65d3752 feat: solve part one using brute-force permutation search 2025-12-08 21:26:06 +01:00
0bd0ec5f1e test: add unit test for part one 2025-12-08 21:24:58 +01:00
0ad418ed1f feat: register d13 2025-12-08 17:39:35 +01:00
ec48231aae chore: add D13 dataset 2025-12-08 17:39:07 +01:00
5631822e73 feat: tiny refactor for part two which we're solving using Kruskal's algorithm 2025-12-08 15:21:42 +01:00
630d32ba11 test: add unit test for part two 2025-12-08 12:30:10 +01:00
22500b7076 feat: solve part one 2025-12-08 12:26:37 +01:00
9d2d27b257 refactor: rename parameter to standardize 2025-12-08 11:42:12 +01:00
879509c7ba refactor: rename parameter 2025-12-08 11:40:08 +01:00
a0805111b4 test: add unit test for part one 2025-12-08 06:08:56 +01:00
b0cd4f37b1 feat: register day 8 2025-12-08 06:01:48 +01:00
8999f45aad chore: day8 dataset 2025-12-08 06:01:39 +01:00
838803c53e feat: solve part two 2025-12-07 22:01:36 +01:00
c4063b5390 test: unit test for part two 2025-12-07 21:59:04 +01:00
1c5bd1e448 feat: solve part one 2025-12-07 21:55:26 +01:00
6d9b2092bd test: add unit test for part one 2025-12-07 21:51:57 +01:00
9b218d763d feat: start 2016 2025-12-07 21:51:41 +01:00
10c5b0fbc6 feat: register day one 2025-12-07 21:39:52 +01:00
503eec14c6 chore: add 2016D1 dataset 2025-12-07 21:39:07 +01:00
deac7f97bb refactor: format imports 2025-12-07 13:34:14 +01:00
a3fb7ac353 feat: solve part two using recursive dfs + memoization 2025-12-07 12:24:40 +01:00
8f4e11215f test: add unit test for part two 2025-12-07 09:55:03 +01:00
78b0032578 feat: solve PartOne using DFS algorithm 2025-12-07 09:54:53 +01:00
536f6f52ff refactor: return directly 2025-12-07 09:35:20 +01:00
96ca1afb9b test: add unit test for PartOne 2025-12-07 09:30:18 +01:00
780263e78b feat: register day seven 2025-12-07 09:27:51 +01:00
49ff399f97 chore: D7 dataset (and it rhymes (in french only)) 2025-12-07 09:26:42 +01:00
27d14b1711 feat: solve part two 2025-12-07 00:00:16 +01:00
89b2ec90f2 test: add unit test for part two 2025-12-06 23:57:23 +01:00
f8a2e839b9 feat: solve part one using maps and regex 2025-12-06 23:55:34 +01:00
94ecbd27bf test: add unit test for part one 2025-12-06 23:45:52 +01:00
b44a592808 chore: D4 dataset 2025-12-06 23:44:13 +01:00
b00d2f13a3 feat: register day four 2025-12-06 23:44:01 +01:00
b26f1531f5 feat: solve part two 2025-12-06 23:43:01 +01:00
7de5fa7794 fix: update parsing to avoid doing split in both functions 2025-12-06 23:40:20 +01:00
66e91e05a4 test: update input to be a []string 2025-12-06 23:40:02 +01:00
a20bb8ab09 test: add unit test for part two 2025-12-06 23:36:12 +01:00
c5fcc8b353 feat: solve part one 2025-12-06 23:34:48 +01:00
0357f263cc test: add unit test for part one 2025-12-06 23:13:21 +01:00
8488debc25 feat: register day four 2025-12-06 23:11:46 +01:00
00dd40428b chore: 2021D4 dataset 2025-12-06 23:11:09 +01:00
3d35a57723 feat: solve part two using right-to-left processing 2025-12-06 12:08:57 +01:00
0d40e32a39 test: add unit test for part two 2025-12-06 11:48:22 +01:00
fd34db28cb feat: solve part one using grid transposition 2025-12-06 11:46:50 +01:00
65edd3258e test: unit test for part one 2025-12-06 11:07:39 +01:00
e914bc6492 feat: register day six 2025-12-06 11:04:13 +01:00
0eed8089b6 chpre: 2025D6 dataset 2025-12-06 11:03:34 +01:00
1048d20cef docs: update requirements 2025-12-05 09:26:46 +01:00
00ccbaf0d0 feat: solve part two using merged ranges 2025-12-05 09:08:10 +01:00
51f733127c test: add unit test for part two 2025-12-05 08:46:10 +01:00
d96febeae3 feat: solve part one using binary search on sorted range 2025-12-05 08:41:39 +01:00
79b31dad19 test: add unit test for part one 2025-12-05 08:03:50 +01:00
d5146e7e3e feat: include day five 2025-12-05 08:01:50 +01:00
d2d6f280b3 chore: 2025D5 dataset 2025-12-05 08:01:40 +01:00
79d9f8d7cc feat: solve part two using json and recursive approach 2025-12-04 21:10:42 +01:00
bcc4fc3432 test: add unit testing for part two 2025-12-04 21:00:19 +01:00
cc2d7d1a3d feat: solve part one using basic regex parsing 2025-12-04 20:59:09 +01:00
83f6db5e33 test: unit tests case for p1 2025-12-04 20:54:43 +01:00
12b54d51d2 feat: include D12 2025-12-04 20:44:48 +01:00
89c154de37 chore: add 2015D12 dataset 2025-12-04 20:44:17 +01:00
ea037debed fix: silence golangci-lint 2025-12-04 17:35:49 +01:00
a0a0c43690 feat: simplified input parsing by appending all lines directly 2025-12-04 17:32:36 +01:00
bce49d51f7 feat: applied De Morgan simplification 2025-12-04 17:32:18 +01:00
77a352aa2e feat: solve part two using the same logic, twice 2025-12-04 16:53:15 +01:00
fd6db0cc65 refactor: add code in helpers for part two 2025-12-04 16:52:28 +01:00
2b548fa1ef feat: solve part one with pruned bruteforce 2025-12-04 16:49:43 +01:00
e0465b9b8d clean: no test cases for this day 2025-12-04 16:32:43 +01:00
0523610080 chore: 2015D11 dataset 2025-12-04 16:24:24 +01:00
e341c12763 feat: include D11 2025-12-04 16:24:14 +01:00
6cff0b7931 feat: solve part two with iterative process 2025-12-04 07:05:56 +01:00
f5bfe1e578 test: unit test for part two 2025-12-04 06:48:41 +01:00
0fbe2956c3 refactor: didn't press :w it seems 2025-12-04 06:46:28 +01:00
9280430285 feat: solve part one using prebuilt map for rolls 2025-12-04 06:45:40 +01:00
b91e34bc8e test: add unit test for part one 2025-12-04 06:32:20 +01:00
9f10576a0c feat: include 2025D4 2025-12-04 06:30:23 +01:00
8a9f4cb506 chore: add 2025D4 dataset 2025-12-04 06:29:55 +01:00
d3098c0d9c cleaning: input.txt is either downloaded or created empty 2025-12-03 15:17:24 +01:00
8be18b6b38 refactor: better explain scaffolding 2025-12-03 15:16:25 +01:00
b39b8c885b feat: solve part two, still with greedy algorithm 2025-12-03 10:36:14 +01:00
56901ca553 test: add unit test for part two 2025-12-03 10:10:45 +01:00
e3c9da9621 feat: solve part one using a prebuild list to reduce comparisons 2025-12-03 10:09:13 +01:00
070bd8be9a fix: modify test, we're parsing [][]int instead of []string for this day 2025-12-03 09:57:12 +01:00
c1ba2ca02b test: add unit test for part one 2025-12-03 09:28:42 +01:00
146b63706a feat: include 2025D3 2025-12-03 09:26:32 +01:00
1421062a75 chore: 2025D3 dataset 2025-12-03 09:26:19 +01:00
b9928789df feat: solve day10 using traditionnal look and say 2025-12-02 23:12:11 +01:00
b7aafeec52 test: no test 2025-12-02 23:11:09 +01:00
a935e35d82 feat: include 2015D10 2025-12-02 23:08:47 +01:00
e2c2d0df71 chore: 2015D10 dataset 2025-12-02 22:56:27 +01:00
e3a47b0e16 feat: solve part two 2025-12-02 22:13:31 +01:00
86370f27c8 refactor: create functions that we gonna use for part two 2025-12-02 22:10:12 +01:00
c61e573e14 test: add unit test for part two 2025-12-02 21:57:27 +01:00
d16f70cf00 feat: solve part one with brute-force and permutation enumeration 2025-12-02 21:56:06 +01:00
6f7561213e test: add unit test for part one 2025-12-02 21:52:56 +01:00
94b15548cf feat: include 2015D9 2025-12-02 21:23:49 +01:00
4e9e2b399c chore: add 2015D9 dataset 2025-12-02 21:23:24 +01:00
035e56bf53 feat: solve part two 2025-12-02 21:21:49 +01:00
61cf84aa8a test: add unit test for part two 2025-12-02 20:39:54 +01:00
5513ae8386 feat: solve part one using basic parsing 2025-12-02 20:38:20 +01:00
f1730c30cb feat: register D8 and parse input 2025-12-02 20:14:37 +01:00
ce7d42621f test: add unit test for part one 2025-12-02 20:13:01 +01:00
8eafb1f7c5 feat: include 2015D8 2025-12-02 19:55:26 +01:00
81be03e8ee chore: add 2015D8 dataset 2025-12-02 19:54:54 +01:00
d662f693b8 feat: don't bruteforce every number, use recursion to generate patterns to look for 2025-12-02 18:09:45 +01:00
b0d16b1bac git: add .test files to ignore 2025-12-02 11:51:21 +01:00
3eb9120dc3 clean: remove test file 2025-12-02 11:50:40 +01:00
85ae14acbf docs: update readme 2025-12-02 09:58:52 +01:00
b7a98033c6 refactor: use package aggregators 2025-12-02 09:51:34 +01:00
8f265eae05 feat: add per-year aggregator packages so main.go remains readable 2025-12-02 09:51:21 +01:00
fe20a0b654 feat: solve part two using a bit of bruteforce 2025-12-02 07:48:48 +01:00
aa80e4eb8e revert: remove useless helper as PartOne and PartTwo will have a different behavior 2025-12-02 07:35:50 +01:00
0d029f2861 feat: unify invalid checks with exactTwo boolean parameter 2025-12-02 07:19:57 +01:00
edf94432f4 test: add unit test for part two 2025-12-02 06:53:45 +01:00
33552358f8 feat: solve p1 2025-12-02 06:52:30 +01:00
45d3e93a93 test: add unit test for p1 2025-12-02 06:46:42 +01:00
707f34e706 feat: include 2025D2 2025-12-02 06:36:56 +01:00
a05450c73a chore: add 2025D2 dataset 2025-12-02 06:27:22 +01:00
6b95f5ced0 test: add an almost arbitrary test for p2 2025-12-01 23:20:37 +01:00
9caee546f0 feat: solve part two by overriding wire b and re-evaluating circuit 2025-12-01 23:11:41 +01:00
8e831d85fe fix: replace Split with SplitSeq as it's a loop (thanks lsp) 2025-12-01 23:09:30 +01:00
b8ab5fae7b test: updateInput to simulate new ParseInput output 2025-12-01 23:08:22 +01:00
3262d1cbb8 refactor: build instruction in ParseInput and add evaluateWire helper 2025-12-01 23:07:29 +01:00
766ee97dd3 feat: solve part one using recursion and memoization 2025-12-01 22:59:28 +01:00
c41c96e628 test: add unit test for p1, based on manual calculations 2025-12-01 22:59:05 +01:00
fb46fceb75 refactor: just moving code here and there 2025-12-01 22:48:56 +01:00
c9fe217e4b feat: include 2015D7 2025-12-01 22:44:45 +01:00
d88d64edd4 chore: 2015D7 dataset 2025-12-01 22:43:24 +01:00
e81194721c refactoring: just better naming 2025-12-01 21:53:50 +01:00
a680e0ba48 refactor: create parseInstruction and instruction{} to use it in both parts 2025-12-01 21:31:51 +01:00
345defec4d feat: solve p2 2025-12-01 21:28:27 +01:00
3756279dab test: add unit test for p2 2025-12-01 20:52:57 +01:00
70189f4295 feat: solve part one 2025-12-01 20:47:02 +01:00
cdacf7ae06 test: add unit test for p1 from paper calculation 2025-12-01 20:46:55 +01:00
074c762960 feat: add 2015D6 dataset 2025-12-01 20:35:08 +01:00
6babf31a20 feat: include 2015D6 2025-12-01 20:35:00 +01:00
cdefd68320 feat: add 2018D3 dataset 2025-12-01 20:09:37 +01:00
f28611a7bf test: add unit tests for p1/p2 2025-12-01 20:09:29 +01:00
f98034b00c feat: solve both parts 2025-12-01 20:09:20 +01:00
375b756718 feat: include 2018D3 2025-12-01 20:09:12 +01:00
6668e8ae1b fix: remove empty branch 2025-12-01 19:37:28 +01:00
e58959778a docs: update readme 2025-12-01 19:36:25 +01:00
eb72fe9ebd build: get rid of "new" target 2025-12-01 19:35:01 +01:00
e355423675 feat: automatically download each day input 2025-12-01 19:32:01 +01:00
b1be29c21c feat: solve part two using modular arithmetic 2025-12-01 12:35:20 +01:00
b04dcc5aea test: add P2 unit test 2025-12-01 12:20:11 +01:00
11b6227d0e feat: add P1 solution 2025-12-01 12:19:01 +01:00
31660c7510 test: add P1 unit test 2025-12-01 12:18:54 +01:00
728bbb2a06 feat: add input for 2022D2 2025-12-01 12:18:42 +01:00
16a99ba8d8 feat: include 2022D2 2025-12-01 12:18:36 +01:00
0949840317 feat: solve P2, same as P1 but check every time the dial passes through 0 during the rotation 2025-12-01 07:41:50 +01:00
daec5a8671 test: add unit test for p2 2025-12-01 07:35:03 +01:00
d66cd1179d feat: solve P1 using modulo to keep it between boundaries 2025-12-01 07:31:15 +01:00
2d3828c55d test: design unit test for part one 2025-12-01 07:20:12 +01:00
b7a7bfb5c7 feat: add 2025D1 input 2025-12-01 07:20:01 +01:00
be918bdf6c feat: include 2025D1 let's gooooo 2025-12-01 07:19:55 +01:00
c8517b674f docs: explain the string answers trick 2025-11-30 13:35:55 +01:00
f3d73b7c4b feat: P2 solution using pairwise comparison 2025-11-30 13:08:46 +01:00
bcef8844ec build: only test internal/ 2025-11-30 13:04:18 +01:00
20ab5fe4e5 test: adapted p2 test as it expects string and not int 2025-11-30 13:04:08 +01:00
959c05b769 feat: add part one solution 2025-11-30 12:55:52 +01:00
4179c88afb feat: include 2018D2 2025-11-30 12:50:47 +01:00
0dc0c3af3d feat: 2018D2 dataset 2025-11-30 12:50:41 +01:00
c6dc950d3f test: add unit test for p1 2025-11-30 12:50:33 +01:00
e5a1504f6b feat: add solutions for P1/P2 2018D1 2025-11-30 12:46:09 +01:00
9da1fa02c8 feat: 2018D1 dataset 2025-11-30 12:46:01 +01:00
99857d8ca5 test: add unit tests for P1/P2 2025-11-30 12:45:53 +01:00
e198caf1b9 feat: include 2018D1 2025-11-30 12:45:45 +01:00
9dd5f1354f docs: comment years 2025-11-29 16:15:14 +01:00
8ad1b166f3 feat: add both solutions 2025-11-29 16:07:02 +01:00
1f3b42b266 feat: 2015D5 dataset 2025-11-29 16:06:54 +01:00
9521677ca8 test: add unit tests for both parts 2025-11-29 16:06:42 +01:00
8938992384 feat: include 2015D5 2025-11-29 16:06:34 +01:00
a0ce63e5a5 feat: solve d4 both parts using md5 bruteforce 2025-11-29 09:57:54 +01:00
a12c8df252 test: add unit tests for both parts 2025-11-29 09:57:23 +01:00
8d69f10924 feat: include 2015D4 2025-11-29 09:55:47 +01:00
e41d1fa220 feat: add 2015D4 input 2025-11-29 09:55:39 +01:00
da78d01d9f test: standardization 2025-11-29 09:39:33 +01:00
ff4b7b281c feat: add p2 solution 2025-11-28 17:59:03 +01:00
a3f54530f6 test: add unit test for p2 2025-11-28 17:56:35 +01:00
120 changed files with 25145 additions and 84 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
bin/aoc bin/aoc
*.test

View File

@@ -1,60 +1,61 @@
GO = go GO = go
BIN = bin/aoc BIN = bin/aoc
.PHONY: build test clean new .PHONY: build test clean
build: build:
@mkdir -p $(dir $(BIN)) @mkdir -p $(dir $(BIN))
@$(GO) build -o $(BIN) ./cmd/aoc @$(GO) build -o $(BIN) ./cmd/aoc
test: test:
@$(GO) test ./... @$(GO) test ./internal/...
clean: clean:
@rm -f $(BIN) @rm -f $(BIN)
new:
@if [ -z "$(filter-out $@,$(MAKECMDGOALS))" ]; then \
echo "Usage: make new 2020D9"; \
exit 1; \
fi
@DAY_ARG=$$(echo $(filter-out $@,$(MAKECMDGOALS)) | awk '{print $$1}'); \
YEAR=$$(echo $$DAY_ARG | sed 's/D.*//'); \
DAY_NUM=$$(echo $$DAY_ARG | sed 's/.*D//'); \
DAY_NAME=$$(case $$DAY_NUM in \
1) echo "One" ;; \
2) echo "Two" ;; \
3) echo "Three" ;; \
4) echo "Four" ;; \
5) echo "Five" ;; \
6) echo "Six" ;; \
7) echo "Seven" ;; \
8) echo "Eight" ;; \
9) echo "Nine" ;; \
10) echo "Ten" ;; \
11) echo "Eleven" ;; \
12) echo "Twelve" ;; \
13) echo "Thirteen" ;; \
14) echo "Fourteen" ;; \
15) echo "Fifteen" ;; \
16) echo "Sixteen" ;; \
17) echo "Seventeen" ;; \
18) echo "Eighteen" ;; \
19) echo "Nineteen" ;; \
20) echo "Twenty" ;; \
21) echo "TwentyOne" ;; \
22) echo "TwentyTwo" ;; \
23) echo "TwentyThree" ;; \
24) echo "TwentyFour" ;; \
25) echo "TwentyFive" ;; \
*) echo "Unknown" ;; \
esac); \
mkdir -p internal/$$YEAR/Day$$DAY_NAME; \
mkdir -p internal/data/$$YEAR/Day$$DAY_NAME; \
touch internal/$$YEAR/Day$$DAY_NAME/code.go; \
touch internal/$$YEAR/Day$$DAY_NAME/code_test.go; \
touch internal/data/$$YEAR/Day$$DAY_NAME/input.txt; \
echo "Created files for $$DAY_ARG"
%: %:
@: @DAY_ARG=$@; \
if echo $$DAY_ARG | grep -qE '^[0-9]{4}D[0-9]+$$'; then \
YEAR=$$(echo $$DAY_ARG | sed 's/D.*//'); \
DAY_NUM=$$(echo $$DAY_ARG | sed 's/.*D//'); \
DAY_NAME=$$(case $$DAY_NUM in \
1) echo "One" ;; \
2) echo "Two" ;; \
3) echo "Three" ;; \
4) echo "Four" ;; \
5) echo "Five" ;; \
6) echo "Six" ;; \
7) echo "Seven" ;; \
8) echo "Eight" ;; \
9) echo "Nine" ;; \
10) echo "Ten" ;; \
11) echo "Eleven" ;; \
12) echo "Twelve" ;; \
13) echo "Thirteen" ;; \
14) echo "Fourteen" ;; \
15) echo "Fifteen" ;; \
16) echo "Sixteen" ;; \
17) echo "Seventeen" ;; \
18) echo "Eighteen" ;; \
19) echo "Nineteen" ;; \
20) echo "Twenty" ;; \
21) echo "TwentyOne" ;; \
22) echo "TwentyTwo" ;; \
23) echo "TwentyThree" ;; \
24) echo "TwentyFour" ;; \
25) echo "TwentyFive" ;; \
*) echo "Unknown" ;; \
esac); \
mkdir -p internal/$$YEAR/Day$$DAY_NAME; \
mkdir -p internal/data/$$YEAR/Day$$DAY_NAME; \
touch internal/$$YEAR/Day$$DAY_NAME/code.go; \
touch internal/$$YEAR/Day$$DAY_NAME/code_test.go; \
if [ -n "$$ADVENTOFCODE_SESSION" ]; then \
curl -s -H "Cookie: session=$$ADVENTOFCODE_SESSION" \
https://adventofcode.com/$$YEAR/day/$$DAY_NUM/input \
| perl -pe 'chomp if eof' > internal/data/$$YEAR/Day$$DAY_NAME/input.txt; \
else \
touch internal/data/$$YEAR/Day$$DAY_NAME/input.txt; \
fi; \
echo "$$DAY_ARG ready to be solved."; \
fi

View File

@@ -13,38 +13,64 @@ Ultimately, my goal is to complete all the years of Advent of Code here.
## Requirements ## Requirements
- Go 1.25 - Go 1.25
- Puzzle input - Puzzle input (or your session cookie to have it downloaded automatically)
## Repository Structure ## Repository Structure
``` ```
├── cmd/ ├── cmd/
│ └── aoc/ │ └── aoc/
│ └── main.go # CLI entry point that runs solutions │ └── main.go # CLI entry point for running puzzles
└── internal/ └── internal/
├── 2020/ ├── 2020/
│ ├── register.go # Aggregates import for main.go
│ ├── DayOne/ │ ├── DayOne/
│ │ ├── code.go # Go solution for Day 1 (2020) │ │ ├── code.go # Day 1 solution for 2020
│ │ └── code_test.go # Unit tests for Day 1 │ │ └── code_test.go # Unit tests for Day 1 solution
│ └── ... │ └── ... # Other days for 2020
├── 2021/ ├── 2021/
│ └── ... # Additional years and days │ └── ... # 2021 days code and tests
├── registry/ ├── registry/
│ └── registry.go # Central registry for day runners │ └── registry.go # Central map/registry for finding and running days
└── data/ └── data/
├── 2020/ ├── 2020/
│ ├── DayOne/ │ ├── DayOne/
│ │ └── input.txt # Puzzle input for Day 1 (2020) │ │ └── input.txt # Puzzle input for Day 1 (2020)
│ └── ... │ └── ... # Inputs for other days
└── ... └── ... # Inputs for other years
``` ```
Each day's solution is organized into its own folder, named according to the day number (e.g., `DayOne`, `DayTwo`). Inside each folder, you'll find a `code.go` file with the Go implementation of the solution and a `code_test.go` file containing corresponding tests. The input data for each puzzle is located in the `internal/data` directory, mirroring the code structure for easy access. Each day's solution is organized into its own folder, named according to the day number (e.g., `DayOne`, `DayTwo`). Inside each folder, you'll find a `code.go` file with the Go implementation of the solution and a `code_test.go` file containing corresponding tests. The input data for each puzzle is located in the `internal/data` directory, mirroring the code structure for easy access.
To connect each solution to the CLI, the repository uses a central registry located in `internal/registry/registry.go`. This registry is essentially a map linking a day key (combining year and day number) to assign a "day runner" which is a struct that specifies the `ParseInput`, `PartOne` and `PartTwo` functions of the day's problem. Each year has its own `register.go` file to aggregate imports. To connect each solution to the CLI, the repository uses a central registry located in `internal/registry/registry.go`. This registry is essentially a map linking a day key (combining year and day number) to assign a "day runner" which is a struct that specifies the `ParseInput`, `PartOne` and `PartTwo` functions of the day's problem.
When running a solution, the CLI (`cmd/aoc/main.go`) looks up the appropriate runner from the registry based on your command-line input, uses the parsing function to load the input data, and then runs the desired part (or both parts) using the registered solution functions. When running a solution, the CLI (`cmd/aoc/main.go`) looks up the appropriate runner from the registry based on your command-line input, uses the parsing function to load the input data, and then runs the desired part (or both parts) using the registered solution functions.
### Starting a new day
```bash
make 2020D1
```
If the `ADVENTOFCODE_SESSION` environment variable is set with your Advent of Code session cookie, the input will be downloaded from the AOC website right into the corresponding `internal/data` directory, else it will create an empty `input.txt` file.
Then, it will create the following files:
```bash
internal/2020/DayOne/code.go
internal/2020/DayOne/code_test.go
```
### Handling string answers
Occasionally, a puzzle requires a string as the answer. However, my solution framework expects PartOne/PartTwo functions to return integers.
To work around this, I print the string result (see [2018D2P2](https://git.kharec.info/Kharec/advent-of-code/tree/main/internal/2018/DayTwo/code.go)) and return a dummy integer to satisfy the type requirements.
Meanwhile, the corresponding [test](https://git.kharec.info/Kharec/advent-of-code/tree/main/internal/2018/DayTwo/code_test.go) captures the output and verifies that the correct string is produced.
It's not the most elegant solution, but since only a handful of days across all Advent of Code years require a string result, this compromise keeps the rest of the code simple.
## Usage ## Usage
Build the CLI tool: Build the CLI tool:

View File

@@ -1,27 +1,21 @@
package main package main
import ( import (
"advent-of-code/internal/registry"
"fmt" "fmt"
"log" "log"
"os" "os"
"path/filepath" "path/filepath"
"regexp" "regexp"
_ "advent-of-code/internal/2015/DayOne" "advent-of-code/internal/registry"
_ "advent-of-code/internal/2015/DayThree"
_ "advent-of-code/internal/2015/DayTwo" _ "advent-of-code/internal/2015"
_ "advent-of-code/internal/2020/DayEight" _ "advent-of-code/internal/2016"
_ "advent-of-code/internal/2020/DayFour" _ "advent-of-code/internal/2018"
_ "advent-of-code/internal/2020/DayOne" _ "advent-of-code/internal/2020"
_ "advent-of-code/internal/2020/DaySeven" _ "advent-of-code/internal/2021"
_ "advent-of-code/internal/2020/DaySix" _ "advent-of-code/internal/2022"
_ "advent-of-code/internal/2020/DayThree" _ "advent-of-code/internal/2025"
_ "advent-of-code/internal/2020/DayTwo"
_ "advent-of-code/internal/2021/DayOne"
_ "advent-of-code/internal/2021/DayThree"
_ "advent-of-code/internal/2021/DayTwo"
_ "advent-of-code/internal/2022/DayOne"
) )
func capitalize(day string) string { func capitalize(day string) string {

View File

@@ -0,0 +1,61 @@
package dayeight
import (
"os"
"strings"
"advent-of-code/internal/registry"
)
func init() {
registry.Register("2015D8", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
return strings.Split(string(content), "\n")
}
func PartOne(data []string) int {
result := 0
for _, line := range data {
codeLength := len(line)
memoryLength := 0
for idx := 1; idx < len(line)-1; idx++ {
if line[idx] == '\\' && idx+1 < len(line)-1 {
switch line[idx+1] {
case '\\', '"':
memoryLength++
idx++
case 'x':
if idx+3 < len(line)-1 {
memoryLength++
idx += 3
}
}
} else {
memoryLength++
}
}
result += codeLength - memoryLength
}
return result
}
func PartTwo(data []string) int {
result := 0
for _, line := range data {
originalLength := len(line)
encodedLength := 2
for _, char := range line {
switch char {
case '\\', '"':
encodedLength += 2
default:
encodedLength++
}
}
result += encodedLength - originalLength
}
return result
}

View File

@@ -0,0 +1,26 @@
package dayeight
import "testing"
var testInput = []string{
`""`,
`"abc"`,
`"aaa\"aaa"`,
`"\x27"`,
}
func TestPartOne(t *testing.T) {
expected := 12
got := PartOne(testInput)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
expected := 19
got := PartTwo(testInput)
if got != expected {
t.Errorf("PartTwo() = %d, want %d", got, expected)
}
}

View File

@@ -0,0 +1,97 @@
package dayeleven
import (
"os"
"advent-of-code/internal/registry"
)
func init() {
registry.Register("2015D11", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) string {
content, _ := os.ReadFile(filepath)
return string(content)
}
func findNextValidPassword(data string) string {
bytes := []byte(data)
increment := func() {
for idx := len(bytes) - 1; idx >= 0; idx-- {
if bytes[idx] == 'z' {
bytes[idx] = 'a'
} else {
bytes[idx]++
if bytes[idx] == 'i' || bytes[idx] == 'o' || bytes[idx] == 'l' {
bytes[idx]++
}
for j := idx + 1; j < len(bytes); j++ {
bytes[j] = 'a'
}
return
}
}
}
increment()
for {
forbiddenPosition := -1
for idx := range bytes {
if bytes[idx] == 'i' || bytes[idx] == 'o' || bytes[idx] == 'l' {
forbiddenPosition = idx
break
}
}
if forbiddenPosition != -1 {
bytes[forbiddenPosition]++
if bytes[forbiddenPosition] == 'i' || bytes[forbiddenPosition] == 'o' || bytes[forbiddenPosition] == 'l' {
bytes[forbiddenPosition]++
}
for j := forbiddenPosition + 1; j < len(bytes); j++ {
bytes[j] = 'a'
}
continue
}
hasStraight := false
for idx := 0; idx < len(bytes)-2; idx++ {
if bytes[idx+1] == bytes[idx]+1 && bytes[idx+2] == bytes[idx]+2 {
hasStraight = true
break
}
}
pairChars := make(map[byte]bool)
for idx := 0; idx < len(bytes)-1; idx++ {
if bytes[idx] == bytes[idx+1] {
pairChars[bytes[idx]] = true
idx++
}
}
if hasStraight && len(pairChars) >= 2 {
break
}
increment()
}
return string(bytes)
}
func PartOne(data string) int {
result := findNextValidPassword(data)
println(result)
return 0
}
func PartTwo(data string) int {
firstPassword := findNextValidPassword(data)
secondPassword := findNextValidPassword(firstPassword)
println(secondPassword)
return 0
}

View File

@@ -0,0 +1,77 @@
package dayfive
import (
"advent-of-code/internal/registry"
"os"
"strings"
)
func init() {
registry.Register("2015D5", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
return strings.Split(string(content), "\n")
}
func PartOne(data []string) int {
count := 0
for _, line := range data {
vowelCount := strings.Count(line, "a") + strings.Count(line, "e") + strings.Count(line, "i") + strings.Count(line, "o") + strings.Count(line, "u")
if vowelCount < 3 {
continue
}
hasDoubleLetter := false
for i := 1; i < len(line); i++ {
if line[i] == line[i-1] {
hasDoubleLetter = true
break
}
}
if !hasDoubleLetter {
continue
}
if strings.Contains(line, "ab") || strings.Contains(line, "cd") || strings.Contains(line, "pq") || strings.Contains(line, "xy") {
continue
}
count++
}
return count
}
func PartTwo(data []string) int {
count := 0
for _, line := range data {
if len(line) < 4 {
continue
}
hasNonOverlappingPair := false
for i := 0; i < len(line)-1; i++ {
pair := line[i : i+2]
if strings.Contains(line[i+2:], pair) {
hasNonOverlappingPair = true
break
}
}
if !hasNonOverlappingPair {
continue
}
hasRepeatingLetterWithGap := false
for i := 0; i < len(line)-2; i++ {
if line[i] == line[i+2] {
hasRepeatingLetterWithGap = true
break
}
}
if hasRepeatingLetterWithGap {
count++
}
}
return count
}

View File

@@ -0,0 +1,32 @@
package dayfive
import "testing"
func TestPartOne(t *testing.T) {
input := []string{
"ugknbfddgicrmopn",
"aaa",
"jchzalrnumimnmhp",
"haegwjzuvuyypxyu",
"dvszwmarrgswjxmb",
}
expected := 2
got := PartOne(input)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
input := []string{
"qjhvhtzxzqqjkmpb",
"xxyxx",
"uurcxstgmygtbstg",
"ieodomkazucvgmuy",
}
expected := 2
got := PartTwo(input)
if got != expected {
t.Errorf("PartTwo() = %d, want %d", got, expected)
}
}

View File

@@ -0,0 +1,46 @@
package dayfour
import (
"advent-of-code/internal/registry"
"bytes"
"crypto/md5"
"os"
"strconv"
)
func init() {
registry.Register("2015D4", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) []byte {
content, _ := os.ReadFile(filepath)
return bytes.TrimSpace(content)
}
func findHashWithZeroes(data []byte, zeroes int) int {
buffer := make([]byte, len(data), len(data)+10)
copy(buffer, data)
for idx := 1; ; idx++ {
buffer = buffer[:len(data)]
buffer = strconv.AppendInt(buffer, int64(idx), 10)
hash := md5.Sum(buffer)
switch zeroes {
case 5:
if hash[0] == 0 && hash[1] == 0 && hash[2]&0xF0 == 0 {
return idx
}
case 6:
if hash[0] == 0 && hash[1] == 0 && hash[2] == 0 {
return idx
}
}
}
}
func PartOne(data []byte) int {
return findHashWithZeroes(data, 5)
}
func PartTwo(data []byte) int {
return findHashWithZeroes(data, 6)
}

View File

@@ -0,0 +1,45 @@
package dayfour
import (
"testing"
)
func TestPartOne(t *testing.T) {
tests := []struct {
name string
input []byte
expected int
}{
{"abcdef", []byte("abcdef"), 609043},
{"pqrstuv", []byte("pqrstuv"), 1048970},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := PartOne(tt.input)
if got != tt.expected {
t.Errorf("PartOne() = %d, want %d", got, tt.expected)
}
})
}
}
func TestPartTwo(t *testing.T) {
tests := []struct {
name string
input []byte
expected int
}{
{"abcdef", []byte("abcdef"), 6742839},
{"pqrstuv", []byte("pqrstuv"), 5714438},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := PartTwo(tt.input)
if got != tt.expected {
t.Errorf("PartTwo() = %d, want %d", got, tt.expected)
}
})
}
}

View File

@@ -0,0 +1,108 @@
package dayfourteen
import (
"advent-of-code/internal/registry"
"os"
"regexp"
"strconv"
"strings"
)
var reindeerPattern = regexp.MustCompile(`\w+ can fly (\d+) km/s for (\d+) seconds, but then must rest for (\d+) seconds\.`)
const raceTime = 2503
type Reindeer struct {
Speed int
FlyTime int
RestTime int
Points int
}
func init() {
registry.Register("2015D14", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
return strings.Split(string(content), "\n")
}
func parseReindeer(line string) Reindeer {
matches := reindeerPattern.FindStringSubmatch(line)
speed, _ := strconv.Atoi(matches[1])
flyTime, _ := strconv.Atoi(matches[2])
restTime, _ := strconv.Atoi(matches[3])
return Reindeer{Speed: speed, FlyTime: flyTime, RestTime: restTime}
}
func parseReindeers(data []string) []Reindeer {
reindeers := make([]Reindeer, 0, len(data))
for _, line := range data {
reindeers = append(reindeers, parseReindeer(line))
}
return reindeers
}
func (reindeer Reindeer) distanceAtTime(time int) int {
cycleTime := reindeer.FlyTime + reindeer.RestTime
fullCycles := time / cycleTime
distance := fullCycles * reindeer.Speed * reindeer.FlyTime
remainingTime := time % cycleTime
distance += reindeer.Speed * min(remainingTime, reindeer.FlyTime)
return distance
}
func calculateMaxDistance(data []string, time int) int {
reindeers := parseReindeers(data)
maxDistance := 0
for _, reindeer := range reindeers {
distance := reindeer.distanceAtTime(time)
if distance > maxDistance {
maxDistance = distance
}
}
return maxDistance
}
func calculateMaxPoints(data []string, time int) int {
reindeers := parseReindeers(data)
for second := 1; second <= time; second++ {
maxDistance := 0
distances := make([]int, len(reindeers))
for idx := range reindeers {
distance := reindeers[idx].distanceAtTime(second)
distances[idx] = distance
if distance > maxDistance {
maxDistance = distance
}
}
for idx := range reindeers {
if distances[idx] == maxDistance {
reindeers[idx].Points++
}
}
}
maxPoints := 0
for idx := range reindeers {
if reindeers[idx].Points > maxPoints {
maxPoints = reindeers[idx].Points
}
}
return maxPoints
}
func PartOne(data []string) int {
return calculateMaxDistance(data, raceTime)
}
func PartTwo(data []string) int {
return calculateMaxPoints(data, raceTime)
}

View File

@@ -0,0 +1,24 @@
package dayfourteen
import "testing"
var testInput = []string{
"Comet can fly 14 km/s for 10 seconds, but then must rest for 127 seconds.",
"Dancer can fly 16 km/s for 11 seconds, but then must rest for 162 seconds.",
}
func TestPartOne(t *testing.T) {
expected := 1120
got := calculateMaxDistance(testInput, 1000)
if got != expected {
t.Errorf("calculateMaxDistance(testInput, 1000) = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
expected := 689
got := calculateMaxPoints(testInput, 1000)
if got != expected {
t.Errorf("calculateMaxPoints(testInput, 1000) = %d, want %d", got, expected)
}
}

View File

@@ -0,0 +1,106 @@
package daynine
import (
"os"
"strconv"
"strings"
"advent-of-code/internal/registry"
)
func init() {
registry.Register("2015D9", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
return strings.Split(string(content), "\n")
}
func buildDistanceMap(data []string) map[string]map[string]int {
distances := make(map[string]map[string]int)
for _, line := range data {
parts := strings.Split(line, " = ")
distance, _ := strconv.Atoi(parts[1])
route := strings.Split(parts[0], " to ")
from, to := route[0], route[1]
if distances[from] == nil {
distances[from] = make(map[string]int)
}
if distances[to] == nil {
distances[to] = make(map[string]int)
}
distances[from][to] = distance
distances[to][from] = distance
}
return distances
}
func getCities(distances map[string]map[string]int) []string {
cities := make([]string, 0, len(distances))
for city := range distances {
cities = append(cities, city)
}
return cities
}
func generatePermutations(cities []string) [][]string {
if len(cities) == 0 {
return [][]string{{}}
}
var result [][]string
for idx, city := range cities {
remaining := make([]string, len(cities)-1)
copy(remaining[:idx], cities[:idx])
copy(remaining[idx:], cities[idx+1:])
for _, permutations := range generatePermutations(remaining) {
result = append(result, append([]string{city}, permutations...))
}
}
return result
}
func calculateRouteDistance(route []string, distances map[string]map[string]int) int {
total := 0
for idx := 0; idx < len(route)-1; idx++ {
total += distances[route[idx]][route[idx+1]]
}
return total
}
func PartOne(data []string) int {
distances := buildDistanceMap(data)
cities := getCities(distances)
permutations := generatePermutations(cities)
minimalDistance := int(^uint(0) >> 1)
for _, route := range permutations {
total := calculateRouteDistance(route, distances)
if total < minimalDistance {
minimalDistance = total
}
}
return minimalDistance
}
func PartTwo(data []string) int {
distances := buildDistanceMap(data)
cities := getCities(distances)
permutations := generatePermutations(cities)
maximalDistance := 0
for _, route := range permutations {
total := calculateRouteDistance(route, distances)
if total > maximalDistance {
maximalDistance = total
}
}
return maximalDistance
}

View File

@@ -0,0 +1,25 @@
package daynine
import "testing"
var testInput = []string{
"London to Dublin = 464",
"London to Belfast = 518",
"Dublin to Belfast = 141",
}
func TestPartOne(t *testing.T) {
expected := 605
got := PartOne(testInput)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
expected := 982
got := PartTwo(testInput)
if got != expected {
t.Errorf("PartTwo() = %d, want %d", got, expected)
}
}

View File

@@ -23,7 +23,7 @@ func TestPartOne(t *testing.T) {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
got := PartOne(tt.input) got := PartOne(tt.input)
if got != tt.expected { if got != tt.expected {
t.Errorf("PartOne(%q) = %d, want %d", tt.input, got, tt.expected) t.Errorf("PartOne() = %d, want %d", got, tt.expected)
} }
}) })
} }
@@ -43,7 +43,7 @@ func TestPartTwo(t *testing.T) {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
got := PartTwo(tt.input) got := PartTwo(tt.input)
if got != tt.expected { if got != tt.expected {
t.Errorf("PartTwo(%q) = %d, want %d", tt.input, got, tt.expected) t.Errorf("PartTwo() = %d, want %d", got, tt.expected)
} }
}) })
} }

View File

@@ -0,0 +1,77 @@
package dayseven
import (
"maps"
"os"
"strconv"
"strings"
"advent-of-code/internal/registry"
)
func init() {
registry.Register("2015D7", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) map[string]string {
content, _ := os.ReadFile(filepath)
instructions := make(map[string]string)
for line := range strings.SplitSeq(string(content), "\n") {
if parts := strings.Split(line, " -> "); len(parts) == 2 {
instructions[parts[1]] = parts[0]
}
}
return instructions
}
func evaluateWire(wire string, instructions map[string]string) uint16 {
cache := make(map[string]uint16)
var evaluate func(string) uint16
evaluate = func(wire string) uint16 {
if value, ok := cache[wire]; ok {
return value
}
if num, err := strconv.Atoi(wire); err == nil {
return uint16(num)
}
expression, exists := instructions[wire]
if !exists {
return 0
}
parts := strings.Fields(expression)
var result uint16
switch {
case len(parts) == 1:
result = evaluate(parts[0])
case parts[0] == "NOT":
result = ^evaluate(parts[1])
default:
left, right := evaluate(parts[0]), evaluate(parts[2])
switch parts[1] {
case "AND":
result = left & right
case "OR":
result = left | right
case "LSHIFT":
result = left << right
case "RSHIFT":
result = left >> right
}
}
cache[wire] = result
return result
}
return evaluate(wire)
}
func PartOne(data map[string]string) int {
return int(evaluateWire("a", data))
}
func PartTwo(data map[string]string) int {
signalA := PartOne(data)
instructionsCopy := make(map[string]string, len(data))
maps.Copy(instructionsCopy, data)
instructionsCopy["b"] = strconv.Itoa(signalA)
return int(evaluateWire("a", instructionsCopy))
}

View File

@@ -0,0 +1,50 @@
package dayseven
import (
"testing"
)
var testInput = map[string]string{
"x": "123",
"y": "456",
"d": "x AND y",
"e": "x OR y",
"f": "x LSHIFT 2",
"g": "y RSHIFT 2",
"h": "NOT x",
"i": "NOT y",
"a": "d",
}
func TestPartOne(t *testing.T) {
expected := 72
got := PartOne(testInput)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
instructions := map[string]string{
"x": "10",
"y": "20",
"z": "x AND y",
"b": "z",
"w": "b LSHIFT 1",
"v": "NOT b",
"u": "w OR v",
"a": "u",
}
partOneResult := PartOne(instructions)
bValue := uint16(partOneResult)
w := bValue << 1
v := ^bValue
u := w | v
expected := int(u)
got := PartTwo(instructions)
if got != expected {
t.Errorf("PartTwo() = %d, want %d (PartOne result: %d)", got, expected, partOneResult)
}
}

View File

@@ -0,0 +1,119 @@
package daysix
import (
"advent-of-code/internal/registry"
"os"
"strconv"
"strings"
)
type instruction struct {
operation string
x1, y1 int
x2, y2 int
}
func init() {
registry.Register("2015D6", ParseInput, PartOne, PartTwo)
}
func parseInstruction(line string) (instruction, bool) {
var op string
var remaining string
switch {
case strings.HasPrefix(line, "turn on "):
op = "on"
remaining = strings.TrimPrefix(line, "turn on ")
case strings.HasPrefix(line, "turn off "):
op = "off"
remaining = strings.TrimPrefix(line, "turn off ")
case strings.HasPrefix(line, "toggle "):
op = "toggle"
remaining = strings.TrimPrefix(line, "toggle ")
default:
return instruction{}, false
}
parts := strings.Split(remaining, " through ")
firstCoordinates := strings.Split(parts[0], ",")
secondCoordinates := strings.Split(parts[1], ",")
x1, _ := strconv.Atoi(firstCoordinates[0])
y1, _ := strconv.Atoi(firstCoordinates[1])
x2, _ := strconv.Atoi(secondCoordinates[0])
y2, _ := strconv.Atoi(secondCoordinates[1])
return instruction{operation: op, x1: x1, y1: y1, x2: x2, y2: y2}, true
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
return strings.Split(strings.TrimSpace(string(content)), "\n")
}
func PartOne(data []string) int {
grid := make([]bool, 1000*1000)
for _, line := range data {
instruction, ok := parseInstruction(line)
if !ok {
continue
}
for y := instruction.y1; y <= instruction.y2; y++ {
for x := instruction.x1; x <= instruction.x2; x++ {
idx := y*1000 + x
switch instruction.operation {
case "on":
grid[idx] = true
case "off":
grid[idx] = false
case "toggle":
grid[idx] = !grid[idx]
}
}
}
}
count := 0
for _, lit := range grid {
if lit {
count++
}
}
return count
}
func PartTwo(data []string) int {
grid := make([]int, 1000*1000)
for _, line := range data {
instruction, ok := parseInstruction(line)
if !ok {
continue
}
for y := instruction.y1; y <= instruction.y2; y++ {
for x := instruction.x1; x <= instruction.x2; x++ {
idx := y*1000 + x
switch instruction.operation {
case "on":
grid[idx]++
case "off":
if grid[idx] > 0 {
grid[idx]--
}
case "toggle":
grid[idx] += 2
}
}
}
}
total := 0
for _, brightness := range grid {
total += brightness
}
return total
}

View File

@@ -0,0 +1,25 @@
package daysix
import "testing"
var testInput = []string{
"turn on 0,0 through 999,999",
"toggle 0,0 through 999,0",
"turn off 499,499 through 500,500",
}
func TestPartOne(t *testing.T) {
expected := 998996
got := PartOne(testInput)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
expected := 1001996
got := PartTwo(testInput)
if got != expected {
t.Errorf("PartTwo() = %d, want %d", got, expected)
}
}

View File

@@ -0,0 +1,45 @@
package dayten
import (
"os"
"strconv"
"strings"
"advent-of-code/internal/registry"
)
func init() {
registry.Register("2015D10", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) string {
content, _ := os.ReadFile(filepath)
return string(content)
}
func applyLookAndSay(data string, iterations int) int {
for range iterations {
var result strings.Builder
idx := 0
for idx < len(data) {
digit := data[idx]
count := 1
for idx+count < len(data) && data[idx+count] == digit {
count++
}
result.WriteString(strconv.Itoa(count))
result.WriteByte(digit)
idx += count
}
data = result.String()
}
return len(data)
}
func PartOne(data string) int {
return applyLookAndSay(data, 40)
}
func PartTwo(data string) int {
return applyLookAndSay(data, 50)
}

View File

@@ -0,0 +1,141 @@
package daythirteen
import (
"advent-of-code/internal/registry"
"math"
"os"
"regexp"
"strconv"
"strings"
)
var inputPattern = regexp.MustCompile(`(\w+) would (gain|lose) (\d+) happiness units by sitting next to (\w+)\.?`)
func init() {
registry.Register("2015D13", ParseInput, PartOne, PartTwo)
}
func buildHappinessMap(data []string) map[string]map[string]int {
happinessMap := make(map[string]map[string]int)
for _, line := range data {
matches := inputPattern.FindStringSubmatch(line)
person := matches[1]
operation := matches[2]
value, _ := strconv.Atoi(matches[3])
neighbor := matches[4]
if happinessMap[person] == nil {
happinessMap[person] = make(map[string]int)
}
if operation == "gain" {
happinessMap[person][neighbor] = value
} else {
happinessMap[person][neighbor] = -value
}
}
return happinessMap
}
func getAllPeople(happinessMap map[string]map[string]int) []string {
people := make([]string, 0, len(happinessMap))
for person := range happinessMap {
people = append(people, person)
}
return people
}
func generatePermutations(items []string) [][]string {
if len(items) == 0 {
return [][]string{{}}
}
var result [][]string
for idx, item := range items {
remaining := make([]string, len(items)-1)
copy(remaining[:idx], items[:idx])
copy(remaining[idx:], items[idx+1:])
for _, permutation := range generatePermutations(remaining) {
result = append(result, append([]string{item}, permutation...))
}
}
return result
}
func calculateTotalHappiness(arrangement []string, happinessMap map[string]map[string]int) int {
totalHappiness := 0
arrangementLength := len(arrangement)
for idx := range arrangementLength {
currentPerson := arrangement[idx]
leftNeighbor := arrangement[(idx-1+arrangementLength)%arrangementLength]
rightNeighbor := arrangement[(idx+1)%arrangementLength]
totalHappiness += happinessMap[currentPerson][leftNeighbor]
totalHappiness += happinessMap[currentPerson][rightNeighbor]
}
return totalHappiness
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
return strings.Split(string(content), "\n")
}
func PartOne(data []string) int {
happinessMap := buildHappinessMap(data)
allPeople := getAllPeople(happinessMap)
fixedPerson := allPeople[0]
remainingPeople := allPeople[1:]
permutations := generatePermutations(remainingPeople)
maxHappiness := math.MinInt
arrangement := make([]string, len(allPeople))
arrangement[0] = fixedPerson
for _, perm := range permutations {
copy(arrangement[1:], perm)
totalHappiness := calculateTotalHappiness(arrangement, happinessMap)
if totalHappiness > maxHappiness {
maxHappiness = totalHappiness
}
}
return maxHappiness
}
func PartTwo(data []string) int {
happinessMap := buildHappinessMap(data)
allPeople := getAllPeople(happinessMap)
me := "Me"
happinessMap[me] = make(map[string]int)
for _, person := range allPeople {
happinessMap[person][me] = 0
happinessMap[me][person] = 0
}
allPeople = append(allPeople, me)
fixedPerson := allPeople[0]
remainingPeople := allPeople[1:]
permutations := generatePermutations(remainingPeople)
maxTotalChange := math.MinInt
arrangement := make([]string, len(allPeople))
arrangement[0] = fixedPerson
for _, permutation := range permutations {
copy(arrangement[1:], permutation)
totalHappiness := calculateTotalHappiness(arrangement, happinessMap)
if totalHappiness > maxTotalChange {
maxTotalChange = totalHappiness
}
}
return maxTotalChange
}

View File

@@ -0,0 +1,28 @@
package daythirteen
import "testing"
var testInput = []string{
"Alice would gain 54 happiness units by sitting next to Bob",
"Alice would lose 79 happiness units by sitting next to Carol",
"Alice would lose 2 happiness units by sitting next to David",
"Bob would gain 83 happiness units by sitting next to Alice",
"Bob would lose 7 happiness units by sitting next to Carol",
"Bob would lose 63 happiness units by sitting next to David",
"Carol would lose 62 happiness units by sitting next to Alice",
"Carol would gain 60 happiness units by sitting next to Bob",
"Carol would gain 55 happiness units by sitting next to David",
"David would gain 46 happiness units by sitting next to Alice",
"David would lose 7 happiness units by sitting next to Bob",
"David would gain 41 happiness units by sitting next to Carol",
}
func TestPartOne(t *testing.T) {
expected := 330
got := PartOne(testInput)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
// no test for part two

View File

@@ -39,5 +39,30 @@ func PartOne(data string) int {
} }
func PartTwo(data string) int { func PartTwo(data string) int {
return 0 houses := make(map[coordinates]int)
santaX, santaY := 0, 0
robotX, robotY := 0, 0
houses[coordinates{0, 0}] = 2
for idx, direction := range data {
var x, y *int
if idx%2 == 0 {
x, y = &santaX, &santaY
} else {
x, y = &robotX, &robotY
}
switch direction {
case '>':
*x++
case '<':
*x--
case '^':
*y++
case 'v':
*y--
}
houses[coordinates{*x, *y}]++
}
return len(houses)
} }

View File

@@ -17,7 +17,28 @@ func TestPartOne(t *testing.T) {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
got := PartOne(tt.input) got := PartOne(tt.input)
if got != tt.expected { if got != tt.expected {
t.Errorf("PartOne(%q) = %d, want %d", tt.input, got, tt.expected) t.Errorf("PartOne() = %d, want %d", got, tt.expected)
}
})
}
}
func TestPartTwo(t *testing.T) {
tests := []struct {
name string
input string
expected int
}{
{"^v", "^v", 3},
{"^>v<", "^>v<", 3},
{"^v^v^v^v^v", "^v^v^v^v^v", 11},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := PartTwo(tt.input)
if got != tt.expected {
t.Errorf("PartTwo() = %d, want %d", got, tt.expected)
} }
}) })
} }

View File

@@ -0,0 +1,68 @@
package daytwelve
import (
"encoding/json"
"os"
"regexp"
"strconv"
"strings"
"advent-of-code/internal/registry"
)
func init() {
registry.Register("2015D12", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
return strings.Split(string(content), "\n")
}
func PartOne(data []string) int {
re := regexp.MustCompile(`-?\d+`)
sum := 0
for _, line := range data {
matches := re.FindAllString(line, -1)
for _, match := range matches {
number, _ := strconv.Atoi(match)
sum += number
}
}
return sum
}
func PartTwo(data []string) int {
var sumNumbers func(any) int
sumNumbers = func(v any) int {
switch value := v.(type) {
case float64:
return int(value)
case []any:
sum := 0
for _, item := range value {
sum += sumNumbers(item)
}
return sum
case map[string]any:
sum := 0
for _, item := range value {
if str, ok := item.(string); ok && str == "red" {
return 0
}
sum += sumNumbers(item)
}
return sum
default:
return 0
}
}
sum := 0
for _, line := range data {
var value any
_ = json.Unmarshal([]byte(line), &value)
sum += sumNumbers(value)
}
return sum
}

View File

@@ -0,0 +1,51 @@
package daytwelve
import "testing"
func TestPartOne(t *testing.T) {
tests := []struct {
name string
input string
expected int
}{
{"[1,2,3]", "[1,2,3]", 6},
{"{\"a\":2,\"b\":4}", "{\"a\":2,\"b\":4}", 6},
{"[[[3]]]", "[[[3]]]", 3},
{"{\"a\":{\"b\":4},\"c\":-1}", "{\"a\":{\"b\":4},\"c\":-1}", 3},
{"{\"a\":[-1,1]}", "{\"a\":[-1,1]}", 0},
{"[-1,{\"a\":1}]", "[-1,{\"a\":1}]", 0},
{"[]", "[]", 0},
{"{}", "{}", 0},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := PartOne([]string{tt.input})
if got != tt.expected {
t.Errorf("PartOne() = %d, want %d", got, tt.expected)
}
})
}
}
func TestPartTwo(t *testing.T) {
tests := []struct {
name string
input string
expected int
}{
{"[1,2,3]", "[1,2,3]", 6},
{"[1,{\"c\":\"red\",\"b\":2},3]", "[1,{\"c\":\"red\",\"b\":2},3]", 4},
{"{\"d\":\"red\",\"e\":[1,2,3,4],\"f\":5}", "{\"d\":\"red\",\"e\":[1,2,3,4],\"f\":5}", 0},
{"[1,\"red\",5]", "[1,\"red\",5]", 6},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := PartTwo([]string{tt.input})
if got != tt.expected {
t.Errorf("PartTwo() = %d, want %d", got, tt.expected)
}
})
}
}

View File

@@ -16,7 +16,7 @@ func TestPartOne(t *testing.T) {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
got := PartOne([]string{tt.input}) got := PartOne([]string{tt.input})
if got != tt.expected { if got != tt.expected {
t.Errorf("PartOne(%q) = %d, want %d", tt.input, got, tt.expected) t.Errorf("PartOne() = %d, want %d", got, tt.expected)
} }
}) })
} }
@@ -36,7 +36,7 @@ func TestPartTwo(t *testing.T) {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
got := PartTwo([]string{tt.input}) got := PartTwo([]string{tt.input})
if got != tt.expected { if got != tt.expected {
t.Errorf("PartTwo(%q) = %d, want %d", tt.input, got, tt.expected) t.Errorf("PartTwo() = %d, want %d", got, tt.expected)
} }
}) })
} }

18
internal/2015/register.go Normal file
View File

@@ -0,0 +1,18 @@
package year2015
import (
_ "advent-of-code/internal/2015/DayEight"
_ "advent-of-code/internal/2015/DayEleven"
_ "advent-of-code/internal/2015/DayFive"
_ "advent-of-code/internal/2015/DayFour"
_ "advent-of-code/internal/2015/DayFourteen"
_ "advent-of-code/internal/2015/DayNine"
_ "advent-of-code/internal/2015/DayOne"
_ "advent-of-code/internal/2015/DaySeven"
_ "advent-of-code/internal/2015/DaySix"
_ "advent-of-code/internal/2015/DayTen"
_ "advent-of-code/internal/2015/DayThirteen"
_ "advent-of-code/internal/2015/DayThree"
_ "advent-of-code/internal/2015/DayTwelve"
_ "advent-of-code/internal/2015/DayTwo"
)

View File

@@ -0,0 +1,73 @@
package dayfive
import (
"advent-of-code/internal/registry"
"crypto/md5"
"fmt"
"os"
"strconv"
)
func init() {
registry.Register("2016D5", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) string {
content, _ := os.ReadFile(filepath)
return string(content)
}
func PartOne(data string) int {
doorIDBytes := []byte(data)
doorIDLen := len(doorIDBytes)
input := make([]byte, doorIDLen, doorIDLen+20)
copy(input, doorIDBytes)
password := make([]byte, 0, 8)
index := 0
hexChars := "0123456789abcdef"
for len(password) < 8 {
indexBytes := strconv.AppendInt(input[:doorIDLen], int64(index), 10)
hash := md5.Sum(indexBytes)
if hash[0] == 0 && hash[1] == 0 && hash[2] < 16 {
char := hexChars[hash[2]&0x0F]
password = append(password, char)
}
index++
}
fmt.Println(string(password))
return 0
}
func PartTwo(data string) int {
doorIDBytes := []byte(data)
doorIDLen := len(doorIDBytes)
input := make([]byte, doorIDLen, doorIDLen+20)
copy(input, doorIDBytes)
password := make([]byte, 8)
filled := make([]bool, 8)
filledCount := 0
index := 0
hexChars := "0123456789abcdef"
for filledCount < 8 {
indexBytes := strconv.AppendInt(input[:doorIDLen], int64(index), 10)
hash := md5.Sum(indexBytes)
if hash[0] == 0 && hash[1] == 0 && hash[2] < 16 {
position := int(hash[2] & 0x0F)
if position < 8 && !filled[position] {
char := hexChars[hash[3]>>4]
password[position] = char
filled[position] = true
filledCount++
}
}
index++
}
fmt.Println(string(password))
return 0
}

View File

@@ -0,0 +1,58 @@
package dayfive
import (
"bytes"
"os"
"strings"
"testing"
)
var testInput = "abc"
func TestPartOne(t *testing.T) {
expected := "18f47a30"
oldStdout := os.Stdout
r, w, err := os.Pipe()
if err != nil {
t.Fatalf("Failed to create pipe: %v", err)
}
os.Stdout = w
PartOne(testInput)
_ = w.Close()
os.Stdout = oldStdout
var buffer bytes.Buffer
_, _ = buffer.ReadFrom(r)
got := strings.TrimSpace(buffer.String())
if got != expected {
t.Errorf("PartOne() printed %q, want %q", got, expected)
}
}
func TestPartTwo(t *testing.T) {
expected := "05ace8e3"
oldStdout := os.Stdout
r, w, err := os.Pipe()
if err != nil {
t.Fatalf("Failed to create pipe: %v", err)
}
os.Stdout = w
PartTwo(testInput)
_ = w.Close()
os.Stdout = oldStdout
var buffer bytes.Buffer
_, _ = buffer.ReadFrom(r)
got := strings.TrimSpace(buffer.String())
if got != expected {
t.Errorf("PartTwo() printed %q, want %q", got, expected)
}
}

View File

@@ -0,0 +1,119 @@
package dayfour
import (
"advent-of-code/internal/registry"
"os"
"regexp"
"sort"
"strconv"
"strings"
)
func init() {
registry.Register("2016D4", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
return strings.Split(string(content), "\n")
}
func isValidRoom(encryptedName string, expectedChecksum string) bool {
letterFrequency := [26]int{}
for _, character := range encryptedName {
if character >= 'a' && character <= 'z' {
letterFrequency[character-'a']++
}
}
type letterFrequencyPair struct {
letter rune
count int
}
letterFrequencyPairs := make([]letterFrequencyPair, 0, 26)
for index, frequency := range letterFrequency {
if frequency > 0 {
letterFrequencyPairs = append(letterFrequencyPairs, letterFrequencyPair{
letter: rune('a' + index),
count: frequency,
})
}
}
sort.Slice(letterFrequencyPairs, func(i, j int) bool {
if letterFrequencyPairs[i].count != letterFrequencyPairs[j].count {
return letterFrequencyPairs[i].count > letterFrequencyPairs[j].count
}
return letterFrequencyPairs[i].letter < letterFrequencyPairs[j].letter
})
if len(letterFrequencyPairs) < 5 {
return false
}
for index := range 5 {
if letterFrequencyPairs[index].letter != rune(expectedChecksum[index]) {
return false
}
}
return true
}
func decryptRoomName(encryptedName string, sectorID int) string {
result := strings.Builder{}
result.Grow(len(encryptedName))
shift := sectorID % 26
for _, char := range encryptedName {
if char == '-' {
result.WriteByte(' ')
} else if char >= 'a' && char <= 'z' {
shifted := ((int(char-'a') + shift) % 26) + 'a'
result.WriteByte(byte(shifted))
}
}
return result.String()
}
var roomPattern = regexp.MustCompile(`^(.+)-(\d+)(?:\[([a-z]{5})\])?$`)
func PartOne(data []string) int {
sum := 0
for _, line := range data {
if line == "" {
continue
}
matches := roomPattern.FindStringSubmatch(line)
if len(matches) < 4 || matches[3] == "" {
continue
}
encryptedName := matches[1]
sectorIdentifier, _ := strconv.Atoi(matches[2])
actualChecksum := matches[3]
if isValidRoom(encryptedName, actualChecksum) {
sum += sectorIdentifier
}
}
return sum
}
func PartTwo(data []string) int {
for _, line := range data {
matches := roomPattern.FindStringSubmatch(line)
encryptedName := matches[1]
sectorIdentifier, _ := strconv.Atoi(matches[2])
checksum := matches[3]
if !isValidRoom(encryptedName, checksum) {
continue
}
decrypted := decryptRoomName(encryptedName, sectorIdentifier)
if strings.Contains(decrypted, "northpole") {
return sectorIdentifier
}
}
return 0
}

View File

@@ -0,0 +1,29 @@
package dayfour
import (
"testing"
)
var testInput = []string{
"aaaaa-bbb-z-y-x-123[abxyz]",
"a-b-c-d-e-f-g-h-987[abcde]",
"not-a-real-room-404[oarel]",
"totally-real-room-200[decoy]",
"ijmockjgz-storage-5[gjoac]",
}
func TestPartOne(t *testing.T) {
expected := 1519
got := PartOne(testInput)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
expected := 5
got := PartTwo(testInput)
if got != expected {
t.Errorf("PartTwo() = %d, want %d", got, expected)
}
}

View File

@@ -0,0 +1,91 @@
package dayone
import (
"os"
"strconv"
"strings"
"advent-of-code/internal/registry"
)
func init() {
registry.Register("2016D1", ParseInput, PartOne, PartTwo)
}
type position struct {
x, y int
}
func abs(n int) int {
if n < 0 {
return -n
}
return n
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
parts := strings.Split(string(content), ",")
for i, p := range parts {
parts[i] = strings.TrimSpace(p)
}
return parts
}
func PartOne(data []string) int {
x, y := 0, 0
directions := [][]int{{0, 1}, {1, 0}, {0, -1}, {-1, 0}}
currentDirection := 0
for _, instruction := range data {
turn := instruction[0]
distance, _ := strconv.Atoi(instruction[1:])
switch turn {
case 'R':
currentDirection = (currentDirection + 1) % 4
case 'L':
currentDirection = (currentDirection + 3) % 4
}
x += directions[currentDirection][0] * distance
y += directions[currentDirection][1] * distance
}
return abs(x) + abs(y)
}
func PartTwo(data []string) int {
x, y := 0, 0
directions := [][]int{{0, 1}, {1, 0}, {0, -1}, {-1, 0}}
currentDirection := 0
visited := make(map[position]bool)
visited[position{0, 0}] = true
for _, instruction := range data {
turn := instruction[0]
distance, _ := strconv.Atoi(instruction[1:])
switch turn {
case 'R':
currentDirection = (currentDirection + 1) % 4
case 'L':
currentDirection = (currentDirection + 3) % 4
}
directionX := directions[currentDirection][0]
directionY := directions[currentDirection][1]
for range distance {
x += directionX
y += directionY
pos := position{x, y}
if visited[pos] {
return abs(x) + abs(y)
}
visited[pos] = true
}
}
return 0
}

View File

@@ -0,0 +1,47 @@
package dayone
import (
"testing"
)
func TestPartOne(t *testing.T) {
tests := []struct {
name string
input []string
expected int
}{
{
name: "Example 1",
input: []string{"R2", "L3"},
expected: 5,
},
{
name: "Example 2",
input: []string{"R2", "R2", "R2"},
expected: 2,
},
{
name: "Example 3",
input: []string{"R5", "L5", "R5", "R3"},
expected: 12,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := PartOne(tt.input)
if got != tt.expected {
t.Errorf("PartOne() = %d, want %d", got, tt.expected)
}
})
}
}
func TestPartTwo(t *testing.T) {
input := []string{"R8", "R4", "R4", "R8"}
expected := 4
got := PartTwo(input)
if got != expected {
t.Errorf("PartTwo() = %d, want %d", got, 4)
}
}

View File

@@ -0,0 +1,49 @@
package daythree
import (
"advent-of-code/internal/registry"
"fmt"
"os"
"strings"
)
func init() {
registry.Register("2016D3", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) [][3]int {
content, _ := os.ReadFile(filepath)
lines := strings.Split(string(content), "\n")
var result [][3]int
for _, line := range lines {
var a, b, c int
fmt.Sscanf(line, "%d %d %d", &a, &b, &c)
result = append(result, [3]int{a, b, c})
}
return result
}
func PartOne(data [][3]int) int {
count := 0
for _, triangle := range data {
a, b, c := triangle[0], triangle[1], triangle[2]
if a+b > c && a+c > b && b+c > a {
count++
}
}
return count
}
func PartTwo(data [][3]int) int {
count := 0
for idx := 0; idx < len(data)-2; idx += 3 {
for column := range 3 {
a, b, c := data[idx][column], data[idx+1][column], data[idx+2][column]
if a+b > c && a+c > b && b+c > a {
count++
}
}
}
return count
}

View File

@@ -0,0 +1,28 @@
package daythree
import "testing"
func TestPartOne(t *testing.T) {
input := [][3]int{{5, 10, 25}}
expected := 0
got := PartOne(input)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
input := [][3]int{
{101, 301, 501},
{102, 302, 502},
{103, 303, 503},
{201, 401, 601},
{202, 402, 602},
{203, 403, 603},
}
expected := 6
got := PartTwo(input)
if got != expected {
t.Errorf("PartTwo() = %d, want %d", got, expected)
}
}

View File

@@ -0,0 +1,101 @@
package daytwo
import (
"advent-of-code/internal/registry"
"fmt"
"os"
"strings"
)
func init() {
registry.Register("2016D2", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
return strings.Split(string(content), "\n")
}
func PartOne(instructions []string) int {
row, column := 1, 1
keypad := [3][3]int{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9},
}
code := 0
for _, line := range instructions {
for _, move := range line {
switch move {
case 'U':
if row > 0 {
row--
}
case 'D':
if row < 2 {
row++
}
case 'L':
if column > 0 {
column--
}
case 'R':
if column < 2 {
column++
}
}
}
code = code*10 + keypad[row][column]
}
return code
}
func PartTwo(instructions []string) int {
row, column := 2, 0
keypad := [5][5]int{
{0, 0, 1, 0, 0},
{0, 2, 3, 4, 0},
{5, 6, 7, 8, 9},
{0, 10, 11, 12, 0},
{0, 0, 13, 0, 0},
}
isValidPosition := func(r, c int) bool {
return r >= 0 && r < 5 && c >= 0 && c < 5 && keypad[r][c] != 0
}
var codeBuilder strings.Builder
for _, line := range instructions {
for _, move := range line {
newRow, newColumn := row, column
switch move {
case 'U':
newRow--
case 'D':
newRow++
case 'L':
newColumn--
case 'R':
newColumn++
}
if isValidPosition(newRow, newColumn) {
row, column = newRow, newColumn
}
}
value := keypad[row][column]
if value < 10 {
codeBuilder.WriteByte(byte('0' + value))
} else {
codeBuilder.WriteByte(byte('A' + value - 10))
}
}
code := codeBuilder.String()
fmt.Println(code)
return 0
}

View File

@@ -0,0 +1,42 @@
package daytwo
import (
"bytes"
"os"
"strings"
"testing"
)
var testInput = []string{"ULL", "RRDDD", "LURDL", "UUUUD"}
func TestPartOne(t *testing.T) {
expected := 1985
got := PartOne(testInput)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
expected := "5DB3"
oldStdout := os.Stdout
r, w, err := os.Pipe()
if err != nil {
t.Fatalf("Failed to create pipe: %v", err)
}
os.Stdout = w
PartTwo(testInput)
_ = w.Close()
os.Stdout = oldStdout
var buffer bytes.Buffer
_, _ = buffer.ReadFrom(r)
got := strings.TrimSpace(buffer.String())
if got != expected {
t.Errorf("PartTwo() printed %q, want %q", got, expected)
}
}

View File

@@ -0,0 +1,9 @@
package year2016
import (
_ "advent-of-code/internal/2016/DayFive"
_ "advent-of-code/internal/2016/DayFour"
_ "advent-of-code/internal/2016/DayOne"
_ "advent-of-code/internal/2016/DayThree"
_ "advent-of-code/internal/2016/DayTwo"
)

View File

@@ -0,0 +1,64 @@
package dayfive
import (
"advent-of-code/internal/registry"
"os"
"unicode"
)
func init() {
registry.Register("2018D5", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) string {
content, _ := os.ReadFile(filepath)
return string(content)
}
func reactPolymer(data string) int {
stack := []rune{}
for _, char := range data {
if len(stack) == 0 {
stack = append(stack, char)
continue
}
top := stack[len(stack)-1]
if unicode.ToLower(top) == unicode.ToLower(char) && top != char {
stack = stack[:len(stack)-1]
} else {
stack = append(stack, char)
}
}
return len(stack)
}
func PartOne(data string) int {
return reactPolymer(data)
}
func PartTwo(data string) int {
unitTypes := make(map[rune]bool)
for _, char := range data {
unitTypes[unicode.ToLower(char)] = true
}
shortestPolymerLength := len(data)
for unitType := range unitTypes {
filtered := make([]rune, 0, len(data))
for _, char := range data {
if unicode.ToLower(char) != unitType {
filtered = append(filtered, char)
}
}
length := reactPolymer(string(filtered))
if length < shortestPolymerLength {
shortestPolymerLength = length
}
}
return shortestPolymerLength
}

View File

@@ -0,0 +1,21 @@
package dayfive
import "testing"
var testInput = "dabAcCaCBAcCcaDA"
func TestPartOne(t *testing.T) {
expected := 10
got := PartOne(testInput)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
expected := 4
got := PartTwo(testInput)
if got != expected {
t.Errorf("PartTwo() = %d, want %d", got, expected)
}
}

View File

@@ -0,0 +1,133 @@
package dayfour
import (
"os"
"regexp"
"slices"
"strconv"
"strings"
"time"
"advent-of-code/internal/registry"
)
var (
guardRegex = regexp.MustCompile(`Guard #(\d+) begins shift`)
timeLayout = "2006-01-02 15:04"
)
func init() {
registry.Register("2018D4", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
return strings.Split(string(content), "\n")
}
type record struct {
timestamp time.Time
action string
guardID int
}
func PartOne(data []string) int {
records := make([]record, 0, len(data))
for _, line := range data {
timeStr, action, _ := strings.Cut(line[1:], "] ")
timestamp, _ := time.Parse(timeLayout, timeStr)
guardID := -1
if matches := guardRegex.FindStringSubmatch(action); matches != nil {
guardID, _ = strconv.Atoi(matches[1])
}
records = append(records, record{timestamp, action, guardID})
}
slices.SortFunc(records, func(a, b record) int {
return a.timestamp.Compare(b.timestamp)
})
guardSleepMinutes := make(map[int]int)
guardMinuteCount := make(map[int]map[int]int)
currentGuard := -1
for i := range records {
if records[i].guardID != -1 {
currentGuard = records[i].guardID
if guardMinuteCount[currentGuard] == nil {
guardMinuteCount[currentGuard] = make(map[int]int)
}
}
if records[i].action == "falls asleep" && i+1 < len(records) {
start, end := records[i].timestamp.Minute(), records[i+1].timestamp.Minute()
guardSleepMinutes[currentGuard] += end - start
for m := start; m < end; m++ {
guardMinuteCount[currentGuard][m]++
}
}
}
maxGuard, maxMinutes := -1, 0
for id, minutes := range guardSleepMinutes {
if minutes > maxMinutes {
maxGuard, maxMinutes = id, minutes
}
}
maxMinute, maxCount := -1, 0
for m, count := range guardMinuteCount[maxGuard] {
if count > maxCount {
maxMinute, maxCount = m, count
}
}
return maxGuard * maxMinute
}
func PartTwo(data []string) int {
records := make([]record, 0, len(data))
for _, line := range data {
timeStr, action, _ := strings.Cut(line[1:], "] ")
timestamp, _ := time.Parse(timeLayout, timeStr)
guardID := -1
if matches := guardRegex.FindStringSubmatch(action); matches != nil {
guardID, _ = strconv.Atoi(matches[1])
}
records = append(records, record{timestamp, action, guardID})
}
slices.SortFunc(records, func(a, b record) int {
return a.timestamp.Compare(b.timestamp)
})
guardMinuteCount := make(map[int]map[int]int)
currentGuard := -1
for idx := range records {
if records[idx].guardID != -1 {
currentGuard = records[idx].guardID
if guardMinuteCount[currentGuard] == nil {
guardMinuteCount[currentGuard] = make(map[int]int)
}
}
if records[idx].action == "falls asleep" && idx+1 < len(records) {
start, end := records[idx].timestamp.Minute(), records[idx+1].timestamp.Minute()
for m := start; m < end; m++ {
guardMinuteCount[currentGuard][m]++
}
}
}
maxGuard, maxMinute, maxCount := -1, -1, 0
for guardID, minuteCounts := range guardMinuteCount {
for minute, count := range minuteCounts {
if count > maxCount {
maxGuard, maxMinute, maxCount = guardID, minute, count
}
}
}
return maxGuard * maxMinute
}

View File

@@ -0,0 +1,39 @@
package dayfour
import "testing"
var testInput = []string{
"[1518-11-01 00:00] Guard #10 begins shift",
"[1518-11-01 00:05] falls asleep",
"[1518-11-01 00:25] wakes up",
"[1518-11-01 00:30] falls asleep",
"[1518-11-01 00:55] wakes up",
"[1518-11-01 23:58] Guard #99 begins shift",
"[1518-11-02 00:40] falls asleep",
"[1518-11-02 00:50] wakes up",
"[1518-11-03 00:05] Guard #10 begins shift",
"[1518-11-03 00:24] falls asleep",
"[1518-11-03 00:29] wakes up",
"[1518-11-04 00:02] Guard #99 begins shift",
"[1518-11-04 00:36] falls asleep",
"[1518-11-04 00:46] wakes up",
"[1518-11-05 00:03] Guard #99 begins shift",
"[1518-11-05 00:45] falls asleep",
"[1518-11-05 00:55] wakes up",
}
func TestPartOne(t *testing.T) {
expected := 240
got := PartOne(testInput)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
expected := 4455
got := PartTwo(testInput)
if got != expected {
t.Errorf("PartTwo() = %d, want %d", got, expected)
}
}

View File

@@ -0,0 +1,45 @@
package dayone
import (
"advent-of-code/internal/registry"
"os"
"strconv"
"strings"
)
func init() {
registry.Register("2018D1", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) []int {
content, _ := os.ReadFile(filepath)
var data []int
for line := range strings.SplitSeq(string(content), "\n") {
num, _ := strconv.Atoi(line)
data = append(data, num)
}
return data
}
func PartOne(data []int) int {
sum := 0
for _, num := range data {
sum += num
}
return sum
}
func PartTwo(data []int) int {
seen := make(map[int]bool)
sum := 0
seen[0] = true
for {
for _, num := range data {
sum += num
if seen[sum] {
return sum
}
seen[sum] = true
}
}
}

View File

@@ -0,0 +1,26 @@
package dayone
import "testing"
var testInput = []int{
+1,
-2,
3,
1,
}
func TestPartOne(t *testing.T) {
expected := 3
got := PartOne(testInput)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
expected := 2
got := PartTwo(testInput)
if got != expected {
t.Errorf("PartTwo() = %d, want %d", got, expected)
}
}

View File

@@ -0,0 +1,101 @@
package daythree
import (
"advent-of-code/internal/registry"
"fmt"
"os"
"regexp"
"strconv"
"strings"
)
func init() {
registry.Register("2018D3", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
return strings.Split(string(content), "\n")
}
func PartOne(data []string) int {
coverage := make(map[string]int)
re := regexp.MustCompile(`#\d+ @ (\d+),(\d+): (\d+)x(\d+)`)
for _, line := range data {
matches := re.FindStringSubmatch(line)
left, _ := strconv.Atoi(matches[1])
top, _ := strconv.Atoi(matches[2])
width, _ := strconv.Atoi(matches[3])
height, _ := strconv.Atoi(matches[4])
for x := left; x < left+width; x++ {
for y := top; y < top+height; y++ {
key := fmt.Sprintf("%d,%d", x, y)
coverage[key]++
}
}
}
overlapCount := 0
for _, count := range coverage {
if count >= 2 {
overlapCount++
}
}
return overlapCount
}
func PartTwo(data []string) int {
coverage := make(map[string]int)
re := regexp.MustCompile(`#\d+ @ (\d+),(\d+): (\d+)x(\d+)`)
for _, line := range data {
matches := re.FindStringSubmatch(line)
left, _ := strconv.Atoi(matches[1])
top, _ := strconv.Atoi(matches[2])
width, _ := strconv.Atoi(matches[3])
height, _ := strconv.Atoi(matches[4])
for x := left; x < left+width; x++ {
for y := top; y < top+height; y++ {
key := fmt.Sprintf("%d,%d", x, y)
coverage[key]++
}
}
}
reWithID := regexp.MustCompile(`#(\d+) @ (\d+),(\d+): (\d+)x(\d+)`)
for _, line := range data {
matches := reWithID.FindStringSubmatch(line)
if len(matches) != 6 {
continue
}
id, _ := strconv.Atoi(matches[1])
left, _ := strconv.Atoi(matches[2])
top, _ := strconv.Atoi(matches[3])
width, _ := strconv.Atoi(matches[4])
height, _ := strconv.Atoi(matches[5])
overlaps := false
for x := left; x < left+width && !overlaps; x++ {
for y := top; y < top+height; y++ {
key := fmt.Sprintf("%d,%d", x, y)
if coverage[key] > 1 {
overlaps = true
break
}
}
}
if !overlaps {
return id
}
}
return 0
}

View File

@@ -0,0 +1,25 @@
package daythree
import "testing"
var testInput = []string{
"#1 @ 1,3: 4x4",
"#2 @ 3,1: 4x4",
"#3 @ 5,5: 2x2",
}
func TestPartOne(t *testing.T) {
expected := 4
got := PartOne(testInput)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
expected := 3
got := PartTwo(testInput)
if got != expected {
t.Errorf("PartTwo() = %d, want %d", got, expected)
}
}

View File

@@ -0,0 +1,81 @@
package daytwo
import (
"advent-of-code/internal/registry"
"fmt"
"os"
"strings"
)
func init() {
registry.Register("2018D2", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
return strings.Split(string(content), "\n")
}
func PartOne(data []string) int {
countWithTwo := 0
countWithThree := 0
for _, boxID := range data {
charCounts := make(map[rune]int)
for _, char := range boxID {
charCounts[char]++
}
hasExactlyTwo := false
hasExactlyThree := false
for _, count := range charCounts {
switch count {
case 2:
hasExactlyTwo = true
case 3:
hasExactlyThree = true
}
}
if hasExactlyTwo {
countWithTwo++
}
if hasExactlyThree {
countWithThree++
}
}
return countWithTwo * countWithThree
}
func PartTwo(data []string) int {
for idx := range data {
for otherIdx := idx + 1; otherIdx < len(data); otherIdx++ {
if data[idx] == "" || data[otherIdx] == "" {
continue
}
differenceCount := 0
differingPosition := -1
if len(data[idx]) != len(data[otherIdx]) {
continue
}
for position := 0; position < len(data[idx]); position++ {
if data[idx][position] != data[otherIdx][position] {
differenceCount++
differingPosition = position
}
}
if differenceCount == 1 {
common := data[idx][:differingPosition] + data[idx][differingPosition+1:]
fmt.Println(common)
return 0
}
}
}
return 0
}

View File

@@ -0,0 +1,58 @@
package daytwo
import (
"bytes"
"os"
"strings"
"testing"
)
func TestPartOne(t *testing.T) {
input := []string{
"abcdef",
"bababc",
"abbcde",
"abcccd",
"aabcdd",
"abcdee",
"ababab",
}
expected := 12
got := PartOne(input)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
input := []string{
"abcde",
"fghij",
"klmno",
"pqrst",
"fguij",
"axcye",
"wvxyz",
}
expected := "fgij"
oldStdout := os.Stdout
r, w, err := os.Pipe()
if err != nil {
t.Fatalf("Failed to create pipe: %v", err)
}
os.Stdout = w
PartTwo(input)
_ = w.Close()
os.Stdout = oldStdout
var buffer bytes.Buffer
_, _ = buffer.ReadFrom(r)
got := strings.TrimSpace(buffer.String())
if got != expected {
t.Errorf("PartTwo() printed %q, want %q", got, expected)
}
}

View File

@@ -0,0 +1,9 @@
package year2018
import (
_ "advent-of-code/internal/2018/DayFive"
_ "advent-of-code/internal/2018/DayFour"
_ "advent-of-code/internal/2018/DayOne"
_ "advent-of-code/internal/2018/DayThree"
_ "advent-of-code/internal/2018/DayTwo"
)

View File

@@ -91,7 +91,7 @@ func PartTwo(data []string) int {
return false return false
} }
for _, c := range value[1:] { for _, c := range value[1:] {
if !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f')) { if (c < '0' || c > '9') && (c < 'a' || c > 'f') {
return false return false
} }
} }

View File

@@ -14,11 +14,8 @@ func init() {
func ParseInput(filepath string) []string { func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath) content, _ := os.ReadFile(filepath)
lines := strings.Split(string(content), "\n") lines := strings.Split(string(content), "\n")
var data []string data := make([]string, 0, len(lines))
for _, line := range lines { return append(data, lines...)
data = append(data, line)
}
return data
} }
func PartOne(data []string) int { func PartOne(data []string) int {

12
internal/2020/register.go Normal file
View File

@@ -0,0 +1,12 @@
package year2020
import (
_ "advent-of-code/internal/2020/DayEight"
_ "advent-of-code/internal/2020/DayFive"
_ "advent-of-code/internal/2020/DayFour"
_ "advent-of-code/internal/2020/DayOne"
_ "advent-of-code/internal/2020/DaySeven"
_ "advent-of-code/internal/2020/DaySix"
_ "advent-of-code/internal/2020/DayThree"
_ "advent-of-code/internal/2020/DayTwo"
)

View File

@@ -0,0 +1,155 @@
package dayfour
import (
"os"
"strconv"
"strings"
"advent-of-code/internal/registry"
)
const boardSize = 5
func init() {
registry.Register("2021D4", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
return strings.Split(strings.TrimSpace(string(content)), "\n")
}
type board struct {
numbers [boardSize][boardSize]int
positionMap map[int][2]int
rowCounts [boardSize]int
columnCounts [boardSize]int
marked map[int]bool
won bool
}
func newBoard() board {
return board{
positionMap: make(map[int][2]int, boardSize*boardSize),
marked: make(map[int]bool),
}
}
func parseBoards(lines []string) []board {
var boards []board
current := newBoard()
row := 0
for _, line := range lines {
line = strings.TrimSpace(line)
if line == "" {
if row == boardSize {
boards = append(boards, current)
current = newBoard()
row = 0
}
continue
}
fields := strings.Fields(line)
for column, field := range fields {
number, _ := strconv.Atoi(field)
current.numbers[row][column] = number
current.positionMap[number] = [2]int{row, column}
}
row++
}
if row == boardSize {
boards = append(boards, current)
}
return boards
}
func (b *board) mark(number int) bool {
if b.won {
return false
}
position, exists := b.positionMap[number]
if !exists {
return false
}
b.marked[number] = true
row, column := position[0], position[1]
b.rowCounts[row]++
b.columnCounts[column]++
if b.rowCounts[row] == boardSize || b.columnCounts[column] == boardSize {
b.won = true
return true
}
return false
}
func (b *board) sumUnmarked() int {
sum := 0
for row := range boardSize {
for column := range boardSize {
number := b.numbers[row][column]
if !b.marked[number] {
sum += number
}
}
}
return sum
}
func parseNumbers(line string) []int {
numbersStr := strings.Split(line, ",")
numbers := make([]int, 0, len(numbersStr))
for _, numStr := range numbersStr {
num, _ := strconv.Atoi(numStr)
numbers = append(numbers, num)
}
return numbers
}
func PartOne(data []string) int {
numbers := parseNumbers(data[0])
boards := parseBoards(data[1:])
for _, number := range numbers {
for idx := range boards {
if boards[idx].mark(number) {
return boards[idx].sumUnmarked() * number
}
}
}
return 0
}
func PartTwo(data []string) int {
numbers := parseNumbers(data[0])
boards := parseBoards(data[1:])
wonCount := 0
totalBoards := len(boards)
var lastWinner *board
var lastNumber int
for _, number := range numbers {
for idx := range boards {
if boards[idx].mark(number) {
wonCount++
lastWinner = &boards[idx]
lastNumber = number
if wonCount == totalBoards {
return lastWinner.sumUnmarked() * lastNumber
}
}
}
}
return 0
}

View File

@@ -0,0 +1,41 @@
package dayfour
import "testing"
var testInput = []string{
"7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1",
"",
"22 13 17 11 0",
" 8 2 23 4 24",
"21 9 14 16 7",
" 6 10 3 18 5",
" 1 12 20 15 19",
"",
" 3 15 0 2 22",
" 9 18 13 17 5",
"19 8 7 25 23",
"20 11 10 24 4",
"14 21 16 12 6",
"",
"14 21 17 24 4",
"10 16 15 9 19",
"18 8 23 26 20",
"22 11 13 6 5",
" 2 0 12 3 7",
}
func TestPartOne(t *testing.T) {
expected := 4512
got := PartOne(testInput)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
expected := 1924
got := PartTwo(testInput)
if got != expected {
t.Errorf("PartTwo() = %d, want %d", got, expected)
}
}

View File

@@ -0,0 +1,8 @@
package year2021
import (
_ "advent-of-code/internal/2021/DayFour"
_ "advent-of-code/internal/2021/DayOne"
_ "advent-of-code/internal/2021/DayThree"
_ "advent-of-code/internal/2021/DayTwo"
)

View File

@@ -0,0 +1,54 @@
package dayfour
import (
"advent-of-code/internal/registry"
"fmt"
"os"
"strings"
)
func init() {
registry.Register("2022D4", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
return strings.Split(string(content), "\n")
}
func PartOne(data []string) int {
count := 0
for _, line := range data {
parts := strings.Split(line, ",")
var firstRangeStart, firstRangeEnd, secondRangeStart, secondRangeEnd int
fmt.Sscanf(parts[0], "%d-%d", &firstRangeStart, &firstRangeEnd)
fmt.Sscanf(parts[1], "%d-%d", &secondRangeStart, &secondRangeEnd)
minStart := min(firstRangeStart, secondRangeStart)
maxEnd := max(firstRangeEnd, secondRangeEnd)
if (minStart == firstRangeStart && maxEnd == firstRangeEnd) || (minStart == secondRangeStart && maxEnd == secondRangeEnd) {
count++
}
}
return count
}
func PartTwo(data []string) int {
count := 0
for _, line := range data {
parts := strings.Split(line, ",")
var firstRangeStart, firstRangeEnd, secondRangeStart, secondRangeEnd int
fmt.Sscanf(parts[0], "%d-%d", &firstRangeStart, &firstRangeEnd)
fmt.Sscanf(parts[1], "%d-%d", &secondRangeStart, &secondRangeEnd)
if firstRangeStart <= secondRangeEnd && secondRangeStart <= firstRangeEnd {
count++
}
}
return count
}

View File

@@ -0,0 +1,28 @@
package dayfour
import "testing"
var testInput = []string{
"2-4,6-8",
"2-3,4-5",
"5-7,7-9",
"2-8,3-7",
"6-6,4-6",
"2-6,4-8",
}
func TestPartOne(t *testing.T) {
expected := 2
got := PartOne(testInput)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
expected := 4
got := PartTwo(testInput)
if got != expected {
t.Errorf("PartTwo() = %d, want %d", got, expected)
}
}

View File

@@ -0,0 +1,87 @@
package daythree
import (
"advent-of-code/internal/registry"
"os"
"strings"
)
func init() {
registry.Register("2022D3", ParseInput, PartOne, PartTwo)
}
func buildItemSet(items string) map[rune]bool {
itemSet := make(map[rune]bool)
for _, item := range items {
itemSet[item] = true
}
return itemSet
}
func findCommonItem(itemSet map[rune]bool, items string) rune {
for _, item := range items {
if itemSet[item] {
return item
}
}
return 0
}
func findIntersection(itemSet map[rune]bool, items string) map[rune]bool {
intersection := make(map[rune]bool)
for _, item := range items {
if itemSet[item] {
intersection[item] = true
}
}
return intersection
}
func getItemPriority(item rune) int {
if item >= 'a' && item <= 'z' {
return int(item - 'a' + 1)
}
if item >= 'A' && item <= 'Z' {
return int(item - 'A' + 27)
}
return 0
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
return strings.Split(string(content), "\n")
}
func PartOne(data []string) int {
totalPriority := 0
for _, rucksack := range data {
compartmentSize := len(rucksack) / 2
firstCompartment := rucksack[:compartmentSize]
secondCompartment := rucksack[compartmentSize:]
firstCompartmentItems := buildItemSet(firstCompartment)
commonItem := findCommonItem(firstCompartmentItems, secondCompartment)
totalPriority += getItemPriority(commonItem)
}
return totalPriority
}
func PartTwo(data []string) int {
totalPriority := 0
for i := 0; i < len(data); i += 3 {
if i+2 >= len(data) {
break
}
firstRucksack := data[i]
secondRucksack := data[i+1]
thirdRucksack := data[i+2]
firstRucksackItems := buildItemSet(firstRucksack)
commonInFirstTwo := findIntersection(firstRucksackItems, secondRucksack)
badge := findCommonItem(commonInFirstTwo, thirdRucksack)
totalPriority += getItemPriority(badge)
}
return totalPriority
}

View File

@@ -0,0 +1,28 @@
package daythree
import "testing"
var testInput = []string{
"vJrwpWtwJgWrhcsFMMfFFhFp",
"jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL",
"PmmdzqPrVvPwwTWBwg",
"wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn",
"ttgJtRGJQctTZtZT",
"CrZsJsPPZsGzwwsLwLmpwMDw",
}
func TestPartOne(t *testing.T) {
expected := 157
got := PartOne(testInput)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
expected := 70
got := PartTwo(testInput)
if got != expected {
t.Errorf("PartTwo() = %d, want %d", got, expected)
}
}

View File

@@ -0,0 +1,62 @@
package daytwo
import (
"advent-of-code/internal/registry"
"os"
"strings"
)
func init() {
registry.Register("2022D2", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
return strings.Split(strings.Trim(string(content), "\n"), "\n")
}
func PartOne(data []string) int {
totalScore := 0
for _, line := range data {
opponent := line[0]
me := line[2]
shapeScore := int(me - 'X' + 1)
var outcomeScore int
if (opponent == 'A' && me == 'Y') || (opponent == 'B' && me == 'Z') || (opponent == 'C' && me == 'X') {
outcomeScore = 6
} else if (opponent == 'A' && me == 'X') || (opponent == 'B' && me == 'Y') || (opponent == 'C' && me == 'Z') {
outcomeScore = 3
} else {
outcomeScore = 0
}
totalScore += shapeScore + outcomeScore
}
return totalScore
}
func PartTwo(data []string) int {
totalScore := 0
for _, line := range data {
opponent := line[0]
outcome := line[2]
var me byte
switch outcome {
case 'Y':
me = 'X' + (opponent - 'A')
case 'Z':
me = 'X' + ((opponent-'A')+1)%3
default:
me = 'X' + ((opponent-'A')+2)%3
}
shapeScore := int(me - 'X' + 1)
outcomeScore := int(outcome-'X') * 3
totalScore += shapeScore + outcomeScore
}
return totalScore
}

View File

@@ -0,0 +1,25 @@
package daytwo
import "testing"
var testInput = []string{
"A Y",
"B X",
"C Z",
}
func TestPartOne(t *testing.T) {
expected := 15
got := PartOne(testInput)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
expected := 12
got := PartTwo(testInput)
if got != expected {
t.Errorf("PartTwo() = %d, want %d", got, expected)
}
}

View File

@@ -0,0 +1,8 @@
package year2022
import (
_ "advent-of-code/internal/2022/DayFour"
_ "advent-of-code/internal/2022/DayOne"
_ "advent-of-code/internal/2022/DayThree"
_ "advent-of-code/internal/2022/DayTwo"
)

View File

@@ -0,0 +1,210 @@
package dayeight
import (
"cmp"
"container/heap"
"os"
"slices"
"strconv"
"strings"
"advent-of-code/internal/registry"
)
func init() {
registry.Register("2025D8", ParseInput, PartOne, PartTwo)
}
type JunctionBox struct {
X, Y, Z int
}
type UnionFind struct {
parent []int
size []int
}
type Connection struct {
firstJunctionBox, secondJunctionBox int
squaredDistance int
}
type ConnectionHeap []Connection
func (h ConnectionHeap) Len() int { return len(h) }
func (h ConnectionHeap) Less(i, j int) bool { return h[i].squaredDistance > h[j].squaredDistance }
func (h ConnectionHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *ConnectionHeap) Push(x any) { *h = append(*h, x.(Connection)) }
func (h *ConnectionHeap) Pop() any {
old := *h
n := len(old)
x := old[n-1]
*h = old[0 : n-1]
return x
}
func NewUnionFind(count int) *UnionFind {
parent := make([]int, count)
size := make([]int, count)
for idx := range parent {
parent[idx] = idx
size[idx] = 1
}
return &UnionFind{parent: parent, size: size}
}
func (uf *UnionFind) Find(junctionBox int) int {
if uf.parent[junctionBox] != junctionBox {
uf.parent[junctionBox] = uf.Find(uf.parent[junctionBox])
}
return uf.parent[junctionBox]
}
func (uf *UnionFind) Union(junctionBox1, junctionBox2 int) (bool, int) {
root1 := uf.Find(junctionBox1)
root2 := uf.Find(junctionBox2)
if root1 == root2 {
return false, root1
}
if uf.size[root1] < uf.size[root2] {
root1, root2 = root2, root1
}
uf.parent[root2] = root1
uf.size[root1] += uf.size[root2]
return true, root1
}
func parseJunctionBoxes(data []string) []JunctionBox {
var junctionBoxes []JunctionBox
for _, line := range data {
parts := strings.Split(line, ",")
x, _ := strconv.Atoi(parts[0])
y, _ := strconv.Atoi(parts[1])
z, _ := strconv.Atoi(parts[2])
junctionBoxes = append(junctionBoxes, JunctionBox{X: x, Y: y, Z: z})
}
return junctionBoxes
}
func generateAllConnections(junctionBoxes []JunctionBox) []Connection {
junctionBoxCount := len(junctionBoxes)
connections := make([]Connection, 0, junctionBoxCount*(junctionBoxCount-1)/2)
for i := range junctionBoxCount {
for j := i + 1; j < junctionBoxCount; j++ {
dx := junctionBoxes[i].X - junctionBoxes[j].X
dy := junctionBoxes[i].Y - junctionBoxes[j].Y
dz := junctionBoxes[i].Z - junctionBoxes[j].Z
squaredDistance := dx*dx + dy*dy + dz*dz
connections = append(connections, Connection{
firstJunctionBox: i,
secondJunctionBox: j,
squaredDistance: squaredDistance,
})
}
}
slices.SortFunc(connections, func(a, b Connection) int {
return cmp.Compare(a.squaredDistance, b.squaredDistance)
})
return connections
}
func findKSmallestConnections(junctionBoxes []JunctionBox, k int) []Connection {
junctionBoxCount := len(junctionBoxes)
connectionHeap := make(ConnectionHeap, 0, k)
heap.Init(&connectionHeap)
for i := range junctionBoxCount {
for j := i + 1; j < junctionBoxCount; j++ {
dx := junctionBoxes[i].X - junctionBoxes[j].X
dy := junctionBoxes[i].Y - junctionBoxes[j].Y
dz := junctionBoxes[i].Z - junctionBoxes[j].Z
squaredDistance := dx*dx + dy*dy + dz*dz
connection := Connection{
firstJunctionBox: i,
secondJunctionBox: j,
squaredDistance: squaredDistance,
}
if len(connectionHeap) < k {
heap.Push(&connectionHeap, connection)
} else if connection.squaredDistance < connectionHeap[0].squaredDistance {
heap.Pop(&connectionHeap)
heap.Push(&connectionHeap, connection)
}
}
}
connections := make([]Connection, 0, len(connectionHeap))
for connectionHeap.Len() > 0 {
connections = append(connections, heap.Pop(&connectionHeap).(Connection))
}
slices.SortFunc(connections, func(a, b Connection) int {
return cmp.Compare(a.squaredDistance, b.squaredDistance)
})
return connections
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
return strings.Split(string(content), "\n")
}
func PartOne(data []string) int {
junctionBoxes := parseJunctionBoxes(data)
junctionBoxCount := len(junctionBoxes)
targetPairs := 1000
if junctionBoxCount <= 20 {
targetPairs = 10
}
connections := findKSmallestConnections(junctionBoxes, targetPairs)
uf := NewUnionFind(junctionBoxCount)
for _, connection := range connections {
uf.Union(connection.firstJunctionBox, connection.secondJunctionBox)
}
circuitSizes := make(map[int]int)
for idx := range junctionBoxes {
root := uf.Find(idx)
circuitSizes[root] = uf.size[root]
}
sizes := make([]int, 0, len(circuitSizes))
for _, size := range circuitSizes {
sizes = append(sizes, size)
}
slices.Sort(sizes)
slices.Reverse(sizes)
return sizes[0] * sizes[1] * sizes[2]
}
func PartTwo(data []string) int {
junctionBoxes := parseJunctionBoxes(data)
connections := generateAllConnections(junctionBoxes)
uf := NewUnionFind(len(junctionBoxes))
var lastConnection Connection
for _, connection := range connections {
merged, root := uf.Union(connection.firstJunctionBox, connection.secondJunctionBox)
if merged {
lastConnection = connection
if uf.size[root] == len(junctionBoxes) {
break
}
}
}
return junctionBoxes[lastConnection.firstJunctionBox].X * junctionBoxes[lastConnection.secondJunctionBox].X
}

View File

@@ -0,0 +1,42 @@
package dayeight
import "testing"
var testInput = []string{
"162,817,812",
"57,618,57",
"906,360,560",
"592,479,940",
"352,342,300",
"466,668,158",
"542,29,236",
"431,825,988",
"739,650,466",
"52,470,668",
"216,146,977",
"819,987,18",
"117,168,530",
"805,96,715",
"346,949,466",
"970,615,88",
"941,993,340",
"862,61,35",
"984,92,344",
"425,690,689",
}
func TestPartOne(t *testing.T) {
expected := 40
got := PartOne(testInput)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
expected := 25272
got := PartTwo(testInput)
if got != expected {
t.Errorf("PartTwo() = %d, want %d", got, expected)
}
}

View File

@@ -0,0 +1,125 @@
package dayfive
import (
"os"
"slices"
"sort"
"strconv"
"strings"
"advent-of-code/internal/registry"
)
type freshRange struct {
start int
end int
}
func init() {
registry.Register("2025D5", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
return strings.Split(string(content), "\n")
}
func PartOne(data []string) int {
var freshRanges []freshRange
var ingredientIDs []int
separatorFound := false
for _, line := range data {
if line == "" {
separatorFound = true
continue
}
if !separatorFound {
startStr, endStr, _ := strings.Cut(line, "-")
start, _ := strconv.Atoi(startStr)
end, _ := strconv.Atoi(endStr)
freshRanges = append(freshRanges, freshRange{start: start, end: end})
} else {
id, _ := strconv.Atoi(line)
ingredientIDs = append(ingredientIDs, id)
}
}
slices.SortFunc(freshRanges, func(a, b freshRange) int {
switch {
case a.start < b.start:
return -1
case a.start > b.start:
return 1
default:
return 0
}
})
freshCount := 0
for _, id := range ingredientIDs {
idx := sort.Search(len(freshRanges), func(idx int) bool {
return freshRanges[idx].start > id
})
for i := idx - 1; i >= 0 && freshRanges[i].start <= id; i-- {
if id <= freshRanges[i].end {
freshCount++
break
}
}
}
return freshCount
}
func PartTwo(data []string) int {
var freshRanges []freshRange
for _, line := range data {
if line == "" {
break
}
startStr, endStr, _ := strings.Cut(line, "-")
start, _ := strconv.Atoi(startStr)
end, _ := strconv.Atoi(endStr)
freshRanges = append(freshRanges, freshRange{start: start, end: end})
}
slices.SortFunc(freshRanges, func(a, b freshRange) int {
switch {
case a.start < b.start:
return -1
case a.start > b.start:
return 1
default:
return 0
}
})
var mergedRanges []freshRange
for _, r := range freshRanges {
if len(mergedRanges) == 0 {
mergedRanges = append(mergedRanges, r)
continue
}
lastRange := &mergedRanges[len(mergedRanges)-1]
if r.start <= lastRange.end+1 {
if r.end > lastRange.end {
lastRange.end = r.end
}
} else {
mergedRanges = append(mergedRanges, r)
}
}
totalFreshIDs := 0
for _, r := range mergedRanges {
totalFreshIDs += r.end - r.start + 1
}
return totalFreshIDs
}

View File

@@ -0,0 +1,33 @@
package dayfive
import "testing"
var testInput = []string{
"3-5",
"10-14",
"16-20",
"12-18",
"",
"1",
"5",
"8",
"11",
"17",
"32",
}
func TestPartOne(t *testing.T) {
expected := 3
got := PartOne(testInput)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
expected := 14
got := PartTwo(testInput)
if got != expected {
t.Errorf("PartTwo() = %d, want %d", got, expected)
}
}

View File

@@ -0,0 +1,104 @@
package dayfour
import (
"os"
"strings"
"advent-of-code/internal/registry"
)
type position struct {
row, column int
}
var directions = []position{
{-1, -1},
{-1, 0},
{-1, 1},
{0, -1},
{0, 1},
{1, -1},
{1, 0},
{1, 1},
}
func init() {
registry.Register("2025D4", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
return strings.Split(string(content), "\n")
}
func PartOne(data []string) int {
isRoll := make(map[position]bool)
for row := range data {
for column := 0; column < len(data[row]); column++ {
if data[row][column] == '@' {
isRoll[position{row, column}] = true
}
}
}
accessibleRolls := 0
for pos := range isRoll {
adjacentRolls := 0
for _, direction := range directions {
neighbor := position{pos.row + direction.row, pos.column + direction.column}
if isRoll[neighbor] {
adjacentRolls++
}
}
if adjacentRolls < 4 {
accessibleRolls++
}
}
return accessibleRolls
}
func PartTwo(data []string) int {
isRoll := make(map[position]bool)
for row := range data {
for column := 0; column < len(data[row]); column++ {
if data[row][column] == '@' {
isRoll[position{row, column}] = true
}
}
}
totalRemoved := 0
for {
accessibleRolls := make(map[position]bool)
for pos := range isRoll {
adjacentRolls := 0
for _, direction := range directions {
neighbor := position{pos.row + direction.row, pos.column + direction.column}
if isRoll[neighbor] {
adjacentRolls++
}
}
if adjacentRolls < 4 {
accessibleRolls[pos] = true
}
}
if len(accessibleRolls) == 0 {
break
}
for pos := range accessibleRolls {
delete(isRoll, pos)
totalRemoved++
}
}
return totalRemoved
}

View File

@@ -0,0 +1,32 @@
package dayfour
import "testing"
var testInput = []string{
"..@@.@@@@.",
"@@@.@.@.@@",
"@@@@@.@.@@",
"@.@@@@..@.",
"@@.@@@@.@@",
".@@@@@@@.@",
".@.@.@.@@@",
"@.@@@.@@@@",
".@@@@@@@@.",
"@.@.@@@.@.",
}
func TestPartOne(t *testing.T) {
expected := 13
got := PartOne(testInput)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
expected := 43
got := PartTwo(testInput)
if got != expected {
t.Errorf("PartTwo() = %d, want %d", got, expected)
}
}

View File

@@ -0,0 +1,234 @@
package daynine
import (
"advent-of-code/internal/registry"
"os"
"slices"
"strconv"
"strings"
)
func init() {
registry.Register("2025D9", ParseInput, PartOne, PartTwo)
}
type Point struct {
x, y int
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
return strings.Split(string(content), "\n")
}
func parsePoints(data []string) []Point {
points := make([]Point, 0, len(data))
for _, line := range data {
parts := strings.Split(line, ",")
x, _ := strconv.Atoi(parts[0])
y, _ := strconv.Atoi(parts[1])
points = append(points, Point{x: x, y: y})
}
return points
}
func abs(x int) int {
if x < 0 {
return -x
}
return x
}
func minMax(a, b int) (int, int) {
if a > b {
return b, a
}
return a, b
}
func compressCoordinates(points []Point) ([]int, []int, map[int]int, map[int]int) {
xs := make(map[int]bool)
ys := make(map[int]bool)
for _, point := range points {
xs[point.x] = true
ys[point.y] = true
}
sortedX := make([]int, 0, len(xs))
sortedY := make([]int, 0, len(ys))
for x := range xs {
sortedX = append(sortedX, x)
}
for y := range ys {
sortedY = append(sortedY, y)
}
slices.Sort(sortedX)
slices.Sort(sortedY)
mapX := make(map[int]int, len(sortedX))
mapY := make(map[int]int, len(sortedY))
for idx, x := range sortedX {
mapX[x] = 2 * idx
}
for idx, y := range sortedY {
mapY[y] = 2 * idx
}
return sortedX, sortedY, mapX, mapY
}
func drawBoundary(grid [][]bool, points []Point, mapX, mapY map[int]int) {
for idx := range points {
current, next := points[idx], points[(idx+1)%len(points)]
cx1, cy1 := mapX[current.x], mapY[current.y]
cx2, cy2 := mapX[next.x], mapY[next.y]
if cx1 == cx2 {
minY, maxY := minMax(cy1, cy2)
for y := minY; y <= maxY; y++ {
grid[cx1][y] = true
}
} else {
minX, maxX := minMax(cx1, cx2)
for x := minX; x <= maxX; x++ {
grid[x][cy1] = true
}
}
}
}
func scanLineFill(grid [][]bool, points []Point, mapX, mapY map[int]int, _, height int) {
type edge struct {
x, yMin, yMax int
}
edges := make([]edge, 0, len(points))
for idx := range points {
current, next := points[idx], points[(idx+1)%len(points)]
if current.x == next.x {
minY, maxY := minMax(mapY[current.y], mapY[next.y])
edges = append(edges, edge{mapX[current.x], minY, maxY})
}
}
for y := range height {
crossings := make([]int, 0, len(edges))
for _, e := range edges {
if e.yMin <= y && y < e.yMax {
crossings = append(crossings, e.x)
}
}
slices.Sort(crossings)
for i := 0; i < len(crossings)-1; i += 2 {
for x := crossings[i]; x <= crossings[i+1]; x++ {
grid[x][y] = true
}
}
}
}
func forceEmptyGaps(grid [][]bool, sortedX, sortedY []int, width, height int) {
for idx := 0; idx < len(sortedX)-1; idx++ {
if sortedX[idx+1] == sortedX[idx]+1 {
cx := 2*idx + 1
for y := range height {
grid[cx][y] = true
}
}
}
for idx := 0; idx < len(sortedY)-1; idx++ {
if sortedY[idx+1] == sortedY[idx]+1 {
cy := 2*idx + 1
for x := range width {
grid[x][cy] = true
}
}
}
}
func buildPrefixSum(grid [][]bool, width, height int) [][]int {
sum := make([][]int, width+1)
for idx := range sum {
sum[idx] = make([]int, height+1)
}
for i := range width {
for j := range height {
value := 0
if grid[i][j] {
value = 1
}
sum[i+1][j+1] = value + sum[i][j+1] + sum[i+1][j] - sum[i][j]
}
}
return sum
}
func getSum(sum [][]int, x1, y1, x2, y2 int) int {
return sum[x2+1][y2+1] - sum[x1][y2+1] - sum[x2+1][y1] + sum[x1][y1]
}
func PartOne(data []string) int {
points := parsePoints(data)
maxArea := 0
for i := range points {
for j := i + 1; j < len(points); j++ {
dx := abs(points[i].x - points[j].x)
dy := abs(points[i].y - points[j].y)
if area := (dx + 1) * (dy + 1); area > maxArea {
maxArea = area
}
}
}
return maxArea
}
func PartTwo(data []string) int {
points := parsePoints(data)
sortedX, sortedY, mapX, mapY := compressCoordinates(points)
width, height := 2*len(sortedX), 2*len(sortedY)
grid := make([][]bool, width)
for idx := range grid {
grid[idx] = make([]bool, height)
}
drawBoundary(grid, points, mapX, mapY)
scanLineFill(grid, points, mapX, mapY, width, height)
forceEmptyGaps(grid, sortedX, sortedY, width, height)
sum := buildPrefixSum(grid, width, height)
compressedPoints := make([]Point, len(points))
for idx, point := range points {
compressedPoints[idx] = Point{mapX[point.x], mapY[point.y]}
}
maxArea := 0
for i := range points {
for j := i + 1; j < len(points); j++ {
p1, p2 := points[i], points[j]
dx := abs(p1.x - p2.x)
dy := abs(p1.y - p2.y)
if dx == 0 || dy == 0 {
continue
}
area := (dx + 1) * (dy + 1)
if area <= maxArea {
continue
}
cx1, cy1 := compressedPoints[i].x, compressedPoints[i].y
cx2, cy2 := compressedPoints[j].x, compressedPoints[j].y
minCX, maxCX := minMax(cx1, cx2)
minCY, maxCY := minMax(cy1, cy2)
totalCells := (maxCX - minCX + 1) * (maxCY - minCY + 1)
if getSum(sum, minCX, minCY, maxCX, maxCY) == totalCells {
maxArea = area
}
}
}
return maxArea
}

View File

@@ -0,0 +1,30 @@
package daynine
import "testing"
var testInput = []string{
"7,1",
"11,1",
"11,7",
"9,7",
"9,5",
"2,5",
"2,3",
"7,3",
}
func TestPartOne(t *testing.T) {
expected := 50
got := PartOne(testInput)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
expected := 24
got := PartTwo(testInput)
if got != expected {
t.Errorf("PartTwo() = %d, want %d", got, expected)
}
}

View File

@@ -0,0 +1,63 @@
package dayone
import (
"advent-of-code/internal/registry"
"os"
"strconv"
"strings"
)
func init() {
registry.Register("2025D1", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
return strings.Split(string(content), "\n")
}
func PartOne(data []string) int {
position := 50
count := 0
for _, rotation := range data {
direction := rotation[0]
distance, _ := strconv.Atoi(rotation[1:])
if direction == 'L' {
position = (position - distance + 100) % 100
} else {
position = (position + distance) % 100
}
if position == 0 {
count++
}
}
return count
}
func PartTwo(data []string) int {
position := 50
count := 0
for _, rotation := range data {
direction := rotation[0]
distance, _ := strconv.Atoi(rotation[1:])
for range distance {
if direction == 'L' {
position = (position - 1 + 100) % 100
} else {
position = (position + 1) % 100
}
if position == 0 {
count++
}
}
}
return count
}

View File

@@ -0,0 +1,32 @@
package dayone
import "testing"
var testInput = []string{
"L68",
"L30",
"R48",
"L5",
"R60",
"L55",
"L1",
"L99",
"R14",
"L82",
}
func TestPartOne(t *testing.T) {
expected := 3
got := PartOne(testInput)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
expected := 6
got := PartTwo(testInput)
if got != expected {
t.Errorf("PartTwo() = %d, want %d", got, expected)
}
}

View File

@@ -0,0 +1,106 @@
package dayseven
import (
"os"
"strings"
"advent-of-code/internal/registry"
)
func init() {
registry.Register("2025D7", ParseInput, PartOne, PartTwo)
}
type Position struct {
row int
column int
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
return strings.Split(string(content), "\n")
}
func findStart(data []string) (int, int) {
for row := range data {
if column := strings.IndexByte(data[row], 'S'); column != -1 {
return row, column
}
}
return -1, -1
}
func PartOne(data []string) int {
rows, columns := len(data), len(data[0])
startRow, startColumn := findStart(data)
queue := []Position{{startRow, startColumn}}
activated := make(map[Position]bool)
splits := 0
for len(queue) > 0 {
current := queue[0]
queue = queue[1:]
row := current.row + 1
column := current.column
for row < rows && data[row][column] != '^' {
row++
}
if row < rows {
splitPosition := Position{row, column}
if !activated[splitPosition] {
activated[splitPosition] = true
splits++
if column > 0 {
queue = append(queue, Position{row, column - 1})
}
if column < columns-1 {
queue = append(queue, Position{row, column + 1})
}
}
}
}
return splits
}
func PartTwo(input []string) int {
rows, columns := len(input), len(input[0])
startRow, startColumn := findStart(input)
cache := make(map[Position]int)
var countTimelines func(row, column int) int
countTimelines = func(row, column int) int {
position := Position{row, column}
if count, exists := cache[position]; exists {
return count
}
r, c := row+1, column
for r < rows && input[r][c] != '^' {
r++
}
if r == rows {
return 1
}
total := 0
if c > 0 {
total += countTimelines(r, c-1)
}
if c < columns-1 {
total += countTimelines(r, c+1)
}
cache[position] = total
return total
}
return countTimelines(startRow, startColumn)
}

View File

@@ -0,0 +1,38 @@
package dayseven
import "testing"
var testInput = []string{
".......S.......",
"...............",
".......^.......",
"...............",
"......^.^......",
"...............",
".....^.^.^.....",
"...............",
"....^.^...^....",
"...............",
"...^.^...^.^...",
"...............",
"..^...^.....^..",
"...............",
".^.^.^.^.^...^.",
"...............",
}
func TestPartOne(t *testing.T) {
expected := 21
got := PartOne(testInput)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
expected := 40
got := PartTwo(testInput)
if got != expected {
t.Errorf("PartTwo() = %d, want %d", got, expected)
}
}

View File

@@ -0,0 +1,174 @@
package daysix
import (
"os"
"strconv"
"strings"
"advent-of-code/internal/registry"
)
func init() {
registry.Register("2025D6", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
return strings.Split(strings.TrimRight(string(content), "\n"), "\n")
}
func transpose(lines []string) []string {
maxWidth := 0
for _, line := range lines {
if len(line) > maxWidth {
maxWidth = len(line)
}
}
transposed := make([]string, maxWidth)
for column := 0; column < maxWidth; column++ {
var builder strings.Builder
for _, line := range lines {
if column < len(line) {
builder.WriteByte(line[column])
} else {
builder.WriteByte(' ')
}
}
transposed[column] = builder.String()
}
return transposed
}
func isSpaceColumn(column string) bool {
return strings.TrimSpace(column) == ""
}
func extractRowFromColumns(transposed []string, row, startColumn, endColumn int) string {
var builder strings.Builder
for column := startColumn; column <= endColumn && column < len(transposed); column++ {
if row < len(transposed[column]) {
builder.WriteByte(transposed[column][row])
} else {
builder.WriteByte(' ')
}
}
return builder.String()
}
func extractNumbers(transposed []string, startColumn, endColumn, operationRow int) []int {
numbers := make([]int, 0)
for row := range operationRow {
rowStr := extractRowFromColumns(transposed, row, startColumn, endColumn)
trimmed := strings.TrimSpace(rowStr)
fields := strings.FieldsSeq(trimmed)
for field := range fields {
if number, err := strconv.Atoi(field); err == nil {
numbers = append(numbers, number)
}
}
}
return numbers
}
func extractNumberFromColumn(column string, operationRow int) (int, bool) {
numberStr := strings.Map(func(r rune) rune {
if r >= '0' && r <= '9' {
return r
}
return -1
}, column[:min(operationRow, len(column))])
number, _ := strconv.Atoi(numberStr)
return number, true
}
func extractOperation(segment string) byte {
if idx := strings.IndexAny(segment, "+*"); idx != -1 {
return segment[idx]
}
return 0
}
func applyOperation(numbers []int, operation byte) int {
result := numbers[0]
if operation == '+' {
for idx := 1; idx < len(numbers); idx++ {
result += numbers[idx]
}
} else {
for idx := 1; idx < len(numbers); idx++ {
result *= numbers[idx]
}
}
return result
}
func PartOne(data []string) int {
operationRow := len(data) - 1
transposed := transpose(data)
total := 0
column := 0
for column < len(transposed) {
if isSpaceColumn(transposed[column]) {
column++
continue
}
startColumn := column
for column < len(transposed) && !isSpaceColumn(transposed[column]) {
column++
}
endColumn := column - 1
numbers := extractNumbers(transposed, startColumn, endColumn, operationRow)
operationRowStr := extractRowFromColumns(transposed, operationRow, startColumn, endColumn)
operation := extractOperation(operationRowStr)
if len(numbers) > 0 && operation != 0 {
result := applyOperation(numbers, operation)
total += result
}
}
return total
}
func PartTwo(data []string) int {
operationRow := len(data) - 1
transposed := transpose(data)
total := 0
column := len(transposed) - 1
for column >= 0 {
if isSpaceColumn(transposed[column]) {
column--
continue
}
endColumn := column
for column >= 0 && !isSpaceColumn(transposed[column]) {
column--
}
startColumn := column + 1
numbers := make([]int, 0)
for column := startColumn; column <= endColumn && column < len(transposed); column++ {
if number, ok := extractNumberFromColumn(transposed[column], operationRow); ok {
numbers = append(numbers, number)
}
}
operationRowStr := extractRowFromColumns(transposed, operationRow, startColumn, endColumn)
operation := extractOperation(operationRowStr)
if len(numbers) > 0 && operation != 0 {
result := applyOperation(numbers, operation)
total += result
}
}
return total
}

View File

@@ -0,0 +1,26 @@
package daysix
import "testing"
var testInput = []string{
"123 328 51 64 ",
" 45 64 387 23 ",
" 6 98 215 314",
"* + * + ",
}
func TestPartOne(t *testing.T) {
expected := 4277556
got := PartOne(testInput)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
expected := 3263827
got := PartTwo(testInput)
if got != expected {
t.Errorf("PartTwo() = %d, want %d", got, expected)
}
}

View File

@@ -0,0 +1,91 @@
package dayten
import (
"advent-of-code/internal/registry"
"os"
"regexp"
"strconv"
"strings"
)
func init() {
registry.Register("2025D10", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
return strings.Split(string(content), "\n")
}
func parseMachine(line string) ([]bool, [][]int) {
bracketRegex := regexp.MustCompile(`\[([.#]+)\]`)
parenthesisRegex := regexp.MustCompile(`\(([^)]+)\)`)
bracketMatch := bracketRegex.FindStringSubmatch(line)
targetString := bracketMatch[1]
target := make([]bool, len(targetString))
for idx, char := range targetString {
target[idx] = char == '#'
}
parenthesisMatches := parenthesisRegex.FindAllStringSubmatch(line, -1)
buttons := make([][]int, 0, len(parenthesisMatches))
for _, match := range parenthesisMatches {
buttonString := match[1]
parts := strings.Split(buttonString, ",")
button := make([]int, 0, len(parts))
for _, part := range parts {
light, _ := strconv.Atoi(part)
button = append(button, light)
}
buttons = append(buttons, button)
}
return target, buttons
}
func PartOne(data []string) int {
total := 0
for _, line := range data {
target, buttons := parseMachine(line)
numberOfLights := len(target)
numberOfButtons := len(buttons)
minimumPresses := numberOfButtons + 1
for mask := 0; mask < (1 << numberOfButtons); mask++ {
lights := make([]bool, numberOfLights)
presses := 0
for buttonIdx := range numberOfButtons {
if mask&(1<<buttonIdx) != 0 {
presses++
for _, light := range buttons[buttonIdx] {
if light < numberOfLights {
lights[light] = !lights[light]
}
}
}
}
matches := true
for idx := range numberOfLights {
if lights[idx] != target[idx] {
matches = false
break
}
}
if matches && presses < minimumPresses {
minimumPresses = presses
}
}
total += minimumPresses
}
return total
}
func PartTwo(data []string) int {
return 0
}

View File

@@ -0,0 +1,25 @@
package dayten
import "testing"
var testInput = []string{
"[.##.] (3) (1,3) (2) (2,3) (0,2) (0,1) {3,5,4,7}",
"[...#.] (0,2,3,4) (2,3) (0,4) (0,1,2) (1,2,3,4) {7,5,12,7,2}",
"[.###.#] (0,1,2,3,4) (0,3,4) (0,1,2,4,5) (1,2) {10,11,11,5,10,5}",
}
func TestPartOne(t *testing.T) {
expected := 7
got := PartOne(testInput)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
expected := 33
got := PartTwo(testInput)
if got != expected {
t.Errorf("PartTwo() = %d, want %d", got, expected)
}
}

View File

@@ -0,0 +1,72 @@
package daythree
import (
"os"
"strings"
"advent-of-code/internal/registry"
)
func init() {
registry.Register("2025D3", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) [][]int {
content, _ := os.ReadFile(filepath)
lines := strings.Split(string(content), "\n")
var data [][]int
for _, line := range lines {
var bank []int
for _, char := range line {
bank = append(bank, int(char-'0'))
}
data = append(data, bank)
}
return data
}
func PartOne(data [][]int) int {
total := 0
for _, bank := range data {
maxAfter := make([]int, len(bank))
for idx := len(bank) - 2; idx >= 0; idx-- {
maxAfter[idx] = max(maxAfter[idx+1], bank[idx+1])
}
maxJoltage := 0
for idx := 0; idx < len(bank)-1; idx++ {
joltage := bank[idx]*10 + maxAfter[idx]
maxJoltage = max(maxJoltage, joltage)
}
total += maxJoltage
}
return total
}
func PartTwo(data [][]int) int {
total := 0
for _, bank := range data {
var joltage int
start := 0
for position := range 12 {
remaining := 12 - position - 1
maxIdx := start
maxValue := bank[start]
for idx := start; idx < len(bank)-remaining; idx++ {
if bank[idx] > maxValue {
maxValue = bank[idx]
maxIdx = idx
}
}
joltage = joltage*10 + maxValue
start = maxIdx + 1
}
total += joltage
}
return total
}

View File

@@ -0,0 +1,26 @@
package daythree
import "testing"
var testInput = [][]int{
{9, 8, 7, 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1},
{8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9},
{2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 7, 8},
{8, 1, 8, 1, 8, 1, 9, 1, 1, 1, 1, 2, 1, 1, 1},
}
func TestPartOne(t *testing.T) {
expected := 357
got := PartOne(testInput)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
expected := 3121910778619
got := PartTwo(testInput)
if got != expected {
t.Errorf("PartTwo() = %d, want %d", got, expected)
}
}

View File

@@ -0,0 +1,87 @@
package daytwo
import (
"os"
"strconv"
"strings"
"advent-of-code/internal/registry"
)
func init() {
registry.Register("2025D2", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
return strings.Split(strings.TrimSpace(string(content)), "\n")
}
func PartOne(data []string) int {
sum := 0
for _, line := range data {
for newRange := range strings.SplitSeq(line, ",") {
parts := strings.Split(newRange, "-")
start, _ := strconv.Atoi(parts[0])
end, _ := strconv.Atoi(parts[1])
for id := start; id <= end; id++ {
sID := strconv.Itoa(id)
if len(sID)%2 == 0 {
half := len(sID) / 2
if sID[:half] == sID[half:] {
sum += id
}
}
}
}
}
return sum
}
func PartTwo(data []string) int {
totalSum := 0
for _, line := range data {
for rangeSpec := range strings.SplitSeq(line, ",") {
rangeStartStr, rangeEndStr, _ := strings.Cut(rangeSpec, "-")
rangeStart, _ := strconv.Atoi(rangeStartStr)
rangeEnd, _ := strconv.Atoi(rangeEndStr)
seenNumbers := make(map[int]bool)
maxDigits := len(rangeEndStr)
var generatePatterns func(string, int, int)
generatePatterns = func(currentPattern string, targetPatternLength, currentDepth int) {
if currentDepth == targetPatternLength {
repeated := currentPattern + currentPattern
for len(repeated) <= maxDigits {
number, err := strconv.Atoi(repeated)
if err != nil || number > rangeEnd {
break
}
if number >= rangeStart && !seenNumbers[number] {
totalSum += number
seenNumbers[number] = true
}
repeated += currentPattern
}
return
}
minDigit := 0
if currentDepth == 0 {
minDigit = 1
}
for digit := minDigit; digit <= 9; digit++ {
extendedPattern := currentPattern + strconv.Itoa(digit)
generatePatterns(extendedPattern, targetPatternLength, currentDepth+1)
}
}
for patternLength := 1; patternLength <= maxDigits/2; patternLength++ {
generatePatterns("", patternLength, 0)
}
}
}
return totalSum
}

View File

@@ -0,0 +1,33 @@
package daytwo
import "testing"
var testInput = []string{
"11-22",
"95-115",
"998-1012",
"1188511880-1188511890",
"222220-222224",
"1698522-1698528",
"446443-446449",
"38593856-38593862",
"565653-565659",
"824824821-824824827",
"2121212118-2121212124",
}
func TestPartOne(t *testing.T) {
expected := 1227775554
got := PartOne(testInput)
if got != expected {
t.Errorf("PartOne() = %d, want %d", got, expected)
}
}
func TestPartTwo(t *testing.T) {
expected := 4174379265
got := PartTwo(testInput)
if got != expected {
t.Errorf("PartTwo() = %d, want %d", got, expected)
}
}

14
internal/2025/register.go Normal file
View File

@@ -0,0 +1,14 @@
package year2025
import (
_ "advent-of-code/internal/2025/DayEight"
_ "advent-of-code/internal/2025/DayFive"
_ "advent-of-code/internal/2025/DayFour"
_ "advent-of-code/internal/2025/DayNine"
_ "advent-of-code/internal/2025/DayOne"
_ "advent-of-code/internal/2025/DaySeven"
_ "advent-of-code/internal/2025/DaySix"
_ "advent-of-code/internal/2025/DayTen"
_ "advent-of-code/internal/2025/DayThree"
_ "advent-of-code/internal/2025/DayTwo"
)

View File

@@ -0,0 +1,300 @@
"\xa8br\x8bjr\""
"nq"
"zjrfcpbktjmrzgsz\xcaqsc\x03n\"huqab"
"daz\\zyyxddpwk"
"draes\xa2n\\g\x27ek\"lj\"\\viqych"
"nnx\\krnrfomdnt\x2flbl\xd2xpo\"cp\"k"
"kwdaapalq"
"u\"ptk"
"ckhorczuiudfjmmcc\\u\"wozqxibsfjma"
"ydctdrxat\"pd\"lwi\"bjesevfw\xe8"
"v\"\xa8rrzep\"\"r"
"nbydghkfvmq\\\xe0\"lfsrsvlsj\"i\x61liif"
"jsas\"u"
"odipikxlo"
"\"rnubsgwltqkbsu\"pcpcs"
"eitk\\f\\mhcqqoym\\ji"
"vnedc"
"\"lhcaurdqzyjyu"
"haxzsa\"zcn\"y\"foclgtjfcnv\"m\x68krc"
"\"eoeggg\"tmiydvcay\"vfavc"
"snqvyqoncwxcvwbdktoywch"
"rnfgjsyr\xd5wacy"
"ik\"hebrpvsts"
"txw"
"\x15pxtdkogd\"urbm\"gevhh\"nxr\x3erxtk"
"cetqtcy"
"inleep\\mgl"
"uflwbxvww\x2cxzezqnaply\"yh\"qlllzk"
"eepak\"xqtedzt"
"na\x61qzfieafvyrsnwkssznohjmc"
"yceaonylz\xc1\\jrlbbkzwsidfi"
"ybqafngkcqpbp"
"\xaft"
"yidjpaobqydso"
"ju\\ldxig\\lrdrhjcmm\x77rc"
"tylacqeslnwj\x48ds\"tjxa"
"efbfm"
"\\fxkgoprgdcjgyajykg\\dtbrz"
"eujvva"
"h\x7acwfpikme\\vwthyvrqdnx\""
"rbpbrxm\\\"\"\"voxx"
"ykiw\"tkb\\lforu\"rsf\\tf\"x\"rqti"
"e\\wh\x77aqeugiq\\ihhfqfuaij"
"g\"t\\o"
"nxzo\"hf\\xp"
"dxiaqfo\xea"
"kali\\zczhiqkqzybjj\"fgdjnik"
"zdkgrqmdv"
"bimxim\xb6lrwsaj\"ui\"a"
"\"rrznitibgx\\olpsjmjqzctxaubdifsq"
"zb\"khzixaacmhuzmlymoformipdzml"
"qfwi"
"hjwsxfpphttjy\"\"zixais\xbblgnqfto"
"puj\\qmyu\"nqgaqfthbwjokbmrpbhpi"
"cyxdpkh\\\""
"q"
"m"
"tbxdzzllarlo"
"gbtys"
"gytilk\\vlqxvcuutjunrqc"
"uugkvcuzan\\eyhb"
"yaxr\"genlbgw\"\\uc"
"nrgecjeip\\sjdvgqaqxwsqactopu"
"pu\"r\"txpyrkfny\\zmwfneyvwmnkkdipv"
"jm\xa3bhwvq"
"qxojmnml\"w\x9airr"
"xbzsuihs\x4dcedy\xaclrhgii\\\""
"drgjirusrekrwmvxllwdm"
"\x28hfxnfpycmpnkku\"csuf\xaarxlqyg\"x"
"\"zvz\\rmg\"\\sxxoifffyqfyn\"iq\"ps"
"\"z"
"zbwkmk\"sgzos\x93gtc\""
"bvm\x28aa\\\\\"pywuhaniox\\z\\hbp\xd7mold"
"aszgvsyna"
"qf\"vdwuss"
"lnohni\"qwiacjsjegstlbfq\\kyjhyd"
"c\\naawulxlqplnacvytspry\xf5ytxxqq"
"razwqmsqgbaaxcd\\f"
"radggyrjrg\"zx"
"\"pu\x11t\\ajcjuieinlkvya"
"veggiskh"
"eglfhjxiet\"kouqfskwsy\"hpthsldel"
"mv\xc1b\"f\\shrssnjwcpmurepdxdlcj"
"dlayjd\"suvzotgdtc"
"\xa9pvxeopn"
"lpplsaxy\"oiwaq"
"hqwh\\lusv"
"hykykwlx\"\xa5atkgh\\d\x63dff"
"vfktanpjy\"xxetc"
"dnhwkgjnsmsswfuelvihvjl\"jtf"
"x\"dwvzra\"nbbsewftehczgbvfzd\"rau"
"csfi\"mzejnjqkqupwadrgti\"von"
"xckf\xf7xsm\\pgvlpetjndpyblais\\z"
"yecy\x6fuj\x58bwpgeuiw\"mdu"
"fgb"
"c\\lx\x3efthet\xfdelgvwvpem"
"kgyrmarvfwjinlowt"
"yzte"
"vc\"z"
"sxevqfzmmdwsuu\""
"fxbaercmcy\xb6md"
"f"
"m\x44gqbcppho\\b"
"gtafr\x57m\x11jy\"\"erwmmpiwjkbckuw"
"ufdjt\"kssprzxqixzxmq\x58q"
"yzbyo\"lfdbyaxexyfbnyv\\\xe8xmre"
"u\x43ntr\\\\byyfjr\"iveujvnwsqbnpuvrta"
"us\xf6bai"
"c\\edh"
"tzckolphexfq\\\x23\xfbdqv\\\"m"
"yjafhbvhhj\x1b\"bplb"
"\"o"
"rubahvmp\""
"qmkukrnrmqumh"
"wdpxyvyidhwjf\\nabbijwhr\xc5bksvy\"p"
"u\"prlpg\""
"nsvcquyxbwilsxxemf\xd9leq"
"y\xcetxuafl"
"it"
"kwdlysf\\xjpelae"
"viwh\x58wpjjlnvryuti\x2chngrx\\nhtkui"
"vhn\x9ehre\xc3ncsqbozms\"nl"
"ytc\xa3mgeeogjcqavmmmd"
"xzlexlitseozoxtpzzutfq"
"cish\x07lmovj"
"ekbflwqzaiivdr\"pq\\azrfbntqwkn"
"uc\"xdbegmlmhksofzohavtrnxf"
"xfdnrdqdrcjzbe"
"ndg\"ckgrpisib\"rg\"p\\lmpfzlssnvk"
"witfjwpbyyzlop"
"zonlww\"emrbcsgdtrg\"rjzy\x64zqntlw"
"dvgb\"zn\\vrbzema\"ckmd"
"\\vdlmxhlvldk\"pmzazeip"
"\"\"r"
"rsntinv"
"iy"
"lr\x20efh"
"csgexlb\"zqdavlxxhtdbh\"\"\x0fkpvhiphm"
"ouwhp\"ogbft"
"cm\\ckltng\"dw\x8brf\xf0eppgckd"
"zmnlsgalhpkejsizfsbtnfliu\"nhc"
"pnrkaayqvwpdjbhcrbb\"yfeq\"aq"
"ozh\\hoxow\x2csrtr\\r\""
"bqxabj\"u\\s"
"cpsjti\"gy"
"aa\"p\\nki\\ajijkqev"
"q\"\"lfdentjgd\\"
"bmokvpoebutfki"
"pielvcbne\xf6efvzxn"
"kx"
"zlgmqagcrbhrwtwtmmg"
"aiyhmntcqjbpv\xb5hhswxbryoedvos"
"tdpaxrb"
"fu\"\x7dttkyvhrlwko"
"oirc\\\"cqlnqffjqt\\k"
"edxlia\\tcyby"
"jpeybgwfayerfrfbvfog\"ol"
"ysr"
"bzwzilgwfugjk"
"tlcc\x75nukvwjgftetjcs\xaecwc"
"dsqssa\"vzrf\"sewbp\\ahhlmhbeihlh"
"qtgmjck\"n\"guki\"gmdivwqxismqj"
"\"f"
"wuorvlovucngbzdszqpikyk"
"dfrdsacoukmgvhbq\"\"iwto"
"\"ey\"ch\\wcgioe\\\"ouvligmsw"
"ciqlszzgs"
"\\tzyrkaoi\"sopjaq"
"lmtnv"
"ar\"fqoroigiertjjlm\"ymgi\\kkjewsxd"
"wehcimlvudpxtamdn\"rwy"
"hr\"zvrwthr\"vruzqfrldn\"b"
"sggekodkiwvym\"mhsco"
"ltlkfbrrdvk\\"
"uut\"sfjnz\"\\ef"
"hxilg\\"
"zsredsiwlzrpedibn"
"vtfi"
"\\h"
"qekfrc\xf6wduodbwrguqcng\\n"
"\"lljlfdrxftwidn\\pkv\xd9ij"
"mrvgqynpehkliuijlpp"
"gikjph"
"yoxcdrdt\"wbaurnyhoyxoihu"
"onmomwuxuammbzxe"
"rnrr\\twviz\x61gqaljr\x0dmtw"
"r\"vupaoi"
"l"
"sei"
"jwxtdtbkd\\kxd"
"\x22v\\"
"ahd"
"j\"bjqxs"
"\\i\x24gglxub\\nzsajokt"
"lviwpu\"uxdlh\\zuy\"xqy\"ytdzlx\"r"
"kptfmys"
"fwxzikfhczkjwyjszqdbkepaeellc"
"nlqpsvbrbd\\ns"
"qryuwkjiodw\"\"vaqyq\"dmyifm"
"tw\x15kdmaudjl\\zorhp\"alwh"
"aatrvczesykekkjfyb\"kb"
"usqcutbqbxxhucwxo\xc1ltb\"j\"bghjcvws"
"ilhsrnzxkz"
"bianqfdfdhvw"
"hqibqs\x7ax\"qoxqoaqtcsz"
"htxtoojbbauztwxuiq\\ngyfy\\obzc"
"rxn\\moxlj"
"mtus\x84erh\"dbe"
"asx\x50huvsitcxadt"
"\"bugggtnrc\"\"kl\"hmpu\x83hqrvhpo"
"ewisbp\"\"vuzf\\w\x5fvalszdhl"
"scusplpwxfnxu\x57\"zynpn\x99xerc\\ri"
"m\\kinmkke\x0cl"
"xhuzit\x7fd"
"kfbo\x04\x50ruqirn"
"t\"\"xpbdscmdoug"
"punvpsgnbgyxe\"sptmpz"
"bxukkazijr"
"nxyrcdaoo\"rjkk\"wntehcvcip\"vrd"
"rdpvqskmihqaw"
"p\\gwdhtqnpgthod"
"nwnuf\"\"yebycearom\"nqym\"\xd4sii\xccle"
"alda\"ptspo\"wkkv\"zoi\"hkb\"vnntyd"
"ixpgpfzbqv"
"znui\"\\fzn\x03qozabh\"rva\"pv\x67"
"e\"zswmwuk"
"hcccygwfa"
"ngmace\\rtyllolr\"\x68bw"
"\\c\"jyufbry\"ryo\"xpo\x26ecninfeckh\\s"
"hdnpngtuc\"dzbvvosn\x31fwtpzbrt"
"hesbpd\xd4"
"dsdbstuzrdfmrnyntufs\"dmv"
"d\xeeibcwhcvkt"
"fvzwrsfjdqdmy\"\"v"
"ns\"dqafz\\lkyoflnazv\"mn\x37\"o\"yj\"e"
"dypilgbwzccayxa\"bnmuernx"
"q\xa9ztqrhreb\"\"kxfeyodqb"
"iz\xa5qjxqulaawuwz\"rqmpcj\\yel"
"z\"\\pq\"\"y\x67zpjtn"
"ifxqvivp\"kiiftdoe"
"jxzebj\"\x35\"qr\"ecglcutuoyywqumcs\"kk"
"q"
"yob\x85qmpuwexptczbkrl"
"cjiavv\"uudpozvibyycnmxhxpxmpjoz"
"xro\\uiqyrcid"
"nod\\k"
"d\"neiec"
"tqyrqvwyvmz\\pzgzzcqsqsrgbqbtapoz"
"r\"xvocpeuxfxslgueb\x05kzyyie\"aoec"
"\"du\\uirlhcbgv\\cjqhfreqnvn"
"zp\x04\x15\"pbjwhrjtmiba"
"\\cv\""
"k\"rwnb\\hiu\"rqd\"rc\\nyakrhly"
"klrmafjzandiddodgz"
"xipzhqzhvlpykzcuppx"
"zdvrvn\xd0mtfvpylbn\\\\sxcznrzugwznl"
"ody\\pvm\"kpjiudzhxazirgxzvumeat\"o"
"kllvhdp\"prjikzrrc\"adgpegc\\\"gk"
"sqtpug\xbcaauxaamw"
"wegxxrrxdvpivrqievfeokmnojsk"
"\\bo"
"gijhz"
"ylowluvabwrigssdgtxdwsiorxev\xdd"
"\""
"ghnsrnsqtxpygikahkrl"
"\"rcfqkbjf\"sgxg\"vnd\\rotn"
"ap\"smgsuexjrbuqs\"mpbstogj\"x"
"koaunz\\sgt\"opv"
"yialiuzwix"
"yp\"ndxgwzml\"bt"
"lpcjxmggfsy\\szbxccarjkqzasqkb\xcfd\x0c"
"x"
"mgakc"
"vjieunoh\x73fjwx"
"erbvv\"qulsd"
"mimycrbfhqkarmz"
"tihfbgcszuej\"c\xfbvoqskkhbgpaddioo"
"mziavkwrmekriqghw"
"izk\\tnjd\\ed\\emokvjoc"
"c\"nhbqzndro\\g"
"usfngdo"
"aypljdftvptt"
"ym\"afvq\xbcc"
"zabi\"wjpvugwhl"
"ebvptcjqjhc\"n\"p\"dxrphegr\\"
"mzlqqxokhye\xd9\\rffhnzs"
"hnipqknwpsjakanuewe"
"rqgbfcjdrmiz\"h"
"kzzp\\z\\txmkwaouxictybwx"
"yzmspjkqrteiydswlvb"
"gjpxklgpzv\"txri\\hotpuiukzzzd"
"p\"rxergtbsxmjmkeeqwvoagnki\""
"santipvuiq"
"\"ihjqlhtwbuy\"hdkiv\"mtiqacnf\\"
"oliaggtqyyx"
"fwwnpmbb"
"yrtdrieazfxyyneo"
"nywbv\\"
"twc\\ehfqxhgomgrgwpxyzmnkioj"
"qludrkkvljljd\\xvdeum\x4e"

View File

@@ -0,0 +1 @@
hxbxwxba

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
iwrupvqb

View File

@@ -0,0 +1,9 @@
Vixen can fly 19 km/s for 7 seconds, but then must rest for 124 seconds.
Rudolph can fly 3 km/s for 15 seconds, but then must rest for 28 seconds.
Donner can fly 19 km/s for 9 seconds, but then must rest for 164 seconds.
Blitzen can fly 19 km/s for 9 seconds, but then must rest for 158 seconds.
Comet can fly 13 km/s for 7 seconds, but then must rest for 82 seconds.
Cupid can fly 25 km/s for 6 seconds, but then must rest for 145 seconds.
Dasher can fly 14 km/s for 3 seconds, but then must rest for 38 seconds.
Dancer can fly 3 km/s for 16 seconds, but then must rest for 37 seconds.
Prancer can fly 25 km/s for 6 seconds, but then must rest for 143 seconds.

View File

@@ -0,0 +1,28 @@
Tristram to AlphaCentauri = 34
Tristram to Snowdin = 100
Tristram to Tambi = 63
Tristram to Faerun = 108
Tristram to Norrath = 111
Tristram to Straylight = 89
Tristram to Arbre = 132
AlphaCentauri to Snowdin = 4
AlphaCentauri to Tambi = 79
AlphaCentauri to Faerun = 44
AlphaCentauri to Norrath = 147
AlphaCentauri to Straylight = 133
AlphaCentauri to Arbre = 74
Snowdin to Tambi = 105
Snowdin to Faerun = 95
Snowdin to Norrath = 48
Snowdin to Straylight = 88
Snowdin to Arbre = 7
Tambi to Faerun = 68
Tambi to Norrath = 134
Tambi to Straylight = 107
Tambi to Arbre = 40
Faerun to Norrath = 11
Faerun to Straylight = 66
Faerun to Arbre = 144
Norrath to Straylight = 115
Norrath to Arbre = 135
Straylight to Arbre = 127

View File

@@ -0,0 +1,339 @@
af AND ah -> ai
NOT lk -> ll
hz RSHIFT 1 -> is
NOT go -> gp
du OR dt -> dv
x RSHIFT 5 -> aa
at OR az -> ba
eo LSHIFT 15 -> es
ci OR ct -> cu
b RSHIFT 5 -> f
fm OR fn -> fo
NOT ag -> ah
v OR w -> x
g AND i -> j
an LSHIFT 15 -> ar
1 AND cx -> cy
jq AND jw -> jy
iu RSHIFT 5 -> ix
gl AND gm -> go
NOT bw -> bx
jp RSHIFT 3 -> jr
hg AND hh -> hj
bv AND bx -> by
er OR es -> et
kl OR kr -> ks
et RSHIFT 1 -> fm
e AND f -> h
u LSHIFT 1 -> ao
he RSHIFT 1 -> hx
eg AND ei -> ej
bo AND bu -> bw
dz OR ef -> eg
dy RSHIFT 3 -> ea
gl OR gm -> gn
da LSHIFT 1 -> du
au OR av -> aw
gj OR gu -> gv
eu OR fa -> fb
lg OR lm -> ln
e OR f -> g
NOT dm -> dn
NOT l -> m
aq OR ar -> as
gj RSHIFT 5 -> gm
hm AND ho -> hp
ge LSHIFT 15 -> gi
jp RSHIFT 1 -> ki
hg OR hh -> hi
lc LSHIFT 1 -> lw
km OR kn -> ko
eq LSHIFT 1 -> fk
1 AND am -> an
gj RSHIFT 1 -> hc
aj AND al -> am
gj AND gu -> gw
ko AND kq -> kr
ha OR gz -> hb
bn OR by -> bz
iv OR jb -> jc
NOT ac -> ad
bo OR bu -> bv
d AND j -> l
bk LSHIFT 1 -> ce
de OR dk -> dl
dd RSHIFT 1 -> dw
hz AND ik -> im
NOT jd -> je
fo RSHIFT 2 -> fp
hb LSHIFT 1 -> hv
lf RSHIFT 2 -> lg
gj RSHIFT 3 -> gl
ki OR kj -> kk
NOT ak -> al
ld OR le -> lf
ci RSHIFT 3 -> ck
1 AND cc -> cd
NOT kx -> ky
fp OR fv -> fw
ev AND ew -> ey
dt LSHIFT 15 -> dx
NOT ax -> ay
bp AND bq -> bs
NOT ii -> ij
ci AND ct -> cv
iq OR ip -> ir
x RSHIFT 2 -> y
fq OR fr -> fs
bn RSHIFT 5 -> bq
0 -> c
14146 -> b
d OR j -> k
z OR aa -> ab
gf OR ge -> gg
df OR dg -> dh
NOT hj -> hk
NOT di -> dj
fj LSHIFT 15 -> fn
lf RSHIFT 1 -> ly
b AND n -> p
jq OR jw -> jx
gn AND gp -> gq
x RSHIFT 1 -> aq
ex AND ez -> fa
NOT fc -> fd
bj OR bi -> bk
as RSHIFT 5 -> av
hu LSHIFT 15 -> hy
NOT gs -> gt
fs AND fu -> fv
dh AND dj -> dk
bz AND cb -> cc
dy RSHIFT 1 -> er
hc OR hd -> he
fo OR fz -> ga
t OR s -> u
b RSHIFT 2 -> d
NOT jy -> jz
hz RSHIFT 2 -> ia
kk AND kv -> kx
ga AND gc -> gd
fl LSHIFT 1 -> gf
bn AND by -> ca
NOT hr -> hs
NOT bs -> bt
lf RSHIFT 3 -> lh
au AND av -> ax
1 AND gd -> ge
jr OR js -> jt
fw AND fy -> fz
NOT iz -> ja
c LSHIFT 1 -> t
dy RSHIFT 5 -> eb
bp OR bq -> br
NOT h -> i
1 AND ds -> dt
ab AND ad -> ae
ap LSHIFT 1 -> bj
br AND bt -> bu
NOT ca -> cb
NOT el -> em
s LSHIFT 15 -> w
gk OR gq -> gr
ff AND fh -> fi
kf LSHIFT 15 -> kj
fp AND fv -> fx
lh OR li -> lj
bn RSHIFT 3 -> bp
jp OR ka -> kb
lw OR lv -> lx
iy AND ja -> jb
dy OR ej -> ek
1 AND bh -> bi
NOT kt -> ku
ao OR an -> ap
ia AND ig -> ii
NOT ey -> ez
bn RSHIFT 1 -> cg
fk OR fj -> fl
ce OR cd -> cf
eu AND fa -> fc
kg OR kf -> kh
jr AND js -> ju
iu RSHIFT 3 -> iw
df AND dg -> di
dl AND dn -> do
la LSHIFT 15 -> le
fo RSHIFT 1 -> gh
NOT gw -> gx
NOT gb -> gc
ir LSHIFT 1 -> jl
x AND ai -> ak
he RSHIFT 5 -> hh
1 AND lu -> lv
NOT ft -> fu
gh OR gi -> gj
lf RSHIFT 5 -> li
x RSHIFT 3 -> z
b RSHIFT 3 -> e
he RSHIFT 2 -> hf
NOT fx -> fy
jt AND jv -> jw
hx OR hy -> hz
jp AND ka -> kc
fb AND fd -> fe
hz OR ik -> il
ci RSHIFT 1 -> db
fo AND fz -> gb
fq AND fr -> ft
gj RSHIFT 2 -> gk
cg OR ch -> ci
cd LSHIFT 15 -> ch
jm LSHIFT 1 -> kg
ih AND ij -> ik
fo RSHIFT 3 -> fq
fo RSHIFT 5 -> fr
1 AND fi -> fj
1 AND kz -> la
iu AND jf -> jh
cq AND cs -> ct
dv LSHIFT 1 -> ep
hf OR hl -> hm
km AND kn -> kp
de AND dk -> dm
dd RSHIFT 5 -> dg
NOT lo -> lp
NOT ju -> jv
NOT fg -> fh
cm AND co -> cp
ea AND eb -> ed
dd RSHIFT 3 -> df
gr AND gt -> gu
ep OR eo -> eq
cj AND cp -> cr
lf OR lq -> lr
gg LSHIFT 1 -> ha
et RSHIFT 2 -> eu
NOT jh -> ji
ek AND em -> en
jk LSHIFT 15 -> jo
ia OR ig -> ih
gv AND gx -> gy
et AND fe -> fg
lh AND li -> lk
1 AND io -> ip
kb AND kd -> ke
kk RSHIFT 5 -> kn
id AND if -> ig
NOT ls -> lt
dw OR dx -> dy
dd AND do -> dq
lf AND lq -> ls
NOT kc -> kd
dy AND ej -> el
1 AND ke -> kf
et OR fe -> ff
hz RSHIFT 5 -> ic
dd OR do -> dp
cj OR cp -> cq
NOT dq -> dr
kk RSHIFT 1 -> ld
jg AND ji -> jj
he OR hp -> hq
hi AND hk -> hl
dp AND dr -> ds
dz AND ef -> eh
hz RSHIFT 3 -> ib
db OR dc -> dd
hw LSHIFT 1 -> iq
he AND hp -> hr
NOT cr -> cs
lg AND lm -> lo
hv OR hu -> hw
il AND in -> io
NOT eh -> ei
gz LSHIFT 15 -> hd
gk AND gq -> gs
1 AND en -> eo
NOT kp -> kq
et RSHIFT 5 -> ew
lj AND ll -> lm
he RSHIFT 3 -> hg
et RSHIFT 3 -> ev
as AND bd -> bf
cu AND cw -> cx
jx AND jz -> ka
b OR n -> o
be AND bg -> bh
1 AND ht -> hu
1 AND gy -> gz
NOT hn -> ho
ck OR cl -> cm
ec AND ee -> ef
lv LSHIFT 15 -> lz
ks AND ku -> kv
NOT ie -> if
hf AND hl -> hn
1 AND r -> s
ib AND ic -> ie
hq AND hs -> ht
y AND ae -> ag
NOT ed -> ee
bi LSHIFT 15 -> bm
dy RSHIFT 2 -> dz
ci RSHIFT 2 -> cj
NOT bf -> bg
NOT im -> in
ev OR ew -> ex
ib OR ic -> id
bn RSHIFT 2 -> bo
dd RSHIFT 2 -> de
bl OR bm -> bn
as RSHIFT 1 -> bl
ea OR eb -> ec
ln AND lp -> lq
kk RSHIFT 3 -> km
is OR it -> iu
iu RSHIFT 2 -> iv
as OR bd -> be
ip LSHIFT 15 -> it
iw OR ix -> iy
kk RSHIFT 2 -> kl
NOT bb -> bc
ci RSHIFT 5 -> cl
ly OR lz -> ma
z AND aa -> ac
iu RSHIFT 1 -> jn
cy LSHIFT 15 -> dc
cf LSHIFT 1 -> cz
as RSHIFT 3 -> au
cz OR cy -> da
kw AND ky -> kz
lx -> a
iw AND ix -> iz
lr AND lt -> lu
jp RSHIFT 5 -> js
aw AND ay -> az
jc AND je -> jf
lb OR la -> lc
NOT cn -> co
kh LSHIFT 1 -> lb
1 AND jj -> jk
y OR ae -> af
ck AND cl -> cn
kk OR kv -> kw
NOT cv -> cw
kl AND kr -> kt
iu OR jf -> jg
at AND az -> bb
jp RSHIFT 2 -> jq
iv AND jb -> jd
jn OR jo -> jp
x OR ai -> aj
ba AND bc -> bd
jl OR jk -> jm
b RSHIFT 1 -> v
o AND q -> r
NOT p -> q
k AND m -> n
as RSHIFT 2 -> at

View File

@@ -0,0 +1,300 @@
turn on 489,959 through 759,964
turn off 820,516 through 871,914
turn off 427,423 through 929,502
turn on 774,14 through 977,877
turn on 410,146 through 864,337
turn on 931,331 through 939,812
turn off 756,53 through 923,339
turn off 313,787 through 545,979
turn off 12,823 through 102,934
toggle 756,965 through 812,992
turn off 743,684 through 789,958
toggle 120,314 through 745,489
toggle 692,845 through 866,994
turn off 587,176 through 850,273
turn off 674,321 through 793,388
toggle 749,672 through 973,965
turn on 943,30 through 990,907
turn on 296,50 through 729,664
turn on 212,957 through 490,987
toggle 171,31 through 688,88
turn off 991,989 through 994,998
turn off 913,943 through 958,953
turn off 278,258 through 367,386
toggle 275,796 through 493,971
turn off 70,873 through 798,923
toggle 258,985 through 663,998
turn on 601,259 through 831,486
turn off 914,94 through 941,102
turn off 558,161 through 994,647
turn on 119,662 through 760,838
toggle 378,775 through 526,852
turn off 384,670 through 674,972
turn off 249,41 through 270,936
turn on 614,742 through 769,780
turn on 427,70 through 575,441
turn on 410,478 through 985,753
turn off 619,46 through 931,342
turn on 284,55 through 768,922
turn off 40,592 through 728,685
turn on 825,291 through 956,950
turn on 147,843 through 592,909
turn off 218,675 through 972,911
toggle 249,291 through 350,960
turn off 556,80 through 967,675
toggle 609,148 through 968,279
toggle 217,605 through 961,862
toggle 407,177 through 548,910
toggle 400,936 through 599,938
turn off 721,101 through 925,455
turn on 268,631 through 735,814
toggle 549,969 through 612,991
toggle 553,268 through 689,432
turn off 817,668 through 889,897
toggle 801,544 through 858,556
toggle 615,729 through 832,951
turn off 427,477 through 958,948
turn on 164,49 through 852,946
turn on 542,449 through 774,776
turn off 923,196 through 980,446
toggle 90,310 through 718,846
turn off 657,215 through 744,252
turn off 800,239 through 811,712
turn on 502,90 through 619,760
toggle 649,512 through 862,844
turn off 334,903 through 823,935
turn off 630,233 through 839,445
turn on 713,67 through 839,865
turn on 932,50 through 982,411
turn off 480,729 through 984,910
turn on 100,219 through 796,395
turn on 758,108 through 850,950
turn off 427,276 through 439,938
turn on 178,284 through 670,536
toggle 540,27 through 625,102
turn off 906,722 through 936,948
toggle 345,418 through 859,627
toggle 175,775 through 580,781
toggle 863,28 through 929,735
turn off 824,858 through 905,973
toggle 752,312 through 863,425
turn on 985,716 through 988,852
turn off 68,504 through 763,745
toggle 76,209 through 810,720
turn off 657,607 through 676,664
toggle 596,869 through 896,921
turn off 915,411 through 968,945
turn off 368,39 through 902,986
turn on 11,549 through 393,597
turn off 842,893 through 976,911
toggle 274,106 through 581,329
toggle 406,403 through 780,950
toggle 408,988 through 500,994
toggle 217,73 through 826,951
turn on 917,872 through 961,911
toggle 394,34 through 510,572
toggle 424,603 through 583,626
toggle 106,159 through 755,738
turn off 244,610 through 472,709
turn on 350,265 through 884,690
turn on 688,184 through 928,280
toggle 279,443 through 720,797
turn off 615,493 through 888,610
toggle 118,413 through 736,632
turn on 798,782 through 829,813
turn off 250,934 through 442,972
turn on 68,503 through 400,949
toggle 297,482 through 313,871
toggle 710,3 through 839,859
turn on 125,300 through 546,888
toggle 482,39 through 584,159
turn off 536,89 through 765,962
turn on 530,518 through 843,676
turn on 994,467 through 994,676
turn on 623,628 through 744,927
toggle 704,912 through 837,983
turn on 154,364 through 517,412
toggle 344,409 through 780,524
turn off 578,740 through 725,879
turn on 251,933 through 632,957
turn on 827,705 through 971,789
toggle 191,282 through 470,929
toggle 324,525 through 446,867
toggle 534,343 through 874,971
toggle 550,650 through 633,980
toggle 837,404 through 881,915
toggle 338,881 through 845,905
turn on 469,462 through 750,696
turn on 741,703 through 892,870
turn off 570,215 through 733,562
turn on 445,576 through 870,775
turn on 466,747 through 554,878
turn off 820,453 through 868,712
turn off 892,706 through 938,792
turn off 300,238 through 894,746
turn off 306,44 through 457,444
turn off 912,569 through 967,963
toggle 109,756 through 297,867
turn on 37,546 through 41,951
turn on 321,637 through 790,910
toggle 66,50 through 579,301
toggle 933,221 through 933,791
turn on 486,676 through 878,797
turn on 417,231 through 556,317
toggle 904,468 through 981,873
turn on 417,675 through 749,712
turn on 692,371 through 821,842
toggle 324,73 through 830,543
turn on 912,490 through 977,757
turn off 634,872 through 902,949
toggle 266,779 through 870,798
turn on 772,982 through 990,996
turn off 607,46 through 798,559
turn on 295,602 through 963,987
turn on 657,86 through 944,742
turn off 334,639 through 456,821
turn off 997,667 through 997,670
turn off 725,832 through 951,945
turn off 30,120 through 952,984
turn on 860,965 through 917,976
toggle 471,997 through 840,998
turn off 319,307 through 928,504
toggle 823,631 through 940,908
toggle 969,984 through 981,993
turn off 691,319 through 865,954
toggle 911,926 through 938,929
turn on 953,937 through 968,991
toggle 914,643 through 975,840
turn on 266,982 through 436,996
turn off 101,896 through 321,932
turn off 193,852 through 751,885
turn off 576,532 through 863,684
turn on 761,456 through 940,783
turn on 20,290 through 398,933
turn off 435,335 through 644,652
turn on 830,569 through 905,770
turn off 630,517 through 905,654
turn on 664,53 through 886,976
toggle 275,416 through 408,719
turn on 370,621 through 515,793
turn on 483,373 through 654,749
turn on 656,786 through 847,928
turn off 532,752 through 945,974
toggle 301,150 through 880,792
turn off 951,488 through 958,952
turn on 207,729 through 882,828
toggle 694,532 through 973,961
toggle 676,639 through 891,802
turn off 653,6 through 905,519
toggle 391,109 through 418,312
turn on 877,423 through 957,932
turn on 340,145 through 563,522
turn off 978,467 through 988,895
turn off 396,418 through 420,885
turn off 31,308 through 816,316
turn on 107,675 through 758,824
turn on 61,82 through 789,876
turn on 750,743 through 754,760
toggle 88,733 through 736,968
turn off 754,349 through 849,897
toggle 157,50 through 975,781
turn off 230,231 through 865,842
turn off 516,317 through 630,329
turn off 697,820 through 829,903
turn on 218,250 through 271,732
toggle 56,167 through 404,431
toggle 626,891 through 680,927
toggle 370,207 through 791,514
toggle 860,74 through 949,888
turn on 416,527 through 616,541
turn off 745,449 through 786,908
turn on 485,554 through 689,689
turn on 586,62 through 693,141
toggle 506,759 through 768,829
turn on 473,109 through 929,166
turn on 760,617 through 773,789
toggle 595,683 through 618,789
turn off 210,775 through 825,972
toggle 12,426 through 179,982
turn on 774,539 through 778,786
turn on 102,498 through 121,807
turn off 706,897 through 834,965
turn off 678,529 through 824,627
turn on 7,765 through 615,870
turn off 730,872 through 974,943
turn off 595,626 through 836,711
turn off 215,424 through 841,959
toggle 341,780 through 861,813
toggle 507,503 through 568,822
turn on 252,603 through 349,655
toggle 93,521 through 154,834
turn on 565,682 through 951,954
turn on 544,318 through 703,418
toggle 756,953 through 891,964
turn on 531,123 through 856,991
turn on 148,315 through 776,559
turn off 925,835 through 963,971
turn on 895,944 through 967,964
turn off 102,527 through 650,747
toggle 626,105 through 738,720
turn off 160,75 through 384,922
toggle 813,724 through 903,941
turn on 207,107 through 982,849
toggle 750,505 through 961,697
toggle 105,410 through 885,819
turn on 226,104 through 298,283
turn off 224,604 through 508,762
turn on 477,368 through 523,506
turn off 477,901 through 627,936
turn off 887,131 through 889,670
turn on 896,994 through 938,999
toggle 401,580 through 493,728
toggle 987,184 through 991,205
turn on 821,643 through 882,674
toggle 784,940 through 968,959
turn off 251,293 through 274,632
turn off 339,840 through 341,844
turn off 675,351 through 675,836
toggle 918,857 through 944,886
toggle 70,253 through 918,736
turn off 612,604 through 772,680
turn off 277,40 through 828,348
toggle 692,139 through 698,880
toggle 124,446 through 883,453
toggle 969,932 through 990,945
toggle 855,692 through 993,693
toggle 722,472 through 887,899
toggle 978,149 through 985,442
toggle 837,540 through 916,889
turn off 612,2 through 835,82
toggle 560,767 through 878,856
turn on 461,734 through 524,991
toggle 206,824 through 976,912
turn on 826,610 through 879,892
turn on 577,699 through 956,933
turn off 9,250 through 50,529
turn off 77,657 through 817,677
turn on 68,419 through 86,426
turn on 991,720 through 992,784
turn on 668,20 through 935,470
turn off 133,418 through 613,458
turn off 487,286 through 540,328
toggle 247,874 through 840,955
toggle 301,808 through 754,970
turn off 34,194 through 578,203
turn off 451,49 through 492,921
turn on 907,256 through 912,737
turn off 479,305 through 702,587
turn on 545,583 through 732,749
toggle 11,16 through 725,868
turn on 965,343 through 986,908
turn on 674,953 through 820,965
toggle 398,147 through 504,583
turn off 778,194 through 898,298
turn on 179,140 through 350,852
turn off 241,118 through 530,832
turn off 41,447 through 932,737
turn off 820,663 through 832,982
turn on 550,460 through 964,782
turn on 31,760 through 655,892
toggle 628,958 through 811,992

View File

@@ -0,0 +1 @@
1113122113

View File

@@ -0,0 +1,56 @@
Alice would lose 57 happiness units by sitting next to Bob.
Alice would lose 62 happiness units by sitting next to Carol.
Alice would lose 75 happiness units by sitting next to David.
Alice would gain 71 happiness units by sitting next to Eric.
Alice would lose 22 happiness units by sitting next to Frank.
Alice would lose 23 happiness units by sitting next to George.
Alice would lose 76 happiness units by sitting next to Mallory.
Bob would lose 14 happiness units by sitting next to Alice.
Bob would gain 48 happiness units by sitting next to Carol.
Bob would gain 89 happiness units by sitting next to David.
Bob would gain 86 happiness units by sitting next to Eric.
Bob would lose 2 happiness units by sitting next to Frank.
Bob would gain 27 happiness units by sitting next to George.
Bob would gain 19 happiness units by sitting next to Mallory.
Carol would gain 37 happiness units by sitting next to Alice.
Carol would gain 45 happiness units by sitting next to Bob.
Carol would gain 24 happiness units by sitting next to David.
Carol would gain 5 happiness units by sitting next to Eric.
Carol would lose 68 happiness units by sitting next to Frank.
Carol would lose 25 happiness units by sitting next to George.
Carol would gain 30 happiness units by sitting next to Mallory.
David would lose 51 happiness units by sitting next to Alice.
David would gain 34 happiness units by sitting next to Bob.
David would gain 99 happiness units by sitting next to Carol.
David would gain 91 happiness units by sitting next to Eric.
David would lose 38 happiness units by sitting next to Frank.
David would gain 60 happiness units by sitting next to George.
David would lose 63 happiness units by sitting next to Mallory.
Eric would gain 23 happiness units by sitting next to Alice.
Eric would lose 69 happiness units by sitting next to Bob.
Eric would lose 33 happiness units by sitting next to Carol.
Eric would lose 47 happiness units by sitting next to David.
Eric would gain 75 happiness units by sitting next to Frank.
Eric would gain 82 happiness units by sitting next to George.
Eric would gain 13 happiness units by sitting next to Mallory.
Frank would gain 77 happiness units by sitting next to Alice.
Frank would gain 27 happiness units by sitting next to Bob.
Frank would lose 87 happiness units by sitting next to Carol.
Frank would gain 74 happiness units by sitting next to David.
Frank would lose 41 happiness units by sitting next to Eric.
Frank would lose 99 happiness units by sitting next to George.
Frank would gain 26 happiness units by sitting next to Mallory.
George would lose 63 happiness units by sitting next to Alice.
George would lose 51 happiness units by sitting next to Bob.
George would lose 60 happiness units by sitting next to Carol.
George would gain 30 happiness units by sitting next to David.
George would lose 100 happiness units by sitting next to Eric.
George would lose 63 happiness units by sitting next to Frank.
George would gain 57 happiness units by sitting next to Mallory.
Mallory would lose 71 happiness units by sitting next to Alice.
Mallory would lose 28 happiness units by sitting next to Bob.
Mallory would lose 10 happiness units by sitting next to Carol.
Mallory would gain 44 happiness units by sitting next to David.
Mallory would gain 22 happiness units by sitting next to Eric.
Mallory would gain 79 happiness units by sitting next to Frank.
Mallory would lose 16 happiness units by sitting next to George.

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
reyedfim

View File

@@ -0,0 +1,953 @@
hqcfqwydw-fbqijys-whqii-huiuqhsx-660[qhiwf]
oxjmxdfkd-pzxsbkdbo-erkq-ixyloxqlov-913[xodkb]
bpvctixr-eaphixr-vgphh-gthtpgrw-947[smrkl]
iwcjapey-lhwopey-cnwoo-wymqeoepekj-992[eowpy]
mvhkvbdib-agjrzm-zibdizzmdib-317[bizdm]
excdklvo-lkcuod-dbksxsxq-146[ztwya]
ocipgvke-ejqeqncvg-octmgvkpi-908[prmku]
ktwbhtvmbox-vetllbybxw-vtgwr-vhtmbgz-tvjnblbmbhg-579[uvnyc]
dpmpsgvm-tdbwfohfs-ivou-tijqqjoh-389[emdac]
forwcoqhwjs-pibbm-igsf-hsghwbu-532[bhswf]
uzfqdzmfuazmx-nmewqf-ogefayqd-eqdhuoq-664[qfdem]
fnjyxwrinm-yujbcrl-pajbb-uxprbcrlb-277[brjcl]
aoubshwq-dzoghwq-ufogg-fsoqeiwgwhwcb-714[nkrmy]
pbeebfvir-rtt-fnyrf-975[frbet]
bnknqetk-qzaahs-trdq-sdrshmf-235[mtcqz]
odiih-ljwmh-lxjcrwp-orwjwlrwp-927[wjlrh]
sxdobxkdsyxkv-bkllsd-cobfsmoc-302[sbdko]
gzefmnxq-omzpk-ymzmsqyqzf-352[saomt]
tvsnigxmpi-gerhc-gsexmrk-qerekiqirx-854[eirgx]
ktfitzbgz-vtgwr-ftgtzxfxgm-267[tgfzx]
lxuxaodu-npp-orwjwlrwp-563[pwlor]
oazegyqd-sdmpq-pkq-xmnadmfadk-352[damqk]
wfruflnsl-gzssd-hzxytrjw-xjwanhj-177[bgxsp]
pbybeshy-qlr-qrfvta-455[tmios]
xmrrq-udskkaxawv-vqw-esfsywewfl-918[fdqsb]
vhehkyne-vahvhetmx-ltexl-917[uvhmy]
molgbzqfib-ciltbo-obzbfsfkd-393[htayl]
veqtekmrk-jpsaiv-wlmttmrk-256[ewyhq]
cvabijtm-lgm-apqxxqvo-512[dinjm]
oaxadrgx-nmewqf-qzsuzqqduzs-456[oevtg]
vehmsegxmzi-veffmx-wepiw-880[emfiv]
fruurvlyh-fubrjhqlf-fdqgb-frdwlqj-ghvljq-413[cgkzy]
otzkxtgzoutgr-inuiurgzk-sgxqkzotm-774[gtzko]
hwbba-eqpuwogt-itcfg-tcddkv-ujkrrkpi-154[ktbcd]
pynffvsvrq-cynfgvp-tenff-ynobengbel-377[fnevy]
aoubshwq-qcbgiasf-ufors-qvcqczohs-hsqvbczcum-558[hypcz]
kzeed-xhfajsljw-mzsy-knsfshnsl-281[nsmtd]
hwdtljsnh-hfsid-htfynsl-ijufwyrjsy-177[hsfjy]
excdklvo-zvkcdsm-qbkcc-psxkxmsxq-900[yznml]
diozmivodjivg-xviyt-pnzm-oznodib-239[iodvz]
nzcczdtgp-clmmte-lnbftdtetzy-743[tczde]
ejpanjwpekjwh-bhksan-iwngapejc-264[mgyfj]
ubhatstkwhnl-vhehkyne-xzz-wxiehrfxgm-917[hexkn]
vhkkhlbox-vtgwr-vhtmbgz-vnlmhfxk-lxkobvx-163[vhkxb]
irdgrxzex-tyftfcrkv-rthlzjzkzfe-373[rzfte]
cvabijtm-rmttgjmiv-lmdmtwxumvb-564[mtvbi]
hqfxxnknji-gfxpjy-xmnuunsl-151[brtjg]
odkasqzuo-dmnnuf-xasuefuoe-690[zyejx]
ixeumktoi-pkrrehkgt-sgtgmksktz-384[ktgei]
atyzghrk-igtje-iugzotm-uvkxgzouty-358[rmnqz]
ktwbhtvmbox-xzz-phkdlahi-865[nmsjb]
nzydfxpc-rclop-ojp-lylwjdtd-951[dlpcj]
vxupkizork-kmm-sgtgmksktz-280[yublv]
cvabijtm-kivlg-kwibqvo-twoqabqka-408[pgush]
hqcfqwydw-fbqijys-whqii-mehaixef-218[vzaur]
bpvctixr-rpcsn-rdpixcv-ldgzhwde-271[cifnu]
fnjyxwrinm-kjbtnc-lxwcjrwvnwc-199[nwcjr]
kzeed-idj-xmnuunsl-593[uazmr]
dsxxw-zyqicr-bcqgel-236[cqxbd]
gpewwmjmih-jpsaiv-wivzmgiw-230[iwmgj]
amjmpdsj-afmamjyrc-bcqgel-470[mszht]
eqpuwogt-itcfg-tcorcikpi-hnqygt-ujkrrkpi-596[nywzt]
pelbtravp-pnaql-erprvivat-533[parve]
yhwooebeaz-bhksan-wymqeoepekj-758[eoabh]
iruzfrtkzmv-upv-kirzezex-529[zpysg]
lxaaxbren-lqxlxujcn-mnenuxyvnwc-953[nxlac]
clxalrtyr-prr-nfdezxpc-dpcgtnp-457[prcdl]
sorozgxe-mxgjk-kmm-vaxingyotm-228[ugkxd]
vdzonmhydc-eknvdq-otqbgzrhmf-469[jnsrl]
gsvvswmzi-gspsvjyp-nippcfier-hizipstqirx-802[mvkcd]
xgvnndadzy-xviyt-xjvodib-yzkgjthzio-707[ncejo]
emixwvqhml-akidmvomz-pcvb-uizsmbqvo-538[mvibo]
dpotvnfs-hsbef-cbtlfu-usbjojoh-597[mnkij]
amjmpdsj-pyzzgr-jyzmpyrmpw-522[rxsqz]
fkqbokxqflkxi-yxphbq-ixyloxqlov-861[xjeyz]
vehmsegxmzi-tpewxmg-kveww-xvemrmrk-256[emvwx]
aietsrmdih-ikk-viwievgl-750[iekva]
zekvierkzferc-gcrjkzt-xirjj-nfibjyfg-763[jlbrc]
krxqjijamxdb-lqxlxujcn-lxwcjrwvnwc-537[opuqe]
dsxxw-zsllw-jyzmpyrmpw-652[hgyae]
mbiyqoxsm-mkxni-mykdsxq-kmaescsdsyx-770[otslp]
oqnidbshkd-vdzonmhydc-idkkxadzm-qdzbpthrhshnm-573[dhkmn]
jqwpihizlwca-moo-apqxxqvo-174[oqaip]
ahngzyzqcntr-azrjds-qdrdzqbg-573[zdqra]
bhksan-lqnydwoejc-472[gutvo]
jvsvymbs-zjhclunly-obua-zlycpjlz-175[ljyzb]
wrs-vhfuhw-hjj-ilqdqflqj-205[hjqfl]
egdytrixat-eaphixr-vgphh-ldgzhwde-661[duchs]
oxmeeuruqp-eomhqzsqd-tgzf-mocgueufuaz-196[uemoq]
ahngzyzqcntr-cxd-ehmzmbhmf-677[dqulm]
gspsvjyp-tpewxmg-kveww-wivzmgiw-568[ghntx]
pualyuhapvuhs-jvuzbtly-nyhkl-wshzapj-nyhzz-thyrlapun-149[kibhn]
nzcczdtgp-mfyyj-pyrtyppctyr-171[ypctr]
guahyncw-nij-mywlyn-vohhs-jolwbumcha-760[hnwya]
bgmxkgtmbhgte-xzz-vhgmtbgfxgm-397[gmbtx]
zixppfcfba-gbiivybxk-zrpqljbo-pbosfzb-653[psocz]
votubcmf-sbccju-nbslfujoh-935[bcufj]
gsrwyqiv-kvehi-nippcfier-irkmriivmrk-204[irkve]
jsvagsulanw-hdsklau-yjskk-ksdwk-632[ltnxs]
irdgrxzex-srjbvk-uvgcfpdvek-503[rvdeg]
krxqjijamxdb-ljwmh-bcxajpn-849[jxabm]
ajmrxjlcren-ljwmh-vjwjpnvnwc-407[yemcd]
ahngzyzqcntr-rbzudmfdq-gtms-btrsnldq-rdquhbd-755[dqrbn]
rzvkjiduzy-ezggtwzvi-hvmfzodib-291[yuzaf]
bwx-amkzmb-ntwemz-aitma-408[mabtw]
wihmogyl-aluxy-vumeyn-mufym-812[wymtu]
xjmmjndqz-nxvqzibzm-cpio-yzkgjthzio-889[mtsyf]
xmtjbzidx-ytz-nojmvbz-525[hyzbw]
bnmrtldq-fqzcd-tmrszakd-qzaahs-cdrhfm-131[wmcrn]
ftzgxmbv-wrx-kxtvjnblbmbhg-293[bxgmt]
gsvvswmzi-gerhc-wepiw-230[wegis]
pdjqhwlf-fdqgb-uhfhlylqj-699[fhlqd]
zsxyfgqj-kzeed-uqfxynh-lwfxx-ijuqtdrjsy-957[xfjqy]
rnqnyfwd-lwfij-uqfxynh-lwfxx-knsfshnsl-359[zbtyx]
wrs-vhfuhw-gbh-whfkqrorjb-231[hrwbf]
iuxxuyobk-hatte-rumoyzoiy-280[ouyit]
oqnidbshkd-bgnbnkzsd-nodqzshnmr-287[xnmzi]
atyzghrk-jek-jkyomt-540[anzom]
ibghopzs-pogysh-rsdofhasbh-818[hsobg]
wbhsfbohwcboz-foppwh-rsjszcdasbh-532[njpay]
excdklvo-mrymyvkdo-ecob-docdsxq-484[docek]
xgsvgmotm-yigbktmkx-natz-yzuxgmk-722[zwckh]
ajyqqgdgcb-afmamjyrc-qfgnngle-964[pzowt]
ugdgjxmd-jsttal-kzahhafy-138[cyirg]
irgyyolokj-iuxxuyobk-inuiurgzk-rumoyzoiy-982[sgadc]
qcbgiasf-ufors-gqojsbusf-vibh-qcbhowbasbh-870[njidq]
bkwzkqsxq-mrymyvkdo-wkxkqowoxd-146[hfdmy]
mybbycsfo-mrymyvkdo-bokmaescsdsyx-120[mlnky]
zuv-ykixkz-jek-ktmotkkxotm-852[mebdc]
dkqjcbctfqwu-lgnnadgcp-fgrctvogpv-648[cgdfn]
vehmsegxmzi-ikk-xvemrmrk-724[byndz]
upq-tfdsfu-cvooz-nbobhfnfou-155[xyskn]
gpewwmjmih-wgezirkiv-lyrx-hitevxqirx-360[ierwx]
rdggdhxkt-ytaanqtpc-bpcpvtbtci-817[mnjpk]
xlrypetn-clmmte-zapcletzyd-405[eltcm]
oxjmxdfkd-oxyyfq-abmxoqjbkq-861[nmhlv]
xjinphzm-bmvyz-kgvnodx-bmvnn-gjbdnodxn-395[nbdmv]
tpspahyf-nyhkl-jhukf-zopwwpun-799[phfkn]
jsvagsulanw-usfvq-mkwj-lwklafy-684[alswf]
ipvohghykvbz-kfl-ylhjxbpzpapvu-877[vmizu]
fydelmwp-awldetn-rcldd-afcnsldtyr-405[dlace]
gpbepvxcv-tvv-steadnbtci-609[vtbce]
tipfxvezt-upv-rthlzjzkzfe-581[ztefp]
bknsykmdsfo-oqq-vyqscdsmc-796[sqcdk]
ejpanjwpekjwh-zua-odellejc-914[ejalp]
ytu-xjhwjy-uqfxynh-lwfxx-jslnsjjwnsl-775[jxlns]
tinnm-aoubshwq-tzcksf-zopcfohcfm-376[cfohm]
xjgjmapg-ezggtwzvi-xpnojhzm-nzmqdxz-811[zgjmx]
tvsnigxmpi-fewoix-hiwmkr-386[tpuvk]
udglrdfwlyh-udeelw-vhuylfhv-829[ldhue]
luxciuwncpy-wbiwifuny-mniluay-786[iunwy]
ftzgxmbv-ktuubm-inkvatlbgz-865[btgkm]
xzwrmkbqtm-zijjqb-twoqabqka-486[erqyp]
diozmivodjivg-zbb-ncdkkdib-499[dibko]
kwvacumz-ozilm-kivlg-lmxizbumvb-980[milvz]
hwbba-dwppa-tgugctej-648[abgpt]
myxcewob-qbkno-bkllsd-cdybkqo-120[atghd]
zekvierkzferc-irsszk-uvjzxe-477[snqzi]
wlsiayhcw-dyffsvyuh-guleyncha-526[yhacf]
clotzlnetgp-ojp-opdtry-249[optlc]
dmybmsuzs-vqxxknqmz-eqdhuoqe-560[qmdes]
mtzslklcozfd-clmmte-dstaatyr-275[rtnyq]
cxy-bnlanc-lqxlxujcn-vjwjpnvnwc-823[ncjlx]
jshzzpmplk-zjhclunly-obua-bzly-alzapun-929[vcuxs]
yuxufmdk-sdmpq-ngzzk-oazfmuzyqzf-508[kghlv]
otzkxtgzoutgr-kmm-sgtgmksktz-722[tgkmz]
xgvnndadzy-xviyt-hvmfzodib-941[qbwmr]
qekrixmg-fyrrc-ywiv-xiwxmrk-230[ikjwl]
dpssptjwf-dpmpsgvm-qmbtujd-hsbtt-bobmztjt-337[tbmps]
tcfkqcevkxg-rncuvke-itcuu-ujkrrkpi-388[tabmn]
hjgbwuladw-tskcwl-xafsfuafy-528[afwls]
ygcrqpkbgf-ecpfa-gpikpggtkpi-154[gpkcf]
hqcfqwydw-sxesebqju-qdqboiyi-608[qbdei]
iehepwnu-cnwza-ydkykhwpa-iwngapejc-706[waenp]
jchipqat-ytaanqtpc-htgkxrth-115[mfnly]
pinovwgz-ezggtwzvi-xpnojhzm-nzmqdxz-967[yzosw]
yhwooebeaz-oywrajcan-dqjp-owhao-628[oaweh]
fhezusjybu-tou-skijecuh-iuhlysu-270[uhsei]
tcrjjzwzvu-upv-kirzezex-659[bdnty]
npmhcargjc-aylbw-amyrgle-qcptgacq-626[tkmzs]
ejpanjwpekjwh-ywjzu-ykwpejc-pnwejejc-160[lnqkc]
cybyjqho-whqtu-ryexqpqhteki-uww-tuiywd-946[qwyht]
cqwdujys-uww-bewyijysi-218[wyijs]
xekdwvwnzkqo-acc-pnwejejc-342[cewjk]
encuukhkgf-uecxgpigt-jwpv-ugtxkegu-440[kwmxr]
mbiyqoxsm-tovvilokx-cobfsmoc-224[doavb]
jvuzbtly-nyhkl-jhukf-zlycpjlz-591[jwxzi]
ncjzrpytn-clmmte-lylwjdtd-691[ltcdj]
enqvbnpgvir-enoovg-erprvivat-117[venrg]
gzefmnxq-ngzzk-ymdwqfuzs-612[zfgmn]
gokzyxsjon-cmkfoxqob-rexd-psxkxmsxq-302[zylnb]
aflwjfslagfsd-xdgowj-xafsfuafy-554[rgqmz]
ugdgjxmd-ujqgywfau-hdsklau-yjskk-kzahhafy-294[daelo]
mvkccspson-mrymyvkdo-nozkbdwoxd-718[odkmc]
egdytrixat-rwdrdapit-stepgibtci-817[ampoz]
qfmcusbwq-pogysh-fsgsofqv-194[gcthj]
wifilzof-qyujihctyx-luvvcn-qilembij-344[ilcfj]
gpbepvxcv-snt-apqdgpidgn-323[dnmyh]
kpvgtpcvkqpcn-gii-gpikpggtkpi-180[vyxnb]
ziuxioqvo-moo-mvoqvmmzqvo-512[omvqi]
fbebmtkr-zktwx-vtgwr-vhtmbgz-wxitkmfxgm-631[zilsp]
wihmogyl-aluxy-luvvcn-wihnuchgyhn-240[hlnuy]
eqnqthwn-lgnnadgcp-rwtejcukpi-726[jwvun]
hdgdovmt-bmvyz-ytz-yzqzgjkhzio-369[zydgh]
aflwjfslagfsd-usfvq-ugslafy-hmjuzskafy-138[vjmnt]
froruixo-iorzhu-uhdftxlvlwlrq-205[eslfx]
xekdwvwnzkqo-zua-skngodkl-368[kdnow]
xtwtelcj-rclop-clmmte-dpcgtnpd-353[jowtx]
lhkhszqx-fqzcd-cxd-nodqzshnmr-911[dhqzc]
fodvvlilhg-fdqgb-xvhu-whvwlqj-725[syfpw]
mtzslklcozfd-dnlgpyrpc-sfye-cpdplcns-873[zngtm]
rwcnawjcrxwju-yujbcrl-pajbb-jwjuhbrb-459[jbrwc]
hcd-gsqfsh-awzwhofm-ufors-suu-twbobqwbu-948[reunt]
pwcvonofrcig-pibbm-obozmgwg-688[zgthm]
vhehkyne-lvtoxgzxk-angm-wxiehrfxgm-345[xeghk]
ucynmlgxcb-njyqrga-epyqq-qrmpyec-938[mgnpj]
fruurvlyh-fdqgb-frdwlqj-uhvhdufk-699[fudhr]
hqfxxnknji-gzssd-yjhmstqtld-697[sdhjn]
qzoggwtwsr-rms-rsdofhasbh-402[gtlom]
gzefmnxq-ngzzk-dqeqmdot-638[yatsz]
rmn-qcapcr-njyqrga-epyqq-pcqcypaf-834[mpqie]
yknnkoera-ywjzu-zarahkliajp-186[yozsd]
clxalrtyr-eza-dpncpe-mldvpe-epnsyzwzrj-483[eplrz]
vkrhzxgbv-cxeeruxtg-vhgmtbgfxgm-137[fsxoz]
ymszqfuo-bxmefuo-sdmee-mzmxkeue-898[ndgcf]
dmbttjgjfe-sbccju-bdrvjtjujpo-649[vkijs]
wifilzof-wbiwifuny-guleyncha-136[ifwln]
oxmeeuruqp-vqxxknqmz-abqdmfuaze-196[baztd]
tinnm-qfmcusbwq-pogysh-gvwddwbu-636[aryhp]
lxaaxbren-ouxfna-bnaerlnb-693[anbxe]
nglmtuex-xzz-mktbgbgz-397[zqyrt]
xlrypetn-mfyyj-pyrtyppctyr-223[yprtc]
fodvvlilhg-fdqgb-vklsslqj-127[lvdfg]
ikhcxvmbex-lvtoxgzxk-angm-ehzblmbvl-761[xblmv]
fkqbokxqflkxi-ciltbo-qoxfkfkd-211[kfoqx]
lujbbrornm-bljenwpna-qdwc-fxatbqxy-589[bnajl]
eqpuwogt-itcfg-tcddkv-vgejpqnqia-258[besga]
lnkfaypeha-ydkykhwpa-zaoecj-108[zamyw]
lhkhszqx-fqzcd-atmmx-lzqjdshmf-859[hmqzd]
aflwjfslagfsd-tskcwl-vwhsjlewfl-190[xevmq]
pbafhzre-tenqr-wryylorna-fuvccvat-507[racef]
jvsvymbs-ibuuf-yljlpcpun-773[ubjlp]
fab-eqodqf-rxaiqd-etubbuzs-612[bqade]
cxy-bnlanc-ljwmh-nwprwnnarwp-251[nwacl]
hdgdovmt-bmvyz-pinovwgz-ytz-omvdidib-239[qfmcj]
wsvsdkbi-qbkno-mkxni-mykdsxq-bokmaescsdsyx-328[skbdm]
njmjubsz-hsbef-gmpxfs-tijqqjoh-727[ykelf]
foadouwbu-qobrm-oqeiwgwhwcb-142[owbqu]
cvabijtm-kivlg-ewzsapwx-538[posuz]
xgsvgmotm-igtje-gtgreyoy-696[gtemo]
oaddaeuhq-ngzzk-efadmsq-612[adeqz]
zgmfyxypbmsq-pyzzgr-yaosgqgrgml-470[efsgy]
wihmogyl-aluxy-vumeyn-zchuhwcha-110[eisnw]
hafgnoyr-fpniratre-uhag-phfgbzre-freivpr-663[rfaeg]
jqwpihizlwca-zijjqb-ewzsapwx-174[ognyv]
uwtojhynqj-hfsid-htfynsl-ijajqturjsy-619[jhsty]
hqfxxnknji-kqtbjw-wjhjnansl-177[ctzqd]
upq-tfdsfu-dboez-dpbujoh-mphjtujdt-103[dujpt]
tfiifjzmv-jtrmvexvi-ylek-wzeretzex-919[kuzli]
ugjjgkanw-hdsklau-yjskk-vwkayf-840[omzwl]
ugdgjxmd-kusnwfywj-zmfl-ogjckzgh-840[gjdfk]
vehmsegxmzi-fewoix-hitevxqirx-308[eixhm]
yflexwxoalrp-bdd-absbilmjbkq-419[esuky]
kwzzwaqdm-rmttgjmiv-lmxizbumvb-330[mzbit]
htqtwkzq-hfsid-yjhmstqtld-593[thqds]
tinnm-qobrm-qcohwbu-difqvogwbu-740[boqim]
tipfxvezt-jtrmvexvi-ylek-nfibjyfg-659[fqnis]
lzfmdshb-atmmx-qdzbpthrhshnm-859[hmbds]
nij-mywlyn-mwupyhayl-bohn-qilembij-292[vwady]
jchipqat-hrpktcvtg-wjci-gthtpgrw-999[tcghp]
dyz-combod-oqq-mecdywob-cobfsmo-250[obcdm]
dkqjcbctfqwu-ecpfa-vgejpqnqia-310[crelp]
gsrwyqiv-kvehi-gerhc-stivexmsrw-646[slxzf]
hmsdqmzshnmzk-bgnbnkzsd-cdozqsldms-261[sdmzn]
tfejldvi-xiruv-srjbvk-uvmvcfgdvek-217[kfcmn]
wrs-vhfuhw-exqqb-dqdobvlv-751[qvbdh]
willimcpy-jfumncw-alumm-mufym-682[dsbwk]
etaqigpke-lgnnadgcp-ceswkukvkqp-856[fnltm]
diozmivodjivg-nxvqzibzm-cpio-gvwjmvojmt-603[vywzn]
oxjmxdfkd-oxyyfq-absbilmjbkq-809[bxdfj]
uqtqbizg-ozilm-moo-wxmzibqwva-564[indml]
rdchjbtg-vgpst-uadltg-gtprfjxhxixdc-323[czknl]
pybgmyargtc-amjmpdsj-njyqrga-epyqq-mncpyrgmlq-808[rzoqv]
sbqiiyvyut-sxesebqju-huiuqhsx-582[suiqb]
clxalrtyr-dnlgpyrpc-sfye-epnsyzwzrj-873[rylpc]
amlqskcp-epybc-cee-bcqgel-756[ceblp]
jrncbavmrq-pnaql-pbngvat-qrirybczrag-377[rabnq]
cebwrpgvyr-onfxrg-qrcnegzrag-221[rgcen]
forwcoqhwjs-tzcksf-rsjszcdasbh-792[scfhj]
ckgvutofkj-pkrrehkgt-jkvgxzsktz-696[wxbfz]
kzeed-uqfxynh-lwfxx-qtlnxynhx-255[xnefh]
vhkkhlbox-vtgwr-hixktmbhgl-683[hkbgl]
mrxivrexmsrep-hci-viwievgl-464[msqei]
nsyjwsfyntsfq-idj-htsyfnsrjsy-931[syfjn]
awzwhofm-ufors-qobrm-qcohwbu-aofyshwbu-272[owbfh]
ahngzyzqcntr-bzmcx-cdoknxldms-651[cnzdm]
nsyjwsfyntsfq-hfsid-wjfhvznxnynts-671[dqrws]
krxqjijamxdb-npp-uxprbcrlb-589[vutpy]
ahngzyzqcntr-azrjds-knfhrshbr-209[qnogp]
pejji-bkllsd-crszzsxq-458[xlhso]
qcffcgwjs-gqojsbusf-vibh-zcuwghwqg-480[njzmp]
ziuxioqvo-moo-amzdqkma-174[zeuba]
ujqgywfau-aflwjfslagfsd-vqw-kwjnauwk-398[wafju]
elrkdcdugrxv-fdqgb-orjlvwlfv-101[mhsyz]
kpvgtpcvkqpcn-tcddkv-qrgtcvkqpu-700[ptqjs]
jfifqxov-doxab-avb-xkxivpfp-107[xfvab]
lsyrkjkbnyec-mkxni-mykdsxq-kmaescsdsyx-978[mbynk]
ocipgvke-lgnnadgcp-wugt-vguvkpi-206[hugza]
hcd-gsqfsh-qvcqczohs-rsgwub-142[dhpmf]
lsyrkjkbnyec-oqq-ckvoc-822[ckoqy]
vhkkhlbox-utldxm-vnlmhfxk-lxkobvx-787[xklhv]
vkppo-cqwdujys-vbemuh-qdqboiyi-504[qbdio]
qjopwxha-ywjzu-zaoecj-654[jaowz]
njmjubsz-hsbef-dipdpmbuf-efqbsunfou-311[bfusd]
ktiaaqnqml-jiasmb-lmdmtwxumvb-694[yxlgt]
vrurcjah-pajmn-lqxlxujcn-fxatbqxy-511[ztgdk]
vagreangvbany-qlr-znexrgvat-325[yblnw]
lgh-kwujwl-wyy-jwsuimakalagf-996[gsubl]
apuut-xgvnndadzy-ezggtwzvi-zibdizzmdib-343[qlykv]
pxtihgbsxw-utldxm-kxlxtkva-787[xtkla]
mfklstdw-esyfwlau-usfvq-vwkayf-762[kljiy]
eqpuwogt-itcfg-hwbba-fag-fgrnqaogpv-232[gafbo]
qzoggwtwsr-rms-rsdzcmasbh-688[srgmw]
yhkpvhjapcl-ibuuf-jbzavtly-zlycpjl-955[skwvb]
gpewwmjmih-hci-gywxsqiv-wivzmgi-620[txcfj]
lahxpnwrl-npp-vjatncrwp-537[aisyo]
ckgvutofkj-hatte-aykx-zkyzotm-436[ntzbr]
iehepwnu-cnwza-lhwopey-cnwoo-ykjpwejiajp-628[wepjn]
fkqbokxqflkxi-yxphbq-obpbxoze-471[napmi]
etyyx-cxd-lzqjdshmf-261[inzys]
ftzgxmbv-utldxm-ftkdxmbgz-267[wqkjm]
jyfvnlupj-jhukf-jvhapun-klwsvftlua-903[yrgnq]
zsxyfgqj-jll-qfgtwfytwd-489[sazdc]
oxjmxdfkd-zxkav-zlxqfkd-rpbo-qbpqfkd-263[vauwt]
dsxxw-cee-bcnyprkclr-470[ghzni]
enzcntvat-fpniratre-uhag-jbexfubc-533[aentb]
froruixo-mhoobehdq-dqdobvlv-803[odbhq]
raphhxuxts-qphzti-bpcpvtbtci-115[pthbc]
jvsvymbs-jhukf-jvhapun-shivyhavyf-955[yabwx]
ykhknbqh-ywjzu-odellejc-498[ehjkl]
avw-zljyla-ihzrla-zlycpjlz-201[uvdxz]
wdjcvuvmyjpn-nxvqzibzm-cpio-hvivbzhzio-967[vizbc]
xgjougizobk-pkrrehkgt-ktmotkkxotm-150[gnkzc]
kyelcrga-aylbw-rcaflmjmew-808[wsmtg]
laffe-atyzghrk-igtje-jkyomt-462[taefg]
hqtyeqsjylu-uww-ijehqwu-608[quweh]
kzgwomvqk-kivlg-kcabwumz-amzdqkm-200[cdavq]
avw-zljyla-jhukf-shivyhavyf-305[ahvyf]
guahyncw-vumeyn-xypyfijgyhn-370[ynghu]
kwtwznct-jiasmb-zmikycqaqbqwv-564[wbjnt]
sorozgxe-mxgjk-hatte-vaxingyotm-228[enmvq]
hqtyeqsjylu-sxesebqju-bqrehqjeho-348[nxucm]
qzoggwtwsr-awzwhofm-ufors-tzcksf-rsdofhasbh-948[sfowh]
jfifqxov-doxab-mixpqfz-doxpp-qbzeklildv-185[rydoa]
gsvvswmzi-vehmsegxmzi-fyrrc-irkmriivmrk-204[imrvs]
dlhwvupglk-qlssfilhu-ylzlhyjo-721[lhsuy]
crwwv-zxkav-absbilmjbkq-679[bakvw]
xzwrmkbqtm-lgm-zmkmqdqvo-720[mqkzb]
eqnqthwn-ecpfa-eqcvkpi-qrgtcvkqpu-570[qcepk]
ftzgxmbv-utldxm-nlxk-mxlmbgz-891[mxlbg]
xqvwdeoh-gbh-ghyhorsphqw-387[hgoqw]
rdchjbtg-vgpst-uadltg-pcpanhxh-141[mtvxn]
sebehvkb-vbemuh-udwyduuhydw-140[ubdeh]
gpsxdprixkt-qphzti-stktadebtci-921[tipdk]
nij-mywlyn-dyffsvyuh-omyl-nymncha-214[obtqu]
rdggdhxkt-rpcsn-rdpixcv-bpgztixcv-843[cdgpr]
pdjqhwlf-iorzhu-uhdftxlvlwlrq-803[rtwsz]
tinnm-dzoghwq-ufogg-twbobqwbu-428[bgown]
etyyx-qzaahs-lzmzfdldms-781[cmnek]
willimcpy-dyffsvyuh-fuvilunils-448[sjytb]
dpotvnfs-hsbef-qmbtujd-hsbtt-ufdiopmphz-831[zmvga]
hdgdovmt-bmvyz-ytz-xpnojhzm-nzmqdxz-109[hzpfs]
ksodcbwnsr-qobrm-aobousasbh-324[bosar]
myvybpev-tovvilokx-kmaescsdsyx-380[vsyek]
nbhofujd-cbtlfu-tbmft-571[mkltr]
sedikcuh-whqtu-uww-jusxdebewo-764[uwedh]
jvsvymbs-jhukf-klclsvwtlua-825[jxhaq]
crwwv-mixpqfz-doxpp-jxohbqfkd-575[serbn]
fmsledevhsyw-hci-xiglrspskc-646[scehi]
xekdwvwnzkqo-ywjzu-oanreyao-576[dwrqm]
gzefmnxq-vqxxknqmz-pqbmdfyqzf-352[xuyzs]
bqvvu-zua-hkceopeyo-706[eouva]
ytu-xjhwjy-gfxpjy-btwpxmtu-151[bynhm]
npmhcargjc-hcjjwzcyl-bctcjmnkclr-886[cjhlm]
xlrypetn-dnlgpyrpc-sfye-dlwpd-119[znfjd]
ejpanjwpekjwh-ydkykhwpa-hkceopeyo-758[patzv]
lhkhszqx-fqzcd-eknvdq-rsnqzfd-287[qdzfh]
froruixo-fdqgb-orjlvwlfv-179[optcg]
jvsvymbs-jovjvshal-jbzavtly-zlycpjl-253[zcnfy]
avw-zljyla-ibuuf-ylzlhyjo-149[xtcfz]
bnmrtldq-fqzcd-bzmcx-bnzshmf-cdudknoldms-157[whdus]
sno-rdbqds-idkkxadzm-rsnqzfd-703[dsknq]
vkppo-sxesebqju-tuiywd-504[epsub]
ryexqpqhteki-zubboruqd-husuylydw-790[nimls]
vetllbybxw-lvtoxgzxk-angm-kxvxbobgz-995[xbglv]
rdchjbtg-vgpst-qphzti-gtrtxkxcv-817[mayne]
dzczkrip-xiruv-irdgrxzex-vxx-rthlzjzkzfe-503[xwhmg]
qcbgiasf-ufors-pogysh-sbuwbssfwbu-454[nshbt]
qcbgiasf-ufors-qobrm-qcohwbu-igsf-hsghwbu-142[bsfgh]
zgmfyxypbmsq-pyzzgr-amlryglkclr-392[yglmr]
myxcewob-qbkno-cmkfoxqob-rexd-vklybkdybi-146[wxnuy]
amlqskcp-epybc-afmamjyrc-pcacgtgle-418[campe]
muqfedyput-isqludwuh-xkdj-huqsgkyiyjyed-660[nbtda]
vkppo-sqdto-vydqdsydw-114[pzbiy]
ziuxioqvo-jcvvg-lmxtwgumvb-668[fnbjv]
rdchjbtg-vgpst-rwdrdapit-stepgibtci-271[tdgip]
zbytomdsvo-zvkcdsm-qbkcc-zebmrkcsxq-614[nwmol]
sbnqbhjoh-fhh-efqbsunfou-103[hjxvu]
vagreangvbany-ohaal-nanylfvf-273[zfytn]
wihmogyl-aluxy-dyffsvyuh-lyuwkocmcncih-760[efwrt]
irgyyolokj-inuiurgzk-ykxboiky-332[ikyog]
gntmfefwitzx-xhfajsljw-mzsy-fhvznxnynts-437[mkuja]
tpspahyf-nyhkl-yhiipa-zhslz-539[yzmib]
encuukhkgf-rncuvke-itcuu-nqikuvkeu-700[ukcen]
mybbycsfo-mkxni-oxqsxoobsxq-198[oxbsm]
kyelcrga-zsllw-kypicrgle-730[nvjmt]
rdggdhxkt-uadltg-stktadebtci-713[btson]
dpssptjwf-qmbtujd-hsbtt-usbjojoh-623[miqos]
tcfkqcevkxg-dcumgv-vgejpqnqia-336[cgqve]
fodvvlilhg-gbh-orjlvwlfv-699[eykml]
bxaxipgn-vgpst-eaphixr-vgphh-ejgrwphxcv-817[rsizj]
pualyuhapvuhs-ibuuf-jvuahputlua-305[hlzmu]
qekrixmg-nippcfier-gsrxemrqirx-646[xhnfm]
pdjqhwlf-plolwdub-judgh-fdqgb-ghsorbphqw-543[aiewf]
fruurvlyh-vfdyhqjhu-kxqw-fxvwrphu-vhuylfh-647[hufvr]
ftzgxmbv-utldxm-ftgtzxfxgm-891[txfgm]
htsxzrjw-lwfij-gfxpjy-btwpxmtu-359[jtwxf]
gpewwmjmih-jyddc-hci-vigimzmrk-932[imcdg]
yuxufmdk-sdmpq-qss-oazfmuzyqzf-378[fmqsu]
oxmeeuruqp-eomhqzsqd-tgzf-efadmsq-508[oxhfu]
qzoggwtwsr-xszzmpsob-hsqvbczcum-610[scyrz]
avw-zljyla-ibuuf-ayhpupun-981[ualpy]
zloolpfsb-oxyyfq-bkdfkbbofkd-471[untjs]
tvsnigxmpi-jpsaiv-erepcwmw-308[nwfcx]
jvuzbtly-nyhkl-qlssfilhu-mpuhujpun-929[ulhjn]
yknnkoera-ydkykhwpa-pnwejejc-290[setqd]
tcrjjzwzvu-gcrjkzt-xirjj-ljvi-kvjkzex-659[jzkrv]
gntmfefwitzx-hmthtqfyj-xytwflj-307[tsebr]
gspsvjyp-wgezirkiv-lyrx-pefsvexsvc-412[svepg]
ugfkmewj-yjsvw-xdgowj-jwuwanafy-944[hysdk]
sbnqbhjoh-qmbtujd-hsbtt-tijqqjoh-597[bzawy]
vetllbybxw-unggr-tgterlbl-631[mfwxo]
tipfxvezt-avccpsvre-tljkfdvi-jvimztv-139[vtice]
hvbizodx-wpiit-yzkvmohzio-603[ytsvn]
sno-rdbqds-eknvdq-nodqzshnmr-209[dnqso]
rtqlgevkng-dcumgv-rwtejcukpi-960[yhfsz]
ugjjgkanw-tmffq-ksdwk-606[bqdtn]
jyfvnlupj-jhukf-jvhapun-ylhjxbpzpapvu-981[ygxts]
kzeed-gzssd-ijufwyrjsy-203[sdejy]
chnylhuncihuf-jfumncw-alumm-uwkocmcncih-864[btkms]
qfmcusbwq-suu-ghcfous-922[btras]
bgmxkgtmbhgte-ietlmbv-zktll-xgzbgxxkbgz-215[isyml]
pwcvonofrcig-xszzmpsob-zopcfohcfm-506[avfiu]
iruzfrtkzmv-dzczkrip-xiruv-treup-tfrkzex-fgvirkzfej-633[rzfik]
mrxivrexmsrep-nippcfier-qerekiqirx-776[ombwt]
iwcjapey-ywjzu-ykwpejc-ykjpwejiajp-420[ztgqm]
joufsobujpobm-qmbtujd-hsbtt-sfbdrvjtjujpo-467[jbotu]
xst-wigvix-yrwxefpi-gerhc-hiwmkr-230[mylsd]
ytu-xjhwjy-ojqqdgjfs-xmnuunsl-931[mvbrl]
zovldbkfz-avb-jxkxdbjbkq-159[bkdjv]
qvbmzvibqwvit-ntwemz-amzdqkma-226[mqvza]
eadalsjq-yjsvw-xdgowj-ljsafafy-840[nqijl]
dszphfojd-tdbwfohfs-ivou-bdrvjtjujpo-233[ximod]
gsvvswmzi-tpewxmg-kveww-erepcwmw-308[wizmq]
ktwbhtvmbox-ktuubm-hixktmbhgl-657[hynsw]
iuruxlar-vrgyzoi-mxgyy-sgtgmksktz-488[ufytd]
nzydfxpc-rclop-awldetn-rcldd-nzyeltyxpye-379[pusht]
iehepwnu-cnwza-ynukcajey-lhwopey-cnwoo-pnwejejc-212[enwcj]
vcibutulxiom-jfumncw-alumm-ijyluncihm-214[muicl]
pyknyegle-aylbw-qyjcq-392[hzumy]
atyzghrk-xghhoz-cuxqynuv-436[cmdsl]
vcibutulxiom-jfumncw-alumm-jolwbumcha-682[dgfeu]
cybyjqho-whqtu-isqludwuh-xkdj-cqdqwucudj-946[qudch]
lejkrscv-jtrmvexvi-ylek-uvgrikdvek-893[vekri]
nvrgfezqvu-upv-jkfirxv-789[vfrue]
fnjyxwrinm-ljwmh-lxjcrwp-bjunb-173[ljyap]
gsrwyqiv-kvehi-qekrixmg-fyrrc-wepiw-360[tnixb]
gsvvswmzi-fyrrc-hitevxqirx-308[irvsx]
nglmtuex-ynssr-vahvhetmx-wxlbzg-267[xeghl]
qjopwxha-acc-ykjpwejiajp-524[gjqhn]
wrs-vhfuhw-mhoobehdq-dqdobvlv-803[pdlvm]
otzkxtgzoutgr-inuiurgzk-uvkxgzouty-878[modya]
gvcskirmg-fyrrc-xvemrmrk-568[rmcgk]
xqvwdeoh-hjj-ghsduwphqw-231[hwdjq]
sbejpbdujwf-cvooz-nbslfujoh-441[nwsha]
zixppfcfba-oxyyfq-ixyloxqlov-315[xfoyi]
bdavqofuxq-rxaiqd-pqhqxabyqzf-846[yzpfi]
vhglnfxk-zktwx-vetllbybxw-ktuubm-hixktmbhgl-501[bkltx]
tinnm-qobrm-qcohwbu-zcuwghwqg-584[ejnps]
rmn-qcapcr-kyelcrga-cee-bcqgel-730[cerag]
apwmeclga-djmucp-ylyjwqgq-756[acgjl]
pybgmyargtc-amlqskcp-epybc-zsllw-pcacgtgle-392[cglpa]
jxdkbqfz-avb-tlohpelm-783[blade]
npmhcargjc-bwc-pcqcypaf-808[phjds]
rdchjbtg-vgpst-qphzti-itrwcdadvn-843[zueyn]
votubcmf-qmbtujd-hsbtt-sfdfjwjoh-259[tbfjd]
ujoon-gpqqxi-advxhixrh-661[mlyen]
ykjoqian-cnwza-lhwopey-cnwoo-iwjwcaiajp-576[waoci]
gpewwmjmih-wgezirkiv-lyrx-xvemrmrk-386[mreiw]
gzefmnxq-ngzzk-pqhqxabyqzf-352[drqzm]
nwilwcejc-nwxxep-oanreyao-394[lqxwm]
hdgdovmt-bmvyz-zbb-gjbdnodxn-785[bdgmn]
gsrwyqiv-kvehi-aietsrmdih-gerhc-gsexmrk-viwievgl-672[bsytl]
rdchjbtg-vgpst-tvv-rdcipxcbtci-999[ctvbd]
joufsobujpobm-fhh-tbmft-389[mnyql]
fnjyxwrinm-mhn-anbnjalq-147[nmbzl]
wfummczcyx-yaa-guhuaygyhn-578[yaucg]
qfkkj-mfyyj-dpcgtnpd-457[dfjkp]
ncjzrpytn-mfyyj-wzrtdetnd-509[qnwdl]
sno-rdbqds-bnknqetk-idkkxadzm-bnmszhmldms-365[dkmns]
wkqxodsm-cmkfoxqob-rexd-vyqscdsmc-380[cdmoq]
dpssptjwf-tdbwfohfs-ivou-tbmft-233[lbdah]
dpssptjwf-dipdpmbuf-xpsltipq-285[pdsfi]
qyujihctyx-wuhxs-wiuncha-jolwbumcha-214[zlbuy]
oxmeeuruqp-pkq-iadwetab-716[eapqu]
wfummczcyx-ohmnuvfy-xsy-womnigyl-mylpcwy-214[ymcwf]
xmtjbzidx-ytz-ncdkkdib-525[wmfvr]
qekrixmg-jpsaiv-xiglrspskc-204[dwvst]
kwtwznct-zijjqb-mvoqvmmzqvo-356[qmnjk]
ltpedcxots-ytaanqtpc-rdcipxcbtci-999[lkmsv]
zovldbkfz-yrkkv-abmxoqjbkq-913[kboqv]
yhkpvhjapcl-wshzapj-nyhzz-jvuahputlua-279[cnmzy]
pdjqhwlf-edvnhw-whfkqrorjb-257[unmsk]
rgllk-bdavqofuxq-rxaiqd-iadwetab-664[mkeil]
wdjcvuvmyjpn-nxvqzibzm-cpio-nzmqdxzn-343[nzmvc]
xzwrmkbqtm-kpwkwtibm-nqvivkqvo-486[dcwog]
rdchjbtg-vgpst-rpcsn-rdpixcv-hidgpvt-765[stnfw]
buzahisl-lnn-thuhnltlua-955[oschg]
enzcntvat-ohaal-bcrengvbaf-793[anbce]
eqpuwogt-itcfg-uecxgpigt-jwpv-hkpcpekpi-362[pgcei]
avw-zljyla-qlssfilhu-dvyrzovw-175[lvasw]
iuruxlar-xgsvgmotm-inuiurgzk-zxgototm-982[mlnut]
tyepcyletzylw-prr-opalcexpye-925[boymz]
hqcfqwydw-rqiauj-huiuqhsx-556[abndo]
tcrjjzwzvu-vxx-kirzezex-841[zxejr]
qspkfdujmf-sbccju-sfdfjwjoh-285[ktqja]
vcibutulxiom-wbiwifuny-guleyncha-682[uzxms]
ejpanjwpekjwh-bqvvu-ywjzu-nayaerejc-628[jeawn]
kwvacumz-ozilm-kivlg-lmdmtwxumvb-330[mlvik]
kzgwomvqk-kwvacumz-ozilm-zijjqb-bziqvqvo-460[zqvik]
wfintfhynaj-wfggny-qfgtwfytwd-775[fwgnt]
tcfkqcevkxg-hnqygt-vgejpqnqia-622[qgcek]
yrwxefpi-nippcfier-wepiw-386[ipewf]
xjinphzm-bmvyz-zbb-omvdidib-109[bimzd]
qlm-pbzobq-ciltbo-abmilvjbkq-107[jvsxc]
tfcfiwlc-gcrjkzt-xirjj-tfekrzedvek-295[wjhqa]
nchhg-moo-lmdmtwxumvb-382[mhobc]
bknsykmdsfo-lkcuod-myxdksxwoxd-692[azknp]
jxdkbqfz-yrkkv-qoxfkfkd-211[kfdqx]
jlidywncfy-dyffsvyuh-lyuwkocmcncih-344[ycfdh]
iuruxlar-igtje-iugzotm-lotgtiotm-358[tigou]
foadouwbu-gqojsbusf-vibh-qighcasf-gsfjwqs-116[sfbgo]
ucynmlgxcb-aylbw-nspafyqgle-288[fswap]
amppmqgtc-aylbw-qfgnngle-808[galmn]
kfg-jvtivk-irsszk-jrcvj-659[jkvir]
xjinphzm-bmvyz-ytz-yzqzgjkhzio-681[ubzyj]
plolwdub-judgh-fdqgb-ilqdqflqj-491[dlqbf]
crwwv-yrkkv-bkdfkbbofkd-783[inhxy]
nuatmlmdpage-otaoaxmfq-pqhqxabyqzf-612[qvdxy]
pualyuhapvuhs-ibuuf-jbzavtly-zlycpjl-435[znegj]
eza-dpncpe-clmmte-lylwjdtd-509[delcm]
tfejldvi-xiruv-irsszk-uvgcfpdvek-659[rvaql]
pybgmyargtc-aylbw-qcptgacq-600[oscut]
kdijqrbu-vbemuh-qdqboiyi-972[biqdu]
irgyyolokj-vrgyzoi-mxgyy-jkvruesktz-644[ygkor]
rgllk-uzfqdzmfuazmx-otaoaxmfq-oazfmuzyqzf-560[zfamo]
iqmbazulqp-eomhqzsqd-tgzf-fqotzaxask-378[qmsxo]
oqnidbshkd-atmmx-kzanqzsnqx-703[vztcl]
vjpwncrl-lqxlxujcn-mnyjacvnwc-615[cnjlv]
bkzrrhehdc-cxd-bnmszhmldms-807[dhmbc]
kgjgrypw-epybc-zyqicr-bcnyprkclr-704[mzsty]
apuut-ezggtwzvi-yzqzgjkhzio-265[pmlri]
rflsjynh-hfsid-htfynsl-qtlnxynhx-567[cqbst]
zilqwikbqdm-lgm-nqvivkqvo-330[wmxzv]
lahxpnwrl-ouxfna-anlnrerwp-355[nzkvm]
veqtekmrk-ikk-tyvglewmrk-386[kemrt]
sgmtkzoi-pkrrehkgt-rumoyzoiy-514[zytsw]
yflexwxoalrp-oxyyfq-mrozexpfkd-341[xfoye]
bwx-amkzmb-kivlg-kwibqvo-xczkpiaqvo-434[lkqrz]
clxalrtyr-nsznzwlep-opdtry-145[nczlj]
bjfutsneji-jll-wjhjnansl-125[szrni]
bcfhvdczs-cpxsqh-ghcfous-324[chsfb]
aflwjfslagfsd-kusnwfywj-zmfl-ugflsafewfl-216[flswa]
gcfcnuls-aluxy-wuhxs-jolwbumcha-578[uclah]
pyknyegle-pybgmyargtc-aylbw-qfgnngle-470[gyeln]
oazegyqd-sdmpq-gzefmnxq-qss-geqd-fqefuzs-508[qesdf]
xjmmjndqz-mvwwdo-yzkvmohzio-551[ypzog]
zekvierkzferc-treup-uvgcfpdvek-789[stzno]
ejpanjwpekjwh-xqjju-odellejc-576[enmtc]
ltpedcxots-tvv-sthxvc-115[skptq]
jshzzpmplk-yhiipa-zavyhnl-981[tluns]
mvhkvbdib-agjrzm-yzqzgjkhzio-629[wcyms]
yhwooebeaz-acc-paydjkhkcu-316[acehk]
gzefmnxq-otaoaxmfq-emxqe-326[emqxa]
frqvxphu-judgh-udeelw-pdqdjhphqw-335[orhsy]
frqvxphu-judgh-gbh-uhfhlylqj-153[hufgj]
cjpibabsepvt-cvooz-fohjoffsjoh-623[emnjh]
yflexwxoalrp-zxkav-zlxqfkd-xkxivpfp-783[xfklp]
froruixo-hjj-zrunvkrs-777[synml]
jvuzbtly-nyhkl-jhukf-jvhapun-jvuahputlua-929[ndjmy]
kwzzwaqdm-kivlg-kwibqvo-nqvivkqvo-460[yzmsr]
ktiaaqnqml-zijjqb-apqxxqvo-798[qaijx]
hqfxxnknji-hfsid-wjhjnansl-931[nhjfi]
xjmmjndqz-wpiit-vxlpdndodji-941[dijmn]
ksodcbwnsr-rms-cdsfohwcbg-896[xvuol]
eza-dpncpe-tyepcyletzylw-nsznzwlep-nzyeltyxpye-847[xydvf]
emixwvqhml-jiasmb-ivitgaqa-928[iamqv]
etyyx-idkkxadzm-ehmzmbhmf-313[josnm]
lhkhszqx-fqzcd-bgnbnkzsd-qdzbpthrhshnm-911[bqzra]
dzczkrip-xiruv-upv-wzeretzex-945[icynm]
wihmogyl-aluxy-mwupyhayl-bohn-lymyulwb-266[nuraz]
kmjezxodgz-xcjxjgvoz-zibdizzmdib-239[yzkgs]
hqfxxnknji-wfggny-hzxytrjw-xjwanhj-593[jnxhw]
oknkvcta-itcfg-eqpuwogt-itcfg-ecpfa-eqcvkpi-ucngu-986[cgtef]
ykhknbqh-oywrajcan-dqjp-qoan-paopejc-810[ondma]
nwilwcejc-ywjzu-ykwpejc-naoawnyd-238[zjwsh]
dzczkrip-xiruv-sleep-rercpjzj-451[wykfr]
gpewwmjmih-nippcfier-qerekiqirx-178[ieprm]
bqvvu-oywrajcan-dqjp-wjwhuoeo-420[jowaq]
kzgwomvqk-xtiabqk-oziaa-bziqvqvo-148[qaiko]
fab-eqodqf-eomhqzsqd-tgzf-fdmuzuzs-820[fqzde]
lzfmdshb-dff-sqzhmhmf-755[fhmds]
bpvctixr-gpqqxi-sthxvc-297[xcipq]
xjgjmapg-kmjezxodgz-xcjxjgvoz-vivgtndn-915[jhigl]
pbybeshy-qlr-bcrengvbaf-715[jwrxz]
uqtqbizg-ozilm-kivlg-tijwzibwzg-902[lrepd]
excdklvo-zbytomdsvo-zvkcdsm-qbkcc-crszzsxq-614[rpnqm]
ucynmlgxcb-njyqrga-epyqq-kylyeckclr-418[yclqe]
hqtyeqsjylu-sxesebqju-mehaixef-556[eqshj]
chnylhuncihuf-wifilzof-jfumncw-alumm-uwkocmcncih-734[cufhi]
wyvqljapsl-ihzrla-zhslz-669[ncmjb]
jlidywncfy-wifilzof-vohhs-omyl-nymncha-578[yfhil]
jfifqxov-doxab-bdd-abpfdk-913[dbfao]
xjgjmapg-wpiit-gjbdnodxn-551[zvmhq]
dkqjcbctfqwu-tcfkqcevkxg-ecpfa-eqcvkpi-tgegkxkpi-414[ckeqf]
tmrszakd-idkkxadzm-lzmzfdldms-365[hwgsv]
nglmtuex-vtgwr-vhtmbgz-mxvaghehzr-215[tsfmz]
uiovmbqk-rmttgjmiv-bziqvqvo-252[vimqb]
iehepwnu-cnwza-fahhuxawj-oanreyao-680[mavot]
tvsnigxmpi-glsgspexi-gsrxemrqirx-100[xwqld]
qcbgiasf-ufors-rms-aobousasbh-818[sabof]
sgmtkzoi-hatte-xkykgxin-722[ktgix]
nglmtuex-xzz-tvjnblbmbhg-787[kopjm]
ikhcxvmbex-vtgwr-xgzbgxxkbgz-683[ncalt]
tbxmlkfwba-molgbzqfib-zxkav-pbosfzbp-419[bfzak]
gspsvjyp-fmsledevhsyw-tpewxmg-kveww-eguymwmxmsr-568[nihyt]
gvcskirmg-gerhc-jmrergmrk-672[lrzta]
xmrrq-uzgugdslw-jwsuimakalagf-502[agulm]
shoewudys-hqrryj-tulubefcudj-530[ixkdy]
mrxivrexmsrep-hci-wxsveki-230[miwqn]
tmrszakd-bgnbnkzsd-otqbgzrhmf-599[qjfny]
rwcnawjcrxwju-kdwwh-fxatbqxy-355[jezwy]
hjgbwuladw-tmffq-ogjckzgh-528[gnlzr]
lxuxaodu-lxwbdvna-pajmn-ajkkrc-dbna-cnbcrwp-511[umnsy]
nsyjwsfyntsfq-idj-jslnsjjwnsl-619[ywpco]
ubhatstkwhnl-ktuubm-mktbgbgz-761[btkug]
lhkhszqx-fqzcd-bgnbnkzsd-dmfhmddqhmf-781[bdnsk]
vehmsegxmzi-ikk-vieguymwmxmsr-854[pnkle]
udskkaxawv-jsttal-esfsywewfl-528[sawef]
jxdkbqfz-avb-cfkxkzfkd-887[kfbdx]
jyddc-jpsaiv-gsrxemrqirx-386[rdijs]
tagzsrsjvgmk-wyy-umklgewj-kwjnauw-606[wgjka]
wyvqljapsl-ihzrla-huhsfzpz-409[znhcm]
jvuzbtly-nyhkl-zjhclunly-obua-jbzavtly-zlycpjl-331[lyjzb]
gvaaz-sbejpbdujwf-gmpxfs-vtfs-uftujoh-467[tsogk]
aczupnetwp-nsznzwlep-cplnbftdtetzy-535[nptze]
gifavtkzcv-vxx-jrcvj-815[vcjxa]
ytu-xjhwjy-uqfxynh-lwfxx-uzwhmfxnsl-255[yzalu]
eqttqukxg-ecpfa-eqcvkpi-cpcnauku-440[zotsy]
ncjzrpytn-nlyoj-nzletyr-nzyeltyxpye-639[zhytj]
bgmxkgtmbhgte-lvtoxgzxk-angm-phkdlahi-605[nyzfq]
ytu-xjhwjy-xhfajsljw-mzsy-qfgtwfytwd-801[rewpl]
gpsxdprixkt-rwdrdapit-prfjxhxixdc-349[qrskt]
ojk-nzxmzo-kgvnodx-bmvnn-hvivbzhzio-629[cvkyu]
ktwbhtvmbox-unggr-ybgtgvbgz-267[nbjvs]
wdjcvuvmyjpn-nxvqzibzm-cpio-kpmxcvndib-109[tndsr]
froruixo-gbh-zrunvkrs-439[roubf]
oazegyqd-sdmpq-otaoaxmfq-fdmuzuzs-352[admoq]
fruurvlyh-fdqgb-sxufkdvlqj-699[mynfj]
votubcmf-qmbtujd-hsbtt-efqmpznfou-441[wznfd]
emixwvqhml-akidmvomz-pcvb-abwziom-928[gwxum]
qcbgiasf-ufors-foppwh-sbuwbssfwbu-506[sbfuw]
mrxivrexmsrep-fyrrc-pskmwxmgw-100[pmxwc]
nsyjwsfyntsfq-uqfxynh-lwfxx-uzwhmfxnsl-125[bwtze]
kwtwznct-kpwkwtibm-nqvivkqvo-928[kwtvi]
lahxpnwrl-ouxfna-vjwjpnvnwc-953[nwajl]
ydjuhdqjyedqb-hqrryj-ixyffydw-114[cwzyi]
rgndvtcxr-snt-igpxcxcv-661[uqvtr]
bgmxkgtmbhgte-pxtihgbsxw-vahvhetmx-tvjnblbmbhg-371[bghtm]
pwcvonofrcig-tzcksf-fsoqeiwgwhwcb-428[swzyd]
yaxsnlcrun-ajkkrc-bqryyrwp-641[ycnxl]
jef-iushuj-hqrryj-bqrehqjeho-738[zaytn]
bdavqofuxq-bxmefuo-sdmee-xmnadmfadk-352[dmaef]
qcffcgwjs-qobrm-rsdzcmasbh-350[mezyn]
jxdkbqfz-yxphbq-tlohpelm-289[wfvbo]
hdgdovmt-bmvyz-wvnfzo-yzndbi-915[dvzbm]
hqcfqwydw-sxesebqju-vydqdsydw-712[smhbn]
qfmcusbwq-qobrm-qcohwbu-zcuwghwqg-636[qwbcu]
jvsvymbs-msvdly-jvuahputlua-955[vsuaj]
hqcfqwydw-rkddo-huiuqhsx-218[dhquw]
shoewudys-uww-jhqydydw-816[jysaf]
dyz-combod-zvkcdsm-qbkcc-dbksxsxq-562[cdbks]
tcrjjzwzvu-treup-tfrkzex-rercpjzj-217[fewxh]
pynffvsvrq-cynfgvp-tenff-grpuabybtl-481[fnpvy]
yhtwhnpun-jyfvnlupj-wshzapj-nyhzz-huhsfzpz-773[zyogh]
bnqqnrhud-bzmcx-lzqjdshmf-443[jmvdf]
yrwxefpi-glsgspexi-hitevxqirx-282[bzvyj]
iuxxuyobk-hgyqkz-zkinturume-540[ukixy]
gpsxdprixkt-rpcsn-prfjxhxixdc-271[ewstq]
vrurcjah-pajmn-ouxfna-anlnrerwp-615[qsfhg]
mrxivrexmsrep-tpewxmg-kveww-hiwmkr-854[votlz]
irgyyolokj-ixeumktoi-jek-rghuxgzuxe-904[egiko]
dsxxw-zyqicr-pcacgtgle-912[swjtv]
yhkpvhjapcl-kfl-ylhjxbpzpapvu-955[phlaj]
gsrwyqiv-kvehi-tpewxmg-kveww-hitevxqirx-724[mnsyt]
muqfedyput-rkddo-vydqdsydw-998[mlqhr]
ykhknbqh-ywjzu-iwngapejc-628[hjknw]
uwtojhynqj-gzssd-ywfnsnsl-619[snjwy]
emixwvqhml-kpwkwtibm-zmkmqdqvo-148[mkqwi]
upv-uvjzxe-347[uvejp]
cqwdujys-ryexqpqhteki-rkddo-skijecuh-iuhlysu-738[uyvln]
fydelmwp-nsznzwlep-dezclrp-379[elpzd]
yknnkoera-fahhuxawj-wymqeoepekj-914[kwucf]
hwbba-vqr-ugetgv-lgnnadgcp-ugtxkegu-908[guabe]
xqvwdeoh-ixccb-udeelw-fxvwrphu-vhuylfh-803[heuvw]
xekdwvwnzkqo-acc-iwjwcaiajp-784[mswzt]
rdchjbtg-vgpst-qphzti-jhtg-ithixcv-609[thgic]
cqwdujys-vbemuh-iqbui-608[ubiqc]
htsxzrjw-lwfij-gfxpjy-rfsfljrjsy-489[jfrsl]
rtqlgevkng-dcumgv-wugt-vguvkpi-362[gvukt]
oxaflxzqfsb-mixpqfz-doxpp-zrpqljbo-pbosfzb-185[pbfox]
lqwhuqdwlrqdo-hjj-sxufkdvlqj-569[qdjlh]
wihmogyl-aluxy-wuhxs-wiuncha-nywbhifias-994[ztysn]
hwbba-oknkvcta-itcfg-dwppa-tgugctej-492[tacgb]
mybbycsfo-oqq-wkxkqowoxd-120[oqbkw]
tyepcyletzylw-dnlgpyrpc-sfye-xlcvpetyr-249[xawqz]
hjgbwuladw-tmffq-ugflsafewfl-684[flwag]
sbnqbhjoh-kfmmzcfbo-bobmztjt-493[jnism]
ykjoqian-cnwza-lhwopey-cnwoo-zarahkliajp-602[ihrlb]
pynffvsvrq-fpniratre-uhag-erfrnepu-585[kwurl]
vetllbybxw-utldxm-mxvaghehzr-787[lxbeh]
ktfitzbgz-lvtoxgzxk-angm-nlxk-mxlmbgz-787[gxzkl]
emixwvqhml-rmttgjmiv-tijwzibwzg-876[tszyl]
esyfwlau-udskkaxawv-hdsklau-yjskk-ksdwk-658[ksadu]
jsvagsulanw-tskcwl-jwuwanafy-216[oklsn]
wfummczcyx-mwupyhayl-bohn-xymcah-552[xcazi]
tbxmlkfwba-oxyyfq-xkxivpfp-705[xfbkp]
ytu-xjhwjy-rflsjynh-uqfxynh-lwfxx-ijuqtdrjsy-853[ztoub]
cvabijtm-jiasmb-tijwzibwzg-564[qatln]
jef-iushuj-uww-ixyffydw-816[ptbea]
zntargvp-fpniratre-uhag-svanapvat-715[dnmgz]
mvydjvxodqz-zbb-jkzmvodjin-343[fxmnr]
xlrypetn-nlyoj-dlwpd-873[ldnpy]
jrncbavmrq-pnaql-pbngvat-ybtvfgvpf-117[hgwjo]
guahyncw-dyffsvyuh-uhufsmcm-786[ufhyc]
ide-htrgti-rpcsn-rdpixcv-igpxcxcv-115[ciprx]
nwilwcejc-ydkykhwpa-qoan-paopejc-628[acpwe]
udpsdjlqj-sodvwlf-judvv-oderudwrub-673[dujvl]
xekdwvwnzkqo-lhwopey-cnwoo-zarahkliajp-966[zdklq]
ixccb-iorzhu-xvhu-whvwlqj-803[emzxn]
gpbepvxcv-gpqqxi-prfjxhxixdc-297[utzsx]
zntargvp-wryylorna-fuvccvat-871[dxepl]
jvyyvzpcl-ipvohghykvbz-yhiipa-yljlpcpun-149[aupdo]
lzfmdshb-okzrshb-fqzrr-lzmzfdldms-651[ndpcm]
krxqjijamxdb-bljenwpna-qdwc-mnyuxhvnwc-381[njwxa]
apuut-xviyt-yzkvmohzio-395[iotuv]
rzvkjiduzy-kgvnodx-bmvnn-mzxzdqdib-187[tayqb]
pkl-oaynap-xwogap-owhao-888[zlbay]
ynukcajey-nwxxep-paydjkhkcu-394[kyace]
fnjyxwrinm-ouxfna-mnbrpw-771[nfmrw]
lejkrscv-tfcfiwlc-irsszk-nfibjyfg-399[fcisj]
dwbcjkun-ljwmh-anlnrerwp-589[nwjlr]
hdgdovmt-bmvyz-ojk-nzxmzo-wpiit-omvdidib-291[nmqdz]
nwzekwypera-xwogap-hwxknwpknu-810[wknpa]
htwwtxnaj-ojqqdgjfs-wjxjfwhm-567[jwfhq]
ynukcajey-zua-lqnydwoejc-420[xqrgw]
pelbtravp-cynfgvp-tenff-npdhvfvgvba-559[vfpna]
ibghopzs-foppwh-aobousasbh-142[ranfu]
qxdwpopgsdjh-tvv-rdcipxcbtci-713[wscpi]
vkppo-sbqiiyvyut-vbemuh-husuylydw-452[uyvbh]
lqwhuqdwlrqdo-vfdyhqjhu-kxqw-orjlvwlfv-699[qlwdh]
tcrjjzwzvu-gcrjkzt-xirjj-vexzevvizex-113[gusom]
wsvsdkbi-qbkno-lexxi-kmaescsdsyx-614[mnoyt]
kmjezxodgz-xviyt-xjvodib-jkzmvodjin-681[jdiov]
kgjgrypw-epybc-kyelcrga-njyqrga-epyqq-asqrmkcp-qcptgac-990[cgpqy]
tagzsrsjvgmk-hdsklau-yjskk-xafsfuafy-736[sakfg]
iwcjapey-xqjju-wymqeoepekj-472[wshmz]
ckgvutofkj-xghhoz-zxgototm-618[dapcq]
excdklvo-bkllsd-zebmrkcsxq-692[sdyzv]
ugdgjxmd-jsttal-ogjckzgh-320[nxksp]
dmbttjgjfe-gmpxfs-fohjoffsjoh-675[emswj]
esyfwlau-wyy-kwjnauwk-762[zfkst]
htsxzrjw-lwfij-gzssd-xytwflj-359[jswfl]
bnmrtldq-fqzcd-bzmcx-bnzshmf-cdozqsldms-157[rchap]
enqvbnpgvir-wryylorna-hfre-grfgvat-247[rgnva]
rzvkjiduzy-mvwwdo-hvivbzhzio-629[vzidh]
rgllk-omzpk-ymzmsqyqzf-742[ytshk]
wyvqljapsl-kfl-shivyhavyf-175[lvyaf]
zloolpfsb-molgbzqfib-oxyyfq-absbilmjbkq-731[rdypn]
wlqqp-srjbvk-glityrjzex-399[jlqrb]
foadouwbu-qvcqczohs-hsqvbczcum-402[coqub]
gsrwyqiv-kvehi-wgezirkiv-lyrx-wlmttmrk-334[dxqri]
apwmeclga-afmamjyrc-amlryglkclr-470[dvjwq]
amjmpdsj-aylbw-amyrgle-bcqgel-756[fmsjn]
pbybeshy-sybjre-ynobengbel-507[beyns]
jchipqat-rpcsn-hwxeexcv-505[yozns]
excdklvo-nio-bomosfsxq-458[bhmlt]
oaxadrgx-ngzzk-ymzmsqyqzf-534[eqjfa]
ajyqqgdgcb-zsllw-umpiqfmn-262[sdmlk]
wkqxodsm-lexxi-cobfsmoc-510[tpnbi]
tcfkqcevkxg-ecpfa-eqcvkpi-octmgvkpi-986[ckepv]
pbybeshy-onfxrg-qrcyblzrag-845[bryga]
rdggdhxkt-hrpktcvtg-wjci-gtrtxkxcv-479[tgckr]
willimcpy-jfumncw-alumm-lywycpcha-500[utskn]
qyujihctyx-luxciuwncpy-yaa-mbcjjcha-942[tzusp]
pelbtravp-pnaql-fgbentr-585[pabel]
jef-iushuj-vbemuh-tuiywd-140[jvndh]
rwcnawjcrxwju-kjbtnc-mnyuxhvnwc-355[cnwjr]
dszphfojd-tdbwfohfs-ivou-ufdiopmphz-285[dfohp]
uqtqbizg-ozilm-kivlg-kwibqvo-ewzsapwx-538[iqwzb]
njmjubsz-hsbef-cbtlfu-bobmztjt-649[dtsjy]
zlilocri-zxkav-zlxqfkd-pefmmfkd-887[zijtp]
iwcjapey-ydkykhwpa-oanreyao-576[jfnpy]
pybgmyargtc-zgmfyxypbmsq-zyqicr-mncpyrgmlq-600[gzfir]
houngfgxjuay-yigbktmkx-natz-ygrky-228[gykan]
lnkfaypeha-zua-odellejc-680[gmnlj]
vhglnfxk-zktwx-cxeeruxtg-kxlxtkva-319[xkteg]
wfintfhynaj-gzssd-qfgtwfytwd-541[mztfn]
amlqskcp-epybc-aylbw-nspafyqgle-886[alpyb]
iuruxlar-pkrrehkgt-ygrky-774[tsflj]
xtwtelcj-rclop-clmmte-opgpwzaxpye-145[tskxr]
bqvvu-ywjzu-ykwpejc-hwxknwpknu-862[wkujn]
enqvbnpgvir-zntargvp-cynfgvp-tenff-ybtvfgvpf-585[vfngp]
rzvkjiduzy-xviyt-xjvodib-xjiovdihzio-967[pjzrk]
njmjubsz-hsbef-sbnqbhjoh-cvooz-pqfsbujpot-623[bjosh]
zixppfcfba-mixpqfz-doxpp-zlkqxfkjbkq-653[pfxkq]
hdgdovmt-bmvyz-kgvnodx-bmvnn-rjmfncjk-239[rpovu]
hdgdovmt-bmvyz-xviyt-yzndbi-109[pdslu]
xjinphzm-bmvyz-kgvnodx-bmvnn-vivgtndn-525[nvmbd]
eqnqthwn-eqttqukxg-hnqygt-rwtejcukpi-544[qteng]
zvyvgnel-tenqr-sybjre-grpuabybtl-793[lyfvq]
tcorcikpi-ecpfa-eqcvkpi-ugtxkegu-596[teibn]
nwzekwypera-fahhuxawj-lqnydwoejc-810[mszph]
mhi-lxvkxm-cxeeruxtg-kxvxbobgz-605[palbn]
wfummczcyx-jlidywncfy-vumeyn-mylpcwym-838[ijqrb]
fhezusjybu-zubboruqd-cqdqwucudj-374[ubdqc]
kgjgrypw-epybc-aylbw-amyrgle-qcptgacq-314[mjlic]
tcfkqcevkxg-dwppa-ucngu-362[trzmu]
oazegyqd-sdmpq-gzefmnxq-eomhqzsqd-tgzf-qzsuzqqduzs-560[dmrkq]
jlidywncfy-vohhs-xypyfijgyhn-110[yhfij]
ftzgxmbv-lvtoxgzxk-angm-hixktmbhgl-163[gxmtb]
xgjougizobk-vrgyzoi-mxgyy-cuxqynuv-644[yntxg]
yknnkoera-lhwopey-cnwoo-odellejc-524[qypjt]
eza-dpncpe-upwwjmply-zapcletzyd-769[pezac]
cvabijtm-ntwemz-zmikycqaqbqwv-564[mqabc]
irgyyolokj-kmm-rghuxgzuxe-410[gkmor]
ahngzyzqcntr-idkkxadzm-sdbgmnknfx-807[ndkza]
surmhfwloh-fkrfrodwh-pdqdjhphqw-829[myflz]
elrkdcdugrxv-edvnhw-xvhu-whvwlqj-387[mhtue]
sbejpbdujwf-xfbqpojafe-ezf-mphjtujdt-155[tqslv]
shoewudys-rkddo-tuiywd-686[sntpq]
qcffcgwjs-dzoghwq-ufogg-igsf-hsghwbu-350[psevy]
ibghopzs-qobrm-qcohwbu-zopcfohcfm-740[obchf]
atyzghrk-vrgyzoi-mxgyy-sgtgmksktz-150[tjpiv]
luxciuwncpy-dyffsvyuh-nluchcha-994[cuhyf]
vcibutulxiom-xsy-uwkocmcncih-214[ciumo]
vkppo-rkddo-cqdqwucudj-140[dckop]
ftzgxmbv-vtgwr-kxlxtkva-163[tvxgk]
jlidywncfy-vumeyn-womnigyl-mylpcwy-682[ylmnw]
mtzslklcozfd-nlyoj-nzletyr-qtylyntyr-639[xswlz]
ixccb-fkrfrodwh-fxvwrphu-vhuylfh-283[fhrcu]
ykjoqian-cnwza-oywrajcan-dqjp-qoan-paopejc-212[tsrfk]
yhkpvhjapcl-yhiipa-jbzavtly-zlycpjl-617[ftaes]
qmpmxevc-kvehi-wgezirkiv-lyrx-xvemrmrk-516[emrvi]
fmsledevhsyw-veffmx-wivzmgiw-204[efmvw]
zlkprjbo-doxab-zxkav-zlxqfkd-obxznrfpfqflk-237[rqgnd]
ksodcbwnsr-qobrm-qcohwbu-aobousasbh-142[bosac]
yrwxefpi-glsgspexi-qevoixmrk-828[atyoc]
dlhwvupglk-wshzapj-nyhzz-klzpnu-877[fbewu]
bjfutsneji-idj-hzxytrjw-xjwanhj-359[wyrxt]
zsxyfgqj-bjfutsneji-hfsid-htfynsl-zxjw-yjxynsl-229[jsfyn]
pualyuhapvuhs-ibuuf-klwsvftlua-643[ualfh]
yknnkoera-ydkykhwpa-klanwpekjo-420[kanye]
iehepwnu-cnwza-ydkykhwpa-zaoecj-420[pozyv]
ftzgxmbv-ktuubm-mxvaghehzr-605[mbght]
gntmfefwitzx-xhfajsljw-mzsy-ywfnsnsl-983[woefn]
xmtjbzidx-wpiit-ncdkkdib-863[idbkt]
ktiaaqnqml-uqtqbizg-ozilm-kpwkwtibm-ivitgaqa-850[ywdzl]
dyz-combod-sxdobxkdsyxkv-mkxni-wkxkqowoxd-224[isamh]
nsyjwsfyntsfq-rnqnyfwd-lwfij-kqtbjw-uzwhmfxnsl-151[roxtn]
ykjoqian-cnwza-xqjju-nayaerejc-524[yvwax]
ixccb-iorzhu-ilqdqflqj-569[fcjsy]
ovbunmneqbhf-ohaal-qrfvta-819[abfhn]
glrcplyrgmlyj-zyqicr-pcyaosgqgrgml-626[glryc]
ajyqqgdgcb-bwc-ylyjwqgq-262[qgybc]
fhezusjybu-rkddo-bewyijysi-608[ybdei]
aflwjfslagfsd-kusnwfywj-zmfl-xafsfuafy-632[wltdc]
iuxxuyobk-lruckx-vaxingyotm-644[xuiko]
jyfvnlupj-kfl-thyrlapun-773[lfjnp]
eqpuwogt-itcfg-tcfkqcevkxg-dcumgv-qrgtcvkqpu-934[ionzm]
hqcfqwydw-sqdto-seqjydw-bqrehqjeho-998[qdehw]
xst-wigvix-ikk-wivzmgiw-724[rtszg]
tinnm-pibbm-zcuwghwqg-766[mfgbn]
vkppo-rqiauj-cqdqwucudj-348[qucdj]
bnmrtldq-fqzcd-ahngzyzqcntr-atmmx-dmfhmddqhmf-989[mdqfh]
vkrhzxgbv-unggr-tgterlbl-319[tsrkm]
wihmogyl-aluxy-wuhxs-uhufsmcm-526[uhmls]
nzydfxpc-rclop-awldetn-rcldd-pyrtyppctyr-951[pcdry]
egdytrixat-eaphixr-vgphh-pcpanhxh-921[hpaxe]
nwzekwypera-lhwopey-cnwoo-hkceopeyo-654[eowpy]
zovldbkfz-zlkprjbo-doxab-zxkav-ixyloxqlov-367[olxzb]
lgh-kwujwl-xmrrq-kusnwfywj-zmfl-hmjuzskafy-372[gmait]
ipvohghykvbz-jhukf-ylzlhyjo-357[awkcb]
dmybmsuzs-otaoaxmfq-dqmocgueufuaz-976[muaod]
zbytomdsvo-bkllsd-cdybkqo-796[eufzt]
sbqiiyvyut-fbqijys-whqii-iqbui-998[ebfqa]
qyujihctyx-wbiwifuny-guleyncha-838[ejitg]
ikhcxvmbex-unggr-kxvxbobgz-683[ejuzo]
hafgnoyr-ohaal-jbexfubc-923[bjmzn]
shmml-wryylorna-genvavat-455[almnr]
yknnkoera-xqjju-klanwpekjo-420[empdo]
upq-tfdsfu-kfmmzcfbo-efwfmpqnfou-415[nmfed]
xcitgcpixdcpa-rdchjbtg-vgpst-hrpktcvtg-wjci-stepgibtci-557[ctgip]
fydelmwp-nsznzwlep-opgpwzaxpye-769[pewzl]
glrcplyrgmlyj-cee-pcqcypaf-548[ymzlj]
xmtjbzidx-wpiit-xjiovdihzio-265[ztyda]
rwcnawjcrxwju-ljwmh-mnbrpw-901[wjrcm]
wlqqp-tyftfcrkv-ivtvzmzex-841[tvfqz]
thnulapj-wshzapj-nyhzz-zopwwpun-669[pzhnw]
bpvctixr-rdggdhxkt-hrpktcvtg-wjci-pcpanhxh-401[chptg]
eza-dpncpe-awldetn-rcldd-dlwpd-743[delpa]
pbybeshy-sybjre-npdhvfvgvba-299[bvyeh]
qmpmxevc-kvehi-jpsaiv-viwievgl-802[viemp]
jrncbavmrq-pnaql-pbngvat-qrcyblzrag-715[arbnq]
ugjjgkanw-wyy-kzahhafy-736[clxvm]
mwupyhayl-bohn-nluchcha-682[hacln]
qjopwxha-xwogap-ykjpwejiajp-108[jpawo]
avw-zljyla-jhukf-huhsfzpz-175[hzafj]
lzfmdshb-okzrshb-fqzrr-cdoknxldms-573[olwsf]
cqwdujys-sbqiiyvyut-uww-iuhlysui-426[cwfuy]
yaxsnlcrun-ljwmh-bqryyrwp-901[rylnw]
cebwrpgvyr-pelbtravp-enoovg-znantrzrag-455[raegn]
nbhofujd-qmbtujd-hsbtt-efwfmpqnfou-389[fbtud]
pynffvsvrq-pnaql-pbngvat-ynobengbel-507[nmyvz]
ltpedcxots-gpqqxi-ldgzhwde-739[bkapm]
nglmtuex-vahvhetmx-wxiehrfxgm-527[zwksp]
kgjgrypw-epybc-aylbw-amyrgle-qyjcq-626[ygabc]
yflexwxoalrp-avb-abmilvjbkq-445[siqmz]
jshzzpmplk-kfl-klclsvwtlua-331[lkpsz]
ujoon-eaphixr-vgphh-prfjxhxixdc-193[hyzjx]
dfcxsqhwzs-qobrm-zcuwghwqg-168[qwcgh]
bqvvu-ydkykhwpa-klanwpekjo-966[kapvw]
aoubshwq-pibbm-kcfygvcd-740[wnucy]

View File

@@ -0,0 +1 @@
L2, L3, L3, L4, R1, R2, L3, R3, R3, L1, L3, R2, R3, L3, R4, R3, R3, L1, L4, R4, L2, R5, R1, L5, R1, R3, L5, R2, L2, R2, R1, L1, L3, L3, R4, R5, R4, L1, L189, L2, R2, L5, R5, R45, L3, R4, R77, L1, R1, R194, R2, L5, L3, L2, L1, R5, L3, L3, L5, L5, L5, R2, L1, L2, L3, R2, R5, R4, L2, R3, R5, L2, L2, R3, L3, L2, L1, L3, R5, R4, R3, R2, L1, R2, L5, R4, L5, L4, R4, L2, R5, L3, L2, R4, L1, L2, R2, R3, L2, L5, R1, R1, R3, R4, R1, R2, R4, R5, L3, L5, L3, L3, R5, R4, R1, L3, R1, L3, R3, R3, R3, L1, R3, R4, L5, L3, L1, L5, L4, R4, R1, L4, R3, R3, R5, R4, R3, R3, L1, L2, R1, L4, L4, L3, L4, L3, L5, R2, R4, L2

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More