summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPrefetch2024-03-02 19:36:12 +0100
committerPrefetch2024-03-02 19:36:12 +0100
commit1fbb07c54523c7a576bfff1cb689e155dd55f15a (patch)
tree7aa9f92a7d99ae9203b538803b7efefd846b67e0
parentaf589b238c1d51960d8af3b36041aca2bad7855b (diff)
Add first five days
-rw-r--r--01/input.txt1
-rw-r--r--01/lib.scm34
-rw-r--r--01/main.scm14
-rw-r--r--01/test.scm43
-rw-r--r--02/input.txt16
-rw-r--r--02/lib.scm74
-rw-r--r--02/main.scm20
-rw-r--r--02/test.scm38
-rw-r--r--03/lib.scm99
-rw-r--r--03/main.scm13
-rw-r--r--03/test.scm42
-rw-r--r--04/input.txt512
-rw-r--r--04/lib.scm74
-rw-r--r--04/main.scm20
-rw-r--r--04/test.scm41
-rw-r--r--05/input.txt1044
-rw-r--r--05/lib.scm29
-rw-r--r--05/main.scm20
-rw-r--r--05/test.scm29
19 files changed, 2163 insertions, 0 deletions
diff --git a/01/input.txt b/01/input.txt
new file mode 100644
index 0000000..eb275f7
--- /dev/null
+++ b/01/input.txt
@@ -0,0 +1 @@
+649713959682898259577777982349515784822684939966191359164369933435366431847754488661965363557985166219358714739318371382388296151195361571216131925158492441461844687324923315381358331571577613789649166486152237945917987977793891739865149734755993241361886336926538482271124755359572791451335842534893192693558659991171983849285489139421425933638614884415896938914992732492192458636484523228244532331587584779552788544667253577324649915274115924611758345676183443982992733966373498385685965768929241477983727921279826727976872556315428434799161759734932659829934562339385328119656823483954856427365892627728163524721467938449943358192632262354854593635831559352247443975945144163183563723562891357859367964126289445982135523535923113589316417623483631637569291941782992213889513714525342468563349385271884221685549996534333765731243895662624829924982971685443825366827923589435254514211489649482374876434549682785459698885521673258939413255158196525696236457911447599947449665542554251486847388823576937167237476556782133227279324526834946534444718161524129285919477959937684728882592779941734186144138883994322742484853925383518651687147246943421311287324867663698432546619583638976637733345251834869985746385371617743498627111441933546356934671639545342515392536574744795732243617113574641284231928489312683617154536648219244996491745718658151648246791826466973654765284263928884137863647623237345882469142933142637583644258427416972595241737254449718531724176538648369253796688931245191382956961544775856872281317743828552629843551844927913147518377362266554334386721313244223233396453291224932499277961525785755863852487141946626663835195286762947172384186667439516367219391823774338692151926472717373235612911848773387771244144969149482477519437822863422662157461968444281972353149695515494992537927492111388193837553844671719291482442337761321272333982924289323437277224565149928416255435841327756139118119744528993269157174414264387573331116323982614862952264597611885999285995516357519648695594299657387614793341626318866519144574571816535351149394735916975448425618171572917195165594323552199346814729617189679698944337146
diff --git a/01/lib.scm b/01/lib.scm
new file mode 100644
index 0000000..fcdf642
--- /dev/null
+++ b/01/lib.scm
@@ -0,0 +1,34 @@
+(library (lib)
+ (export solve-part1 solve-part2)
+ (import (chezscheme))
+
+ ; Rotate contents of `ilist' to the right `times' times
+ (define (list-rotate ilist times)
+ (let loop ((xs ilist) (n times))
+ (if (= n 0)
+ xs
+ (loop (append (cdr xs) (list (car xs))) (- n 1)))))
+
+ (define (solve-puzzle chars chars-rot)
+ (fold-left
+ (lambda (accum c1 c2)
+ ; Does `k'th char in list match with `k'th char in rotated list?
+ (if (char=? c1 c2)
+ ; Assume `c1' is a digit, convert it to integer in [0,9]
+ (+ accum (string->number (string c1)))
+ accum))
+ 0 chars chars-rot))
+
+ ; Compare each char to its right neighbour in circular list
+ (define (solve-part1 str)
+ (let* ((chars (string->list str))
+ (chars-rot (list-rotate chars 1)))
+ (solve-puzzle chars chars-rot)))
+
+ ; Compare each char to char halfway across circular list
+ (define (solve-part2 str)
+ (let* ((chars (string->list str))
+ (chars-rot (list-rotate chars (div (length chars) 2))))
+ (solve-puzzle chars chars-rot)))
+
+)
diff --git a/01/main.scm b/01/main.scm
new file mode 100644
index 0000000..9ec5afa
--- /dev/null
+++ b/01/main.scm
@@ -0,0 +1,14 @@
+(import (chezscheme))
+
+; Where the magic happens
+(import (lib))
+
+; Read my personal puzzle input
+(define input
+ (call-with-input-file "input.txt" get-line))
+
+; Part 1 gives 1228 for me
+(printf "Part 1 solution: ~a\n" (solve-part1 input))
+
+; Part 2 gives 1238 for me
+(printf "Part 2 solution: ~a\n" (solve-part2 input))
diff --git a/01/test.scm b/01/test.scm
new file mode 100644
index 0000000..6dbff81
--- /dev/null
+++ b/01/test.scm
@@ -0,0 +1,43 @@
+(import (chezscheme))
+
+; Where the magic happens
+(import (lib))
+
+; My quick-and-dirty unit testing framework (copied for each day)
+(define (run-test name proc input expected)
+ (let ((result (proc input)))
+ (if (= result expected)
+ (printf "\x1b;[32;1mPASS\x1b;[0m: ~a\n"
+ name)
+ (printf "\x1b;[31;1mFAIL\x1b;[0m: ~a: got ~a, expected ~a\n"
+ name result expected))))
+
+(printf "Part 1 tests:\n")
+
+(define (test-part1 name input expected)
+ (run-test name solve-part1 input expected))
+
+(test-part1 "part 1 example 1"
+ "1122" 3)
+(test-part1 "part 1 example 2"
+ "1111" 4)
+(test-part1 "part 1 example 3"
+ "1234" 0)
+(test-part1 "part 1 example 4"
+ "91212129" 9)
+
+(printf "Part 2 tests:\n")
+
+(define (test-part2 name input expected)
+ (run-test name solve-part2 input expected))
+
+(test-part2 "part 2 example 1"
+ "1212" 6)
+(test-part2 "part 2 example 2"
+ "1221" 0)
+(test-part2 "part 2 example 3"
+ "123425" 4)
+(test-part2 "part 2 example 4"
+ "123123" 12)
+(test-part2 "part 2 example 5"
+ "12131415" 4)
diff --git a/02/input.txt b/02/input.txt
new file mode 100644
index 0000000..315a416
--- /dev/null
+++ b/02/input.txt
@@ -0,0 +1,16 @@
+62 1649 1731 76 51 1295 349 719 52 1984 2015 2171 981 1809 181 1715
+161 99 1506 1658 84 78 533 242 1685 86 107 1548 670 960 1641 610
+95 2420 2404 2293 542 2107 2198 121 109 209 2759 1373 1446 905 1837 111
+552 186 751 527 696 164 114 530 558 307 252 200 481 142 205 479
+581 1344 994 1413 120 112 656 1315 1249 193 1411 1280 110 103 74 1007
+2536 5252 159 179 4701 1264 1400 2313 4237 161 142 4336 1061 3987 2268 4669
+3270 1026 381 185 293 3520 1705 1610 3302 628 3420 524 3172 244 295 39
+4142 1835 4137 3821 3730 2094 468 141 150 3982 147 4271 1741 2039 4410 179
+1796 83 2039 1252 84 1641 2165 1218 1936 335 1807 2268 66 102 1977 2445
+96 65 201 275 257 282 233 60 57 200 216 134 72 105 81 212
+3218 5576 5616 5253 178 3317 6147 5973 2424 274 4878 234 200 4781 5372 276
+4171 2436 134 3705 3831 3952 2603 115 660 125 610 152 4517 587 1554 619
+2970 128 2877 1565 1001 167 254 2672 59 473 2086 181 1305 162 1663 2918
+271 348 229 278 981 1785 2290 516 473 2037 737 2291 2521 1494 1121 244
+2208 2236 1451 621 1937 1952 865 61 1934 49 1510 50 1767 59 194 1344
+94 2312 2397 333 1192 106 2713 2351 2650 2663 703 157 89 510 1824 125
diff --git a/02/lib.scm b/02/lib.scm
new file mode 100644
index 0000000..0274dad
--- /dev/null
+++ b/02/lib.scm
@@ -0,0 +1,74 @@
+(library (lib)
+ (export solve-part1 solve-part2)
+ (import (chezscheme))
+
+ ; Split list at first delimiter into `prefix' and `suffix'
+ ; Return value is a pair like `((p r e f i x) s u f f i x)'
+ (define (list-split-left delimiter? xs)
+ (let loop ((prefix '())
+ (suffix xs))
+ (if (null? suffix)
+ (cons prefix suffix)
+ (let ((x (car suffix)))
+ (if (delimiter? x)
+ ; Found first delimiter, so return immediately
+ (cons prefix (cdr suffix))
+ ; `x' isn't a delimiter, so append it to `prefix'
+ (loop (append prefix (list x)) (cdr suffix)))))))
+
+ ; Split list at given delimiter into list of sublists
+ (define (list-split delimiter? xs)
+ (let loop ((pieces '())
+ (rest xs))
+ (if (null? rest)
+ ; Fix order and remove all empty sublists from output
+ ; (which are caused by consecutive delimiters in `xs')
+ (reverse (remp null? pieces))
+ ; Extract next piece from `rest' and prepend it to `pieces'
+ (let ((next (list-split-left delimiter? rest)))
+ (loop (cons (car next) pieces) (cdr next))))))
+
+ ; Split string at whitespace into list of words
+ (define (string-split str)
+ (map list->string (list-split char-whitespace? (string->list str))))
+
+ ; Partially applied divisibility check
+ (define (check-divisor? x)
+ (lambda (y)
+ (and (not (= y 0)) ; Don't try dividing by zero
+ (not (= x y)) ; Disallow trivial solution
+ (= (mod x y) 0))))
+
+ ; Find minimum and maximum in row, return difference
+ (define (find-range row)
+ (- (apply max row) (apply min row)))
+
+ ; Find `x' and `y' where `y' is divisor of `x', return quotient
+ (define (find-quotient row)
+ ; Note: we don't check if we've reached the end of `xs',
+ ; because we're guaranteed success before that happens.
+ ; We're also guaranteed only one non-trivial solution.
+ (let loop ((xs row))
+ (let* ((x (car xs))
+ (y (find (check-divisor? x) row)))
+ ; Is this the (`x',`y') combination we're looking for,
+ ; i.e. have we found a valid divisor `y' for this `x'?
+ (if y
+ (div x y)
+ (loop (cdr xs))))))
+
+ ; Add up result of `proc' for each `row' of numbers in `lines'
+ (define (solve-puzzle proc lines)
+ (fold-left
+ (lambda (accum row)
+ (+ accum (proc (map string->number row))))
+ 0
+ (map string-split lines)))
+
+ (define (solve-part1 lines)
+ (solve-puzzle find-range lines))
+
+ (define (solve-part2 lines)
+ (solve-puzzle find-quotient lines))
+
+)
diff --git a/02/main.scm b/02/main.scm
new file mode 100644
index 0000000..746fa01
--- /dev/null
+++ b/02/main.scm
@@ -0,0 +1,20 @@
+(import (chezscheme))
+
+; Where the magic happens
+(import (lib))
+
+; Read my personal puzzle input
+(define input
+ (call-with-input-file "input.txt"
+ (lambda (port)
+ (let loop ((line (get-line port))
+ (result '()))
+ (if (eof-object? line)
+ (reverse result)
+ (loop (get-line port) (cons line result)))))))
+
+; Part 1 gives 44216 for me
+(printf "Part 1 solution: ~a\n" (solve-part1 input))
+
+; Part 2 gives 320 for me
+(printf "Part 2 solution: ~a\n" (solve-part2 input))
diff --git a/02/test.scm b/02/test.scm
new file mode 100644
index 0000000..10ee751
--- /dev/null
+++ b/02/test.scm
@@ -0,0 +1,38 @@
+(import (chezscheme))
+
+; Where the magic happens
+(import (lib))
+
+; My quick-and-dirty unit testing framework (copied for each day)
+(define (run-test name proc input expected)
+ (let ((result (proc input)))
+ (if (= result expected)
+ (printf "\x1b;[32;1mPASS\x1b;[0m: ~a\n"
+ name)
+ (printf "\x1b;[31;1mFAIL\x1b;[0m: ~a: got ~a, expected ~a\n"
+ name result expected))))
+
+(printf "Part 1 tests:\n")
+
+(define (test-part1 name input expected)
+ (run-test name solve-part1 input expected))
+
+(define part1-example1
+ '("5 1 9 5"
+ "7 5 3"
+ "2 4 6 8"))
+(test-part1 "part 1 example 1"
+ part1-example1 18)
+
+(printf "Part 2 tests:\n")
+
+(define (test-part2 name input expected)
+ (run-test name solve-part2 input expected))
+
+(define part2-example1
+ '("5 9 2 8"
+ "9 4 7 3"
+ "3 8 6 5"))
+(test-part2 "part 2 example 1"
+ part2-example1 9)
+
diff --git a/03/lib.scm b/03/lib.scm
new file mode 100644
index 0000000..6e1e4d1
--- /dev/null
+++ b/03/lib.scm
@@ -0,0 +1,99 @@
+(library (lib)
+ (export solve-part1 solve-part2)
+ (import (chezscheme))
+
+ ; Is this direction up or down?
+ (define (vertical? dir)
+ (= 0 (vector-ref dir 0)))
+
+ ; Rotate stepping direction counterclockwise 90 degrees
+ (define (rotate-ccw dir)
+ (cond
+ ((equal? dir '#(1 0))
+ '#(0 1))
+ ((equal? dir '#(0 1))
+ '#(-1 0))
+ ((equal? dir '#(-1 0))
+ '#(0 -1))
+ ((equal? dir '#(0 -1))
+ '#(1 0))))
+
+ ; Follow the spiral to find (x,y) `pos' of the `address'th square.
+ ; The idea is to take `steps' steps in the current direction `dir',
+ ; rotate `dir', take `steps' steps again, rotate, increment `steps',
+ ; then start over, and so on. So the sequence starts like this:
+ ; 1 step right, 1 step up,
+ ; 2 steps left, 2 steps down,
+ ; 3 steps right, 3 steps up,
+ ; 4 steps left, 4 steps down,
+ ; etc.
+ ; Note: for each value of `steps', the last stage is always up/down.
+ (define (get-position address)
+ (let loop ((pos '#(0 0))
+ (dir '#(1 0))
+ (steps 1)
+ (count 0)
+ (total 1))
+ (if (= total address)
+ pos
+ (if (= count (- steps 1))
+ ; Yes, this is the last step before we need to turn
+ (loop
+ ; Take the step, i.e. add direction to position
+ (vector-map + pos dir)
+ ; Rotate counterclockwise after this step
+ (rotate-ccw dir)
+ ; If this step is vertical, we need to increment
+ (+ steps (if (vertical? dir) 1 0))
+ ; Reset step counter for the current direction
+ 0
+ ; Keep track of total steps since square one
+ (+ total 1))
+ ; No, this is an ordinary step, no rotation needed
+ (loop
+ (vector-map + pos dir)
+ dir
+ steps
+ (+ count 1)
+ (+ total 1))))))
+
+ ; Given a position, return all eight positions adjacent to it
+ (define (get-adjacent pos)
+ (map
+ (lambda (dir) (vector-map + pos dir))
+ '(#(1 0) #(1 1) #(0 1) #(-1 1) #(-1 0) #(-1 -1) #(0 -1) #(1 -1))))
+
+ ; Given a position, sum the values of all initialized adjacent squares
+ (define (sum-adjacent pos memory)
+ (fold-left
+ (lambda (sum adj)
+ ; Try to retrieve `pair' from memory
+ (let ((pair (assoc adj memory)))
+ (+ sum
+ ; If position `(car pair)' has been written,
+ ; add its value `(cdr pair) to the sum total.
+ (if pair (cdr pair) 0))))
+ 0
+ (get-adjacent pos)))
+
+ (define (solve-part1 target)
+ (let* ((xy (get-position target))
+ (x (vector-ref xy 0))
+ (y (vector-ref xy 1)))
+ (+ (abs x) (abs y))))
+
+ (define (solve-part2 target)
+ (let loop ((address 2)
+ (memory '((#(0 0) . 1))))
+ (let ((value (cdar memory)))
+ ; Has the most recently written `value' crossed the threshold?
+ (if (> value target)
+ value
+ ; If not, move on, writing a new `val' to the next `pos'
+ (let* ((pos (get-position address))
+ (val (sum-adjacent pos memory)))
+ (loop
+ (+ address 1)
+ (cons (cons pos val) memory)))))))
+
+)
diff --git a/03/main.scm b/03/main.scm
new file mode 100644
index 0000000..561fcd7
--- /dev/null
+++ b/03/main.scm
@@ -0,0 +1,13 @@
+(import (chezscheme))
+
+; Where the magic happens
+(import (lib))
+
+; My personal puzzle input
+(define input 289326)
+
+; Part 1 gives 419 for me
+(printf "Part 1 solution: ~a\n" (solve-part1 input))
+
+; Part 2 gives 295229 for me
+(printf "Part 2 solution: ~a\n" (solve-part2 input))
diff --git a/03/test.scm b/03/test.scm
new file mode 100644
index 0000000..0f7817c
--- /dev/null
+++ b/03/test.scm
@@ -0,0 +1,42 @@
+(import (chezscheme))
+
+; Where the magic happens
+(import (lib))
+
+; My quick-and-dirty unit testing framework (copied for each day)
+(define (run-test name proc input expected)
+ (let ((result (proc input)))
+ (if (= result expected)
+ (printf "\x1b;[32;1mPASS\x1b;[0m: ~a\n"
+ name)
+ (printf "\x1b;[31;1mFAIL\x1b;[0m: ~a: got ~a, expected ~a\n"
+ name result expected))))
+
+(printf "Part 1 tests:\n")
+
+(define (test-part1 name input expected)
+ (run-test name solve-part1 input expected))
+
+(test-part1 "part 1 example 1"
+ 1 0)
+(test-part1 "part 1 example 2"
+ 12 3)
+(test-part1 "part 1 example 3"
+ 23 2)
+(test-part1 "part 1 example 4"
+ 1024 31)
+
+(printf "Part 2 tests:\n")
+
+(define (test-part2 name input expected)
+ (run-test name solve-part2 input expected))
+
+(test-part2 "part 2 example 1"
+ 1 2)
+(test-part2 "part 2 example 2"
+ 23 25)
+(test-part2 "part 2 example 3"
+ 133 142)
+(test-part2 "part 2 example 4"
+ 747 806)
+
diff --git a/04/input.txt b/04/input.txt
new file mode 100644
index 0000000..bf3fffb
--- /dev/null
+++ b/04/input.txt
@@ -0,0 +1,512 @@
+pphsv ojtou brvhsj cer ntfhlra udeh ccgtyzc zoyzmh jum lugbnk
+vxjnf fzqitnj uyfck blnl impo kxoow nngd worcm bdesehw
+caibh nfuk kfnu llfdbz uxjty yxjut jcea
+qiho qif eupwww avyglnj nxzotsu hio lws
+xjty usocjsh pivk qnknunc yjcgh bwya djw zpyr
+ycfmfe mgq sjiomg nfzjul bjwkmgu yvsnvgj dcjupu wzz blmn
+rdowgbt vpwfdoi blzl laghnk gsa vhnpo cztxzlb rtz hvwonhb eciju pfjtbo
+bqs bqs dbutvgf mmzb izpyud rap izpyud xlzeb mnj hjncs
+xpu vwp nujcos piu irindir tpmfd umtvlm gznu
+sfpuxar qcnbte omouazv cnh uaxspfr sepolf rusafpx
+xbmaf iceyqqq sabpt gliexel muubepe qqiyqce fmrcc eazk obkeonl fmccr kgk
+apg gbycwe gap pag
+gagv saqbk lwtllc wnhzz khxsjc
+lgc alen rlmsp anel gcbvg
+bujlaz rks rlqf deknmee yrp
+scqvl weusbc bgvaz vgg cjwsfno vqy zbq aqy tvf bgzav
+hbki vei fxdwljs myjuba elbsib pvy xxjxgi dtgv
+linzaeu qbwdke fdg pykw
+qvtdd aco aav bpu mvkcuc kjfj japgfki jfdl gem hog bdzsiea
+wpbigkb lzhwba jssjkn qvb kmwu qddv
+iny osyvqnt tumunzb torq bdeneg wywank poza ipp iggorw
+tuko mhdbsf vmjdop jomaqpj rcdsud hmgspr lsas nzmwc
+cirkjq nmjuu xtgejv gtexvj vjcmtqq unjmu
+xsdmezq xvqjvqp exhygy qahju hvd qadmdh lok
+wvvys kax rohrrar rwhnvi lhnmefp lsktouy bxilosp
+wayf diobnl zvu obnidl oibnld
+cewil ygsf ffzp ruxhu vah lnvwt aef lnnjc kgkb gxtlx feko
+uti epphrin pywths cpzzh csjei nczhamy gayxmb bdcytq xkx fgmt
+qvzyuwi dwo swkw bwjdrn dasgd ijgw vzabaop yefyhmc wgij
+dyg sugrf vid etz weyqg nyntx dwfgwm khon hnzzzn xfyra
+ofbh bdrsk rdrjj elaxvk jrjdr
+msxau rsocvx zxdda mxz lknl
+qktaywx dirpdbf unqnd wbrwkuu fvmqwl emxr big
+xwz kvsydc ayokjyy qiah omw neo htltxx fxhwqwj colqvbb sxmo ephfkex
+ncjxoaf fwjkc czmhv ylg axcjofn dvj bzqjku opvcr jiwzucg vmhzc
+gmmnrt zqar twdwrg qiwwki fcbr lixm hjdwwe moiva
+roinlxg cxeezve whannk cxeezve pyoj boweioy cpkgxsz
+qkct qso xlb xyy aellfet rzt cbboow devfb nih fhbfxzi
+qyc ltxia alixt atilx xtgrv
+svruz ufvo rvesnxv dik vzurs jjg idk
+xeudhrg hudn cilo ljplosb
+kpb oyzvywx vldko qhfkwod bkeutk zqcqug pbriu wqocos
+qkngzfy whobyri aze jvipdty ocirbep icqwc
+kzxxlab sjr zhymws xkbx
+nnxs gkwtld dwhkry snuibq dtdl aicug bhtlfzp qzk jctos
+regvro mxcq hqof yraucxi jhkol iuxineo pbtnk rfjwc szgjpr ndqqj vfgm
+yqrfox xoqrfy utbryu utubyr
+jdubjt wqrl wnk rlqw nwiq pnbn qinw uaff ftdo htfrav
+rum mur umr tij ovbahl losao imawwpb wadhww tbteyqc
+napxd kzeiqcp ppgqucm xkityt frq hugrp gjgtt gmuqppc zwqme
+xyuzs ysch howlzgu dkqppbs nvbiz mks mtxv vivouex uvawq
+ffe lfsn nlq mpulheq ikcfo wdtz cnwsbph zkib muu
+bqkxav wtecb lxwdhr kqbavx aqxvbk
+czwswqx ldkxapd pfwd bdkkj iqohla cwosw ihqpd pcc ckhabbn
+foiip hau rbqiyhh htm omeubgh symh evfcqg
+lqx xlq rsgf izu esetis
+npsrkdj fvulgkw eovw mzr uobcze azb tij ihoer ehori jit wknsqhm
+gnrksh xwggt oosi bpnmhx qqaa mpmryu jhzyz
+yad gbexqcr gbexqcr gbexqcr
+ldca xxhznn twyy ytwy zhxnnx xfmpi
+floioot kfyh dhibv ezyznar sfg sfg ezyznar
+cinioim iiocmin ypla aypl
+mhwcjbz dftuqsy wswop eizbf ptsd
+ehx mlh nfxgfkz uuw xftmn ptlkbo vsnyo ttwce
+oexvf orcg cncnkfk comvhl
+lqewsj lyulrcl efixd qvd fhznqnz yvrkwyi xmhgc vzbp
+dmr wrxqh thcm giomp rtvl ssc gwq rbklw hcmt fjvud
+teozhb dmzwfv qkq pvcqfqq
+hvlebc qqmg repxk zwrjdx ztruwb such tyligs ybg
+psa rqznokd lgc jstqres yiqt mbiody xazb xjuk dtb
+lea ncm rnh myzqzwm
+wjml eums ueflvbr cjpgnl qduunu zfxaai jwlm lprzzg vrn ttetyr sume
+uwkgeu uiahd plyewgi vveo nwhsitz mcitc uvk zsxehgs sewl
+lnbdrka sgtivn sozzq mgd vhxfnlr twrfpk
+gadphmk mbx lmlbrf tsnehnr lawdpm fnima gxgl
+umty vrn dpow fsnnpjv fsnvnjp nnsvpjf cioaio
+euu uue zeskmtk hob stekkzm
+ypqpri qwdju ypriqp iprqyp jnoxqa
+lkppi ingfxw wlulvp yhwrli nxwigf oyuhq ggfslx
+kdd ypvr pyvr waw vyrp khqq mamxca bapq gobfm
+iuq upvdpv zxef bfwns lmq lxswr kpsqo pwde iaaou nsw udy
+lgzo nil ovgrmt omgtrv jrqp pqrj lit
+uumyu iiakfj gvdtzz qbux yxn ejs dvlts
+hcm ghutxq zswi tmyhqef hgxtuq
+shkhkdk kad seubeax kdl mzu
+cpykgr skx rfhpor xsk moyhlai ogv ophfrr dxipuuh
+beyw jvrre opodn zdoajhx fhg ijs drczy drczy hjungq
+jrzieja gfg yzdn yxm wshibsn fgg
+xtylh vxscmvp rfymq uzhpyea spxcmvv dlni msj yxhlt
+eov awql miv miv eov
+mmvrfbg fjiyf hvqz zpuqmbf fszyuz ldfgni wemfjl fjjpl rbnpy rfb
+ppzpeh nam ntv xnchtyk hja hpepzp foj bibvx nmmdlff bsrkp
+qiy qiy umhlnh qiy
+tyds oepk wae tdsy sdty
+ukawr rkwau ghtjhm axy
+wtbjiv btjivw ewaf hwk ttq
+kdpun myve sqv rhvpy fnjwt puw ujhf thsp nkdadqr
+vyw wkkpdpy xlgz lmmcuve ncuq lmotk
+pmsfw vxd jpe qxlyasx ejp gwuv
+pmgyndm ezofbvx nicbwrw kwnlj yjvnas fdpkfo mqcsyhn pyjpf fbexvzo vkftm erl
+trmwvk rywuzoz hbidea kicohfz heidab deaibh
+sogf govd dknpk vxrvk rlm vwhjk
+xnxbfmw wguzrhd zbmkz piwppa mkbzz xvwrdgy flusfqb
+cgduq hbnwr xfx mrejb ckw zkbaihf cloow cwk wuvthv iwqctx
+vugx qbucd gxuv ocb cob
+ilmet fbelxxz qratdfn unoj hbc duv srmikz
+vnzuw zgpbqgf uzm thysyxd dinfh bgvr olungg ksd dsetwqz hpg
+omagsf zpr coa kknx bzithq pewp flvoz xiiq weojqr wpep
+aagj gcglqt gqcglt xbfx dhdx lbx
+pljq plxuscw ilh wfk lhi hli fouieyw
+hvnh zvm aqy dzitirm veq ctux
+lglhs aqibdii hjbn cfgc qrg pnbntcx owoks ebz
+jozngde lwne mbo omb fnyzvvj gndozje
+bbdgc igtdj uhahgp sqduko
+uuspedu fgnspm ewc slly jbs chl heanm abqijx kadvgxu
+akfsft skna kusjqr rkqujs
+erc vrljpu lruvjp lpvjur
+iors hcdr fsqtcj vop vmn dtqnz tov oscjlw cdrh ctfjsq lrnts
+fxp mczo sjlcxa mzoc jmsq hcxybow dmrr bcoxhyw
+aac ewraerq odmxpz aac aac
+zzio zebmxa szeej poordr gmi owwnnh xfx rzrab lfey jesze
+akc yyoj vqod drtne
+joxhvyf ymasnbr omouvq isxdrr
+qyi ayrkzu jsk vqvvno jkkuxi zufnnwu mrsszdf
+ocqi htfb tzjna cdt wkzhynm eergf
+yokzugl usyuqu qvotq uweqyow lygkzuo kpmqmb uglyzok
+glvshl imqv jrv xlpnsy gcg psj irtiamg wkl
+bjcpc nvyloa dkkan efj okubpc cxlowm eone kmpny
+cyxqys nmuaftv gqxj gtvsc
+beouh dioxiah kizdy hyi cozrray rave fqxmxmj gdm
+frjz amrsat lxvhzj azhevtu vxlzhj
+zwmnrk sbk txzrcsj sbk oosgfej cvh zuthibi onvwd sbk nhwpzq
+gzamt vraw kuk ugayl lyaug bww rwav ijah
+bdjirxg vifjr rhbxpa oao yrhjxoi pbn
+navb umesiys yhix phuhu aekkciu nlnsiq wjf idqdwp
+cmhw rsu urs ziprlfe
+kyhxitv cgty bnwjyq cygt sgjn pdab imarvhg yjbnqw
+axaa ejancv yau njpc jvwy bpft kwjvg qzrbvtm diu njpc bpft
+ambj upe rmqr yudbiqf krudp pqyf
+tnb mobnpv vep ohxoc cyip wxyccfo jrbi rwsws kls zlv oohxc
+fjh dmb hlbq bqc jhf kax suz fjjg rkpc
+wjnn byfirm goeyh xtjmdka
+tgyfxx hefpxln mveobqr yeo ftfn srt vim vlcu hevoi xtaaff
+imyql xotcl poql rlueapq bkwykm hlalk bkwykm
+gkec zff hbmtq rjxjbcf arerlu pvz cdaqi nijmhv uodwjh
+mpctof mopftc ksfbat sbkatf
+nvdd jub bvi kyggdbx nwtiok gjt mgsm dbhsn rzibgjm dvdn eqi
+ysd iirp dfgzza wiyeoou ysd ispkv bcqg wwzqgq xphse
+ntq ivposb gsd ezl tlkztp lez qyurp vxsmg dgs
+wijs rydbj onm usiyqzb hwrol giusanb kewukl yziuqbs doojam nom
+lfacyy xwwast truqtt tzneimn uxsydc ktu eqyaj ndszak
+ffleooc kikif fohgop aucy moubqxu
+iaxc pnwexdl ncy vmwm xrqoi wpgftq rofx utyzjuf stdxq twpgfq
+ppmlp etsvi cjdx poly ynx vfxpslg mqjo qnpsage flpsxvg jwsxiqt
+lbyhnb kflrpeq ssoti webxr embbjd kbnx ubzqco
+khhc vwuqzb ebocbko rwmonkz edfqn hzh qhncoq gbwdi wjeg ocwow
+ghzhd kcxblp lzwkkr gzhdh umk pblcxk
+wyajtw jiff ouylv sni lwhlrg avqjiis igzx wbl lhrwgl
+glhh kaxha tqii hwzx rgic kaxha rgyidmt qdgxfl ynjc oibfij
+bapj bix rjniw ynbql idlvnmt wynpzbl zlpuoix kvn kakwys
+aldpxxu iojxp rif xbyqtr jffdvy qnrq tqwsdiu
+ulssco ktbymjw bfj zhkg zgc ctyri
+ilrmq wfahcgk mrlqi bguad inj
+cjzc rekuy ifr wfkg sple
+cvjkp qbmumnp mprg ltmwxxh zpemtyb ozzssfd ksu mgrp
+nvc sxp mpkxz bhlctq hguaa yrdkm iwsgfg qjssh gobbies hucdh
+jdxrjw qmo qmo vobhnu
+dnjib wtjp rfdjqdj skpvrb vkwevb kxxovp
+fzi kicta zkuvr rfaawv ehklq cfdjsyb tukahwr zkuvr kicta ouq
+aba ytdguk gqmpn hvxabff hvxabff dckj
+fna wxyqhxd hvy khsu yypoyy lvvue medheua gim slf drdbeh ikihf
+jquz wwo wwo ghlz jrbvb jrbvb
+jwzvkl yjw ouwla yjw ouwla
+zsvlgyf rzqbtj qygynem ukdgjm lbsyh tmdzp fbcaim eymzr
+pvw sbs dvsa plmepl pwv ayxk vpw dwt
+inayadn pnti yzhxk azga gxq aznbciu gjnmyqm
+isgf ndqmk beyqq ebyqq srtzxo aiiw oqfuwp uoqwfp buejctv pxbk
+pzl irv tzvzdb wcy eszm ybwiw ycw riizifd iybww
+btpu cua azzqffy owcr
+ofwq sqlpzat lozdxlc aevjmpc lcolzxd wbbysn qwfo vcrx gdzgi
+dbpfmxu ydsxwl ijn svxtop csep ldqeog ffye zcrl soh aclw
+wyiyyhv vyhiywy obgi hiyywvy
+ddvaoc lhv spurn rgxyy onjw illvn yryxg xyyrg
+vid wdttqq kajr myip
+wolqlue phlunpt dcmmkfm sgxk dmmckmf sfng jlbsntq dxp
+zmneyho fswj xdgsjc oefwjdi htgxvbd tgqrq xodoa
+ynw bygqdnh hhmnkuw cojqrke qszzdjo orskwq mdfae asabn
+vvpm vkj pcxghao caoxphg axhblxb vvmp
+txox nzy eqn zgir dytsi girz ffa ugjjbzj brob fll
+kbz pukqbd fiwmuh umwihf bkz dvz
+vgs vejs vejs vejs mbkyjjy
+viqmnmu bitkyw nddnk dknnd cldnpp hipub plcdpn fdzzpb mmyomn
+ndylnfx gozlrx ngptk rnpteb wtacx xmtcjy xldha
+fey doyxis ampmtr ycqh syw cqhlj hnngx
+dijf nac tvkq ayo akbj lzmngdm wfxpn bpyvrf cvdqpa
+zsofz lhho hgat wqskga mnt
+mylwm zxsd omzpa waz hcrr lxmpq jsw sqtwak pzoma
+rwhgsgt ysdq ztihici mpwcawv alkqg wsxiwx
+snldn bcb anjdv cbb awsscc cqxult hjmjew mcycb fdpdg sesrh
+kukrqm fawafz qdim wyobtqx bnvjnqg dcvqxta yptr nnpu ughldqp duo zafwaf
+knb yjqb bscpnt nzg sqeu zkahna ttuf nsbtpc ixwit vucwj idix
+bfqyx xlnpc ijrxu zkqi kjxtahr fgag orusms adi bfqyx bfqyx
+dqddc ncbv bvfk hefikb dqddc hqjl otpx zfiu
+ntkv qunrzx eztzure ctt rjo bkdt znvd jwdf gqhf mmhrzgt
+zeavm hkbf rawqwuf pis dojlkt vnjhmi uvk cufmn qginezd xyut
+hnidzk chlctc yst pepd dxntbxg vqk daxfpmu wshyddl
+jgd vesqgo bdyqy igl ahstdm wjtd lrtkjsv tjsj sccxbih esn gkkzj
+iisiswh jll rhlaf jqwwgfa wmhyo izva vrg zjkak nlxxfer rvhx
+mkrkd jlqtpy ukstro ktuors wsj ynqpbp kpiyxzv nxeiwg xpzvkiy
+jbr gnct fwklekg cmfqnm ctn gqobrs kwht
+pztmjs yiffc kfhsblx yiffc yiffc
+biezil iiezbl bzeiil smocoju
+viiigm gmmmk yeiv dxzogro qsmzsur hukzwjn lcle syo mdj uruf rxfseu
+extchsd adeff ouikoj fyaclr rwwvqsd dooe tcxheds zrdqqhm fdoxv kbxi tlcj
+aycnydq qlxhka zoi shplo qll
+bfry lbwckm ltq rbfy gpn vojp ruj dpxcve geq
+svtvfwh lca lac qia vhwsftv nookdfz xgjiaf yvcdlt
+aspgqym fryuzhx bbydf tbn bwutsc fqgi zij lmxhog qnmse
+rbb gsys volnas onvlas lonasv vwjdso lnteapy
+got iauk kficn jvfuy yvoe jcxwui hyamqx mke mwh jcxwui hyamqx
+avutfi ggmha dkopc kothnnb syoi xsd wjedywy
+oziejyz yzeijoz hnthyn knj juuq qujtp kgq bymlnlf yicf
+zsejuy dybeap hvowmvn okxb yoi epadby cnzjk xfwprzc
+lacg iiix fblhxvf nrkkol lnafzw qspzsn gvdy ipj zub uouseo
+evukwkh ycjxxc lptwmf pmd izxdsos zrkavf pgjoy zwokg mpjiej
+vqw ijwoy eaw wvq svmcq ccxi nyub ynlq eqornax uprt pygfe
+plue okbbm btvm gba kutn jacjx ysqt lvx pcxxu qcf
+pyw ffjfudq bvk hsdwdva fjnivhf odbmw krpgrj
+hziesm bxa dceiwt tmvivjk snl fkh dahsxyx kqlhak lurtk
+xss sswyxrg yqff dbkx kbxd mpzbmnl bzplnmm
+uvz pjm ilrol pmj uzct ztcu brhkv
+heiz jcn syjt zfvlvaq aflvqvz amcjh rxnitw
+cxl nxvrn vjnz aewtr cxtko nnvcp ltptd adpxt zvjn fntklj
+aymmm tuirj hzngq zhbh paqs kvpfo aqsp kmo acprw sabrso kdqmp
+ndqjspv mmhp pndjsvq rti usm
+ije oad mvelyg jadz ekm dao zdcmv
+qwww tmwmdbb oxxfoza rgmf eonku brh gcgiuoi ojscn
+fjedeek ohlax fiydku rbnxpg wfivg cdgs
+axwbni hojye mwfe oyqknxp whdgfy ihku mbhr gagnz hehagxj
+hibautd blnayq lnayqb gepml mgpel qunw
+ircx oeb kujtip zbu ebo cmmn
+upyqvot wbponp hnn vav avv tvrky omm
+yzqsnf agbfsw dbxoya sfnqzy hqrxek qsnyzf oagyerm xxhukm
+xzvk mvcwz oujr hell hoe xexa dqlpqt xdqz ucola hsvv tcmybhl
+skldxr mzyol ybzyzd jnnxb rxncdy nkpwy fwlnsw omylz oiwieu fshv ngvha
+jkwqf yxrox hejfoq orxyx
+rijken xiwf mawqcfu erinjk jsi yyg mmu mdkfqb
+ornjes krp eornjs enjros pyqp nnwwjl
+wzd uqqo kyeli tikdle aykdjog uiz rbpnw mjxezf ihiz rlgyg
+cjm ajqgvkz kfgyy dmczlc mjc kxcm zctyqgh ymsk jwhqfd czpqgan
+vxkzvco owo qogj uyictoj kfr pyoo ejrru npluynx bvv jhhzu kuciwc
+eqk pcsly kelu arzgoe trfo fotr cuaax
+lagonw qvcssqz sdoklh uvovi sfrkmd hnvafj ltg wfjj
+viwbkm hpwe kzzwrbr axjtlq mznin wwpjg unlwur
+nuzorgo qfoz ydisca qxdfutv hzg
+nqgge tobtt hjocx ntyqyi rxzkynw wrnxzyk ciscy trjt ottbt
+yuii srawx gljxe eteogz kcu jlgxe tjik ktsnp agudqok jwol vfnyv
+vgicg dhnrmxz sjhozy hlalx rutwq
+nyoyoje kco hoyam hoyam tta iflud amh gdxcsj vqr fvsqcgv
+xdmbtph ueen cskerl rxjvpdc
+nricn addljzg obq rikez igq bxygkmv qmgojou uheubk qor
+snzd ztusvr vrstzu mceddga hgu
+vvrbfjg mcdhmsf ldtwl otuna gmjurrx jgrurxm rxmurjg yrioq
+iotkvo sftfvn vvoit lllju xvlg rdsb ywmdf mzxigu kzq
+sgqw gqsw lqfu wgqs xpiwou jurgucd azq wgaqpm
+ijntzi chlnfj yjqatz hjflcn vys ofq oqf oadthe jrfw
+mmc motjo vcwmod rpaszfk zgkkua bpja vjb htrk
+bpfvvka kmger mnvvfl hakudy yfprdoo mvnlfv rgmek evnwg
+mykpu juavkn cecdvi aszbi lxm hmps oaqoif
+fshizd fsdzhi lvcq hhpb eavwno auqlwz rpv owcdojx amsmf qgnddd
+pohmcn hlcxk qsesxh rncr
+fgyrsis ldem avxmnh frpodq oefzn
+plfpu qdyojz xdrzrjy kpv abkh fge bbnotvp liikmcu czvwl oyh
+ovha muitw pzy edfjoo fhsxuh dliyruc dikcd cqem ywfy
+exyry jtzqn tscr qbtxno cikk poqgr tnjzq eofe sxea anlikep kick
+zcie purpw dmhhms bcdo prwup uprpw wfejgjd
+kwtjc cmixp dodfwj hcgmmat pkeyspo ubnl ajxvj ffkh xvw
+nvlgq oduus psufiqg lrwpn dleftn xtllqvf usgz
+liarf sczsf sczsf wky qtzq qvve qvve
+cit vtjsh jrhkyvi txj urmq hppx
+rhblmxn rhblmxn lkgow dylurwc beyk gfcewxj ehpl disoe tjbjy lkgow
+nbkrm jvk ffux ars agns bebic jzjfm kmnbr gptvtsa ufxf
+hrlvup jaz tafyr qcgq wkd fiz bgsrx jmtcvo qkbvj
+eontk djf tiafrng mtwat puainel nyjoh meynxbf eqdw
+aspvmbx tgzuszm fpj xkl nzpr fjp vnomk byx sbtov tnu utn
+ldyww gwmiddv hwyh gcgsdit gtgdisc suufl xsw dlwyw
+sye dgbd wyf ixqzthx dgdb esy
+nsdgera fqz xwbdgui ngdgbcd bcn qrdxml cwcmxws tncm mqsodj cqgk
+estayas cocmbpv cdcf vygtswo aplwa estayas
+ndc ndc wntr sfls sfls
+gse svv esmi lcdii lnr kemrk gnk ildic blnqy wvn
+mwlpm awkr sxsudub yauwww hnktbog fpnqc nmxoq yoparu tqjpkug nbipft
+czwnkk hrodtmx yyzpil ooqjb cvxzfh
+kwa wak gipak gsgrw
+jyy fja jjk kuvoqdy urqx
+doyu chgn gvtxi qjdigvy kxr dizwrjc sll zenl yyblj
+epxeqih kfi hlog pakk kkiidrh hiufw wuhif baqzxzi bgcd phi jzjdxjp
+hllhyad sodc nyrtfe kygof hyyqi txddqg wcwxvnt ewqmj wwv
+vxymuoe caat diqwbo vfruxdf sqniefn hetcbl nvtttu ouesb
+yvoez pvthzc tdowuci wjijicn fhpmq kfobag yctdwj
+xaugkb rprkg tidpx pjk tpwwm pbcfhr wmwpt sfynrl iouaw zbnyu
+auakc culuxg bffg rodyhea ixlmtfb jdurl szoa
+xgona fjzho buh khbvti ddh mgj ptgaqps
+dqldupd udpldqd poku gfgpcg zsvk grvk kntx jih uwvxdvq sivk
+mwdnq wmqdn uzto mdqnw
+alvfm qxqo thwru xqqo jilnsgs rnonk fwntuby ogbha
+gvxlxyf cdpv khvpka kgt gshlaa tenb
+mtgvvxh mrjrsd truk rrerzx tujweaz
+ozepw gsqkr rtmmc cmrtm
+spnthg xhlzuu xwcrxz aqqejhh bpzh
+ectdftk rgp mkp vxp pevriz wkgfkaw vfygj peg gep wjn
+bksbu ywsszf tsbrps vxicr hfustju ynnlbo
+sio urbvf ujezjk vkyc ukjezj bvrfu qwwgqmw uqfekvx bzipxus qfumwh
+druru kycweog ycmef rjyy fkgp
+rmf ifbip rsztco coju wlr bfbmsug lwr bsufbgm nwmp
+jjuxtyd yif rkldsvu binq spepa mfg aszm
+ghilaau ncm sgbavz omzeotz azukf bgjw zqzo gjbw pld
+gtog iqheik budeu guvljmi
+qqlj jqql ttk xcxu
+cfq cfq kpagib dxfxufw hhksbjh gpcp
+xkeax acnia jjubfc mhot uxlhh gnkj pavta rciondm rkquh xudqian
+wqhqzg psqh rnnc uujlgq
+hpjpaoa maa rdndl xewqj nmagwx xewqj hxuyvou xziv rdndl fbxmbz hmfwghy
+dtwnrca hbfcptw qrmvat sdatx les zwizogq
+bodiwzg sgoas fsf wgkrn zgbdowi wfkz
+ngcsg grtao wcfxpyl gngcs fxwycpl fkpt
+txvngo vxngot tkoap zqjc qzcj oeruix myh ihgdfik qtt
+rxeh fcbnoo rxeh lve wvoc pmnxej dlcbrh rztt noibg
+zyvq lwxqu oyjv bvidmf wxuql
+wzc zcw czw dnhkvrg nzslrf
+cfgl uwhxu qnsfmt tgyabes mqnq nkitq hmcvxlt qqmn yzmb uomqp
+lwziur hgmdmv zuvipkp vir apr gfaq zeo dunat mqgafzg
+prq pqkr xlrw njf ncqni kgpoma cmtklv
+jwfuc poz opz fuple
+fgleub lcgnifu lkwo kftbc onvwvdx lukpod xgmh rnj
+rwqvv ezjmoni llq ekd cdvv kzcci gzsj vuipv fnw
+rtnua gbnzg kqtogns iozzwc kjpzz kiiurey yzlvzx cpy xrue
+fexcjmw ebwssx ewbcgwd uwolou nfdhic vupiykn jss djoo xftbkgo
+idf ipvmez qyevwd wfsjxja dif dig
+szpbtsa bssaztp sptzasb qppgz odur cpmn wpmg
+pxn zjmq rbnr azwstzm mln upaqyty nxp oge nlm
+bfaryqv hag phtvh ypi
+epeeog lip zqio wuehlnb bau sbd dsb
+xbrrp sej agrqnpa aarpnqg bnwyi jbn
+uqmsvd asmuyy czxviw pznnmvc
+sddwmek wnaea iwphupk sabo
+cingdks ksh mtyip zltgafm dflkcd wbdnqup uokm gmxpyd libz svv akce
+qge ewv dkabkmb xcpi nrkmsu mkmb djvamg mhhrwjh
+krjt etfhm bxzatw zdkvz ehov seyxbw mkiirs plzoplu sogmwb wodfcle
+qwea adibdp emo homrd pjcrhlc eqaw kqsrp rphjlcc
+gajzo nwjg qxjra jztcnir ijvjwez avxb afz zyywqz kcszgh elmlkfh
+lbz ozia bctf bumoji anhil rta xvit
+ejybire ypjl qevak fzalx mlh qxlei zib
+xmzas kwojjz ntrnrw nbmxlv mdgxs xjhxg suo zdcrxl qkujisz pxmu
+eezyd unrtm wyu vhufvto rpb isfcy ygh hgy
+nszvbzv ebtt memrsva ebtt qwcaq bhbas pvzfbov ppjbdy nszvbzv jabvrp
+rlo zbmi lugvu yeby
+tfcd tvl faaq mnural nyarh xnxk ctdf bodz
+vwdrhc gub bgu fpcovx rcvwhd jukwsue
+aekrhi lpknnrh bett tkib ioqrap igwnst aekrhi lhha
+acg mknhazp pcgjuk tajplv
+masq fyjkn agq qhxbbl qga npzj fme xtihic rntisg iqv aqg
+ipagh fjth mswztpi iexd cocojy vhqrla joe wrsrmw
+njztu tsh auqrxca zpp
+jctn webxi haq irrr qox irrr webxi
+reaw axmnvd voakf lnz ftbxfh zjyxzl pryfjpv sistgb pov mshs
+gsy ctsngl ptmnyx vpjx zpvtori pfu ioycdrq
+aobdtlj osdnrth sgqe geqs qegs
+oamrlxk ygbb rkamoxl nztl sarbmtj yqupjt plu sbtarmj vpa rxea
+yvhgp yznko epwpza gqrsod rilukp cglhomj wnaplu ugvdko qdr
+cggztg ajw gggzct ubmiefj kpa
+rel lvasbh kobm mdnzla pwnyj ehep gzx nhjdnsg rxa
+qaz gook rplqwh vsht
+dhe aneq ivrn awekad ckcbt zsqca ehd rvni oulwfuu
+oxgzzow wntz tkqaoi oxgzzow lwkdpgy lhd aekjasp tkqaoi dnhaw
+alxghco cpanoa onjh hyeyebe whxn zfu zozbll gojn
+zdqulsa dlqsazu zqudals sfedw
+rydtrsv rrtvysd fvyza drdgh lsfzt blnxr cnxe tslzf iijyds ylcxn
+cczea nxx kwol kopaza wuvr cyvoo whlicv
+zbmrwdq tlzbevx jwzpsc uvkwpd bmss rbzblj
+jogx jgi gji hypmtkg ijg oscjv
+flkoqja kwmrqv wzehel fvmcfap mkwqvr ivwxg jqfwdvo hweezl
+vgjg nzucho nuohcz ggvj tmxci
+fqaqx zeybhtg bxeic lftuqp wzuerz sww qfltxk
+keiy myrvp blkxcg lncqmsu diittlg fqrf digrel cpwrk ipan dkxb bymlzo
+owm irygdz pyhj mow wmo
+noul pbvvt zcv ueqyjl zhetlw lpjfhli
+felvwb wdykz kyibdz haq qkouj vuav oztyqh
+dyxo njcr hcuk ysrr pucw qbajztc
+ooyaz pmt hqwu gjx tmp tpm pwz
+lyhzajz dfot avyifo kdwka pwypcep kyyw tirlku zdpjmft
+aexle hfxo dacwvcy xsiotyg cifq ibupshj aktt rzvf pgafj
+pxubhw ibpm jxtxg iwnssf osbpj
+exmtfyx blbfg emrunru zkuhoi lfzn zrj unmcece phuppi
+icomb rmy mvsqqkh zwjubz lumq wekx
+cmdgs gsr pfhqx pfhqx cmdgs pga
+rpyf jejc adaiou dutv imbenyu dqw zhebjhu pryf vtxs yprf
+cxj roprjn rqoh qacagru snxd
+rczvi hfpl luc yowgj nvavlhw vjudkmv dwu teq
+klwc cktzh ksnvswl nsgeu xyohp mhs fxnjhm fwrcg rdeadkx cim
+ounvb vzqje ujctzzk iyy vxck ebtvbqr uswsmcr jveqz qejzv jmi pboq
+lwffygh mqsh vnnj ufz qhms gqfuxo lurzmu
+buf psdluck gapwoo wgll sbfavbc lljfvzx cdgo rpt sfvabcb
+svefr kubbri fervs nboi zkvq
+jwr vtc zkcpzb kczbzp cdned pzbzkc wigjuak fszgweu odflfek
+vwdqm khnnj plokjg vnce venc vecn yzxtgb
+tawl yrhoz tawl yrhoz
+vvehsl kdhzgme rix rcs btm pxnlsps vlhesv sxpnslp yqjtool
+eqpyw kpmkcyw wqhglxg ajfzo hbd qvmhy nhokah iisqvad kxuyd fxek
+jsz txhwhah hxt djnvl srylveu pxp dzmmn epek tzs
+joyzql jqczueb rtdyw fyc fjirfyn tjcalz joyzql fyc
+pjrmiz xwnmwns kcqjuut zfgxhdr octwn kqppg zhfgxrd wmwnnxs
+ema yqxqs aljjo ajloj wozb
+urgmhiz epqj vhhaxdm ptlsvig qzbmm cumbho lkg gyzmg eaopyzf ncfy mqe
+ijvwvo oszkees ugvyk hjdj ftip itfp
+ylfw qutzdj mgqp cyjss yzsdqqi iykvs fyor sthyqp mrjtzee hgo zwqbtgk
+bkfkns gco bykzc mje dwmkrwt ljegqor yxjxp oaleuu
+xeltq ggyqis aud frtyxhx iwz wiz fwoxz fozxw
+zdu nwduqsa nced iphaaxo
+bqjj oah ezd brhgxrc pmkz kdog exw
+ihatt hck iepn egemprp wrz wzcuo xjzeaa wku ivjvihh
+cwkuof bmj qmxd qbtms zgdei bsqmt ssndhw eeenku lcsqy bvvodr
+tek zsgytci vgoun kwwu
+jcxvp ijxc buqgix uil zfoku
+ggndshq bmjeo yqaxtik blspz yofh edaroy
+ipvtxh ouye elln dllvx iqza nhwf zyfw pvlky
+iydcx gvarm gvarm wegmiy
+sfjd liiflle mulboe qywzs tzbns trojl pad mnfcrhb sltb
+gthqj jvpsof jwlfyeg jwhlfj
+qckv umzrge gnzc mnr xde
+gvgxmhv txnait taxint ius iboqdj
+vsfex kbpvsby qembkb efxvs vhflzvm eaazg dyg bbmekq
+wxpfk xwfpk xwkpf cjsyi
+knzg eefq feqe seppop ttxz qnqfn atgsy cch mkjlbwt uyhct
+quzw jbiw miqehe qvf jyipqh kzcjxyh
+teuvzf tdtwoi pcuafa cwgjk ccur lgmqv jpjdkk efrnw uloqn dpkjkj lwloeph
+yaffjy xntstsv gygq sxttvsn tvnstxs
+cvbmdf pfrfkna wupv van iocb hsiyke obspj ytyfkl hbsqtij hkcw
+oeddmnu koso mdodeun ybe mhjbmwy ubejz soko yxvuv
+nylhy ylnyh olb vcdik
+gsp ilba llnu jjk urbvuma qzypf bkceotg ezxq hyvjngf
+tfnegyq rue waeif tfnegyq mvqm
+wvgnsk cpd oib wrdfaz kohwgkc kzzig hogkwck gkizz
+fecuuyp yfq bvanvxb cjeqwf unw dccr qzh zqu voakj
+utoazh bjuq kmhcre izmny mirorsy twnl jyoc
+fnnpd dmr ccgu eqgewc zuqivf
+kkxiba qdabuen oikaz dnuywmm
+aogud adugo uzcglpj lucv dgoua mdsqa mvrg
+lymhv sof hvyml mlvhy nit
+chu bwxp xpbw ghaix seklnc ola zofnrwt uch
+wtt abob vblijtd oabb qjws
+uozrpw kgf gxidxm uehdr fta pqakkrq atf fat woaolk
+gaee voshd ghlyy emvzlkg cmcgk tuwlsj jwtsul znrta mjieqph glker
+qiugxas gkg cbzmoz kahs obzzcm
+puz omcokz gjc heuqb
+dgndhb wid wdi scwnrjf juaisgo eivaw hgdndb
+mgcrd hnqg pkpeb vprxcp
+atlcnzp fyp cpkivxi bzj ypf cqpt bysu
+pnd jiitmzs csw mxnpck vxutdrs ivipzy cws xiegsy qut
+txlk avcvbuu hnq yyriq ajyswd urgiwc
+qgiqut gvblizs giqnfrk tty mvoj wpikl giqnfrk bkdpndu xztmxn hsmqxf
+llthg zjslki wilj rcyfois bavz hrqxn
+ytbw hlkl vip skycogy ejiirhx
+ndmtg bthlbw lsoq cvlvo sqol sqlo bppl sdkbls dtpyzrq vgm
+psm xpj xjp lqi spm gqirw aglpj
+htg fcchvyt xffev szdu lieadft
+nbjo qohgzu vofg vvild dbtyi pdolxn plnoao jxze xlpbxj brajzg
+urpp jjv lihmvp ivkwdqr sesyp ypbry qok sesyp ivkwdqr was
+yinepzv qvnzdtf apv ucxo bdioo juga hjfsyl hmowo avc
+dmiv tplae iiuiaxx tpale pyzkc
+giwhst mpexd byfyc swuzkc
+yydkwp xuu vjya kav ujmcxy qrtp zvlk
+lsvdyn tkw qxu omvlc wwmfvov mrgcoov dhpu tfair hupd zbx njzgwtw
+zuz rsxc xsrc gdwwf nycsv zzu kcu
+unlvzv jerqqgm nozma ykbflj qihqkx
+pctffo begf ivrvy ezru mvqt waocq
+tubtuk gxkc ikgw bjrird kxjebbh sbjyc yafkd khqajmt aclpmf gqfo yrpf
+rdt vrxa fyudo myeosb ursflwk
+wbjras edlbwdp ctobtw jbvtvcd xjgoo cmunxm mjtbpi klovx bypmsab unc
+xckml uztr htublq vilabvr jdiwus qejxur evfw qqm
+tzqq tzqq wkb wkb
+dgmg ljzc dgmg mbmco cgze qsap jccvot uors iiq
+rwvac woylk dmn teorprx nyuvz hcwwxlj lvej drbjo asjgq
+ljen tpfl vixcivr guaf lnje waim jlen
+djgaa janhi adudm yzv zkcb xqw fgvrz
+kpkjoon ggzx skp rqcsw xgzg zgxg jtf ghc
+rtnyxo qixfd nphekk mouzk gny fpzquw qgywx rpr gqydze
+gawdlv vrivoof rte iyp gaih sfzplm
+csojx wzojode uzy qulr lylmb guvtkwv
+ovxj aamms ftxo ebckdqw wqvsdci jwfqxks jafrcrn yyomrot
+qnu jqwr ywudxk qpsez rdc kiyfz iiecf dthxjjb bown
+typ zxcvjo rip acjhl paaab qhqipg xkguye sbxy pomkvn
+ofvaegv hgak oafevgv hkemar rqkha grklnsp msvkkku rekahm bxmjnw
+ahoihju sdyn phi uhz lupbx
+lavt jef klmq oqyfpf kis nazul ymezxek xpla fxyrfnt
+nwnagwy hvpjqfg sgm ungfstr gso owqqxjh
+hey hye ipyrt qxmthg jth wpbr hxgmtq cvfkfux qykdzhk movcfnl vxyoc
+zsras abnrj fgaczuk ssazr xzf cnxu gns wnqqy dwjh szars
+uhb zanlvh lvdotkb xekl kcofo
+lhx iccy ibkjw ciykxaj imsx ehamqlz iwzapxc rhaltv
+pofit owmpqej vwrobh jvox gdqehss yyxd styu tfkm fiotp
+ecz mdpoqsv mdpoqsv yxx rexok hcfll yvury hdhcfu juhkvpt rspnfj hxvgdir
+ohed mtigaoe eodh agmiteo
+vjvv hfco cppbxtw hawsjxz ovlsq qgs risgwhg auhj
+togivgg czrtvw ccz wzvtrc bse lsk
+ndc ndc lrfi iyleol nchx jxpv xdcsfmp nnx wtvq pih tgc
+hzpf sur zhfp klfmhx lbuidp xiqimnf
+qddpdk trfxpip pnsowj hidgvnf prur rsrautp aamykfm fysqjmq xwzjane mbmtxhf oqctt
+lfd eops govslp ultbye vrqai hcjkcf snpape
+cbok koumkad otpozb pqcs emilpe wpcyvxd bock
+spjb xkkak anuvk ejoklh nyerw bsjp zxuq vcwitnd xxtjmjg zfgq xkpf
+juo pmiyoh xxk myphio ogfyf dovlmwm moevao qqxidn
diff --git a/04/lib.scm b/04/lib.scm
new file mode 100644
index 0000000..5a1fff5
--- /dev/null
+++ b/04/lib.scm
@@ -0,0 +1,74 @@
+(library (lib)
+ (export solve-part1 solve-part2)
+ (import (chezscheme))
+
+ ; Split list at first delimiter into `prefix' and `suffix'
+ ; Return value is a pair like `((p r e f i x) s u f f i x)'
+ (define (list-split-left delimiter? xs)
+ (let loop ((prefix '())
+ (suffix xs))
+ (if (null? suffix)
+ (cons prefix suffix)
+ (let ((x (car suffix)))
+ (if (delimiter? x)
+ ; Found first delimiter, so return immediately
+ (cons prefix (cdr suffix))
+ ; `x' isn't a delimiter, so append it to `prefix'
+ (loop (append prefix (list x)) (cdr suffix)))))))
+
+ ; Split list at given delimiter into list of sublists
+ (define (list-split delimiter? xs)
+ (let loop ((pieces '())
+ (rest xs))
+ (if (null? rest)
+ ; Fix order and remove all empty sublists from output
+ ; (which are caused by consecutive delimiters in `xs')
+ (reverse (remp null? pieces))
+ ; Extract next piece from `rest' and prepend it to `pieces'
+ (let ((next (list-split-left delimiter? rest)))
+ (loop (cons (car next) pieces) (cdr next))))))
+
+ ; Split string at whitespace into list of words
+ (define (string-split str)
+ (map list->string (list-split char-whitespace? (string->list str))))
+
+ ; Sort chars in string according to `proc'
+ (define (string-sort proc str)
+ (list->string (list-sort proc (string->list str))))
+
+ ; Partially applied equality check
+ (define (check-identical? word1)
+ (lambda (word2) (equal? word1 word2)))
+
+ ; Partially applied anagram check
+ (define (check-anagram? word1)
+ (lambda (word2)
+ ; Sort chars by Unicode value, then check string equality
+ (string=? (string-sort char<? word1)
+ (string-sort char<? word2))))
+
+ ; Count for how many elements of `xs' `proc' returns true
+ (define (count proc xs)
+ (length (filter proc xs)))
+
+ ; Count how many passphrases in `lines' are reported valid by `proc'
+ (define (solve-puzzle proc lines)
+ (count
+ (lambda (phrase)
+ ; For each word in `phrase', does it have any copies/anagrams?
+ (let loop ((words phrase))
+ (if (null? words)
+ #t
+ ; Count copies/anagrams, including `(car words)' itself
+ (if (> (count (proc (car words)) phrase) 1)
+ #f
+ (loop (cdr words))))))
+ (map string-split lines)))
+
+ (define (solve-part1 lines)
+ (solve-puzzle check-identical? lines))
+
+ (define (solve-part2 lines)
+ (solve-puzzle check-anagram? lines))
+
+)
diff --git a/04/main.scm b/04/main.scm
new file mode 100644
index 0000000..c8f57bb
--- /dev/null
+++ b/04/main.scm
@@ -0,0 +1,20 @@
+(import (chezscheme))
+
+; Where the magic happens
+(import (lib))
+
+; Read my personal puzzle input
+(define input
+ (call-with-input-file "input.txt"
+ (lambda (port)
+ (let loop ((line (get-line port))
+ (result '()))
+ (if (eof-object? line)
+ (reverse result)
+ (loop (get-line port) (cons line result)))))))
+
+; Part 1 gives 466 for me
+(printf "Part 1 solution: ~a\n" (solve-part1 input))
+
+; Part 2 gives 251 for me
+(printf "Part 2 solution: ~a\n" (solve-part2 input))
diff --git a/04/test.scm b/04/test.scm
new file mode 100644
index 0000000..564016a
--- /dev/null
+++ b/04/test.scm
@@ -0,0 +1,41 @@
+(import (chezscheme))
+
+; Where the magic happens
+(import (lib))
+
+; My quick-and-dirty unit testing framework (copied for each day)
+(define (run-test name proc input expected)
+ (let ((result (proc input)))
+ (if (= result expected)
+ (printf "\x1b;[32;1mPASS\x1b;[0m: ~a\n"
+ name)
+ (printf "\x1b;[31;1mFAIL\x1b;[0m: ~a: got ~a, expected ~a\n"
+ name result expected))))
+
+(printf "Part 1 tests:\n")
+
+(define (test-part1 name input expected)
+ (run-test name solve-part1 input expected))
+
+(test-part1 "part 1 example 1"
+ '("aa bb cc dd ee") 1)
+(test-part1 "part 1 example 2"
+ '("aa bb cc dd aa") 0)
+(test-part1 "part 1 example 3"
+ '("aa bb cc dd aaa") 1)
+
+(printf "Part 2 tests:\n")
+
+(define (test-part2 name input expected)
+ (run-test name solve-part2 input expected))
+
+(test-part2 "part 2 example 1"
+ '("abcde fghij") 1)
+(test-part2 "part 2 example 2"
+ '("abcde xyz ecdab") 0)
+(test-part2 "part 2 example 3"
+ '("a ab abc abd abf abj") 1)
+(test-part2 "part 2 example 4"
+ '("iiii oiii ooii oooi oooo") 1)
+(test-part2 "part 2 example 5"
+ '("oiii ioii iioi iiio") 0)
diff --git a/05/input.txt b/05/input.txt
new file mode 100644
index 0000000..857d86c
--- /dev/null
+++ b/05/input.txt
@@ -0,0 +1,1044 @@
+0
+1
+0
+1
+0
+-1
+0
+1
+2
+2
+-8
+-7
+-3
+1
+0
+-2
+-6
+-7
+-11
+2
+-11
+0
+-18
+0
+-18
+-1
+1
+-16
+-3
+-28
+-10
+-6
+-11
+-6
+-17
+-20
+-15
+-31
+-37
+-34
+-14
+-35
+-34
+-17
+-28
+-20
+-12
+-41
+-29
+-8
+-1
+-50
+-46
+-26
+-41
+-33
+-17
+0
+-28
+-52
+-38
+-28
+-29
+-60
+-23
+-60
+-55
+-28
+-43
+-57
+-66
+-35
+-48
+-71
+-25
+-6
+-27
+-47
+-77
+-68
+-21
+2
+-39
+-82
+-2
+-59
+-61
+-67
+-26
+-11
+0
+-68
+-85
+-10
+-62
+-49
+-28
+-15
+-34
+-55
+-92
+-92
+-37
+-82
+-49
+-86
+-25
+-24
+-81
+-86
+-6
+-48
+-79
+-22
+-30
+-1
+-63
+-77
+-64
+-70
+-86
+-118
+-36
+-44
+-50
+-70
+-76
+-5
+-72
+-72
+-84
+-1
+-104
+-116
+-18
+-69
+-78
+-23
+-99
+-69
+-32
+-26
+-4
+-134
+-22
+-18
+-70
+-95
+-13
+-136
+-73
+-131
+-24
+-101
+-136
+-29
+-132
+-154
+-108
+-127
+-48
+-134
+-122
+-162
+-2
+-61
+-9
+-4
+-126
+-146
+-161
+-157
+-116
+-95
+-83
+-36
+-86
+-57
+-42
+-103
+-73
+1
+0
+-28
+-156
+-67
+-178
+-36
+-169
+-46
+-16
+-97
+-86
+-112
+-186
+-111
+-69
+-158
+-37
+-75
+-109
+-186
+-16
+-84
+-73
+-83
+-139
+-54
+-89
+-191
+-126
+-15
+-158
+-19
+-116
+-73
+-13
+-184
+-121
+-14
+-116
+-167
+-174
+-103
+-66
+-128
+-156
+-5
+-174
+-220
+-213
+-96
+-139
+-22
+-102
+-33
+-118
+-163
+-184
+-17
+-76
+-72
+-96
+-106
+-203
+-55
+-181
+-207
+-40
+-235
+-139
+-5
+-127
+-21
+-155
+-183
+-51
+-54
+-38
+-247
+-218
+-56
+-34
+-173
+-241
+-187
+-38
+-13
+-172
+-2
+-235
+-167
+-191
+-250
+-150
+-34
+-151
+-183
+-119
+-90
+-21
+-93
+-275
+-168
+-160
+-97
+-100
+-25
+-273
+-245
+-44
+-223
+-201
+-156
+-12
+-55
+-189
+-181
+-10
+-92
+-152
+-90
+-217
+-68
+-81
+-76
+-86
+-48
+-287
+-281
+-63
+-83
+-66
+-50
+-49
+-310
+-254
+-121
+-294
+-132
+-53
+-30
+-223
+-85
+-297
+-264
+-58
+-51
+-294
+-283
+-3
+0
+-262
+-33
+-136
+-14
+-238
+-6
+-312
+-17
+-328
+-299
+-245
+-266
+-6
+-330
+-117
+-172
+-260
+-224
+-139
+-156
+-165
+-13
+-243
+-173
+-42
+-67
+-7
+-148
+-1
+-105
+-205
+-223
+-122
+-82
+-221
+-317
+-330
+-240
+-189
+-12
+-268
+-243
+-177
+-120
+-320
+-127
+-351
+-178
+-219
+-351
+-128
+-28
+-227
+-188
+-195
+-205
+-204
+-283
+-316
+-276
+-319
+-312
+-337
+-318
+-136
+-33
+-307
+-397
+-387
+-303
+-12
+-347
+-112
+-171
+-222
+-358
+-215
+-71
+-99
+-108
+-24
+-291
+-344
+-97
+-99
+-6
+-270
+-327
+-32
+-387
+-402
+-13
+-175
+-243
+-374
+-422
+-382
+-152
+-420
+-266
+-326
+-37
+-215
+-357
+-423
+-16
+-272
+-357
+-87
+-184
+-21
+-351
+-300
+-219
+-390
+-12
+-15
+-78
+-69
+-35
+-308
+-303
+-300
+-265
+-440
+-19
+-117
+-87
+-218
+-163
+-317
+-42
+-55
+-185
+-245
+-196
+-183
+-327
+-467
+-102
+-432
+-162
+-202
+-39
+-179
+-301
+-237
+-299
+-33
+-198
+-127
+-138
+-454
+-46
+-87
+-362
+-448
+-382
+-42
+-358
+-475
+-350
+-50
+-380
+-316
+-380
+-463
+-108
+-405
+-139
+-480
+-30
+-212
+-308
+-239
+-223
+-306
+-81
+-89
+-172
+-304
+-87
+-380
+-394
+-507
+-392
+-98
+-403
+-155
+-13
+-197
+-66
+-244
+-401
+-278
+-391
+-64
+-460
+-368
+-178
+-145
+-440
+-49
+-369
+-418
+-332
+-200
+-294
+-495
+-104
+-5
+-261
+-168
+-392
+-230
+-154
+-472
+-404
+-472
+-307
+-256
+-169
+-330
+-500
+-365
+-146
+-133
+-84
+-336
+-405
+-555
+-74
+-68
+-354
+-552
+-108
+-80
+-406
+-164
+-119
+-487
+-151
+-113
+-244
+-471
+-80
+-312
+-495
+-556
+-76
+-24
+-546
+-493
+-340
+-464
+-328
+-7
+-474
+-246
+-237
+-40
+-199
+-346
+-330
+-139
+-284
+-435
+-83
+-210
+-423
+-361
+-56
+-271
+-140
+-162
+-232
+-391
+-42
+-99
+-590
+2
+-271
+-101
+-114
+-117
+-310
+-502
+-287
+-319
+-323
+-362
+-551
+-439
+-533
+-183
+-404
+-401
+-343
+-36
+-89
+-454
+-128
+-611
+-6
+-619
+-110
+-389
+-290
+-270
+-375
+-283
+-472
+-65
+-195
+-129
+-61
+-548
+-151
+-74
+-612
+-156
+-371
+-42
+-447
+-565
+-394
+-550
+-476
+-592
+-262
+-96
+-529
+-395
+-204
+-491
+-167
+-186
+-527
+-508
+-245
+-455
+-552
+-672
+-338
+-269
+-104
+-240
+-77
+-303
+-227
+-453
+-126
+-294
+-572
+-8
+-527
+-361
+-438
+-457
+-513
+-560
+-442
+-649
+-321
+-123
+-52
+-166
+-320
+-301
+-570
+-684
+-325
+-515
+-547
+-52
+-221
+-488
+-182
+-618
+-109
+-497
+-167
+-288
+-358
+-334
+-313
+-288
+-102
+-409
+-143
+-204
+-216
+-681
+-512
+-245
+-301
+-35
+-262
+-239
+-405
+-682
+-715
+-438
+-314
+-179
+-611
+-667
+-622
+-511
+-463
+-370
+-338
+-434
+-580
+-637
+-201
+-213
+-357
+-443
+-382
+-315
+-483
+-399
+-624
+-318
+-226
+-652
+-638
+-743
+-330
+-647
+-146
+-138
+-698
+-511
+-173
+-663
+-333
+-564
+-160
+-239
+-243
+-91
+-65
+-468
+-256
+-197
+-210
+-575
+-420
+-715
+-681
+-454
+-226
+-226
+-339
+-473
+-737
+-62
+-149
+-351
+-770
+-313
+-216
+-491
+-511
+-269
+-628
+-391
+-429
+-110
+-199
+-409
+-516
+-7
+-433
+-405
+-792
+-685
+-615
+-287
+-385
+-627
+-527
+-426
+-626
+-164
+-767
+-794
+-115
+-483
+-323
+-371
+-679
+-772
+-808
+-2
+-16
+-459
+-749
+-569
+-139
+-7
+-555
+-161
+-613
+-230
+-771
+-825
+-241
+-579
+-710
+-73
+-790
+-653
+-655
+-394
+-218
+-711
+-467
+-774
+-694
+-664
+-357
+-29
+-121
+-643
+-742
+-388
+-633
+-440
+-755
+-581
+-661
+-653
+-536
+-596
+-10
+-796
+-230
+-813
+-125
+-540
+-584
+-389
+-144
+-346
+-213
+-444
+-205
+-712
+-651
+-670
+-139
+-60
+-620
+-49
+-284
+-212
+-452
+-520
+-243
+-356
+-348
+-442
+-585
+-202
+-207
+-222
+-47
+-49
+-408
+-571
+-154
+-695
+-802
+-524
+-523
+-617
+-615
+-571
+-92
+-344
+-675
+-613
+-759
+-29
+-833
+-662
+-223
+-46
+-156
+-373
+-412
+-848
+-93
+-695
+-250
+-810
+-477
+-150
+-282
+-789
+-193
+-443
+-193
+-159
+-840
+-755
+-508
+-404
+-307
+-80
+-320
+-14
+-245
+-746
+-610
+-855
+-552
+-323
+-366
+-45
+-16
+-335
+-852
+-46
+-459
+-461
+-537
+-547
+-180
+-842
+-213
+-447
+-712
+-633
+-362
+-953
+-407
+-47
+0
+-466
+-107
+-648
+-528
+-413
+-828
+-217
+-484
+-969
+-121
+-858
+-208
+-618
+-384
+-16
+-91
+-662
+-348
+-675
+-63
+-713
+-966
+-678
+-293
+-827
+-445
+-387
+-212
+-763
+-847
+-756
+-299
+-443
+-80
+-286
+-954
+-521
+-394
+-357
+-861
+-530
+-649
+-671
+-437
+-884
+-606
+-73
+-452
+-354
+-729
+-927
+-248
+-2
+-738
+-521
+-440
+-435
+-291
+-104
+-402
+-375
+-875
+-686
+-812
+-539
+-934
+-536
+-924
+-924
+-365
diff --git a/05/lib.scm b/05/lib.scm
new file mode 100644
index 0000000..9a9951b
--- /dev/null
+++ b/05/lib.scm
@@ -0,0 +1,29 @@
+(library (lib)
+ (export solve-part1 solve-part2)
+ (import (chezscheme))
+
+ ; Follow the jump instructions until we end up outside,
+ ; updating every offset we touch according to `proc'
+ (define (solve-puzzle proc lines)
+ (define code (list->vector (map string->number lines)))
+ (let loop ((i 0) (count 0))
+ (if (or (< i 0) (>= i (vector-length code)))
+ count
+ (let ((offset (vector-ref code i)))
+ (vector-set! code i (proc offset))
+ (loop (+ i offset) (+ count 1))))))
+
+ (define (solve-part1 lines)
+ (solve-puzzle
+ (lambda (offset) (+ offset 1))
+ lines))
+
+ (define (solve-part2 lines)
+ (solve-puzzle
+ (lambda (offset)
+ (if (>= offset 3)
+ (- offset 1)
+ (+ offset 1)))
+ lines))
+
+)
diff --git a/05/main.scm b/05/main.scm
new file mode 100644
index 0000000..2ec4357
--- /dev/null
+++ b/05/main.scm
@@ -0,0 +1,20 @@
+(import (chezscheme))
+
+; Where the magic happens
+(import (lib))
+
+; Read my personal puzzle input
+(define input
+ (call-with-input-file "input.txt"
+ (lambda (port)
+ (let loop ((line (get-line port))
+ (result '()))
+ (if (eof-object? line)
+ (reverse result)
+ (loop (get-line port) (cons line result)))))))
+
+; Part 1 gives 342669 for me
+(printf "Part 1 solution: ~a\n" (solve-part1 input))
+
+; Part 2 gives 25136209 for me
+(printf "Part 2 solution: ~a\n" (solve-part2 input))
diff --git a/05/test.scm b/05/test.scm
new file mode 100644
index 0000000..36e52ed
--- /dev/null
+++ b/05/test.scm
@@ -0,0 +1,29 @@
+(import (chezscheme))
+
+; Where the magic happens
+(import (lib))
+
+; My quick-and-dirty unit testing framework (copied for each day)
+(define (run-test name proc input expected)
+ (let ((result (proc input)))
+ (if (= result expected)
+ (printf "\x1b;[32;1mPASS\x1b;[0m: ~a\n"
+ name)
+ (printf "\x1b;[31;1mFAIL\x1b;[0m: ~a: got ~a, expected ~a\n"
+ name result expected))))
+
+(printf "Part 1 tests:\n")
+
+(define (test-part1 name input expected)
+ (run-test name solve-part1 input expected))
+
+(test-part1 "part 1 example 1"
+ '("0" "3" "0" "1" "-3") 5)
+
+(printf "Part 2 tests:\n")
+
+(define (test-part2 name input expected)
+ (run-test name solve-part2 input expected))
+
+(test-part2 "part 2 example 1"
+ '("0" "3" "0" "1" "-3") 10)