diff options
| -rw-r--r-- | 06/input.txt | 1 | ||||
| -rw-r--r-- | 06/lib.scm | 82 | ||||
| -rw-r--r-- | 06/main.scm | 14 | ||||
| -rw-r--r-- | 06/test.scm | 29 | ||||
| -rw-r--r-- | 07/input.txt | 1193 | ||||
| -rw-r--r-- | 07/lib.scm | 192 | ||||
| -rw-r--r-- | 07/main.scm | 20 | ||||
| -rw-r--r-- | 07/test.scm | 43 | ||||
| -rw-r--r-- | 08/input.txt | 1000 | ||||
| -rw-r--r-- | 08/lib.scm | 105 | ||||
| -rw-r--r-- | 08/main.scm | 20 | ||||
| -rw-r--r-- | 08/test.scm | 34 | ||||
| -rw-r--r-- | 09/input.txt | 1 | ||||
| -rw-r--r-- | 09/lib.scm | 70 | ||||
| -rw-r--r-- | 09/main.scm | 14 | ||||
| -rw-r--r-- | 09/test.scm | 68 | ||||
| -rw-r--r-- | 10/input.txt | 1 | ||||
| -rw-r--r-- | 10/lib.scm | 123 | ||||
| -rw-r--r-- | 10/main.scm | 14 | ||||
| -rw-r--r-- | 10/test.scm | 42 |
20 files changed, 3066 insertions, 0 deletions
diff --git a/06/input.txt b/06/input.txt new file mode 100644 index 0000000..04f1425 --- /dev/null +++ b/06/input.txt @@ -0,0 +1 @@ +4 1 15 12 0 9 9 5 5 8 7 3 14 5 12 3 diff --git a/06/lib.scm b/06/lib.scm new file mode 100644 index 0000000..76bd34d --- /dev/null +++ b/06/lib.scm @@ -0,0 +1,82 @@ +(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)))) + + ; Find the index at which `needle' occurs in `haystack', or `#f' + (define (find-index needle haystack) + (let loop ((xs haystack) (i 0)) + (if (null? xs) + #f + (if (equal? needle (car xs)) + i + (loop (cdr xs) (+ i 1)))))) + + ; `apply' but for vectors, assuming `proc' returns a scalar + (define (vector-apply proc vec) + (apply proc (vector->list vec))) + + ; Redistribute the items according to the puzzle description + (define (redistribute old) + (let* ((n-max (vector-apply max old)) ; largest value in `old' + (i-max (find-index n-max (vector->list old))) ; index of `n-max' in `old' + (new (vector-apply vector old)) ; allocate copy of `old' + (len (vector-length old))) ; number of slots in `old' + ; Clear the slot that had the most items + (vector-set! new i-max 0) + ; Add those items to the other slots one by one + (let loop ((i (mod (+ i-max 1) len)) + (remaining n-max)) + (if (= remaining 0) + new + (let ((n (vector-ref new i))) + (vector-set! new i (+ n 1)) + (loop (mod (+ i 1) len) (- remaining 1))))))) + + ; Keep redistributing items until a previous state is revisited + (define (solve-puzzle str) + (let ((init (list->vector (map string->number (string-split str))))) + (let loop ((states (list init))) + (if (find-index (car states) (cdr states)) + states + (loop (cons (redistribute (car states)) states)))))) + + ; Loop detected after `(length states)' cycles, minus initial state + (define (solve-part1 str) + (- (length (solve-puzzle str)) 1)) + + ; Loop start state first seen somewhere in `(cdr states)', at which index? + (define (solve-part2 str) + (let ((states (solve-puzzle str))) + (+ (find-index (car states) (cdr states)) 1))) + +) diff --git a/06/main.scm b/06/main.scm new file mode 100644 index 0000000..4e58151 --- /dev/null +++ b/06/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 6681 for me +(printf "Part 1 solution: ~a\n" (solve-part1 input)) + +; Part 2 gives 2392 for me +(printf "Part 2 solution: ~a\n" (solve-part2 input)) diff --git a/06/test.scm b/06/test.scm new file mode 100644 index 0000000..e8efb7c --- /dev/null +++ b/06/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 (equal? 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 2 7 0" 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 2 7 0" 4) diff --git a/07/input.txt b/07/input.txt new file mode 100644 index 0000000..4f6dd1c --- /dev/null +++ b/07/input.txt @@ -0,0 +1,1193 @@ +yvpwz (50) +vfosh (261) -> aziwd, tubze, dhjrv +xtvawvt (19) +nspsk (24) +sgtfap (19) -> bohjocj, bqvzg +oyuteie (52) +irrpz (226) -> cibfe, hemjsj, upbldz +vtvku (426) +vbsfwqh (6055) -> govhrck, pglpu, rwuflbi, ppgaoz +nupmnv (47) -> cngdg, olgsb, lmvmb +ulndqey (71) +fujgzbt (198) -> fbesgp, hewtnrw +nsbvvsi (39) +ajvtdl (36) +xrgca (85) +mksrqb (45) +ozfsktz (56) -> xzwjii, uhxjy +peretma (15) -> suzsw, ycvvjgc, cdyhvr, jixggay +boplau (77) -> boggvxt, cnyasj +rzqffr (84) -> tbppaj, htyeqf, pgnyu, ruhqn +shkkwp (5) +bpptuqh (68) -> ugxls, zlshut, ltqljtw +bngres (944) -> ktwby, tblhhg, jzgpty, skbprng +tjnyo (55) +ujfeg (13) -> vldxkw, kfbsjv, rlqwaz, dvwsrc, ymxlwf, zvmhx, wfdxfxq +mxplky (35) +ezkqh (91) +kozgi (48) +pgnyu (94) +yhunajf (25) +pvpmt (77) +cvitrpt (88) +zjwih (46) -> cvitrpt, chtamif +mhfnxk (6) -> jddyhz, gvrhj, ctpdk, oprvyxy, luzjys +dbrnqc (77) +iorlbdv (43) +twwzhwf (118) -> ndgupvi, aumbaa +mvngvtg (67) +kwkprrw (187) -> uobxcai, aklrjg +wtvffu (120) -> vzxvex, mtsbrje, slfile +vjwivnq (52) +cbwbdsv (157) -> przuau, atjtgjx +rwuflbi (8) -> lapoix, dkdovw, spgcwtn +upbldz (27) +xgnqi (64) +ksotbs (48) -> cqbvru, tqbvdu +romrjs (55) -> vhilqk, gzxuw +ftmwqqj (76) +kqpvqie (63) -> qomhp, fwvsi +xxrsnzv (39) +trqfblp (85) +rmjktk (28) -> wtkfiw, mlrdsj, pnicdos, woujz, psrzr +lwygknn (96) +ctgbkrb (76) -> iavuhwe, onvkja +iqbrs (67) -> tghoyv, hoheog, kjpzwp, wwvad, ezmjqnt +efuqu (136) -> umljkr, qblnh +egwjjg (85) +dgtvwiy (27) +ndgupvi (28) +zdvai (85) +auhio (82) +dywjt (40) +hhboca (18) +pptbkz (96) +iqsvbk (73) +nwjibjk (31) +veclzy (308) -> dohjma, hbiwkt +repak (139) -> bcjxhps, eyckbl +xguqlvl (74) +rkjmp (59) +eqviuw (171) -> mqlsvih, lrnjjfq, njgkkxo +zogylog (80) +kroqr (38) +onvkja (49) +tedehrz (94) -> ipqjff, dmiqf +lhwyt (287) -> jbwbw, htyyatf, ppvwkei, vtbzq, pynomi, uswsg +mrbqk (64) +aoxtau (64) +gvrhj (59) -> qurrva, xrgca +lfksu (72) +tnwle (49) +dgnpr (93) +ucsxzhl (21) -> tpefei, ntkeax, jvayv, yuobv +wbibf (183) -> pvtat, ygnww, akngdu, swpkkpi +ljaktj (21939) -> seeqikh, mqrfbqc, ihnus +agqkf (69) +tubze (48) +fcapw (105) -> nkhzrd, shkkwp +sdied (47) +zfmeblt (56) +wqyzjzi (41) +zxjeza (185) -> ioumv, pjersb +vecxd (56) -> civozek, qzsypj +dkxebg (73) -> atrmuc, mhfnxk, zwwbw, ryaotx, yqhmb, yztqpc +oqiye (35) +edyqn (60) +fujwzoc (404) +llcbiqi (79) +yejkld (41) +utbev (25) -> hsxru, jfuxeo, zyshq, eznabc, lgsda, uobxonm +ojxyv (79) +vbpde (20) +fyjowg (26) +yfzjc (31) +obwzec (41) +zcanxq (85) +woujz (125) -> qntvn, kwzrzn +adhwzp (305) -> agqkf, yallk +zvcfznz (184) -> rjuhrpu, yzwnh, hikik +dxbrl (66) +appays (423) -> nupmnv, cyppxr, rqoczb +rgndu (81) -> tsbbzu, dtxrjg +jncex (74) -> rrdczem, bhhgpe, gtvnow, vndrx +cfvbuip (53) +vsqfx (29) +zocaag (38) +ppymmsf (19) +amwxj (69) -> pptbkz, kweqtf, jwmbs +svadhfo (99) +xdsbnr (8) +duvrzrl (22) +dfaro (8) +vgugdtt (220) -> nxpakq, fhsecp +fwddmmv (43) +igaww (28) +bbxbrsh (31) +swpkkpi (13) +bkqexxz (77) +ovfduq (16) +rtzce (39) +gmwto (119) -> wbeizj, refgrip +rmdhj (24) +yeref (77) +ifstrgw (23) -> qpixldb, tukirqp, bwcyqb, bzbmt +untdpje (45) -> owimy, yejkld +esiwujq (41) +emvxet (131) -> vecdh, ftgvx +mztuzb (764) -> jgzvrf, eaqiocy, fsagr +bwnabqh (83) +gypsfc (43) +bhemin (44) +imydd (164) -> iabqb, vdpnsak +qajpehv (49) +oxnfnsv (76) -> twwzhwf, uiyyc, gfaamu, umhcrc, bcjpzpk, vrqeade +qfdldyu (231) +dmsmgs (29) +oqady (7) -> mhtzh, cpreh +zbhwrc (759) -> esrilo, dcngdo +cyppxr (272) -> pitmcu, nvlqab +jtzjrke (45) +przuau (59) +eexkce (44) +xsewlv (124) -> fwfpmti, rszjhxn +fbesgp (28) +sxegjbz (297) -> yhycc, gxmry, favzt +nxpakq (17) +hbvvse (98) +ygzwut (83) +cngdg (93) +tfzum (69) +ccghjn (58) +ylbpwah (190) -> htlpx, eduzave, peqgox, fkqkfdu +mobbhp (141) -> clgbo, jtzjrke +icdlpb (62) +wkrtcw (1663) -> qqzhz, ybewhak, mazbb +uswsg (312) +zdvlgn (63) -> rmpryj, qrtdtt +hfcifm (107) -> tpfuxx, wdivd +cltqhc (25) +gnrnwtz (513) -> efxakc, jxlgwb, ksotbs, gvayfu, wqvtdc +rdufpid (25) +kszmj (137) -> eemfgbx, amvjukd +ykuto (662) -> pvuoltd, kcyiwqs, kbjnzw, kszmj +ckswvj (264) -> cleanrs, ntixh +czhsx (51) +luayjsp (47) -> alhjba, qjghc +djnsvq (295) -> nbnqidn, ijjfn +qxzfv (57) +qyzja (94) +rmpryj (96) +eyreht (45) +vzkii (216) +rwheyic (68) +rjmdre (21) +qntvn (71) +lescv (32) +qomhp (32) +oegwh (70) +tukirqp (85) +pumxr (103) -> wvpwez, kiuiq +fjrpc (89) +gmoliax (1327) -> jniisu, cfafhwl +wsrwgvc (80) +zhgzg (62) -> aonfu, vqiqglo +fxcuah (208) -> uofigyp, kfxyzqc +fnjnhmk (76) +zlshut (62) +hsnbry (26) +pjnyxo (30) +luzjys (115) -> kisjb, owsosl +vecdh (14) +vfrqc (13) +udjcwm (18) +twpmx (30) +oiysq (64) +lcazsyd (78) +ryaotx (399) -> lmctbp, imydd, wlkatbq, sikzsc +rbnfwkf (51) +kdtpg (4260) -> lymwlyg, xgqzb, appays +djvps (30) +vjqjwk (76) +pbrdt (66) +rciilr (33) +heumdl (75) +whqvs (146) -> ttxrd, qxuakjr +zvtxa (77) +cpkkq (18) -> romrjs, xmpdevf, nnofr, qgqou, nmkjx, nbvwta +sxada (7) -> dgrwv, irlfj, rmjpia, ciafn +frbmr (67) -> tnwle, nnyqes +tgksxw (53) -> dkffgot, yvpwz +ijvux (77) +tblhhg (44) +xxsivgz (17) -> kkhfzgn, rbqcbvl +ylxxmlt (83) -> qxzfv, dacbtyf, aqhcy +vndrx (248) -> xecqd, tznkdt +jwezuh (57) -> kxrxtq, cijfsu +ztqvzwj (86) +dluyef (1987) -> zcicmp, qkhhg, eivrwbt, iqzdu, rmvry +ybzvav (873) -> agwyte, kawloxz, bmdxyf +pvuoltd (115) -> glgrdm, gfizf, bnehbkl, lkyeyn +ceefghr (21) -> mksrqb, saqjax, llild, qwvvha +khphs (101) -> qwlepd, acgrw +yxvgj (13) +zifogt (85) +wgwlbz (83) -> uwaij, qklota +xlyvge (235) -> zgnoqml, trqfblp +qaxvec (41) +ylkfgx (6) +pzgvdt (37) +vtzdfjg (77) +tyiekxm (24) +jaiqusy (18) +avhkram (73) +akluijb (77) +bohjocj (73) +ofoto (1287) -> sgrcmj, jxykl +qgqou (227) +xtoaq (18) +peqgox (25) +kobcmy (64) -> haeymgy, egwjjg, zcanxq, zifogt +namzy (79) +vldxkw (463) -> gmwto, aflmt, boplau, khphs, qlthpj, epqsj +chtamif (88) +vqsuh (92) +iofsrh (35) +njgkkxo (17) +zsqqhe (94) +xupdam (64) +bqvzg (73) +hmetm (889) -> aklagd, ceefghr, whcxfwf, guztl +hoheog (296) +llsvd (18) +giupn (30) +dfzfwun (64) +nmfvmam (125) -> qxwlhxh, obwzec +ioumv (86) +gxmry (143) -> cyvplfd, wmcusr +ywgvsdb (131) -> fzfxs, yvdkbo, igaww +pwsye (49) +mywezi (407) -> gimkyms, bnxvusb +fzfxs (28) +kurgrkq (76) +txeucf (61) +gjwflt (84) -> xmfzu, gcbjhu, xxnannn, bwnabqh +vrgxe (1226) -> zbfyg, rocbcw, zouml, wbibf +izwze (16) +jwmbs (96) +euvev (46) +dgzvf (30) +iezdimc (82) +zkhll (992) -> bbqtwv, xupdam +jhxxfq (71) +hemjsj (27) +ryxkvxj (124) -> bhemin, apghde +qxuakjr (54) +aonfu (95) +dvopaww (98) +uobwwa (69) +dojvyuv (96) +ezcmm (886) -> ntjmwf, qfdldyu, vokxlx +yzwnh (15) +jfqanu (302) -> dcgarog, tcpqh +gfizf (14) +kvbdsv (46) +qzsypj (98) +vyffcrm (24) +iuoxs (13) +zitfb (23) -> ctagl, ddpgq +yueoma (46) +bbqtwv (64) +hgsng (45) +wgehfu (77) -> lescv, hnjbsg, bxvwe, evmuxia +arwqmho (66) +amvjukd (17) +ntixh (10) +zfzblty (47) +cxzuprb (592) -> texfyi, dvgstr, irhxzg +ekqux (76) +abxalr (697) -> zjwih, gjwuf, eqviuw +choiui (65) +tgjdwlh (24) +glhsr (60) +rtymngs (66) +rocbcw (169) -> djizg, dtnaqds +bjwws (46) -> evgtp, ztqvzwj +gowbiey (78) +yqhmb (497) -> njgrpbo, tedehrz, bjwws +lapoix (240) -> xkizl, dyhate, disan +vckqsrm (30) +sxdljm (66) +frpmd (13) +uwhwsv (86) +wknic (47) +pnicdos (165) -> czhsx, rbnfwkf +wrsik (80) +wbogdd (66) -> eibtll, ppmvpn +fyrqw (28) -> ekqux, zxoqwjv, ipogzy, dhzuvup +uttjzap (22) +gqjkk (41) +gcbjhu (83) +bnxvusb (21) +bxvwe (32) +difjqqd (47) +xxnannn (83) +lxzucvk (94) +ehynj (98) -> ijvuozb, wutdi +vwkbje (25) +ciafn (62) +pyyuj (34) +zofljd (685) -> hfcifm, emvxet, ahrdgu +zyshq (140) -> dpcmm, eosuf +zgslahq (101) -> ximrxj, auvxopo +xszci (72) +fomxzjj (47) +mcduoz (6) +rcltx (73) -> djnsvq, hqmum, ifstrgw +pemna (98) +fgnsyw (39) +tfppg (77) -> uwhwsv, fmapm +tohlady (84) +gzxuw (86) +mkdiuil (96) +qfhkgt (52) +csxwyly (47) +intuzzk (82) -> jqqxv, dlnyi, pbides, qtcqtv +bfxhl (78) -> qvmorke, pazbvum +eduzave (25) +kwbni (74) -> abxalr, bbsuv, gnrnwtz, rmjktk, eqcnl, pdwesa, sunvhgy +hhnvuv (83) +ismgnve (68) +alhjba (84) +mspkmg (94) +rszjhxn (34) +frleu (60) +mewfm (48) -> gowbiey, yevks +mpulnxr (42) -> eziuhsd, xsewlv, tckcxhb, bfxhl +mzksj (68) +shnqfh (1649) -> wnnov, mdtniv, fwpuy +bxpfop (153) +zucsr (26) +gmpqmio (93) +wzjbp (174) +zcicmp (301) +ppvwkei (93) -> eqjfyj, lghygm, grrycy +tcsoaw (239) -> kzfzp, oypzs +nnsial (78) +mazbb (98) -> dsxhhub, fqoqkzk +lclbeiq (81) -> bwxicc, uttjzap +jddyhz (91) -> vmmww, mvalh +umqrwk (132) -> itvhd, jbuxnpr, mxopf +qxfan (34) +cdafdq (26) +drrjnr (80) +kxrxtq (68) +cnyasj (56) +kpdbki (38) +dgzoyx (72) +zwwbw (155) -> eqbvn, qcghv, tfppg, xaanoft +zsxbg (22) +fwvsi (32) +hefgter (6) -> pirieql, hikocbe +mwelezd (81) +eptcqns (16) +jmbiky (96) +gnozwfo (242) -> vqsuh, cxlfgl +wtkfiw (48) -> owresw, grqjew, okbzzwd +ltqljtw (62) +lymwlyg (72) -> snkox, adhwzp, cvdjts +mgeizij (60) -> sbcuc, rqrfl +zghvta (57) +uqcqc (85) +tozwp (19) +nqjrds (81) +cfufhn (11) +yznhjg (60) -> choiui, yhecio, lprpgxe +qtbhnxr (27) +bwdfws (27) +kiuiq (89) +zjfrc (141) -> zghvta, lkqiqa +ooiyeep (80) +xiawjb (38) +wgzdt (216) -> vfrqc, frpmd +lugkrb (36) +mvalh (69) +cruxrmy (52) +azwmkej (33) +tqbvdu (61) +szvlte (21) +bzbmt (85) +gcczhgd (43) -> eecoekq, kwpnxyh +jxlgwb (24) -> pzahn, yadtxl +gfaamu (8) -> ygzwut, hhnvuv +ntjmwf (211) -> owqdo, umvvwsq +rqhrb (19) +jixggay (28) +gavjzk (91) +mbydswv (69) +unqbwiz (10) -> rixge, lkwapf, phvbwg +veycd (62) +lmctbp (106) -> wqyzjzi, gqjkk +jwpjy (94) -> ywlub, rtymngs +febjzqn (46461) -> mwtojre, iqmqju, dkxebg +yvdkbo (28) +iayzdx (7181) -> fakyd, fjwmd, uzicvdh +uobxonm (118) -> wrsik, wsrwgvc +sehxgj (41) -> wpezjoi, dcnuouj, vrpqev, kjwvqdz, vzkii +eziuhsd (192) +gcichoe (79) +jwzmsv (45) +fmapm (86) +rbtvx (53) +sgkksme (94) +zmces (86) +rmjpia (62) +feiki (376) -> oqady, fcymcb, wlleabp +sgrcmj (54) +dohjma (76) +kgzqclo (71) +eqjfyj (73) +zcjrk (1009) -> zdvlgn, sxada, yznhjg, pnoxhe +zhudrmb (78) -> mvngvtg, kvags +iylwxgn (98) -> edebwk, gjwflt, rlapq +beraoor (10) -> pumxr, gasnep, ulznkvm +gxnoomf (185) -> ihrhkj, cfufhn +fhoprd (71) +pbides (59) +xqgjvz (192) -> twpmx, zwofu +mexuge (52) +rbfbf (47) +oprvyxy (125) -> oyuteie, yibxqhs +eqcnl (637) -> kgjcj, wgzdt, rrgffal +kikfs (40) +ntvul (77) +bwxicc (22) +rttwea (55) -> fnjnhmk, kurgrkq +kfxyzqc (9) +ddmrgzp (69) +clgbo (45) +qoapjhr (173) +kkhfzgn (88) +njgrpbo (74) -> dgzoyx, rlywif +bwcyqb (85) +esrilo (47) +blutjw (717) -> fxcuah, efuqu, jwpjy +owimy (41) +oeeqrsd (62) +akoqk (16) +owqdo (10) +fwpuy (26) -> eqnpvwk, lbhxdbr, lqqkjjr, tlvpv +tzqzk (52) +gxobd (91) +npqroe (36) +pstaxvr (761) -> peretma, kqpvqie, untdpje +boggvxt (56) +uobxcai (10) +vmyda (63912) -> rcltx, ajwxaa, yvqasth +jznrci (51) -> mclgebd, emdsyso +ktgfsm (50) +kweqtf (96) +mtsbrje (66) +rjuhrpu (15) +zgnoqml (85) +qlthpj (57) -> arwqmho, yydyjr +cdudjbj (128) -> iofsrh, nuuwbui, mxplky +estwket (94) +adjlg (67) +jbwbw (114) -> dxbrl, lhdhko, fdjhpq +ezfky (71) +rrdczem (71) -> dgrfhvi, adjlg, ajyqxh +xqrmgdk (6543) -> unqbwiz, cxzuprb, rmkhel +nmkjx (213) -> wycesn, gpfipvk +qklota (16) +jbuxnpr (30) +xtzqooh (27) +vbcfe (49938) -> yuepckc, ybzvav, sxapjc, cfvlt, dluyef +drzrtpi (96) -> nuuqqqy, scqutwb +xkfps (7) +nvxlr (49) +hazbs (31) +ajyqxh (67) +guhyk (66) +ipwxws (190) -> difjqqd, wknic +akngdu (13) +evgtp (86) +eznabc (150) -> dvhbwl, xnuoisk +limjm (52) +bykjeka (71) -> sdied, zfzblty, csxwyly, fomxzjj +gpfipvk (7) +cpreh (86) +qurrva (85) +sikzsc (46) -> dpetvw, pridma +vokxlx (69) -> gadnfmt, nqjrds +scbycx (193) +qjghc (84) +ctpjjsh (964) -> thlbs, wgehfu, fetns +uzicvdh (42) -> altsh, xhhhix, calvq, bykjeka, iucuw +tpefei (109) -> qtznzyx, myznok +sizfqfs (116) -> vsqfx, dmsmgs +qumahjn (71) +ctagl (97) +hewtnrw (28) +ocpzltp (67) +ihnus (40) -> vrgxe, shnqfh, auzded, hkhsc, jwddn, mcxki, lhwyt +iuydxn (253) -> fhoaub, kmnjo +evubadn (49) +wpezjoi (112) -> zpxqtrg, tzqzk +qtznzyx (57) +dcnuouj (76) -> oegwh, ztzfled +ddpgq (97) +ktrkhe (67) +podcsx (71) +univhdj (26) +puxaz (60) +jadome (50) +uplbokf (5475) -> vbxqhoy, cpkkq, iqozz +llild (45) +lylaoh (170) -> lomhz, tzjzmmv, cefbp +owsosl (57) +iqozz (681) -> syykbn, mbmzme, cdudjbj +nvdon (345) -> dgzvf, djvps +iigqfh (327) +ctatrbo (279) -> tyiekxm, rmdhj +yevks (78) +cipxwb (85) +edmljb (134) -> ligev, glhsr +yallk (69) +owtxsq (71) -> zxjeza, pzgvsxu, amwxj +pejmc (151) -> fjvoff, esgqip +pridma (71) +vdpnsak (12) +hlfbt (200) -> univhdj, xnxdmdb +wyuwk (315) -> ibcbvy, ztaff +phvbwg (86) -> yachdf, utncpu, tohlady +nbnqidn (34) +tnyjkok (93) +kwpnxyh (41) +yachdf (84) +ximrxj (42) +appok (73) +rrgffal (78) -> trxgpy, zmjfa +uiyyc (126) -> nspsk, plxdglq +rcxtjte (210) -> drrvse, szvlte +ruild (9) -> zqdezgy, cxpoqyu +mqlsvih (17) +xgqzb (451) -> mgeizij, hefgter, ajtjnwp, ljhezx, pwwqvhw +gmdcbyg (214) -> mexuge, limjm +mxopf (30) +wnnov (170) +qgwcfll (95) +smtbsys (49) +jiyuw (40) +sunvhgy (218) -> fmlhgs, clmyzsu, zvcfznz, xrkca, jznrci +wycesn (7) +sbgwln (66) +dkffgot (50) +ximrdyg (217) -> tpbgp, ibmcytl +mvqfvit (38) +spgcwtn (63) -> yeref, itxaax, ntvul +apmpzd (46) +njkeu (67) -> vecxd, rpcoxd, emqoxss, elusirt, hlfbt, xqgjvz +irlfj (62) +zxoqwjv (76) +vjwlck (28) +ezmjqnt (146) -> wdssrl, gwcig +plzfjy (41) +beeeaye (71) +nqkwmyd (254) +hbiwkt (76) +hspol (20) +ntjawca (63) +yuobv (91) -> vtdpkof, basjwp, pfvpb +lqqkjjr (36) +zzqwzy (48) -> cnbzj, vftqnj, mywezi +goyzt (22) +apghde (44) +ahrdgu (23) -> ismgnve, rwheyic +vqiqglo (95) +ruclz (25) +wuqbe (98) +nedbkp (49) +fpmipcr (40) +gadnfmt (81) +kxrfley (55) +thlbs (59) -> iqsvbk, tbyihc +wqvtdc (126) -> uyjre, dvkrlzc +omfvqhv (29) -> iorlbdv, fwddmmv +lihivo (81) +ligev (60) +iabqb (12) +zwjqar (71) +ddsqd (61) +wwvad (23) -> owzybm, gavjzk, gxobd +plhybj (48) +rgyamx (79) +trxgpy (82) +vzxvex (66) +favzt (69) -> qxfan, pyyuj, lhahl +atrmuc (1081) -> qrsgca, bhthbfj +mqrfbqc (9769) -> vbqtd, ykuto, mgktiii, iylwxgn +ihkcni (66) +ttxrd (54) +dvhbwl (64) +nlhxju (31) +kjwvqdz (140) -> zocaag, gszqlv +gulset (80) +vubst (114) -> giupn, vckqsrm +pvejq (52) +lhahl (34) +rqoczb (310) -> ropzx, xdsbnr +xhhhix (259) +ictdnyf (1551) -> ezfky, ckxblyq +jexvtb (15) +fmlhgs (103) -> ntjawca, jwpwt +fcymcb (17) -> mwelezd, jaoiiae +cepddei (195) -> ppymmsf, mcdmpq, tozwp +suzsw (28) +dlnyi (59) +nzrfhb (198) -> xwpwer, vjwlck +kmnjo (35) +itvhd (30) +tpbgp (11) +syykbn (127) -> teastj, ntazqjk +vhilqk (86) +ctpdk (31) -> yzciq, ljlotlp +putpp (92) -> pbrdt, ihkcni, sxdljm +peydhei (737) -> dojvyuv, nnogow, lwygknn, ndajgou +yzciq (99) +xmfzu (83) +plzgfx (98) +qckem (28) +kuakyv (77) +qpixldb (85) +nnjbjm (23) -> cgwnn, veclzy, rzqffr +nrkdm (200) -> dgtvwiy, qtbhnxr +xwkski (59) +mgktiii (827) -> ggbxd, gjfoe, qoapjhr +elusirt (106) -> appok, avhkram +ttkboa (24) +ckxblyq (71) +disan (18) +owresw (73) +pyuuxw (39) +hwsrjah (176) -> pvejq, cruxrmy, vjwivnq +skbprng (44) +lkyeyn (14) +mdtniv (82) -> eexkce, oiiagw +ljhezx (130) -> jpxogsl, pjnyxo +upsiumf (18) +glgrdm (14) +rvcmif (288) -> jdmjou, ddmrgzp +wvsspk (25) -> lqnwffm, edgplu, qyzja +umljkr (45) +ggbxd (67) -> jikpfbk, siqksje +kuujprz (67) -> ctatrbo, xibdlh, wyuwk, siflauk, iigqfh, jhwltnv +aklagd (201) +lprpgxe (65) +auvxopo (42) +uorika (69) +avbgwvm (81) +nnogow (96) +iybvphk (85) +sxapjc (129) -> peydhei, sehxgj, lgtffok +utrdhz (75) +nbvwta (153) -> bbviexo, pzgvdt +jzgpty (44) +qqzhz (32) -> eyreht, xxswgx +ropzx (8) +xaanoft (42) -> cwgrjoh, uorika, uobwwa +ybnpc (307) -> dibqua, ozfsktz, txrxyqh +cfvlt (753) -> rusayd, feiki, ucsxzhl +ruxuw (43) +ywpjusg (64) -> joxmxc, mzksj +qtcqtv (59) +qwddgc (82) +eyckbl (58) +lgsda (44) -> lcazsyd, mwdfwe, nnsial +tlvpv (36) +rlqwaz (901) -> sizfqfs, ehynj, wzjbp, vubst +fgbnlu (66) +zvmhx (105) -> tcsoaw, rtnpvf, lbkvgme, xtttnfp +oiiagw (44) +jpxogsl (30) +lomhz (78) +calvq (85) -> ccghjn, lpascsz, zkecjv +ljlotlp (99) +jqqxv (59) +iqzdu (187) -> itygd, cdvmqs +ugkey (86) +tjjrys (94) +dtjhnzr (85) +tqeeva (214) -> xwkski, rkjmp +tznkdt (12) +daiah (26) +cwgrjoh (69) +dibqua (24) -> rgyamx, gcichoe +scqutwb (94) +yeifw (71) +dyhate (18) +acgrw (44) +fndpz (18) +pynomi (170) -> kgzqclo, ygvkw +kcyiwqs (35) -> givljl, yntnjp +lbkvgme (223) -> jadome, dtwbpl, ktgfsm +ygvkw (71) +dgsutv (25) +rlywif (72) +nevpm (49) +xtttnfp (73) -> heumdl, axgpyq, utrdhz, paeea +ptmqo (284) +ibmcytl (11) +ejwno (80) +mcdmpq (19) +azvke (170) -> wscktm, jexvtb +govhrck (176) -> vuqriq, crfse, eoditdi +tzjzmmv (78) +dhjrv (48) +dlifqat (49) +ruhqn (94) +mhtzh (86) +bhhgpe (124) -> bywwy, xguqlvl +ucicsdu (199) -> itvizjy, wsnqied +agwyte (498) -> gcczhgd, lclbeiq, rgndu +gapjnb (200) +pitmcu (27) +vtdpkof (44) +joxmxc (68) +mclgebd (89) +refgrip (35) +hsxru (30) -> oeeqrsd, icdlpb, veycd, dlrpnot +jikpfbk (53) +usztpox (160) -> goyzt, eagggd +aqhcy (57) +umhcrc (174) +qwvvha (45) +crxnz (10) +mbmzme (37) -> qajpehv, dlifqat, bponwxc, hjzehyw +uyjre (22) +tsbbzu (22) +tenzzu (67) +ijvuozb (38) +oypzs (67) +ymxlwf (327) -> nzrfhb, wbogdd, fujgzbt, nqkwmyd, vgugdtt +dvgstr (87) -> rqhrb, xtvawvt, receu +yzuygum (57) -> oiysq, jibdphs +vuqriq (238) +lsysd (68) +meayff (35) +guztl (73) -> mrbqk, aoxtau +rtnpvf (177) -> pwsye, nevpm, nvxlr, smtbsys +zbqpk (112) -> apmpzd, yueoma +bbviexo (37) +gimkyms (21) +fjwmd (692) -> luayjsp, njqzaxg, ywgvsdb +igfhu (31) +qkhhg (105) -> yknwap, qqqsv +ybewhak (122) +xkizl (18) +siqksje (53) +vtbzq (178) -> tenzzu, ocpzltp +giblwzi (7) +atjtgjx (59) +bjlwfmo (49) +jibdphs (64) +cxlfgl (92) +wltlu (1495) -> swumt, qeosq, guhyk +lkqiqa (57) +qwlepd (44) +rmvry (145) -> ejzfwt, pknjpc, qfhkgt +xmpdevf (185) -> rjmdre, abcyotz +utwzg (10) +lpascsz (58) +abcyotz (21) +grqjew (73) +vindom (25) +tzmes (28) +ktwby (44) +gfsnsdu (38) +ywlub (66) +iryrfjs (31) +fwfpmti (34) +givljl (68) +edebwk (161) -> dtjhnzr, cipxwb, uqcqc +aziwd (48) +ajtjnwp (46) -> clfrs, qdwkxia +nvlqab (27) +dvwsrc (1517) -> jiyuw, dvtdje +basjwp (44) +rhchuf (67) -> sedysm, nedbkp +cdvmqs (57) +dkdovw (262) -> afglbpz, ovfduq +seeqikh (10944) -> mztuzb, zovbvcr, nnjbjm +bgcrdqu (174) +huqpiix (121) -> eptcqns, aiget +bywwy (74) +aujxmm (89) +xecqd (12) +tbppaj (94) +zkecjv (58) +utncpu (84) +grrycy (73) +htlpx (25) +pvtat (13) +dfdlzzt (71) +uwaij (16) +edgplu (94) +aflmt (153) -> puyiail, jaiqusy +eoditdi (10) -> boqtohm, odsrv, iblrer +imshim (39) +nioeugr (38) +eagggd (22) +ulznkvm (211) -> meayff, oqiye +psrzr (213) -> bwdfws, sdrhiyo +vmmww (69) +blofdav (18) +zbfyg (49) -> xoqxrbl, dgnpr +qzhyumq (25) +dpcmm (69) +qvmorke (57) +exuwhfs (89) -> qumahjn, kkvkz +rdqvi (56) +axlgwj (38) +vbxqhoy (744) -> nquonb, zhudrmb, ryxkvxj +rqlaf (67) +mlrdsj (107) -> tzdtm, etmvojh +tnzqj (1057) -> nbpic, ctgbkrb, bgcrdqu +lghygm (73) +wvjjht (60) +wmvht (36) +xibdlh (255) -> tgjdwlh, vyffcrm, ahridq +pjersb (86) +pdwesa (407) -> ximrdyg, xaebyo, qqpsrts, ucicsdu +tflulu (3299) -> ezcmm, tnzqj, njkeu, ctpjjsh +rmkhel (55) -> olkcm, yquqk, iuydxn +odsrv (76) +kfbsjv (73) -> ylxxmlt, whqvs, edmljb, bpptuqh, jwjggy, nrkdm +vywqra (18) +bnehbkl (14) +lkwapf (290) -> ttkboa, xvcikqe +kawloxz (45) -> rttwea, nmfvmam, kwkprrw, gxnoomf +drrvse (21) +tklfj (465) -> fcapw, omfvqhv, wgwlbz +receu (19) +zqdezgy (72) +ntkeax (91) -> sbgwln, fgbnlu +boqtohm (76) +rpcoxd (252) +hiqqg (82) +cdyhvr (28) +snkox (67) -> mspkmg, lxzucvk, zsqqhe, sgkksme +zpxqtrg (52) +olgsb (93) +hikocbe (92) +xwpwer (28) +kzfzp (67) +dfyyjta (33822) -> hvhjh, ujfeg, iayzdx +hvhjh (6551) -> uveybq, iqbrs, zrnnyet +kjpzwp (160) -> fmvyjwj, lsysd +htyyatf (240) -> fndpz, xtoaq, hhboca, llsvd +uveybq (947) -> ywpjusg, gapjnb, azvke +cqbvru (61) +saqjax (45) +emlqbo (18) +jvayv (171) -> daiah, fyjowg +dtnaqds (33) +rxuwet (92) +xnuoisk (64) +etmvojh (80) +eqnpvwk (36) +puyiail (18) +ijrzzr (77) +jfuxeo (150) -> xgnqi, dfzfwun +pzgvsxu (282) -> cltqhc, ruclz, vindom +tqpgc (1018) -> bbxbrsh, uwxbv, nlhxju, hazbs +nadbbgx (258) -> akoqk, izwze +qdwkxia (72) +rbqcbvl (88) +wutdi (38) +mlrjfy (38) +efxakc (154) -> dfaro, lcsqgx +dacbtyf (57) +mevea (303) -> qaxvec, esiwujq, plzfjy +dsxhhub (12) +wjzyxt (252) +pnoxhe (27) -> vjqjwk, enpprra, ftmwqqj +kkvkz (71) +clfrs (72) +zovbvcr (383) -> diyvlug, xhodnx, repak, zjfrc +jwjggy (210) -> duvrzrl, zsxbg +xjfkrjs (33) -> ibzalz, rxuwet +gtvnow (180) -> euvev, kvbdsv +etfuhz (123) -> zoicqbj, ajvtdl, wmvht +afglbpz (16) +nquonb (50) -> avbgwvm, lihivo +nbpic (148) -> iuoxs, yxvgj +eivrwbt (17) -> yeifw, podcsx, fhoprd, beeeaye +gszqlv (38) +yhycc (121) -> vwkbje, qzhyumq +gjzddf (38) +cxpoqyu (72) +emdsyso (89) +qqpsrts (85) -> doudbv, mmzdk +gjwuf (124) -> bjlwfmo, evubadn +hkhsc (171) -> ipwxws, yrdgv, ckswvj, yjlrwzu, ptmqo, ojishwt, drzrtpi +mwtojre (207) -> hmetm, utbev, wltlu, ictdnyf +fqoqkzk (12) +nkhzrd (5) +enpprra (76) +gwcig (75) +uqcpah (91) +koued (75) -> kxrfley, tjnyo +dtxrjg (22) +pnkag (93) -> ofoto, zzqwzy, zobjfxe, blutjw, aisfhs, gmoliax +iucuw (99) -> gulset, drrjnr +fhsecp (17) +dgrwv (62) +ibzalz (92) +tbyihc (73) +cleanrs (10) +cibfe (27) +ycvvjgc (28) +dnphyfm (7185) -> mpulnxr, sxegjbz, tklfj +xnxdmdb (26) +jniisu (34) +eaqiocy (93) -> dywjt, kikfs, fpmipcr +bugtxto (26) +pprkvq (26) +myznok (57) +iblrer (76) +bhmzx (64) -> tgoeoh, ojxyv +yibxqhs (52) +xoqxrbl (93) +hoeqoas (99) +oxvfpna (222) +okbzzwd (73) +yhecio (65) +esgqip (62) +zwofu (30) +nnyqes (49) +yydyjr (66) +ztzfled (70) +yvqasth (1018) -> lfksu, xszci +eqbvn (153) -> plhybj, kozgi +hqmum (79) -> dfdlzzt, ulndqey, zwjqar, jhxxfq +gvayfu (64) -> cfvbuip, rbtvx +fsagr (141) -> lugkrb, npqroe +pfvpb (44) +cvdjts (271) -> zmces, ugkey +bcjpzpk (174) +jxykl (54) +mwdfwe (78) +diyvlug (133) -> ddsqd, txeucf +wbeizj (35) +xxswgx (45) +wfdxfxq (676) -> irrpz, wvsspk, dqtthnn +lcsqgx (8) +lmvmb (93) +cyvplfd (14) +olkcm (131) -> mkdiuil, msbsjpj +kloumi (39) +xzwjii (63) +zmjfa (82) +fakyd (842) -> sgtfap, frbmr, rhchuf +jgzvrf (173) -> hspol, vbpde +slfile (66) +jwpwt (63) +xhodnx (67) -> estwket, tjjrys +ihrhkj (11) +wlkatbq (188) +cijfsu (68) +ipqjff (62) +ztaff (6) +eecoekq (41) +oaxskk (266) -> azwmkej, rciilr +sedysm (49) +jhwltnv (19) -> akluijb, zvtxa, pvpmt, bkqexxz +xhqgsro (6) +bmdxyf (318) -> zgslahq, koued, yzuygum +dmyzfr (18) +rqrfl (65) +clmyzsu (115) -> mlrjfy, xiawjb, kroqr +rusayd (901) -> ylkfgx, lxsurts +tzdtm (80) +dpetvw (71) +eccwi (6) +wdssrl (75) +uofigyp (9) +aisfhs (183) -> lylaoh, fujwzoc, kobcmy +dcgarog (15) +eosuf (69) +qeosq (66) +itxaax (77) +mmzdk (77) +dvtdje (40) +aumbaa (28) +wdivd (26) +eemfgbx (17) +dlrpnot (62) +ugxls (62) +qqqsv (98) +lfhaqdn (27) +qblnh (45) +yknwap (98) +ipogzy (76) +irhxzg (124) -> utwzg, crxnz +dtwbpl (50) +lqnwffm (94) +ygnww (13) +xrkca (217) -> xhqgsro, avymjz +qrsgca (35) +ftgvx (14) +fhoaub (35) +nuuqqqy (94) +ppmvpn (94) +kisjb (57) +owzybm (91) +jwddn (134) -> vfosh, nvdon, kopmae, inhqoxd, xlyvge +cnbzj (141) -> kuakyv, vnsrv, ijrzzr, dbrnqc +wlleabp (179) +lhdhko (66) +bbsuv (439) -> ionnpk, etfuhz, mobbhp, exuwhfs +umvvwsq (10) +eibtll (94) +otuwt (35) -> ejwno, zogylog, ooiyeep +epqsj (137) -> bugtxto, hsnbry +yuepckc (66) -> tqpgc, pstaxvr, owtxsq +dhzuvup (76) +crfse (238) +ibcbvy (6) +cefbp (78) +uhxjy (63) +bponwxc (49) +mcxki (29) -> rvcmif, gnozwfo, mevea, vtvku, dmtzxui +emqoxss (66) -> tnyjkok, gmpqmio +ionnpk (97) -> rqlaf, ktrkhe +gasnep (91) -> qgwcfll, nkcet +avymjz (6) +fetns (37) -> zfmeblt, jtsyj, rdqvi +altsh (89) -> zdvai, iybvphk +kgjcj (242) +bltmlm (93) -> xdlvys, tflulu, xqrmgdk, dnphyfm, kwbni, uplbokf, vbsfwqh +hikik (15) +nnofr (71) -> xxrsnzv, pucsbv, rtzce, kloumi +siflauk (271) -> qckem, tzmes +nkcet (95) +ijjfn (34) +itvizjy (20) +numadl (98) +jkjsi (98) +xaebyo (41) -> svadhfo, hoeqoas +yntnjp (68) +axgpyq (75) +civozek (98) +djizg (33) +qrtdtt (96) +kopmae (13) -> pemna, vuzsg, numadl, wuqbe +yztqpc (572) -> xxsivgz, scbycx, jwezuh +msbsjpj (96) +yjlrwzu (77) -> mbydswv, tfzum, kwhwph +tcpqh (15) +fkqkfdu (25) +vbqtd (86) -> cepddei, rcxtjte, zkibug, wjzyxt, zhgzg +wmcusr (14) +zrnnyet (731) -> zbqpk, tayyz, usztpox, mewfm +yadtxl (73) +eqctwan (511) -> zitfb, xjfkrjs, xddom +evmuxia (32) +lbhxdbr (36) +fjvoff (62) +wsnqied (20) +vftqnj (57) -> dvopaww, hbvvse, plzgfx, jkjsi +pwwqvhw (34) -> fgnsyw, pyuuxw, nsbvvsi, imshim +hnjbsg (32) +pglpu (224) -> oxvfpna, umqrwk, bhmzx +etcces (4977) -> eqctwan, jncex, zofljd +fmvyjwj (68) +lgtffok (509) -> ruild, bxpfop, huqpiix, tgksxw +iqmqju (3619) -> oxnfnsv, bngres, zkhll +xvcikqe (24) +wvpwez (89) +saijc (96) +aiget (16) +fdjhpq (66) +adcbil (47) +lrnjjfq (17) +teastj (53) +csybv (33546) -> kdtpg, wseyo, etcces, pnkag +zkibug (238) -> xkfps, giblwzi +pzahn (73) +auzded (499) -> tqeeva, fyrqw, oaxskk, hwsrjah, jfqanu +bhthbfj (35) +dvkrlzc (22) +dgrfhvi (67) +qcghv (67) -> ezkqh, uqcpah +sdrhiyo (27) +kwhwph (69) +ejzfwt (52) +vuzsg (98) +tgoeoh (79) +vrpqev (64) -> axlgwj, gfsnsdu, kpdbki, mvqfvit +vrydu (43) +vnsrv (77) +gjfoe (161) -> mcduoz, eccwi +ppgaoz (65) -> pejmc, cbwbdsv, otuwt +xddom (39) -> aujxmm, fjrpc +lxsurts (6) +tayyz (50) -> vtzdfjg, ijvux +kwzrzn (71) +doudbv (77) +ahridq (24) +dqtthnn (217) -> hgsng, jwzmsv +haeymgy (85) +zoicqbj (36) +bcjxhps (58) +swumt (66) +iywwyn (43) +pirieql (92) +ntazqjk (53) +ajwxaa (208) -> wtvffu, gmdcbyg, intuzzk +wscktm (15) +itygd (57) +hjzehyw (49) +jdmjou (69) +iavuhwe (49) +tpfuxx (26) +wseyo (5904) -> beraoor, zbhwrc, ybnpc +rlapq (322) -> adcbil, rbfbf +jtsyj (56) +zouml (199) -> dmyzfr, udjcwm +txrxyqh (107) -> rdufpid, yhunajf, dgsutv +zobjfxe (525) -> ylbpwah, nadbbgx, putpp +inhqoxd (327) -> cdafdq, zucsr, pprkvq +ndajgou (96) +paeea (75) +yrdgv (284) +sbcuc (65) +aklrjg (10) +kbjnzw (117) -> xtzqooh, lfhaqdn +cfafhwl (34) +htyeqf (94) +dmiqf (62) +tghoyv (210) -> iywwyn, gypsfc +plxdglq (24) +qxwlhxh (41) +pknjpc (52) +njqzaxg (23) -> saijc, jmbiky +tckcxhb (68) -> yfzjc, nwjibjk, igfhu, iryrfjs +xdlvys (3528) -> zcjrk, wkrtcw, kuujprz +dcngdo (47) +pazbvum (57) +kvags (67) +nuuwbui (35) +whcxfwf (115) -> vrydu, ruxuw +ojishwt (126) -> llcbiqi, namzy +uwxbv (31) +vrqeade (102) -> emlqbo, vywqra, upsiumf, blofdav +rixge (338) +dmtzxui (98) -> auhio, qwddgc, hiqqg, iezdimc +texfyi (144) +cgwnn (384) -> nioeugr, gjzddf +mwzaxaj (59) -> csybv, febjzqn, bltmlm, dfyyjta, ljaktj, vmyda, vbcfe +yquqk (83) -> wvjjht, edyqn, frleu, puxaz +jaoiiae (81) +pucsbv (39) diff --git a/07/lib.scm b/07/lib.scm new file mode 100644 index 0000000..52847a0 --- /dev/null +++ b/07/lib.scm @@ -0,0 +1,192 @@ +(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)))) + + ; Remove the first character from `str' + (define (string-strip-first str) + (substring str 1 (string-length str))) + + ; Remove the last character from `str' + (define (string-strip-last str) + (substring str 0 (- (string-length str) 1))) + + ; Strip the parenthesis on each side and parse the number + (define (parse-weight str) + (string->number (string-strip-first (string-strip-last str)))) + + ; Parse the current node's optional children into a list of names + (define (parse-children words) + (let loop ((input words) + (output '())) + (cond + ; If there are no children, or we've exhausted the input list + ((= (length input) 0) + output) + ; If this is is the last child, we can read its name directly + ((= (length input) 1) + (loop (cdr input) (cons (car input) output))) + ; The input contains multiple words, possibly including "->" + (else + (if (string=? "->" (car input)) + ; Ignore the first "->" + (loop (cdr input) output) + ; This isn't the last child, so must strip comma from name + (loop + (cdr input) + (cons (string-strip-last (car input)) output))))))) + + ; Record type representing a single tree node. Implicitly defines + ; `make-tree-node', `tree-node-children', and `tree-node-weight'. + (define-record-type tree-node + (fields + (immutable weight) + (immutable children))) + + ; Parse each line of the input into a `(name . tree-node)' pair + (define (parse lines) + (let loop ((input lines) + (output '())) + (if (null? input) + output + (let ((words (string-split (car input)))) + (let ((name (car words)) + (weight (parse-weight (cadr words))) + (children (parse-children (cddr words)))) + (loop + (cdr input) + (cons + (cons name (make-tree-node weight children)) + output))))))) + + ; Given a node name, find its parent according to `tree' + (define (find-parent name tree) + (let loop ((candidates tree)) + (if (null? candidates) + #f + (if (find + (lambda (child-name) (string=? name child-name)) + (tree-node-children (cdar candidates))) + (caar candidates) + (loop (cdr candidates)))))) + + ; Find the root node name of the tree stored in `tree' + (define (find-root tree) + (let loop ((name (caar tree))) + (let ((parent-name (find-parent name tree))) + (if (not parent-name) + name + (loop parent-name))))) + + ; Return the `(name . weight)' pair for the `name' + ; that has the lowest `weight' in `child-weights'. + (define (find-lightest child-weights) + (define target-weight (apply min (map cdr child-weights))) + (find (lambda (cw) (= (cdr cw) target-weight)) child-weights)) + + ; Return the `(name . weight)' pair for the `name' + ; that has the highest `weight' in `child-weights'. + (define (find-heaviest child-weights) + (define target-weight (apply max (map cdr child-weights))) + (find (lambda (cw) (= (cdr cw) target-weight)) child-weights)) + + ; Count how many times `needle' occurs in `haystack' + (define (count needle haystack) + (length (filter (lambda (h) (equal? h needle)) haystack))) + + ; For `child-weights', i.e. a list of `(name . total-weight)' pairs + ; for several nodes with a common parent, we find the "bad" child + ; whose `total-weight' differs from the others. If there are only + ; two children, this can't be decided; then `known-error' tells us + ; whether the "bad" child is lighter or heavier than a "good" one. + ; `known-error' is the bad-good weight difference, calculated by + ; the caller at a time when there were more than two children. + (define (odd-one-out child-weights known-error) + (let ((lightest (find-lightest child-weights)) + (heaviest (find-heaviest child-weights))) + (if (equal? lightest heaviest) + ; If all children have the same weight, the parent must be bad + #f + (if known-error + ; If we already know that the bad node is too light, + ; always pick the lightest child, and vice versa. + (if (< known-error 0) + lightest + heaviest) + ; If we don't know yet whether the bad node is too light or heavy, + ; pray that `(length child-weights)' > 2 and pick the rarest weight. + (if (< (count (cdr lightest) (map cdr child-weights)) + (count (cdr heaviest) (map cdr child-weights))) + lightest + heaviest))))) + + ; Add up the weight of `name' and all of its descendants + (define (subtree-weight name tree) + (define node (cdr (assoc name tree))) + (let loop ((children (tree-node-children node)) + (total (tree-node-weight node))) + (if (null? children) + total + (loop + (cdr children) + (+ total (subtree-weight (car children) tree)))))) + + ; Given `name', create a list of `(child-name . total-weight)' pairs + (define (filter-child-weights name tree) + (map + (lambda (child-name) + (cons child-name (subtree-weight child-name tree))) + (tree-node-children (cdr (assoc name tree))))) + + (define (solve-part1 lines) + (define tree (parse lines)) + (find-root tree)) + + (define (solve-part2 lines) + (define tree (parse lines)) + (define root (find-root tree)) + ; Traverse the tree until we find the "bad" node with the wrong weight + (let loop ((subtree-root root) + (weight-error #f)) + ; Figure out which branch of `subtree-root' contains the bad node + (let* ((child-weights (filter-child-weights subtree-root tree)) + (wrong-subtree (odd-one-out child-weights weight-error)) + (right-subtree (car (remove wrong-subtree child-weights)))) + (if (not wrong-subtree) + ; If we can't find the bad branch, `subtree-root' itself is bad + (- (tree-node-weight (cdr (assoc subtree-root tree))) weight-error) + ; Recurse into the bad branch (N.B. `weight-error' doesn't change) + (loop + (car wrong-subtree) + (- (cdr wrong-subtree) (cdr right-subtree))))))) + +) diff --git a/07/main.scm b/07/main.scm new file mode 100644 index 0000000..d639aed --- /dev/null +++ b/07/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 "mwzaxaj" for me +(printf "Part 1 solution: ~a\n" (solve-part1 input)) + +; Part 2 gives 1219 for me +(printf "Part 2 solution: ~a\n" (solve-part2 input)) diff --git a/07/test.scm b/07/test.scm new file mode 100644 index 0000000..ed299f8 --- /dev/null +++ b/07/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 (equal? 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)))) + +(define input '("pbga (66)" + "xhth (57)" + "ebii (61)" + "havc (66)" + "ktlj (57)" + "fwft (72) -> ktlj, cntj, xhth" + "qoyq (66)" + "padx (45) -> pbga, havc, qoyq" + "tknk (41) -> ugml, padx, fwft" + "jptl (61)" + "ugml (68) -> gyxo, ebii, jptl" + "gyxo (61)" + "cntj (57)")) + +(printf "Part 1 tests:\n") + +(define (test-part1 name input expected) + (run-test name solve-part1 input expected)) + +(test-part1 "part 1 example 1" + input "tknk") + +(printf "Part 2 tests:\n") + +(define (test-part2 name input expected) + (run-test name solve-part2 input expected)) + +(test-part2 "part 2 example 1" + input 60) diff --git a/08/input.txt b/08/input.txt new file mode 100644 index 0000000..767fcba --- /dev/null +++ b/08/input.txt @@ -0,0 +1,1000 @@ +n dec 271 if az < 3 +f inc -978 if nm <= 9 +g inc -336 if ga < 2 +egk dec 437 if y < 5 +z dec -550 if g == -336 +mx dec 12 if bqr == 0 +mx dec 433 if ns == 0 +ic inc 506 if g <= -327 +ga dec -560 if ic != 506 +bqr dec 570 if az >= -9 +g dec 372 if egk != -429 +f dec -863 if b >= -9 +gyc inc 844 if av >= 7 +cr inc -781 if mx >= -453 +ga dec 346 if cr == -781 +b inc -162 if z < 554 +nno inc 504 if g <= -700 +mx dec -32 if vkg <= 6 +mx dec -961 if nno < 509 +az dec 320 if ic < 510 +nm dec 594 if ga != -354 +cr inc -784 if az <= -311 +bqr inc -321 if mx > 547 +y inc -951 if egk > -438 +y inc 703 if y <= -950 +vkg inc -852 if g > -716 +n dec -596 if az < -316 +n dec 410 if e <= 4 +f inc -693 if ic <= 510 +egk dec 498 if zqo != 7 +rn inc 626 if u == 0 +bqr dec -770 if bqr > -898 +n dec 193 if ic == 506 +egk inc -263 if e == 0 +cr dec -473 if mx <= 554 +vkg inc 667 if e != 10 +ga dec 793 if v <= 5 +f dec -673 if v != 0 +g inc 797 if g >= -708 +n inc 361 if v == 0 +y inc 399 if zqo == 0 +av dec -894 if zqo == 0 +az dec 785 if z <= 559 +y inc -121 if nm < -593 +v inc 873 if vkg > -189 +ns inc -205 if n >= 80 +cr dec 452 if ns != -202 +nm dec -35 if f < -799 +ic inc 790 if zqo > 3 +gyc dec 456 if nm <= -565 +rn inc 198 if y != 32 +y dec -917 if f == -806 +e dec -694 if zqo != 7 +nno inc 676 if rn < 825 +u inc 414 if ns >= -213 +f dec -405 if bqr <= -113 +g dec 456 if ga > -1145 +by inc 613 if nno != 1185 +n dec 414 if ga >= -1131 +ga dec 844 if u <= 418 +av dec -404 if ga >= -1974 +g dec -171 if ns > -208 +av dec -302 if f == -403 +ic inc -935 if y >= 30 +u inc -807 if bqr > -126 +az inc -536 if v >= 865 +vkg dec -77 if vkg == -185 +n dec 209 if n == 83 +u inc -92 if y >= 26 +ic dec 43 if u != -491 +ic inc 701 if z == 550 +bqr inc -473 if e != 699 +av dec -44 if egk != -1198 +e dec 134 if ga == -1974 +v dec 479 if mx <= 544 +n inc -748 if y >= 21 +bqr inc 726 if u >= -492 +z dec -368 if ns == -205 +y inc -296 if e >= 694 +f inc 271 if nno >= 1177 +y dec -881 if cr < -1535 +nno inc -493 if az > -1649 +z dec -434 if v != 882 +bqr inc 783 if e <= 694 +gyc inc 930 if gyc != -1 +nm dec -712 if e < 696 +mx inc -342 if nno > 685 +av inc -292 if gyc > 927 +rn inc -269 if rn <= 831 +vkg dec -799 if nno == 687 +v inc 31 if vkg < 694 +egk dec -227 if v != 913 +ga inc -248 if u == -485 +ga dec -655 if ic >= 228 +nm inc 335 if by != 613 +av inc 251 if u >= -477 +bqr inc 834 if ns >= -209 +gyc dec -580 if rn > 549 +u dec 390 if e < 701 +cr inc -936 if b > -170 +nm dec -60 if g < -188 +ic inc -226 if by < 615 +y dec -698 if zqo != 0 +vkg inc -938 if av == 904 +vkg inc -131 if zqo == 0 +y inc -792 if zqo < -3 +gyc dec -43 if ns < -211 +ga dec 783 if az <= -1637 +az inc -359 if cr <= -2479 +e inc -117 if v != 908 +rn inc 231 if av < 898 +nno inc -594 if z != 1354 +egk inc -119 if b >= -170 +mx dec 866 if mx != 214 +g inc -688 if mx < -655 +ga inc 451 if z <= 1352 +bqr inc 315 if g != -876 +vkg dec -636 if egk != -1090 +bqr inc -395 if by < 610 +mx inc 914 if ga < -1908 +by dec -623 if egk > -1090 +ns dec 219 if vkg >= -380 +egk dec -976 if av >= 896 +egk dec -681 if ic != -1 +vkg inc 971 if nno < 101 +nno dec 490 if bqr > 2060 +u inc 479 if z <= 1358 +z dec -552 if nno < -389 +y inc 696 if nno <= -405 +nm dec 876 if nno >= -399 +f dec 197 if nm > -670 +f inc 584 if e <= 575 +av dec -548 if y <= 616 +cr dec -975 if mx >= -664 +vkg dec -532 if egk > 567 +cr inc 115 if zqo <= 2 +e inc 315 if nm <= -663 +e inc -850 if ns > -430 +vkg inc -72 if z < 1906 +b inc 7 if y != 618 +cr dec -270 if by < 613 +v inc 505 if ns > -430 +ga dec 51 if nm != -670 +z dec -657 if zqo <= 1 +u inc -777 if nm == -663 +y dec -37 if nno < -396 +gyc inc 62 if f < -322 +z inc -565 if az > -1996 +e dec -223 if vkg <= 516 +nno inc 481 if e == 34 +rn inc 316 if nno >= -406 +e dec 531 if ns <= -423 +vkg inc -940 if v >= 1408 +by inc 935 if b <= -152 +rn inc 254 if ns < -416 +gyc dec 822 if zqo > -6 +n inc 334 if b < -155 +by inc 987 if nno == -397 +gyc dec -701 if ic >= -6 +nno inc -764 if z <= 2568 +nno inc -541 if mx == -660 +ns dec -327 if ns != -424 +z inc -328 if bqr == 2064 +cr inc 550 if cr != -1385 +ga dec -441 if rn <= 1123 +gyc inc -461 if zqo == 0 +egk dec 554 if ic < -6 +av inc 300 if zqo == 0 +nno dec 324 if av <= 1754 +y dec 235 if b > -165 +rn inc -1 if v < 1415 +b dec 230 if y > 413 +mx inc -836 if b <= -384 +av dec 464 if zqo != -7 +rn inc 208 if egk >= 563 +e dec 385 if v >= 1413 +g dec -443 if z < 2240 +v dec 296 if nno < -2027 +nm dec 394 if az != -1992 +u dec 609 if nno == -2026 +nno dec -178 if ns > -428 +f dec -340 if z >= 2231 +e dec 124 if u > -1783 +bqr dec -221 if bqr == 2064 +rn dec -427 if by != 2539 +n dec -242 if cr == -840 +az dec 267 if y < 418 +by inc 737 if cr <= -833 +rn inc -938 if ic >= 1 +az inc 181 if zqo >= -6 +f inc -874 if z >= 2233 +cr inc -867 if vkg <= -414 +mx inc 424 if ic >= -6 +f inc -125 if g <= -435 +az inc 30 if n < -625 +av inc -575 if y < 418 +ga dec -726 if ns <= -418 +u dec 1000 if b >= -393 +ns inc -88 if av < 720 +ns inc -80 if f < -983 +z dec 73 if e != -613 +bqr dec 350 if nm > -1065 +az inc 247 if gyc > 980 +v dec -156 if g != -435 +mx inc 32 if f > -996 +b dec 349 if mx < -1032 +mx dec -934 if nm != -1067 +ga inc -502 if egk < 573 +gyc inc -106 if nm == -1057 +ga inc 669 if mx != -102 +nno dec -335 if g >= -438 +g dec -757 if v != 1566 +cr dec -887 if z == 2233 +rn dec -768 if by < 3280 +bqr dec -289 if gyc < 890 +u inc 817 if by > 3265 +nm dec -136 if by <= 3270 +b dec 192 if y == 417 +f inc -787 if b <= -929 +f dec 188 if f == -988 +cr inc -488 if nno != -1846 +nno inc -116 if az > -1807 +cr inc 899 if by < 3278 +nno dec -454 if b >= -928 +f dec 237 if cr != -409 +e inc -910 if b != -926 +zqo dec -710 if egk > 564 +v dec 651 if cr != -407 +z inc 45 if ic < 10 +rn inc -16 if n > -633 +u dec -433 if n != -636 +z inc -55 if vkg >= -425 +y inc 536 if v <= 916 +nm dec 269 if cr == -409 +vkg inc -811 if gyc > 875 +y inc -269 if rn <= 1576 +rn inc -445 if av >= 709 +av inc -131 if ic != 1 +egk dec -35 if y <= 687 +mx dec -947 if nm == -1326 +bqr inc -296 if nno >= -1399 +vkg inc -176 if az == -1809 +z inc -7 if ga <= -1058 +v dec -105 if v != 908 +by dec -935 if g > 315 +y dec -674 if rn <= 1132 +ga dec -482 if v <= 1026 +nm dec 500 if f >= -1176 +by dec 653 if f < -1177 +cr dec 156 if mx == 841 +ns inc 446 if u > -1535 +e inc 256 if mx < 840 +av dec -883 if nm == -1826 +gyc inc 204 if by < 4198 +g dec 158 if av > 1456 +z dec -314 if av <= 1466 +egk inc -367 if cr > -568 +by dec -847 if f <= -1171 +f dec -361 if z < 2532 +z dec 647 if ns == -146 +z inc -416 if z <= 1892 +e dec 138 if cr <= -571 +ic inc -393 if gyc < 891 +zqo dec 338 if e < -605 +zqo dec -644 if ic == -390 +ns inc -790 if b != -917 +az dec 136 if av == 1465 +nm inc 971 if gyc != 884 +av inc 171 if ic != -390 +u inc -715 if zqo <= 1024 +av inc 27 if zqo != 1021 +n inc 845 if zqo < 1023 +cr inc -576 if v == 1019 +y inc 456 if ga >= -583 +mx dec 843 if f > -823 +v dec -589 if ns != -926 +e dec -797 if nno > -1395 +g dec 828 if bqr >= 1925 +vkg inc 176 if az > -1949 +nno inc 261 if zqo < 1017 +f inc -429 if b == -926 +f dec 658 if mx == -2 +e dec -221 if gyc < 890 +y dec 362 if v < 1605 +rn inc 849 if v != 1610 +b inc -650 if y <= 1363 +ic inc 39 if g != -668 +by dec -365 if u > -2248 +nm dec 779 if u == -2247 +nm inc -482 if cr <= -1137 +ns dec -873 if nm == -3087 +e dec -993 if rn <= 1979 +vkg dec 291 if n <= 220 +nno inc 937 if nno > -1139 +bqr inc -321 if b <= -1570 +av inc 86 if v < 1612 +by inc 872 if gyc > 878 +egk inc 858 if bqr > 1603 +e inc -199 if ns <= -62 +az dec 600 if v >= 1615 +nno inc -115 if g < -660 +ga inc 614 if f > -1910 +g inc 950 if zqo > 1009 +f dec -319 if cr == -1141 +gyc dec 498 if nm <= -3078 +u inc 61 if z != 1464 +av inc 127 if zqo > 1012 +ic inc -78 if f < -1573 +b dec -601 if nm <= -3082 +av inc -475 if gyc < 396 +av dec 613 if gyc < 383 +vkg inc 425 if rn <= 1981 +nno inc 543 if az >= -1946 +rn dec 280 if vkg >= -1096 +ns dec -366 if gyc <= 388 +v dec -558 if egk == 1093 +vkg inc -446 if ns <= 301 +y dec 617 if b <= -970 +n dec -890 if az != -1947 +vkg dec -102 if nm != -3092 +e inc -668 if ga < 33 +zqo inc -305 if e >= 529 +vkg inc -97 if vkg != -997 +rn inc 188 if nm < -3087 +cr dec 613 if rn < 1700 +v dec 647 if g < 284 +az dec -205 if e == 531 +av inc -359 if vkg == -1091 +y dec 252 if ns >= 301 +n inc 251 if f != -1593 +mx inc 438 if gyc < 385 +by dec -984 if nm != -3087 +mx dec 354 if ic < -425 +by dec 395 if ns > 298 +egk inc 119 if b == -966 +gyc inc -887 if vkg == -1091 +rn inc 898 if ga != 30 +mx dec 35 if y >= 485 +e inc 889 if ns != 300 +ga dec 992 if b > -968 +g dec 432 if cr > -1755 +nno dec -669 if gyc > -504 +bqr inc -442 if rn == 1697 +u inc -44 if b > -976 +u inc 5 if gyc <= -497 +gyc inc 36 if ns <= 304 +nm inc -528 if b >= -973 +y inc -617 if mx <= -400 +g dec 47 if e >= 1418 +b inc 292 if egk != 1083 +vkg inc 734 if ga <= 30 +n inc -678 if b != -691 +ic dec 581 if vkg >= -365 +u dec 562 if b == -683 +nno dec 751 if cr > -1757 +egk inc 709 if gyc != -461 +n inc -347 if rn == 1697 +gyc inc 960 if cr <= -1751 +z dec 627 if ns < 310 +gyc dec -190 if z < 842 +v inc 868 if mx == -398 +n inc -280 if b != -683 +n inc -302 if e == 1420 +av dec -389 if g != -209 +nm inc 241 if ic == -1018 +n inc -493 if nno <= 157 +f dec -932 if n == -466 +u inc -880 if y >= 480 +y dec -697 if egk < 1807 +az dec 332 if nno != 149 +g dec 971 if z <= 848 +by inc -510 if z >= 849 +u inc 103 if bqr < 1161 +av inc -830 if gyc > 678 +rn inc 110 if ns < 306 +b dec 616 if ga < 40 +egk inc -749 if y <= 1176 +z inc 669 if ns != 301 +n dec 365 if nno >= 152 +ns inc -464 if egk > 1801 +e inc -516 if by > 5894 +bqr inc 934 if g < -1165 +nno inc 224 if cr < -1744 +f inc -480 if n >= -456 +gyc inc 101 if g > -1168 +cr inc 501 if e == 905 +z dec -836 if f < -643 +ic dec 750 if rn != 1808 +u dec -318 if gyc <= 687 +ga inc -631 if av >= 430 +nno inc -261 if ga > -606 +b dec 723 if by >= 5889 +ns inc -109 if bqr != 2095 +cr dec 731 if e >= 903 +nno dec -251 if b >= -2024 +mx dec -206 if rn > 1810 +ns dec 249 if rn > 1799 +u inc 201 if egk < 1809 +vkg dec 283 if z > 2338 +rn dec -759 if u >= -3141 +f dec 540 if y != 1186 +by dec -523 if z == 2345 +by inc -894 if ga > -608 +rn inc -418 if cr >= -2489 +bqr inc -837 if nno > 361 +cr inc -485 if zqo == 711 +y dec -672 if nno == 364 +g inc 159 if nm == -3087 +vkg inc 873 if az >= -2074 +b inc 83 if z != 2347 +gyc inc 321 if e < 904 +e dec 283 if gyc < 689 +f dec 257 if b >= -1948 +by inc -526 if az < -2063 +cr dec 119 if b == -1939 +e inc -534 if g <= -1016 +bqr dec 923 if av == 430 +gyc dec 513 if bqr > 334 +u inc -756 if z > 2339 +nm dec 343 if gyc >= 165 +bqr inc -114 if ga <= -601 +gyc inc 355 if cr >= -3091 +gyc dec -458 if mx >= -398 +by dec 24 if v != 1519 +cr inc -155 if v <= 1526 +v dec 512 if av >= 427 +f dec 297 if f > -911 +nno dec 783 if ns <= -524 +az inc 985 if ga > -592 +cr inc 300 if egk >= 1800 +vkg dec 542 if mx == -391 +zqo dec -844 if bqr == 218 +av inc 860 if gyc == 985 +nno dec -253 if nno != 366 +v dec 542 if b >= -1941 +z dec -76 if ns > -526 +y inc -336 if az == -2073 +nm inc 995 if egk > 1793 +f inc -95 if e < 622 +zqo inc -46 if rn > 1379 +b dec 470 if av <= 1299 +gyc inc 839 if f >= -1304 +bqr inc -766 if bqr < 227 +n inc 980 if v < 460 +bqr dec -757 if ns >= -528 +g dec -507 if f > -1308 +mx inc 249 if ns > -522 +av dec 524 if g < -507 +e dec -962 if rn > 1397 +ns inc 139 if zqo < 666 +av inc -443 if zqo <= 656 +z dec -753 if rn != 1391 +g inc 616 if v <= 474 +ga dec 196 if nno < 618 +av dec -317 if gyc > 1826 +f dec -673 if cr < -2939 +b inc -670 if zqo > 670 +cr inc -948 if ga <= -795 +av dec -977 if zqo == 665 +f dec 521 if ic != -1764 +ga inc 342 if nno != 618 +av dec -989 if gyc >= 1823 +rn inc -118 if mx < -137 +ic inc 874 if nm < -2429 +cr dec 441 if by > 4996 +az dec 920 if cr == -4333 +by inc 486 if z >= 3168 +zqo dec -614 if u <= -3897 +zqo inc -359 if g > 105 +cr inc 725 if av <= 3257 +nm dec 816 if mx >= -133 +f inc -174 if az < -2996 +n dec -832 if egk <= 1803 +z dec -351 if av > 3257 +rn inc 814 if egk == 1802 +rn dec 516 if bqr > 206 +ic inc -181 if ns >= -383 +cr dec 476 if av < 3261 +rn dec -446 if mx > -141 +rn dec 966 if bqr > 213 +u dec 426 if b != -2408 +ic inc 841 if ic >= -1071 +u inc -990 if n < 371 +gyc inc -436 if az != -2991 +egk inc 673 if by == 5485 +g dec -510 if egk >= 2474 +v inc -104 if ic != -225 +b dec 862 if ga != -452 +n dec -733 if mx != -132 +b dec -726 if nno > 618 +f dec -259 if rn == 597 +e inc 51 if nm == -2435 +y inc -251 if ns >= -388 +bqr inc -684 if u >= -5325 +bqr inc -427 if b > -3278 +n inc 526 if mx >= -149 +f inc -727 if egk != 2475 +ga inc 345 if g >= 622 +ic dec -398 if ga > -113 +rn dec 581 if egk < 2478 +rn inc 926 if g < 614 +ns inc 469 if nno != 615 +n inc -870 if vkg > -311 +mx inc 124 if ga <= -103 +z dec -983 if ns != 96 +vkg dec 530 if mx < -18 +rn dec -899 if g < 625 +gyc dec 98 if g < 627 +av inc -497 if n < 760 +nno dec -115 if egk >= 2470 +z inc 610 if z > 4156 +mx inc -184 if ns > 91 +cr dec 724 if nm != -2438 +ns dec 527 if nno > 727 +ns inc -177 if cr >= -4811 +v dec 423 if rn != 921 +vkg dec 658 if av >= 2755 +y inc -464 if bqr > -890 +nm dec 440 if e < 673 +ic dec -963 if mx == -18 +n dec -613 if by < 5488 +v inc -412 if egk < 2482 +vkg inc -278 if y < 1609 +by inc 200 if e == 672 +ns inc -627 if v == -51 +n dec -176 if e == 672 +n inc -511 if gyc <= 1289 +zqo inc 589 if ga == -108 +v dec 533 if egk < 2485 +zqo dec -93 if n > 1536 +e dec -618 if nno < 742 +gyc inc 258 if f != -1139 +ga inc 562 if vkg >= -1254 +n inc -492 if f > -1158 +rn dec -267 if nno < 738 +v dec -263 if y < 1603 +vkg inc 206 if mx == -18 +av dec -610 if n <= 1060 +by dec -352 if mx <= -24 +zqo dec 74 if vkg >= -1046 +ns inc -251 if ga > 457 +cr dec 531 if n != 1047 +ga inc 892 if by < 5683 +vkg inc -687 if b >= -3273 +av inc -208 if v <= -580 +g dec 550 if az != -2985 +ga dec -595 if gyc >= 1548 +egk dec -240 if zqo >= 930 +b dec 262 if az == -2992 +egk dec 831 if ga < 1055 +zqo inc 928 if ga > 1044 +nno inc -90 if gyc >= 1542 +e inc -47 if f < -1144 +u dec 131 if zqo > 1871 +g dec 268 if f != -1148 +b dec -964 if n <= 1045 +gyc dec -952 if az > -3001 +egk inc 324 if vkg != -1735 +by inc -460 if av == 3167 +bqr inc 494 if nm >= -2878 +by inc -616 if rn < 1191 +ga dec -150 if u != -5312 +ns dec -535 if av == 3161 +rn inc -720 if ic > 1135 +n inc -821 if gyc < 2508 +n inc 670 if ns < -705 +f inc 419 if ga == 1197 +mx dec -96 if nm >= -2876 +vkg inc -270 if n < 909 +z dec -907 if ns < -700 +ns inc 160 if gyc >= 2491 +av dec -250 if e > 1240 +f inc 768 if ns >= -542 +ga inc 443 if gyc > 2498 +rn dec 107 if g == 72 +ga inc -420 if mx != 74 +mx dec -763 if ic == 1140 +b inc 586 if gyc <= 2505 +mx dec -948 if gyc > 2509 +zqo dec -384 if vkg < -1991 +z dec 234 if rn > 1072 +gyc dec -821 if v > -590 +z inc 83 if v == -584 +egk dec -835 if b <= -2941 +cr dec -495 if v > -590 +by inc 259 if cr <= -4852 +cr inc 530 if mx != 77 +vkg inc 381 if g <= 80 +by dec -71 if az == -2992 +mx inc -453 if g > 64 +ic inc 410 if vkg > -1618 +f inc 945 if n == 901 +y dec 409 if nm >= -2884 +z inc 870 if vkg >= -1606 +av inc 187 if z >= 5521 +nno inc -852 if ga > 1212 +cr inc 788 if av < 3608 +e dec -182 if by != 5143 +nno inc -706 if ga >= 1228 +vkg inc 782 if z < 5532 +mx dec 839 if nno > -219 +v dec 267 if b > -2952 +v inc 901 if gyc == 3321 +g dec -820 if rn != 1079 +ic dec -221 if zqo <= 2259 +ga inc -784 if e == 1425 +ga inc -569 if bqr >= -404 +u inc -206 if mx <= -1212 +gyc inc -685 if nm == -2881 +e dec 269 if mx <= -1208 +av dec -207 if by >= 5137 +nno inc -109 if ga != -131 +ga dec 3 if ic != 1761 +zqo inc 181 if nm < -2866 +y inc -15 if by >= 5140 +rn dec -617 if g != 884 +g dec 574 if mx < -1213 +ga dec -775 if bqr >= -404 +ic dec 186 if v < 55 +gyc dec 497 if ns >= -552 +z dec 619 if nno >= -319 +b dec -753 if av == 3809 +by inc -890 if n != 901 +b inc -714 if z == 4902 +n inc 927 if v <= 43 +b inc -107 if b <= -2947 +nno dec 707 if y == 1183 +vkg dec 199 if az <= -2996 +gyc inc -684 if cr <= -3523 +z dec -518 if zqo == 2429 +ga inc -220 if cr >= -3527 +zqo inc -922 if y <= 1183 +rn dec 852 if gyc != 2138 +nno inc 419 if ic == 1577 +rn dec -951 if by <= 5130 +av inc -557 if z == 4904 +mx dec 599 if g > 327 +az dec -594 if u != -5525 +gyc dec 187 if y > 1173 +v dec 2 if e >= 1153 +gyc inc -814 if ns < -540 +zqo dec -401 if av != 3249 +ic dec -511 if g == 318 +g dec -447 if g == 318 +zqo dec 965 if by != 5146 +gyc inc 658 if vkg != -824 +nm inc -663 if e > 1156 +n inc -974 if zqo <= 954 +n dec 363 if az <= -2389 +ga dec 300 if v <= 53 +n inc -402 if y > 1186 +b dec 839 if bqr >= -406 +rn inc -188 if v > 57 +av inc 952 if rn < 852 +bqr inc 973 if v == 56 +f dec -234 if b > -3899 +nm dec -96 if zqo != 949 +e dec 141 if ic != 2084 +ga dec 146 if g > 755 +av inc -333 if ga > -33 +z dec 698 if e == 1015 +e dec -493 if z >= 4200 +v dec 234 if v >= 48 +az dec 572 if vkg < -831 +vkg dec 164 if u >= -5527 +ga dec -933 if rn != 846 +gyc inc -180 if ic > 2081 +vkg dec -305 if z >= 4198 +ic inc 50 if cr == -3526 +egk inc -956 if zqo <= 939 +n inc 265 if z >= 4215 +az inc -574 if nm <= -2776 +bqr dec -19 if ic == 2141 +ga inc -682 if cr != -3525 +g dec 864 if g > 764 +ns inc -746 if f < 452 +g inc -969 if f >= 450 +ga inc -127 if e < 1518 +v inc -903 if egk == 3043 +cr dec 714 if nm < -2775 +f inc 33 if ga != -835 +bqr inc 919 if bqr != -382 +nm dec -489 if z < 4210 +vkg dec 962 if gyc != 1611 +z inc -698 if ga >= -844 +z dec 645 if e <= 1510 +ns dec -501 if y != 1174 +az inc -314 if av < 3868 +mx inc -207 if ns == -792 +z inc -604 if zqo < 952 +g inc 466 if g > -1067 +b inc -704 if nm >= -2295 +nno dec 284 if e != 1500 +cr dec 58 if z < 2263 +rn dec 494 if ic > 2148 +nm dec 211 if by < 5141 +by inc 150 if av >= 3862 +gyc inc -716 if b <= -4596 +u dec 466 if ns > -798 +mx inc -935 if cr == -4288 +bqr inc 275 if b < -4587 +v dec 771 if egk == 3043 +vkg inc -902 if u != -6000 +b dec -683 if nno == -1311 +egk dec 525 if v == -1860 +az inc 708 if by > 5284 +y inc -820 if ic >= 2137 +az inc -720 if zqo <= 940 +u inc -299 if zqo < 955 +bqr inc 248 if rn == 846 +g inc 148 if n > -441 +nm dec 213 if egk >= 2509 +ic inc -840 if g < -928 +f inc 98 if by >= 5287 +nm inc 909 if v != -1863 +vkg dec -856 if y >= 360 +v inc -156 if zqo == 946 +bqr dec 908 if gyc >= 900 +zqo inc 836 if f == 581 +ns inc -157 if ns == -792 +egk inc -899 if z == 2259 +ga dec 658 if ic < 2142 +nno inc -278 if by < 5291 +egk inc 502 if f > 580 +z dec 807 if y >= 363 +nm dec 612 if nno == -1583 +y inc 914 if ns <= -942 +gyc inc 419 if v != -2013 +g inc 897 if v <= -2015 +gyc inc 107 if vkg >= -1709 +bqr inc 224 if z < 1460 +mx dec 809 if ga < -1488 +cr inc -401 if av < 3875 +ns inc -521 if by == 5290 +az inc -269 if ga == -1494 +b dec -688 if by != 5294 +n inc -746 if mx < -2225 +y inc -452 if e < 1509 +z dec 495 if n <= -1175 +av dec 204 if egk != 2117 +cr inc 30 if ga >= -1498 +y dec -821 if gyc < 1437 +av dec -105 if bqr != -543 +by inc -897 if egk < 2130 +az inc 392 if vkg != -1703 +egk inc -34 if ga <= -1490 +mx dec -635 if av >= 3658 +gyc inc 307 if zqo < 1787 +v dec 263 if v >= -2018 +n dec 574 if f < 582 +f inc -432 if g < -28 +z dec 259 if av == 3663 +zqo inc 472 if b == -3909 +e inc -779 if bqr > -545 +zqo inc 187 if v > -2282 +e dec -395 if y != 1652 +y inc 312 if az < -3021 +ga dec -324 if egk < 2082 +cr dec -409 if az < -3023 +nm inc -790 if bqr != -533 +ga dec 252 if ga <= -1493 +ic inc -932 if u <= -6292 +e inc -547 if vkg >= -1698 +nno inc -171 if b != -3909 +g dec -891 if vkg < -1690 +ga inc 441 if egk < 2089 +z dec -708 if ic != 2147 +nm inc -402 if b == -3919 +f inc -374 if u != -6291 +ic inc -48 if ga >= -1312 +egk dec -19 if b > -3911 +av dec 305 if ga >= -1313 +g inc -475 if mx < -1588 +vkg inc -269 if vkg == -1700 +gyc inc -535 if f > 572 +nno dec -382 if ns >= -1475 +nno dec 650 if y <= 1959 +y inc 148 if zqo <= 2442 +by dec -223 if u != -6286 +y inc -319 if ga > -1313 +nno dec 13 if av == 3358 +ga inc -402 if gyc > 1198 +rn inc 37 if f == 581 +gyc inc -884 if rn > 882 +ic dec 676 if zqo <= 2438 +u inc 417 if ic != 2098 +n inc 930 if zqo <= 2449 +av inc 509 if ns >= -1477 +y dec -981 if y < 1779 +az inc -780 if ns < -1472 +f dec -834 if by != 4622 +ic inc 721 if av == 3867 +e dec 916 if g <= 400 +zqo inc 169 if cr > -4254 +nno inc -685 if z == 1406 +v dec -920 if zqo > 2440 +nno inc 91 if gyc < 317 +n inc -395 if nno != -2459 +egk inc -746 if v == -1359 +av inc 66 if cr == -4260 +gyc inc 40 if ga > -1711 +egk inc 914 if y < 1788 +g dec 176 if u != -5869 +b dec -550 if vkg >= -1974 +g inc -545 if ic < 2824 +nm inc -645 if cr <= -4256 +b inc -103 if ns >= -1477 +g dec 166 if zqo >= 2436 +nno dec 665 if by <= 4618 +rn dec 622 if nno > -3130 +nno inc -591 if b < -3461 +az inc -807 if egk >= 2272 +g dec -417 if f >= 1425 +by dec 547 if by != 4606 +cr inc -579 if e != 212 +nm dec 650 if e == 208 +b dec -65 if by > 4064 +b inc -263 if ns <= -1473 +az inc -784 if g >= -494 +b dec -193 if z > 1415 +bqr dec 143 if zqo >= 2443 +nno dec 385 if g >= -496 +v dec 352 if ic != 2814 +nno dec -521 if by != 4065 +ga dec 198 if az <= -4612 +by inc 926 if b > -3404 +bqr inc -697 if zqo == 2441 +vkg inc 124 if mx < -1588 +u dec -564 if bqr < -1237 +v inc -763 if ic >= 2812 +egk inc 339 if az > -4611 +z dec -617 if mx <= -1588 +av inc -876 if cr >= -4837 +n dec -600 if mx == -1595 +v inc -354 if vkg > -1850 +v inc 194 if vkg <= -1841 +bqr dec -206 if av <= 3934 +rn dec 547 if z != 2033 +b inc 217 if u <= -5305 +v dec -230 if egk != 2264 +n inc -447 if b != -3180 +az inc 497 if g >= -499 +e inc -527 if v < -2051 +u inc -889 if by == 4995 +b inc 74 if egk < 2282 +ga dec -65 if v == -2052 +nno inc 156 if av != 3933 +rn inc -880 if av != 3934 +cr dec 825 if ga == -1840 +y inc 499 if e == -319 +b inc 525 if mx > -1604 +f inc -731 if zqo >= 2437 +cr inc 398 if gyc < 360 +f inc 286 if vkg > -1846 +zqo inc 761 if ic > 2816 +y dec -877 if rn != -1166 +vkg inc -405 if ga != -1838 +vkg dec -522 if v <= -2060 +mx inc 281 if nno > -3586 +vkg dec -203 if bqr >= -1043 +vkg inc 278 if az >= -4125 +rn dec 544 if b < -2573 +av dec 730 if mx > -1318 +ic inc 49 if n < -620 +f dec -599 if nno != -3583 +e inc -871 if gyc == 355 +e dec -735 if mx != -1307 +n dec -73 if rn <= -1707 +ns inc 896 if g >= -502 +z dec -480 if z <= 2023 +zqo inc 595 if v < -2043 +mx dec 647 if vkg == -1769 +n inc 743 if nno > -3589 +gyc inc 129 if cr > -5267 +vkg inc 703 if mx > -1966 +bqr inc 378 if g <= -487 +ga dec 852 if zqo > 3035 +zqo dec -43 if y > 2280 +ga dec 849 if cr != -5259 +gyc inc -363 if av >= 3203 +vkg dec 481 if nm <= -3884 +g dec 609 if f < 964 +av inc -951 if n != 187 +ns inc -676 if zqo == 3079 +nno dec -998 if av == 2252 +n dec -624 if vkg > -1544 +y inc -262 if ns == -1250 +av dec 248 if ns < -1250 +f dec 351 if z == 2503 +bqr inc 535 if ic > 2858 +f inc -725 if nno > -2589 +ic inc 860 if v == -2052 +nno inc -211 if v >= -2055 +ic dec -324 if bqr <= -126 +az dec 746 if f <= -99 +g dec 985 if e <= -454 +f dec 434 if z < 2495 +egk dec 842 if bqr == -121 +gyc inc 715 if y >= 2022 +ns inc -573 if nm != -3888 +b dec 415 if mx >= -1951 +by inc -719 if ga == -3551 +n dec -783 if cr >= -5268 +nm dec 409 if by > 4988 +u inc -72 if av >= 2246 +ns inc 338 if v <= -2050 +e inc 12 if rn < -1706 +ns dec -354 if nm == -4299 +egk inc -589 if zqo >= 3084 +egk dec 856 if vkg != -1555 +ns inc -439 if zqo >= 3076 +by inc -942 if cr != -5272 +z inc 119 if b >= -2588 +cr inc -864 if ga != -3537 +nno inc -333 if gyc > 828 +z inc -530 if e > -451 +nno inc -113 if u > -6271 +g inc -213 if mx <= -1953 +y inc 107 if ga < -3536 +y dec -971 if az < -4859 +n dec -424 if av < 2258 +ic dec 632 if rn <= -1705 +az dec -701 if ns > -1576 +by dec -45 if egk > 581 +z inc 111 if vkg == -1547 +ic dec -737 if u <= -6266 +v dec 13 if nm != -4289 +b inc -616 if ic < 3838 +av inc 266 if b <= -3190 +nno dec -699 if gyc >= 834 +y dec 400 if gyc >= 835 +y dec -119 if ns <= -1567 +n dec 452 if rn < -1703 +egk inc -254 if vkg == -1556 +az inc 568 if ns <= -1580 +f dec -399 if bqr < -115 +zqo dec 948 if nno > -2440 +rn inc 154 if zqo == 2131 +f dec -21 if b != -3190 +nno inc -204 if g > -1683 +v dec 190 if az >= -4168 +bqr inc 236 if v > -2263 +cr dec 554 if nm >= -4303 +gyc inc -657 if e > -449 +e inc 65 if nm != -4306 +v inc 340 if az > -4171 +mx dec 527 if nm <= -4296 +g dec -426 if ic > 3819 +b dec -766 if z < 2205 +ic inc 822 if cr < -6677 +cr inc -733 if n != 958 +rn inc -759 if vkg == -1547 +nm dec 588 if rn == -2315 +n dec 310 if ic < 4641 +n dec -24 if g >= -1274 +n dec 341 if nm == -4887 +cr dec 131 if av > 2513 +zqo inc -78 if gyc < 181 +mx inc 368 if vkg < -1537 +gyc inc 157 if zqo >= 2053 +rn inc -871 if vkg <= -1544 +bqr dec 299 if egk == 576 +cr dec 27 if b <= -2423 +rn dec 848 if az < -4170 +av dec 836 if egk <= 577 +v dec -334 if cr < -7576 +f dec -820 if u == -6271 +az dec -367 if egk == 576 +by inc -267 if bqr != -192 +bqr dec 95 if cr == -7575 +ga dec -641 if bqr == -279 +ns inc -776 if y != 2821 +by dec 177 if cr != -7575 +nno dec 656 if g >= -1261 +z inc -641 if az >= -3789 +rn dec 93 if v != -1911 +az dec -664 if f > 1139 +ic dec -565 if e >= -380 +by inc -600 if ga == -2894 +zqo dec 580 if g <= -1263 +zqo dec -324 if by != 3784 +gyc dec -987 if ns != -1570 +gyc dec -921 if mx >= -2111 +by inc -529 if ic < 5211 +av dec 272 if ic == 5210 +nno inc 745 if e < -374 +ga inc 893 if by >= 3782 +egk dec -936 if bqr >= -284 +vkg dec -146 if nno <= -1679 +y inc -686 if ga != -2000 +b dec -659 if u < -6265 +b dec 418 if n < 629 +az inc 613 if ns == -1563 +vkg inc 385 if ga != -2017 +egk dec 54 if az == -3802 +vkg inc 330 if by == 3786 +f inc -243 if u != -6271 +gyc dec 751 if ns != -1574 +nno dec -285 if ga <= -2006 +vkg inc -257 if v >= -1921 diff --git a/08/lib.scm b/08/lib.scm new file mode 100644 index 0000000..6e402c3 --- /dev/null +++ b/08/lib.scm @@ -0,0 +1,105 @@ +(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)))) + + ; Evaluate a test of the form: `rval' `test' `rlit' + (define (satisfied? rval test rlit) + (cond + ((string=? test "<" ) (< rval rlit)) + ((string=? test "<=") (<= rval rlit)) + ((string=? test "==") ( = rval rlit)) + ((string=? test ">=") (>= rval rlit)) + ((string=? test ">" ) (> rval rlit)) + (else (not (= rval rlit))))) + + ; To copy the register state list from one cycle to the next, the usual + ; `(apply list xs)' trick isn't good enough, because `xs' contains pairs. + (define (list-deep-copy xs) + (if (not (pair? xs)) + xs + (cons (list-deep-copy (car xs)) (list-deep-copy (cdr xs))))) + + ; Execute one instruction (`words') given current state (`registers-old') + (define (execute words registers-old) + ; Make a copy of the input state, to be modified and returned. + ; The state is an association list of (register . value) pairs. + (define registers-new (list-deep-copy registers-old)) + ; "Parse" the instruction, which has the following form: + ; `wreg' (inc|dec) `wlit' if `rreg' `test' `rlit' + (define wreg (list-ref words 0)) + (define inc? (string=? "inc" (list-ref words 1))) + (define wlit (string->number (list-ref words 2))) + (define rreg (list-ref words 4)) + (define test (list-ref words 5)) + (define rlit (string->number (list-ref words 6))) + ; If register `wreg' isn't initialized yet, set it to zero + (if (not (assoc wreg registers-old)) + (set! registers-new (cons (cons wreg 0) registers-new))) + ; If register `rreg' isn't initialized yet, set it to zero + (if (not (assoc rreg registers-old)) + (set! registers-new (cons (cons rreg 0) registers-new))) + ; Read the values stored in registers `rreg' and `wreg' + (let ((wval (cdr (assoc wreg registers-new))) + (rval (cdr (assoc rreg registers-new)))) + (if (satisfied? rval test rlit) + ; If the test condition is true, apply the increment/decrement + (set-cdr! (assoc wreg registers-new) + (if inc? + (+ wval wlit) + (- wval wlit)))) + ; Return the new state + registers-new)) + + ; Execute the "program" and return the history of register states + (define (solve-puzzle lines) + (let loop ((instructions (map string-split lines)) + (registers '()) + (history '())) + (if (null? instructions) + history + (let ((state (execute (car instructions) registers))) + (loop (cdr instructions) state (cons state history)))))) + + (define (solve-part1 lines) + (define history (solve-puzzle lines)) + (apply max (map cdr (car history)))) + + (define (solve-part2 lines) + (define history (solve-puzzle lines)) + (let loop ((states history) + (highest -999999)) + (if (null? states) + highest + (loop (cdr states) (max highest (apply max (map cdr (car states)))))))) + +) diff --git a/08/main.scm b/08/main.scm new file mode 100644 index 0000000..fbcd10e --- /dev/null +++ b/08/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 5215 for me +(printf "Part 1 solution: ~a\n" (solve-part1 input)) + +; Part 2 gives 6419 for me +(printf "Part 2 solution: ~a\n" (solve-part2 input)) diff --git a/08/test.scm b/08/test.scm new file mode 100644 index 0000000..b18ae33 --- /dev/null +++ b/08/test.scm @@ -0,0 +1,34 @@ +(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 (equal? 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)))) + +(define input '("b inc 5 if a > 1" + "a inc 1 if b < 5" + "c dec -10 if a >= 1" + "c inc -20 if c == 10")) + +(printf "Part 1 tests:\n") + +(define (test-part1 name input expected) + (run-test name solve-part1 input expected)) + +(test-part1 "part 1 example 1" + input 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" + input 10) diff --git a/09/input.txt b/09/input.txt new file mode 100644 index 0000000..da21895 --- /dev/null +++ b/09/input.txt @@ -0,0 +1 @@ +{{},{{{{{},{{<!!!>!<"<!>,<!!!>!>},<!>,<'e">},{<!!<}!uu!!!>!!a!!a!>},<!!!!!>ue!>,<"!!!>!}>,<}!!!>,ii>}}},{},{}},{{},{{<!!!>!>,<i!!'!!{>},{},{<{}}!>},<i<"{,}{!!oo>}},{{{{<}i<}"">},{<o<!>>}},<!!!>uo{}!!'!!<!!!>o!>>},{<!!!!!>!>},<!!!>!>,<>,{<!!!!!>{<!>,<>}}}},{{{},{{}}}},{{<{u'""o>,{<ee!!!!!!!>!!!!e{uea!>!!i>}},{<o{!!!>!!!!e<!>},<!>,<e!!!!>,<>}}},{{{{},{{{<a!!>},{<}<{!>},<!>},<o!e!!},!>!!<u{i>}},{<a{!,!!u!!e}a!>},<u{!!!>},<>}}},{<i,>,{}},{<u!!!>!>eie!>,"!!!,,!>,<}<eo!>},<>,<>}},{{{}}},{},{{{<!>,<iooi!!ueao!>,<!!!>}!>},<"ai>,{<u}a{e!<!!!!!!!>!!u{{!{!>},<<{o!>,<!o>}}},{{{},{<<,"!>},<u!!u'!!!>au!o>,<!!"!!!>'!!!>,<!>},<'oaaou!!!!!>},!>,<e>},{{{{{},<uo,{eiu,!''!ui">}},{<!>,<!>},<!a!!>}},{{},{{},<i!i!!,iu!!!>ie"e!>},<a!>!"i!>{!>},<>},{{{{<!>,<}}!>},<!!!>},<!>},<!!'!>,<,'!>!!<,}{e>},{<ua!>,<>,<}!>!!!>"!>},<'!!!>}<>}},{{<a}!!,ee!!!>!>},<a!e!!!>},<>}},{{{},{<}"a}!>,<!!!>!>},<!!,!>,<<}{o""!!a!!,a>}},{{<>}},{{}}}},{<o!>},<!!<"!>},<!e!!!!!>!>{>},{<>,<<>}}}}}}}},{{{{<!>},<}}'!>,}>}},{<"!!!!!>,'<!>!!i}{o!>ai{"!!!>>,<!!!o!>},<!><!!!>">}},{{}},{{{{<e!>},<e>,{<}!!!><!>,<!!oia,!>,<e}e!i>}},{{<!!!o!!u!!eu"{}!>,<i}"e!!!>}!e>},{<}a'!,}>}}},{{{},<i!!!>!!u"}>},{<!!"!,!>!>,<ae{!>},<!>,<!!!!!>i,!i}'!!!!'">},{{<!>},<!>,<!"!!{u<ea">,<"!>!{}a{"!!o<"'!!!>o}{a>},{<eue!!!>},<"!{<'>}}},{{{{{<e">},{<!>},<>}},{{<!!<a>}}},{{{{{{<o<>}},{}},<i>},{{<u!!!>!!ua!>oa}uia>}}}},{{<!>,<!!e{e!!!>,<}"!!!!ei!!!>!>!"ii}>}}},{{{{<!>u!!!!!>,o",!!!>!u!>,<>},<ue!!!!,!!!>!!!>!!o!>,<{,!>!>},<>}},{<!!!>'>,{<!!o!!u!>!>,<ia!!!!!>!!}!>,<e!>,<>,{<uu!!!!}!!>}}},{}},{{<>},{<o}!!i{!!!>!>},<a'o!>o!>},<!!!!!>},<>},{{<!!!>,aa!!>},{<>}}}},{{{{},<!!!!!>,<'!>},<!!}!!!>!!<>}},{{<!>},<ai>,{{<!!!>!!!>a!!!>!!{>},<a!>!>},<u!!!!!!!e!!!>!>,<e}>}}},{<'oei!>},<uo{!!!>!{e!>,<i<>,{<>,{<!>,<o!!!!!!'""!>,<!>!>,<!!!>},<}>}}}}}},{{{{<e"a!}!>,<!>},<!>!!!>},<{!!!>>,{<!>!>"ua!!!>!!,}'!!ai,e!>},<!!}!!!!i,>}},{<>},{}},{{{{<<!!>}},{<u>}},{<,,o!"uu",,!{'>,<!!!o<ii'!>!!!>},<'!i!>},<!>},<!'o>}}},{{},<<u!!!!!!!>!!{!>}"a>}}}},{},{{{{{{<a!>,<!>},<<>}},{{<}!!!>}!!>}},{{<!'"'>,{<}!!i!'eu<a,o>}},{{}},{<!>!<e!'a<}!>},<e!!!>ii!!<a!>},<"!!!>!'o>}}},{{{<!ou!!'e!!e{a!"!>},<!>,<!!uo<e!!>}},{},{{<!}<!!,u!<!!{<}!!!!!>},<!!u!!!>!!!>}!>,<>},<!>},<eua{!!ai!i!o!>,<!>,<}'>}},{{{<!>},<!'!!!>!>,<!>},<!!'">}},{{<!>},<{!!!>!"<!!e!>},<"!!!!a!!e!>,<!>e}>},{{<!!'!>},<>},<">}}},{{<<!>o}>}}},{{{{{<>}},{{<!!!>a'>},{<!ui!>,<}i}"{}!<,e>}}},{{{}},{{<ee!!i!!>,<uue!!!!!>!!o!!!'u{!!!>},<!>u!,!!"i}>},{{<"!!}{u'<!>,<!<a!!!>,<{!!!>eu!!!!!>>},{{}}}},{{{{<'i!!},a!>,<o<ii!>!>!>,<!>,<"!>},<!>>,{<u!>ou},!!!>"a!!o!{a!!'"}!!">}},{{<<!!!><,!!>},{{<!>,<oo>},{<!!!>!!i}'!!!>!>,<uau!"!>,i!!!>>}}}}}}}},{{{<}uo!!!>i!!ii!>{!!o">}},{{{{<!!'}!>,!!!>>},{<!'}}}uei>}},{{<,!!>},{},{{<a!><!>},<"!!!>!!!>'o"o{!!e'"a>},{}}},{<o,"',!>},<,u!>,!!!><{au}!>>,{<u!!a{!><!!!!"i!!,"!"'{<'!<>}}}},{<{!!ee!!!>!!a!i!>ei!!e!!!!!>!!!>e!!a">}},{{{{{},{{<"o!!{>},{}}},{<!>,<!>,<!!o!<!>,<{,}{!<{<!o!!!!!>>}}},{{{<!e!!!>{o}i!!i!>},<}'>,{}}},{<i'!!e!!"!!!>},<!>,<!ao{a!>},<!}!>},<u>}},{}},{{{{}},<{!!},{{>}}},{{{{{<!!o!!!!e!>,<!!'!'!>},<!>,<ie{,,},>},<e!!{'!!!>!!}<!!!>,<!i<>},{{<!>!!e",""'a!!o}!!!>"!!!>}>}},{{<!!i"!!oa"!>},<{',{a>}}},{{{<eui!!eo"!!!><!",!>},<{i!!!!!><!,u!>,<>}},<}!!!!'>},{{<!>,<>,{<!a!>},<!!!>o!!"'!>,<aoo>}},{{<{<!"!!!>"!!o!!!>!<a!!!>!!,>}},{{}}}},{{{},{},{}},{{},{{}},{{{<i!!e!,e!ua'o!!!>!>},<u!!,a>,{<,a!!!>}oa<'ii>}}},{},{<!!!>!!!>{oiu>}}},{{{{{<!!{<!>},<e!>}!!">,{<<!!"!>},<!>!>,<<<!o<">}}}},{{{{{}}},{{<uea!!'!e"!u!!!>!>},<!a!,a!{<<!>},<!>,<!!!>>}},{{<!>},<>},<!>},<!>"!>!!!>!>e>}},{{{{<!>,<<">}},{{<!>,<!i!>},<}!>,<!!!>!!!>,<!>,<!>!>},<,!>,<o!!!!!>o>}}}},{{<!>},<!!!!{i!!,e>,{<o!!i{>}}},{{},{}}},{{<e!>!!!>>},{{},{<!!!>,<u<a!!'!o}i!"!>},<,{>}},{<,!!!><!>},<!!!!i!!!>},<<>,<u<<!!!!!u<e'"!!oe,a,!>,<"a>}}},{{{<,i'"!!u}!>,<,o!!{!>,<{ou<!!>,<ieeo",!!<!!a}!>,<'!!}>}},{{{<e>}},{{{<!!!>},!!<o!>a!!!>e<!!!>>,{<,>}},{{<!!{{!>},<!<}}{,i!!!>u!>>}}},{<"!!''"!>,<!!!!<>,<}',!>e!>,<a}uo!!!!i"!>u>},{<<ei{>}}}},{{{<i!!ea!>,<i<!>},<!>,<!>,<!'o{!>!!!>"!>,<!>>},{{<!>,<"!>},<!>,<!>,<!><!!!>{!i"a!e{!!>}}},{{<,,"!!o!>ei"''u>,{{<<o!!!!!!o,!i!>!!u!>!>!>,!'!}<u>}}},{{{{{<i{a{a!e!!!>ea!!!!!!!>},<'!>},<>},<!!!>!!,'e!>,<,}!!">}}},{{<!o!!<a!>,<!>},<!>,<!>},<!!,!>e{<a,u!!!>ie>,{{<!>>}}},{<!>!!i"u!!!!o!>},<}e!u{!>{u!>},<'i}>}},{<!!ea!,!>,<<oea,!!!!}'!!a>}},{<,!>!!!>},<<!>!!!eu!>!>},<{!!}ao"iu>,<!!!>'<!!!>e!>!>},<!>},<<!e}eo{}e'>}},{{{{<!!!>,<i!!!>oa<!a'>},<!!o!!!>{e!!!!a!!!>,<!>,<','"a!!!!!a!u>},{{<!!!>!!!>,<u,!!!>>}},{{{{{<a!>eoi>}}},{{{<e!>!>,<>},<uu">}},{{<!>,<!"ei'!!!>!!a!>},<{,}!!!>e!>>},{<a!!!>},<!!{!'eu!!!>!!i!!!>'a>}}},{{<!>,<!'e{!!!eo,oe!>!>},<}">},<uo!!ou}!>},<e{!!!>'o!!!>}'!!,>}}},{{<!>u{i}>,{<e<!!!>',}!,ia!!i,!!!!>}},{},{}},{{{{{<"<!!!>e!!!!<a'<!>}!!!>!>},<>}}}},{<{{,"}!'o!!a!!!>!!!!""{}!!!>>,{}}}}},{{<!>},<o">},{{<!,!!{!>},<!!!>!>},<}!!!>!!i,!>{!>a!"{!!!>!!>},<<{!>,<"o!>,<!>'!><aa!>o}>},{<!>,<u<a!o,!>!i,>,<}<o<a!!!>!>!!o!!!>{!!'o!!i>}}}},{{{<i!>},<!,}!!'">,{{<!><oi!!!>'<e!>}{!!!!<i!!!>>}}},{{<!>},<!>!>,<u{!,!!,>},<'{o"!!!!o!>o,<{,o{!!!>,<a>},{{},{},{{<!>,<"!!{iu"i!>euoa}!!!!<!u>},{<!>!!u'!>,<"!!!!<!>},<auu<'u"}}>}}}},{{{<>},<}'"o!!!>""!!!>},<',{<!!{!!!>},<>},{{<i!>,<!!!>uao!>},<>,{{<o<!!o<!>},<!>},<,!>i!!!>o<{!e,i>,<o}"e<!!u<!ii}!a>},<!!'!!'e"!!!!!>oei!>,<u>}},<,!!!>'!!!!{o>}},{{<'u!!!>!>},<!!oa>},{{{{<!>,<!!!>},<i">,<e!o{a!>,'!!o!!u>},{}},{{<'!u!!!>"}!ui!uo!{!!!>!>,<o!!e"!!!>'e>}}},{},{<ou>,<<'>}},{{<{u'}'!>i!!i!!!"!!'!>},<!>},<!!!>}}!!e!>,<!i>},{<'a{o!>},<,<!!,!>!!>}}},{{},{{},{{<!!!>},!!!>},<!!!>,e!!!!!>'!!!!!>!!o!!{!!{<!!!>,<>},{<!>},<>}}},{<ui!>,<}>}}},{{<!"}!>,<,'u'e>,{{}}},{<!>,<i!!!>iae{>}}},{{{{{{<}}o!!,"{<!!!>},<!>o{!>},<"!!!>,<!!!><>}},{}}},{{{{<!><!}{a}eu"}!!!>euu!>,<>,{<,!>},<!!!>!>!>},<e!>{!>},<,!!!!"!>,<!a}>}},<a{u!>},<{!>,<!>},<,u"!!u,!!{}ouo>},{{{{}}},{<!ooe,u{!!!>},<i<!!ia!!!>},<!>!!e!!<!>{a>}}},{{<!>},<!>},<!!!>}!!'i!>"!!e"',!!'!>>},{{{{{<!!!>!ae!!"}!>},<<'!}!!'!!!>},<e{{!e>}},<>},<a!!!>,<eu,a<!>>},{<!>>},{{{{<!>},<a!>}u>},{}},<!!,!}}!!o!!""}>}}}}}},{{<e}e!!{!!!>,<a"">,{<!>o!!ie}!!>}},{}},{{{{<u!o!>,<!}!!!!}!!!>e!{!e<o!!!>,<,,<>}},{<<}!!<!!!>e!!e!!''oa>}},{{{<!>,i!>,<!!!>!'>},{<oea!>,<"u!>},<'<!!}!>},<<!>,<!!!!}!!u>}},{<!!o!>,<}!!'!>,<<!i{!e'e!!!>>}},{{{<{!!!>}a!>},<!aou!!'!>},<!>!!!!u<o!>,<'a!>,<>}},{{<!>},<!!i!!!>a!!'!!!>e'!!>}}}}},{{{{{{<i!'{oe<ao>}},{<"i!>},<!>,<"{o}"{!!a!>},<>,<!>,<!!!>!>!>},<!!i,o!!!>!><o""!!ue{>},{{<!!'!>,<<!>,<"!!!!io{}o"e!>o!!o}{u>}}},{{{{{}},{{},<!>},<!!'<e{!>}!<!>,<i!!!!!>"{<'{a>},{{<oeuu!!!!!!}''!!i{>,{<"'!,!<!!!>},<e,!>,<ae{o!>},<}>}},{}}},{<!>,<!oa"a>,<!!!>!>,<!!!!!>!!!u>},{<!!{!ou!>,<{a"eu<i!!,<!>u>,{<'>}}},{<}ia!>},<!!!>!>!!!>!!!!!o!!!>,<!!!>">,<"u'>}},{},{{<'!>{a}!>},<!!!>!o!e}!>"e<!!!!!>!e}!!!>},<>,{<!>},<!!i!!<a!>},<!>},<u{!>,<{!{e!!!!!>a!!!!!>>}},{{{<e!>,{!!!!a<>}}}}},{{}},{{{{<'!>,<o!>{{i!!i!!!>!!!!{!""<ee!!}>},{<}{e!!,e"'<i"!!o,eu>,{<<i!!!!}!>,<!>,<e!{i!>},<aa!>,<!>},<'>}}},{{{}},<{"a!!!>!e>},{{{{<!>!>,<}!>},<!>,<!!!>!!!>!>,<!>,<}!!!{e<a!>,<>},<!>'o!!!!a!>!>,<!!!>},<>},<!ui!o!>}!!ei!!!!<!>},<!!aa}!u!!}>},<<!!ao<u!}<!!e"!!!!ou<!>,<!!!<>}},{{{<o}<!>},<o"!>!>},<<e!u,a>},{}},{<<!i'}"a!!!>},<uo{!>},<!>a"!!"!"!>,<'!!!>,<>,<!!e},!>!!!>,<}!!i!!!}"!>,<!!!!i!!!>!!!!!>,<>}}},{{<eeu!>,<>,{}},{{<!o{u!!>,<,!>!!!>!!!!!ae!>},<!!!>>},{{},<,',{!>,<<>},{{<'<!!a'{i!!"i!!!>!>},<!>,<o<"!!!>!!{<>},{{<a!>}!""a!!!>!>,!!!!!!!>>}},{{<!>},<,'!!uu"{o!!!>"ea!!e!>},<u,"',>},<!{!!!<!!!>u!>i!}}!{<e!!u!>},<!>},<!!!>!>},<{!>,<>}}}}},{{{<!e"o}e>},<!!!>u!!"!!!>}a{!!!>oie!!!u!!!>ua,!!o<>}},{{{{{<!>},<!>!!!>!>,<>},<e<>}},{{{}}}}}}},{{{{{{<!>},<!!!>!!!>!!a!o,}i{o!!!>!!!>,<>},<a!>},<!>,<!a!!!>!!!>!o,"!>euu!>!!!>!>},<!>!>,<>},{{<o!>>},{}},{{<{>},{}}},{{{{}},{{{{},<<{i!!ao!!!>'!"e">},{{{}},{}}}},{{{<<'!!!>"!!!!!o!>},<{'oi!!o!!!>},<>},<o"ea!!,a!>,<!!!>',!{e{>},{{{<>}},{<e<u'!>,<!>},<!>},<auo}!!!>i>},{<uue,!!ei!e!>,<!!{u{i!>o!!!!}!!!>>,{<eu'a!!o>}}},{<!!!!u,>,{<!!!>!>,<,!>},<a<}"e,!>i!!!>iei>}}}},{}},{{<!!}i}e!>u<{e<!!}!!!>!!{e">},<!!!!!!!>>}},{}},{{{{{<<!!!!"'!!!!!>},<u,o!>},<!!aa!!!!o!!!>},<<<u<>}},{<!!!!!>!!!>i!>>,{{},{<'!>,<o}u}ea}",!!!!'!>,<>}}}},{{<!!!>!!!>!>,<aa!>,<oe!>},<a!aa!!"!>,iu>,{<!a{!!!!!"!!!!!>!!!!!>!au!>'>}},<>},{{<a!>},<"!o!>},<<!}!>,<!iueeiai!>},<,e>},{{<!!>}}}},{{{{<!>,<!!!>!>'}i!>},<ua"o!!io<!!!>>,<!>},<u{,oou>},{{{{<!>},<!!!o}!!u">},{}}},{<!!!!u{}o!a!e'{"!">,{<,"{!!!!,o"},!>},<!>,<i!!<!>!!"!!!>,>}}}},{<!{'!>},<!>,<,u"!>,<e!!!>u>,<,!!!}!>,<a!!!>!"!>,<>}},{{<i!!}e!!!>{{!!"!!!!"!i<a"'ie<!!{>,{<{!!o!!{!>,<u>}},{}},{{<{e<!>!!!!,,!!e}!e!>,<!>,""!>},<u!o>}},{{{{}},<!!!>u!{>}}}},{{{{}},{{},{{},{<"!!!>!>,<!!!>,<,e!,a>}},{<a<,{!a!>"u<>,{<e!!,,!>},<!>},<e!>,<>,<!>,<u{{!!!>!!<}{!!!,"uo>}}},{}},{{{{<{"a!>},<!>},<!>,<,>},<!>!!a!>,<}!!!!!>!!!!o!>,<}!!{oe!u">},{{{<{!>},<!"o!>o!",>},<uoi<ee>},{{<}>},<<}""a!!!>},<!u!!!>>}}},{{<o!!!!!>,<"i!>},<>},{<'>}},{{{<e!!!>,<!>!,e<<!>!>},<<!>o!>},<!!!>!!i!>>},{<,i">}}}},{{<>},{<>}},{{{},{{{<<!!!>,<!!a!!"<!u!!i!>,<!>,<u'a>}}},{{<,}'!!!!!!'!!!>},<>,<!!!>>},{<'e!>}}<!!i!>,<o>,{<u>}},{{},{{<u'!!!>,<oi,u!!!>o!>aa>},{<uo,{ia!>>}}}}},{{{{<e{!!!>a!ie>},<!!'!>au!>"!!{!{i!!i,'{!!!>!!'>},{<!!a}i,"""},'!!!>!!!!e>,{}}},{{}}},{<'a!o!>},<>}}},{{{<o!!"'!a,o}o!>!!ae!u!!<e'e,'>,{{<!!}!{u"!>,<}!!u!>,<!>,<!>u!!e!!"!o>},<!>,<uu}oo!>,<!>,<!>,<<!!!}!!!!!>>}},{<!!o}!i!!!>e!}'!>,<,!"u!!ou{}>}},{{{<{!!!>a'!>,<!>},<o{>}},{<}a!!!!,!!<!>io!{>,<}u!>!!!>i!>!eu!>},<{!!}!!!>{!!!>u>}}},{{{},{{}}},{{{{<{<eaa!>},<!>,<!>},<!>,<e!>,<!'>}}},{},{<}!!!>}i!!}u!>,<!>},<e!!u>}},{{},{},{{<>}}},{{{{<e!!!ua!!!>,<<{i!!!>!!>},<{!>},<!>'u"e<,!!i!">},{{},{}},{<o!>!>},<">,{<!!}!!}i>,<>}}},{{{<',<<!!u!>,<!!i!>},<!>!>>,{}}}}}}},{{{{<}e"!>{!!!>!!,a<e}u'i<"!>}!<>},{{<aa"uia}>,{<o,!!!!!o!>,<aaa"u<!!{!!ue<{!>,<>}},{<,}>,<!>,<!>},<'!!'>},{<!!!>>,{{<!e!!!>!>"!>,<{ue<'}{>}}}}}},{{{{{<i,!>!!ea!"!i>,{<!>,<>}},{},{{{{<!!!>,<!>,<,,ii!u!>},<,i!>,<!!!>,>}},<!!!!!!!>!>,<'!!!!!>{!>,<>},{<!"!>},<!!!>,<""uo!!!>!>"!!aa,o!uu>,<iao!>},<a!!!>}}!i!!"!!!!!>!!!>!>},<>},{<>}}},{{{<oe!!{',!>>,<!>},<},!>,<ao!>},<<,{!<!>,<ueu!<!a!!>}},{<!e!!}}<eu!>},<!!<!e!!i"!!'ui>,<}}!!<>}}}},{{{<>,{{}}},{{<o!!!!{,!!!>o"u!!!!!!e!!io<!!!!!>},<>},{{<!!!>!>,<o!!!!!><,!!!!'ei!>{>},<e!o!!!>!!!>o!>},<ei!i!>},<uo>}},{{<!>},<'u"e}u>},<!!!!}!>},<!!!!o!>!>,<!!!!!>!!!>!!!>!!,o!>i!!>}},{{{<!!u!>e<!!!!uu}!>'!>},<!!!>,<!>"!>!>,<>},{},{<u,!uo<!!,!!!>},<}u!!!a"!>}>}},{},{{{<!!!>{!!"!!'!ou!>},<!!!>"uuio!u{>},<,!>,<!!"!!,,!>}{!ae'!!!>e}>},{{<!"<>},<}!!i!i{}i!ii>}}},{{{{{},<a}!!a}!!!!!a!!!>>},{{{<,u"!!!>aae!u<!>},<u>},<{<>}}},{{{<!!a'<!!u!>},<ei}i'!!"!!!>},<!!!<<"e>}},{<!!}a!>},<,'<!!,!}<a!>,<!>,<!>,<<aee!!>}}},{{{{<!!!>,!!!!'!>,<,!!}!!!>!>,<a{,>}}},{}}}},{{{{{<,!!!>},<!!{<u>},{<>,<!>},<'"!>,<!>,<>}},<!!uo>}},{{{{{<!>},<'i>}}},{{},{<!!!!!>},<'!!!>,<u>,{}}}}},{{<'<!>,<i!>{u,>,{<!!!>!>!ia!>},<uu>}},{{},{<iu!o,!>!>,<!!!>!>,<oa,!!!>!!!>o,o{}o>,{<>}},{{},{{<{'!>},<!!!>,<!!!><o!><e>}}}},{{<}!>!>},<!>},<>}}},{{{{<!!!>>,<e}i!>},<!>,<!!'i!>!>},<a!>,<!>,<o,>},{{{<a{<{<"!!!>,!!!>,<!>,<!>,<!>,<o,e>,{{<!>},<<,!!!>e!!!>'}!<e,',!>}!><'>}}}}}},{{{{{{},{}},<!>i'!!!>},<}o>},{<{!>i!>},<u!><>,<i!>,<<!>},<>},{{{<{!!!>}!>},<'>},{{{{<u!>},<!!!>},<,}!>,<!!!!}!>}e>}},{{{{<a}!>!!<!!!!a{!!<!!}!!!!!>a'{i!>},<>}}},<!!e!>,<!!!!!>aa{!>},<!>},<!!e!>},<!>,<'!!!!!<,>}},<'e!!{!>},<!!!>!>,<}>}}}},{}},{<!>,<!!a!!}!>}aa}>},{{<!!!>'!{<!>,<!>'u,!>,<i!ui!!!>},<!>,<!!>},{}}},{<}"}e}!!'!>},<,!!!>}!!}>}},{{<!>,<!!e!!}a>},{{},<<}"<au}!!ue{{>}},{{<"!!}},!>,<!>},<!>,<!>},<o{o>},<!!!!'!>},<o,!>,<!>!!e!>,<>}}},{{{{{{}},{{}}},{{},{}},{{{{<!u!!ou{!a{ua!}!!!>>},{<,!!!!!>'!,a'!!i!"aooo>}},{<'!!!!!{au!!'!eaueuo!!i'!!!!!>{!!e>},{<!>,<'uu!>},<!!!>{!>,<iou!>,<>,{}}},{{<,>}},{{<"a>},{<'!!<ae{!!!>!>"!>,<i!>,<i!>},<e>,<!!!>}i!>},<!>},<u!>,<}{,i>},{{<!o>,<ia!!{!<oo{!>},<o>}}}},{{<!>,<!>,<,a!!,!>!!!>'!>},<}!>,<{ua}"o>},{{},{<o!!!<,!>!}">}},{<a!>,!>,<o!!!>,ei!>,<!{!>,<!a>,<<o}!"u>}}},{{{{{{<o'!!ia}uee!>,<">}},{},{{{{{{}}}},{<o{!><e!!}}!!'}>,{<"iu!<<,!>"{<!>au>}}},{{{}}}}},{{{{{{<<!{!!!>,u}a!>,<,!>},<i!!,!!!>i!>,<o!>},<,>,<!!!>!<>}}},{{<!!!>!>!!!>>,{}},{{<i>}}}},{{}}},{{{<>}},{{<u!,!<!>,<<>},<i!>},<!!!>>},{}},{{<!!!>!>},<!>'>},{}},{{<}{e!>},<e,a!>}i!>,<o{!!!>,!!{>,<>},{{<>},<!!!>!>,">}}},{{},{{{<au!>>}}}},{{{{<!!a!>},<<!>!>},<!"e,!>},<>},{}},{{<!>},<!!a!ieoe!>},<>},{<i!ii{>}},{}},{{}}}},{{{<!!!>,<,!!!>!!}!!!>,<"a<<!!ea'!iu{>},{<!!oo!}<a>}},{{},{{<u,!!!>!'!>e!!!>!>},<o'uu!>,<!>,<!!!!!!!!!!!>,<ui!>>,{<!>!!{!!e!>!}>}},<'o!}!>},<!!!>!e<,,<e"!>},<>}},{}},{},{{{<!!!!e,!!u!!!>}e!!!!io!!<!>,<i<>}},{{{<!}!!!e!!!>'{,!!u}>},{}}}}},{{{{}},<>},{{<{!>,<!!o!<a!!!>iu!>,}!>},<,!>">}},{{},{{{{<!!oo'!!!>"!>!!!!!!>}},{<'o}u>,{<}!!i!!!>},<!>},<u!,}!!!>oo>}},{{},{{{<!!!>},<!!i}!!!>,<"{<!!!!!>{>},<e!!,'!>{!!!>o,,>}}}},{{<}!>},,!!}!!!oi!!>},{{<>}}}},{{{{}}},{<"!!!>},<{>,{}}}}},{{{<!!<!>"!>,<!u!!!>!!}!au!!>},{{<>},{<!i!"!!!>>}},{{<!!e}o!!{u!!!"a!!!!!>,,ui>},{<,!>,<'!e>}}}}},{{{{<'{}u}u!>,<!>,e!!o!o!>},<}!>}>,<!!!>{!!u!!"<,!>!>!!",{>},{{{<!!!>!!!>!>e}!>,<!>,<"!!}}ii!>!!!>}>}}},{{}}},{{{{}},{<<}>}}}},{{{{{<}!}<!!a!a!>},<>},{{{{}},{{<ii!o!!e!>},<u!!,e!,,o<>,{<!'i,!>,<>}}}},<i!!!!!!!>!!aa!>>}}},{{<{'ia}!>},<!>},<!>},<eai<,>,{}},{{{{<!!!>},<>}}},{}},{<!!au}!!!!>,{<!>,<a}!"e},a'!{}o!i!!!!"{>}}}},{{{{<}">}}}},{{{},{{{{<,{!>{!>},<!!!>},<e!>,<!!!!!!i<!!}i!eu>}},<!>},<u!>""!>,<!>,<"e!!<!!'!!!!!>!>},<!!!!>}}},{{{<a!>!>!>!>,<!!!>!!!>!>,<>},{}},{{},{{{}}}},{<e!'!!!>},<!!aa,{!!i<,a<!!<>,{<>}}}},{{<"!e<,i>,<!e!!e!o}u{!<!e!!!!!>ia,uu>}}}}},{{{{<!"!!!{!>},<!!!>i!!!>!>,<!>!>!!!>!<!!!!!>!!!>}!>},<!>},<e>},{<!!'!>,<u,o!o>}},{<'a">,{<e<!>},<>}}}},{{{{{}},{<!>!>"o>,<>},{{},{<>,<e!>>}}},{{<!>},<u!!'!>!>}}>},{{<{!!!!,'e>}}},{{<{eea'!!ui"a<o}>}},{{<',!>>}}}},{{{{<<e}e,!}!!!>,<i,,!>},<}<,>}},{{{}}},{{<!!!!uo!!!!!>u'!!uaa!!!>},<u}{!!{>},{{<,!>},<i}a",!!!i!!!!,,!>!e!!!>!!>},{<"}!!!>"}!!!><>,{}}},{{<!!!!!>!>,!e!!!>eu,>,{}},{{<!{a!!'<'"a!>!>,<,!!'},}!!!>},<!u>}}}}},{{},{<a!!>},{{<!!!!<i!!!!!!o}!!,'>},{<!>},<"io>}}},{{{<e!{<eo!>>}},{{{{},{}}},{<}oo<}!!!!i<>,{}},{}}},{{},{{<o!!!>i!i!oi!>o"!>,<!!,!'}!>},<<'>},{{},<{u!u!>{<>}}}}},{{},{{{{{{<!>,<{<!!!>!!!>!>,<!>},<,!'{,'}<a!>},<,>},{<i,<!>!{>,<<}!!!>!>,<i!!!>e!>},<{!!!<}!!<},>},{{},{{{}}}}}},{}},{{{{{<{!!!>>},<!a!e!>!"<"!><e">},{},{}},{},{{<{'io!>},<>,{<eoo!!!>},<<!!!!!>!oa'>}}},{{{<>,<!>},<}{a!>,<>},{{{<!>'!>oa!>!>},<!>!!!>!!!>a!>,<!!">,{<,}<,"i!>,<""!>!!!!!au!!}i!!>}},{<>,<!!}!!'>},{{{<o}{'!>,<o,}!!!>,<!>,<!!!>o!!!!>}}}},{{<!>!!!>e}i!!!>,<!!!>}}'}<>},{{},{{{<{e!>}!>,<!!!!!>{i!>,<!!!>!>},<!>,<eo<>,{}}},{{{},{<'a!!{"au!!!>!>{!<}!>!>,<{>}}},{{{<}!"!!a"e>}}}},{{<!>},<a!!eoa<!!e'!!!!iua!!!>i!e!!!!!!!>>}}}},{<ei!>,}o!!!!!!!><!}}>,{<!>!>,<!>},<<!!!>},<!!!>!>},<!!">}}},{{<'o<'>},<>}},{{{},{<a>}}},{{},{{<o"!!!>'!!ouee<e!>,<!!!>},<<>}},{{{}},{<ao!!'!!!>oee!!!>!>!>},<'!>,<!,a{ao>}}}}},{{{{{<!>!!!>!!u!>},<>},{<,uo!!!>a>}},{{{<a<'>},<!>},<u!!!>,!>,<!!uu}o,<!!!>!!!!!o!,>},{}},{{<ei!>},<}!>iu!!a!!'e,"">}}}},{{<'!{,}a!a'!!a!><}!i}>,{<,{aii!u!!!i>}},{},{{<!!!>,<!"{>},{<aua'!!ea!!}i!!!>,<uiu<o>}}}},{{{{{{<>,{<e"!>,<,i,!>,<i!>,<'{>}}},{{<"u>},{<!!a"u}!>},<{!<!>},<e"u!!!!!!}!!!>!!e!!!>!>},<>}}},{}},{{{<!!",!!!>,<u{!'o"{<!!a!<e"ee<!>},<>,{<!!u!!u!!"a'!>,<!!!>{!!!>!!>}},{{<!>!>,<i'!!ooo'o!!!>!>,<">,<"i<>}}},{{{<!!!!!!,oa!!a!>!!!>o{>,{{<}i"i}!!i{a,<<u>}}},{{{<uu!!!>,!!!>!!!>{!><i!!a,{{!{}!>ia>}},<,!i,u!!!>!u!>,<!!u!>,<>}},{{},{},{<<!>e<!!"!>},<a,!>,<i}<i!!a},>,{<aio'!'a}!!e!!{a'<'"!>>}}},{{{<!>!!!!!!!!!!!>},<,!!!>!!>}},{<}o">,{}},{<<}""}!>,<>}},{{{<"!{'a>,{<!!!a"{"{!!!>o!!!!oa!>,<u!!>}},{<,!>{,ii"u,!>!!!>!!!>"o"ui!'>}},{<i>},{{<!>!!!>,<i!a<'!>},<>},<!>,<o!o!>,<i!>>}}},{{<!!!>!>ae<e!!>},{}},{{{<!!e<!>},<u!>,<!>!oie!>!>},<'!!u'!}>,{}},{{<!!!!!>,<!!!!!e!>,<!!"!>a{ae<}e!!,!>},<!!!!!>!>,<>},{<!>,<u!>},<{a!>,<a!!!>},<e{!!!>>}},{<}!>},<>,<!!!>!!e!u!>'a!!!!!>a!!'>}},{{{{<!"u<o'!>},<e!"!>,<!!!>,!>,'>}},{}},{{{{<"!>,<u!!!>!,!>},<u!>}i,a>}},{<u!!!!!>},<>}}},{{},<!"i!>},<o>}},{{{{{<'!!{!>},<!!!>!,a,ia!!e!>,<'}!>,<'!!!>,<>}}},{<<!>{e!>,<!>},<!!"',>}},{{{},{<!!',,{!!!>},<i>,{{{{},{<"!!!>'!>''!!!>!!{{>}},<eaeu>},<<,,i!>},<o!!!>}i>}}},<',u"o,'uou!!!>,<!!!!u<!>!!!u!>,<!!!>>},{<"i!!'<>}}}},{{{},<<!'>},{}},{{<>,{<>}},{<!!{!>"!!!>,<!>},<,<<}!>},<i!!i<e>,{<o!!uu>}},{<!>!'{o!!!>},<!!"'!<oo!e!!eo!!!>!>},<>,<!!!a{!>},<e<e"!!e!!a'!"<!aio}>}}},{{{{<>},{<!>},<<'e>}},{{{},{{},{{}}}},<!!!>},<!>!!{{u'o!>!>},<!>,<!>},<},!!a}>},{<!"!>},<!>''o<!o!>,<i>,{<oa!>,<<'<!!!!,!>,<!>,<!!<!!!>!!!>>,{<!><a!!!>i!>},<!'!>},<a!!!>!>},<u>}}}},{{{<!!{!>},<}>},<!>,<!>{!>},<o>},{{{},{{<i!!!!{''!i'!!,>,{{<i""e<!!e!>},<>},{<!!!!!{}{!>>}}}},{{<!!!"e!!'!>u"a"'}e!>}<!!<!!!>>,{}}}},{{<}>,<o{"{>},{<!>,<u}!>,<!!!!'!!!>!!,!!ue!>!>>}},{{<"'}"!!!>>},<!{!!!!!><<"{<!!!>!>aie"!>,<"e!>>}}},{{{{{<},!!!>!!!!a!>,<>},<!>,!>,<<oe>}}},{}},{}},{{<!}!>!!}!!<!>},<!!'a"!!uo,a"!!!>e{{>,{{<!>!>,<u>}}},{{}},{<a!>},<'{ii>,<!>},<!>,<,au!},e!}!>>}},{{{},{}},{{},{}},{{},{}}}},{{{{<o}!>,<e>}}},{{<"!!!>!>,<!>,<!!'<!>},<'>}}},{{},{{{<!!>},<{'{,!'{<>}},{{},{<"!,!}{{{!>,<>}},{{<!">,{}}}}},{{{{{<eo!!!>!!oe!>,<!a{!>'!!!>!!!>o>},<!!!>},<a!!"!o!!!!}'!!ie!!{u>},{<<<!!}'e!!!>!}>,<!!!!!<!>},<}!!!}u!>},<!>!!!>!!!>!!a!!!!!!ou!>!>,<>},{}},{}},{{<oe}>}}},{{{<!!''!>,<ii!<o!>,<!>},<ie!>!>},<!!!>>,{<!!ea!!!>!>"!>!>,<<!!ue'eu!!!!a>}}}},{{{{<'!}}>,{}},{<!!e>},{{<!!!>o!!"!>!!>},<!!}ii!{!ee"!>},<!>},<!!!>u'!{"!>,<!"">}},{{<!!>,<!!!>},<!!!>!!!>!>a!>},<!!<!!!}',!!!>u>}}},{{{{<aui}'"!!!>>,{<,a<i<uu!>''a,!!}>}},<<!>,<i!>},<>}},{{},{{{<a<!>"o{'"{}!!!>!>},<>},{<ia!>,<!!'!>},<!!i!!'e!>e!>},<}"!>!!!!!o!<!!>,{<,,a!!}!!!uiuai!!!>!!,>}}},<!!!i!>},<!!!o!i>},{{},{{<>}}}},{},{{<!!{<o!!!>,<i!>!!!!i!!,>},{{{<!!e}!!}!>},<<i!>},<<'<>},{<!!!!a!',{<{"e'u,!{!a>}}},{{<!>,<>}}}},{{},{{<<io!>e}o>},{{{<!>,<!!u"!!!>!!u!!''>},<uea}a!>!!}iu}>},{<!,!!!!{,!!!>i,!'{au{'!!!eueu>}}},{{<!>,<u}e"!!!>{!!e>,<!!!!!><!!a!!{'!!o!!!>!>}!>},<!>e!!"!"!!!!!>!e}{>},{<o'e!!!!!>,<u!!!>o!>},<'}!>},<!>,<!>a<"u>},{<"{!!!>,<<>,{<!!,!!!>},<o!>},<,!!eaa',<{uo>}}}},{{{{<e!!'!!!>}!>},<'!e!!"a!>!<}!>,<!>,<!>,<u!!!>>},<<!!!!!!<!!!>,<<!>,<oau}>},{{{{{}},{}},{<!i!>},<!!!>!>"o",u'!<!>"!<!!!!!>!!!>>,{<!!!>!!!>'{u!>},<o!'!!ao>}},{{<!><!!}!!!!>},<'!!'!>},<!!!!!>},<!!!>!e<a"<,!!!>'u,>}},{{{},{},{<!}ii!>,<o<!>}''!!!ae}!>,<"o">,<u!"!!!!!>!>},<!!!!!!"!!aee}!!!>!>},<'!>},<},a!!!>>}}}}},{{{<!!!>"i!>!>e!>},<>,{{<'{!!!!<"a'ou!>},<>},{{}}}},{{<a!!!>,<!!!!u!i"au<>,{}},{<,!!!>!>},<!>,<!!!!!e!>,<<!u!!>},{}}}},{{<,o!!<!!!>o!}'!!!>},<,!!!!o}!>},<u!>,<ii!>>}},{{{<,!!a!>>}}}}}}},{{{},{}},{{},{}},{{{},<'!!!!!>!!<!>,<'u!!u'!>!!}!>,<>},{{{<}"u!>!>,<!!!>i<"'i!i{!!!>!>},<uu!!!i}>},{<{,!>!!oa{,a,'!>},<a>}},{{},<""!>,<!>},<"!!!>!!!!!"!>},<o!>},<>}}}}}},{{{{{},{}}}},{{<e!i'}!ei}'u!>!i!!""<!>""e>,<}>}},{{{<!>},<,<!!!!!!!>ue"eoo}"!!!>},<!!!!}u!!!!!>!><>}},{{{}},{}}}},{{{{<!!!>!>!>,<!!!>!>},<!>iue!>},<}!>},<}<ae>,<!!!>i>},{<{",},!!!>!>!!!!!>!!!>>,{<i!!!>i!>,<ui,'}o,'u!!",!>,<u>}}}},{{<"}!>},<''{!}ie}!au"<!>},<!>},<!!,>,{{<>},{}}},{{{<!>!!!>},<o>},<!>,<!{a!>,<'!>},<u>},<ue!>},<,u>}},{{{},<}!>},<,a<'u{,!>u!>!!!>!>},<!>,<o},>}},{{{{<a"!!!>}ou>}},<<!!<{i>},{{},<!e!!!!"}'!!},!!}!!!>,<!!!>>},{{<!>!>}!a'!><!>,<!!<!!!a!!i}{!!!>!!!!{>},{{<!!!!oi,!!!o!!!>!!!!<,!>u}!!!!e!!!>!i>}}}}},{{{<!a}!>,<}!a>,<!!!!!>!!,"}<"!!,ai!>,<}u>},{},{{<!"}!>},<u!>},<a{!>,<>},{<!u}!!<!!!>u!!i!!!>!>"""!'ou>}}},{{{{<aaie!!ieu>},<i"'}a'a!>},<!'{'!!}!!u<>}}},{{{{<o!",!'>},<<!!!>!!!!!>},<a!!!!!>a,!<!!}<o}>},{},{<"'{!>},<!!"!!!>u!!!>!'!}e!!aaa>,{}}},{{{},{},{{},<!!<{{!!!>},<>}},{{{{{{<a'i'!!,u!!!>''{<a!oo!>},<>}},{<!,i"!}!!!>ei!>},<"e!!!>!!oo!>!!i>}},{{<!>,<{ioi!>,<>,<,>},{{{<!!!,iiau{{e!>eu'<!><>,<!u}!!!>!>!!a,>},{}},{<!>},<{!o}'!!!!!!!>u!>!>u!!!!">,{<!!"!'!i{!{a}>}},{{},<}>}},{{}}}}},{{}},{{<!>,<!!eu!}"a!!i!>{}oa!!!>!>,<o!>,<"!!'>}}},{{{{}},<!>!e>},{<u!>,<!>,<!!!>!>,<<<!o!!!!'{}e>}},{{<!!!>,e!{u<"!!'!!ioo},ei!!o,!!!>>},{}}},{{{<!!!>,<!{!!!>>}},{{},{{{<!"!!"!>!!!!!>!>}!>},<!,"!!!i>}}},{<<!!,!>},<!"<"o>}},{<{>}}},{{{<!>},<>,<i!>!>,<a{}oa>}}}}},{{{{{<{!u<!>!!!aa<!!!>,<!>},<e!!a'a!>,<>},{<<!>},<ii}"<<>}},{{{{{},{<{","!!<!!!>,<a}!>o}!!,i!!u>,<a!>,<<!!!>,<a!>a!!!!!>!!!>},<!!!>!>},<e!}i>}},{}},<!>!,'u!>,<<oo>},{<>,<>}},{<u>,<o!!!>e!<o!>,<u,{">}},{{{{{{<}{!a"!>},<a!>},<!!!>!!!!u!'!>,!>!>,<e>}},{<!>,<"}iu!!!!!>!}>}},{<{o{!}>}},{}},{<>,<>},{{{}}}},{{<,!><{ii}!>,<ii!>!>},<">},{{<'<!>},<!>,<>,<o!>},<{!!''}u!>i>},{<!>},<{<e!ii!!}>,{<!!!>>}}},{<!!!!!>!{!>},<<<{au!!!>e!!'!>,<,{i,>,{<!>'},!!u"!e!!!!!>!>!,u,{!>,<!!u!!!>>}}},{{{{<u!>{a'<"!>,<e!!!>e<o!!a!!!>!!"!!!!!>>},{{<ei{>},{<u<}>}}}},{{{{<'"o{!i!<,!"!<oi>,{<"!!o!>,<u"!>!>!!!>{!>,<!>,<!!u'>}}}},{{{{{<!!!>,<!>},<o!!!u'ea!!!>},<uu{u>},<ou!{''!>'"}!>{'!a!>,<!>}>},{<ai{'!>},<!>iu!u>,<o!>oa{'>}},{{{{},{{<!!}!!<!!'ui>}}},{<{!!'>}},{{<>}}}},{{{<e>}}},{{<ou!!}i!u!!!>}!!"!!>,<',!i!<!>,<<!!!>!>,<!!!>a!>},<!>,<{!!!>{>},{{<e!!!>{!}e<'!>,<!!ui"'!!i>,{<uiu>}},{{<!>,<!!!>!>!><!!""'!!!>,<>}},{{{<!>!!!>!!!>!'!!a{a!>},<!!!>},<!!!>}eae<a>}},{<!!!<oi!>},<i'!!<"!!,e!>},<o!!,a!>!!>,{<'u,aeu!>},<eu,aa>}}}}}},{{}}}}},{{{{},{<{!,>}},{{<!!u}!!!>ui"!!i'au!>},<!i!>e!!!>>},{{<!!{{!e!>{!>},<!>!}"!>!>,<!>!!!'iee!!}>}}}},{{{},{<"!!,aa<u!!!!,!{>,{}}},{},{{<!>,<!!{{{!!!>'!!!>!!<}!>,<u!>,<>}}},{{{<<i!!!!!!"!{!>},<!!u'u!aoe<<!!!!!>iu!!a!>>},{{{<"i!!!>>},{{<!>,<!!o!u!!!!o!!!>e}!>,<"!>!o}!>,<!!"<oo<>},{}}}}},{{<!>,<!>},<!o!>,<aoea!>},<!>eo!!e!u'!!!!!>{!!!!!!">,<{!!!>,<!>o!!u"!!!>e>},<i,o}!!!>!>,!!!{'!>},<i<!!!>"i<o!>,<!!!!>},{<!>,<>,<{aau{!!'"!!!!!i!!}<i{ue,>}}},{},{{{{{<!>,<'!>>}},{{{<!>,<{>},{<o>}},<}e>}},{<!>},<{}},u!!}!{<o}!!!>},<!>{i'!>},<>},{{{<<ia<!"<<!!e<!!!>{'!>,<"!!,!}>}}}},{{{{{},<e!>},<{,u<>}},{<",!!!>!>},<"!!o!>!}!!!!i>,<!>e!!!>},<}!!!>!!!!!>!!!>a!>},<a>}},{{<eo!!,!!e',!{<{u!>,<{>},{{<!>},<!>!!}!!i{!>,<!!!>>}}},{}},{{{},{}},{{<,o'"{}!>},<u>,{{<!ua,o!>!!io!!!>!>,<!>},<!>u!!"{!>},<e>},<!>!!{o!!!u}"!!!>u!i<e!>},<o"'u,!o!>,<>}},{<ou!!>}}},{{{<o>},<''!u!>,<,!>!}"!>!!!>},<!e"!>!>},<>}}},{}},{{{},{{{{{<!!"}u'!>},<'!!!><!!'!>a!o!>},<>},{<!!'<!!<!>!!!>u!>,<!!}u'<iua!}!!"!!>}},<"}!>,<!>},<!e!!!>!>,<!e>},{{<i!>},<{!>!>o<u!>iia!!!>,a!!u!>!!a!>},<>}}}}},{{{{<>}},{{{<u!}"!>},<<o!!!>,<},e<>}},{{{<{!>,<{>}},<>}}},{{{},{{{<i<!>},<!>,<'i!>},<u}"}!!!>!!!>!!{}>},{{<,ui!>,<au!ae!>!!}<!!!>}!'!!!!!>>}}},{{{<i,!>},<,{!!"<!>,<u!>},<!!<<!"uu,ie>,{<!!!>},<'"!>},<!>!>},<!>},<!!!>},<{!>},<o!!"!>'aa>}},{<o!!ea!!{{a!>,<!!!!!!!>a!!!>!!a'}>}},{<''!"e{<!o!>,<!!e!!i!>,<>}}}}}},{{{{{{},{}},{},{{<!!!>},<,!!,o'<!>!!!>ea!>,<!!!>!!!!!!!!!>,<>}}}},{{<i<i"}!!!>!>},<!>a!>,<!>,<!!!!!>"!>,<aa,o!>>,<!!"!>u!>>}},{{{{<<!>!>}!!!!!!!!!!e<<!!!!u<<<!!!!}!">,{{<!!!uuia!!!>o!!!>!!!>'"e'>},{<!>,<!!!!>}}},{{<}!>},<!!!!!!<!>{!>},<!}!>>}}},{}}},{{<e!!aou"!!<!"uoao!!!!<'!>,<""!!!!!>">,{}},{{<!>},<!>,}}uoou!'!>},<'>}}}},{{{{<!>,<!!e!>,<<!!"a'!>,<!!i>,<<!>!>,<o>},{},{{{<!!!>!!!!oe!>""<u!!u!'{i!!!>},<,>}},<,!<!>e!<>}},{<!!!>,<"!!!>ii}"!!o!!!>!!!{!i!!!>},<"!o!!u!}>},{{{<'!!"!>ea'}!>},<>,<}!>,<<o!!!>>},{{<!>},<!!!!!>,<i!>,<!!!!""<u!>},<ua!o!!!>,<!>,<,<}>}},{{{{<"}!!e>}},<}!>},<!!!!!>!!!!""e'!!!>u'!!!i!!!>!!!o!>,<!>,<>}}}}},{{{{<!>!>},<{!>!!{>},{{<a"!}i!>u<!>!>},<!!!>>}}},{{}},{<e!!!!!>a>}}}},{{{<!!}!!!!!!!>}i>,{<!u'!>,<<!>!!'i!!,a!a}>}},{{{}},<!!!>>},{{{{<!>,<!!!!uu!!o'!>,<<i!"!u}!i!!{>}}}}},{{{<{<u}!>,<u'<'>,<'!>,<!!e'!a!>!>},<,>},<oa<!>,<>},{{<!u'!!!>},<>,<u"!>,e!>},<}"!>!{!!!!}i!i!!!>u>},{{{},{{<!!!!>}}},<ao!!!>}a,{'!>,<{>},{{<ao<>,<"u}>}}},{{<'u!>,<!,a'!>},<<!>},<!!!>>},<<!!!>{e>}}},{{{{<{ouu<!!a>},<!!!!{!>,<e!>!!e}i!!a!!">},{<!>},<!!!!}!>!!!!!>},<u!>},<ea!!i!!i>},{{{<!!!>>},{<!>{a!>,<!!u'!!{!!i!>,<o,!>,<!>!!e!>,<>}},{{{<!!}{!!!!,o!>a'a>},<>},{<aa!>,<!>!"!!!>,<!>,<e',!>>}},{{{<u!!!!!>{<'a!!a!iae}u!!!!a!!"!!!>'!>},<>}}}}},{{{{},{<i<ao"},!!!!!!!>!'>}}},{{{{},<{,oaa!>{<eo!>,<!},oei,oe>}},{{{<!aoe{!>!!"{>},<o!>},<o>}},{{<'!ia!!!>>}}},{{<!>ea!!<!>,<}!>!'i"!!e'}!{!!>,<!!ioo'!!!>,<a!!!>!!{<!'u!<i!!!!o!!!!!>!>!!!>},<!!>}},{{<{}!!!>"!<a!!u!!{!!{e!!'>},{{{{<{e'e"!>},<!>,<!>,<',!o!!!>,!!!>oe<o!!>,{<'!!!>!>!>,<o>}}},{{<'!>},<!!o!!!>u!>!!!!{!>},<{'!>},<">},{}},{{<'!{"!!!>!!"">,<'ei"!!oa>}}}},{{<!!!>!'e"i{i!!">},{}}}}},{{{{<"i>,{<i"a!!i>}},{},{<!!!>o>}},{{{<!>!!!>},<ua!,!!}!!!>!>,<u<'>},{}},{<a{a!>},<!!"!>,<>,{<!e"a>}},{<u}!{!{i!>!>o"!>},<i>}},{{{<}!!'o{!>},<!!<}!!oe!!u!>},<!u>}},{{{<o!>,<!!<>},{{<a!>,<!,!!u>}}},<!!!>,<'o},a{!>u!!!>},<e!>},<!!!>!>,<e!>},<>},{{{<<e!!!><iu<>,{<o!!!>},<io!>},<},!!}!!!!!>">}}},{<>,{<!>,<!!!!!>!>!>}!>,<a!!,ae!>},<e>}},{<!>},<!>o{<}!<,e!>,<!!!>>}}}},{{<!!,<!!,!>'!>",u,!}<,!!!>},<>,{{},{<uo"{!!!ou!>,<}o{<!>"!!!!u!!o!>o>}}}},{{{},{<'!e'!!!>!!!>a!>},<!>!!!!i>,<!>!!!!!!!>!>,<"!!!>!"',}uo"!!<!>o>},{{<a'!!!>!>a"o',>},{{{{<!>},<}!>},<!!"a!>},<'!>,<>}}}},{<o,!!ua'!!!!ai!>,<!!!>!>!!!>!!i>}}},{{<o!!!!<,,!!!><{oa<}ou!!aa!!!{>,{}},{{{<{!!e}e!>!>,<!{!>,<!!o!!!>!!!><>}},{}},{<>,{<!>!>},<!!!>!!!!ae''!!"u!!!>,<!!!!'!!"!i!!'{!!'>}}},{{<}oi"uue!}eiu>,<!>{!!}o,>},{{},{{<}!>,<!!i{!!!!!a!!{""e<,!!!>},<!!!>!!!'>},{{<!!"!>},<!!!>o>},{<,!"'!>'e'!>!>},<!!!!!>"!>>}}}},{<aea{,!>>}}},{{<}!>},<'!>,<!!!>!!}!>,<!>,<e!!,<>},{{{<!!"!>,<o<>}},{{{<!!!>u<!>,<o!!o!!!>>},{<!!a!<!!{!!!>a'!!i!!!>u>}},{{},{}},{<"o!!'<<!>,<<!!">}},{<,o!!!>!<,>,{}}},{{<}>},{<"!!o'!!a!!!>'>},{{{{<e'!>,<a!>,<o'o!!"<>},{<!>},<>}}},{}}}}}},{},{{{{},{}},{{<!!,!!!!o"!!!>,<!!i,!>,<}o'!>,<!!!>,<!!!>>,{{<!!!>!!!>}}{!!!>!!i!>},<>}}},{}},{<<!>,<'!!!>ei!>,<!>},<!>},<>,{}}},{{{<!!!!!o}!>},<}!<'{!au!!{!!}>},{<'u!!{a,!!'!}oo<o{i{>}},{{{<'!!!{!!!>!!a!>>,<'<"'!i}o!u>}},{{<!oe!>!!!!!>a}!!!!i!!!>}>},{<u!!!>>}},{{{{<u!>,<>},<,!u,!!e{!!i!>,<,!>},<!!!>!"!!!>>},{},{{{<,}}"!!!>u<>},{}},{{<!!!!!>!!<>},{<o,'>}},{<{!>},<!>},<eu!'e!>,<i{!>,<a'!>!<!>{!!!>},<o>}}}}},{{},{<a!}>}}},{{{<!!i>},<{}'<!>{}!!ao,<i!!!""!!!>>},{{<!>,<!!ai}{o,"o"!i!{!!}o}>},<{!!<eia!!ue!!!>!>u!!!!!>,<<e>},{{},{<,>}}}}}},{{{{{{<!>},<!{e!!{a<!!!!}!>ui!!}!>ao!,>,{<!><,o'a!!!!!!!>'i>}},<!>,<{au!a!>,<!!!>,<>}},{{{<!!!>,<!>,<!>},<e>}},{{<"!!u"!!!ao'>,{<u<}!!!>},<<au"!!!>o!!!>e<!i}!!!!!>>}},{{{{},{<ie>,{<!>,<>}}}},{{<iea!u!!!>},<"{>}},{{<u!<,u!>,<a!!!>!>,<!>,<e>},<{>}},{{{<!!u!!'o}!>,<>},{<{!>,<oe,!{o!!!>!!a!!e!!',i>}}}}},{{}}},{{<!!!>!>},<!!!>!>,<'o<,i'!>,<u,}!!<!!!>,<,!uo>,<!>,<o{{i!!!!!>'{i!>"!>},<!>,<}!'!iu>},{{<!>},<e"o>}}},{{}},{{{{<a!!,!e{i!,,'ioe!!a!>},<,!>},<ii<e>},{}},{{<e>}},{{<!>,<!>eee!!!>!>},<!>,<"!!>},{}}},{{{{<!i!,,!>,<a!}'"!>},<!!!!!>},<a!,a""<{>,{<!!'!!!><u!!!<!!!>!>!!!>'!>},<!!!!>}}}},<!'au!o,aai!>!>,<!!}a!>}u!!>},{{},<a!>},<'o!!!>{!!!>},<!!!>!>},<,"!!!>i'>}}},{{{<,!!<!>},<!>,<,!!!!!>,<!>!>,<!!!>'!>},<>,{<!!!>!ai!>},<!a'>}}},{{{<ei!!,!>,<!!}{u!{!>,<<!!!>'!"},>},{}},{{},{<ou,!>ao'{!}<>}}},{{<"a!!!<',!,ou>,<a!>},<,!}"!!!i!>,<<!',!>},<!!!>},<>},{{{<!!{}"!>},<a"!!!>"!!o">},{{<}!>},<!>,<a,e!!o,!!!>o!!e{,<{>}}},{<<!>>,<!>,<}!>!,ouiou!!'o!!!!!>i{>}}},{{{{<"!'}>}},{<!>},<!>,<!>!!!>au!!}e!>>,<"!!a!!!>,<!o,>},{<!!}!>},<<u!>},<{>,{{<!>},<a!aa<!,{!!!>}"{"!>,<!>},<>}}}},{{},{{{{<!!e!!u<o!!"!>!>},<""'o!>!>>}},<!!!><<!!!>},<{!!!>o!!{'!>,<!!<!>},<!!!!a!!u}!!!!<>},{{{<<oo!>,<",au!!!>!!"!>!!!>!>},<'e!>u>}}},{{<i!a!,!!!>!!!>,<!!!>!o!<ai!>},<<!!!>>},<!>!>,<!>!>},<!>,<!!'!>},<!>},<!!o'>}}}}},{{{<>},{{},<,!>},<!>},<!>},<o!>,<!!{a!>,<o>},{{<<e>},{<!>},<!!<u{!!>}}},{{{},<!!}o!!!>>}},{{<!!!>o>,{<!>,<!>,<!!!>!>!!e!!!!}'>}},{{<o"i!!a!!!!>}}},{{{{<!!o!>,<i}<!>,<!>,<"!!!!!>a{,!!!!!!"a'>,<uu}>}},{{{{<!!!!e>}},{},{<!>,<!!!>}!!<a!>},<'ou!>,<!u!>,<i>}},{{{{<!>,<i{,<!>,<,!o}">},<!!}">}},{{<}!!,!>,<ae!!,!!!>"!>,<!>},<a!e!!!>a!'!!!>!!!>>,<o,a!>}e!!u!!!>}}<!>},<<>},{<{,>}},{{<a}!>},<!!!!!>'!>!!!>!!>}}},{{<i{{!!!!a}e!!,{!}!>!>},<!!!!!>!>,<'!!!>'!!e!!{i>,<!>},<!!!!!!!>"i!>i'!!,e!>,<!'!>},<}<!>,<o>},{{{<"!!<u!!!e}o,!!!>},<,!>,<o>}},{{},<"!!i!!!>,<!o"<o!io>},{{{<}{!>,<!}oo"!ui"},,!!!!}<!u>},<>}}}},{{<!>,<!!e!!!>!>,<!>,<'o!>,<,<a!!>,<!!!>!!!>i!>},<!!<!>},<!!!!!!!>!>!!!>,<!>},<!>},<}o'!>,<e!e!>,<>},{<!>,<!!!>,<,!!!>u!!!>,<a!<iiia!,e!!!!a!!"o!!!!!>>},{{<!!!{'!<!!!>!,{!>},<e!,!>},<a>,<!!!>e!'<a!!!!!>oe!>,<'!>},<a!!o>},{{<ae,!>},<}"!!!>!>,<!>,<i>},{{}}}}}},{{<>},{<{!>!>!!!>!!!>!>,<!!!!!!!!<!{<!!!>>}}},{{}},{{{{}}},{}},{{},{{{},{<{!>,<''!>,<'<i!!!!!!!>,<!>,<!!!>>}}},{{<<!!!>e,!!!!a!!<"u{!>},<!!,!>},<!>},<'>}}}}}},{{{{{<!>},<!>},<!!!>!>,<>},{<oa!,'!!<u}{o!>},<o!>},<}>}},{{<{!!">},{<<>}}},{{{},{<!!!!!"u!>'!>!!'i!!!>},<ei>}},{{<!>!!>}}},{{<!>},<e"ea<!>,<u!!!>,<!!!>a,>,{{<!>},<,{e{!>,<i{!>}e!>,<!!''a!!ii>}}},{}},{{{{{{<{e!!!>!!!>!!!>,<!>,<"{>},<<!!e{"!!i,}!!,ou!!!>}<<!!>},{{<!>},<}!!!>'!!ee!>!"a!!a'a!!!>},<!>!>},<>},{<a!}!'a!>!!!>!!!>!!!!!>!{!>>}},{}},{{<!!!>{ue<i!!e'!>""!>,<>}},{{<o",!>},<e!>,<!!!!"!>},<auui<"!!!>,<!>},<>,<>},{{{<o!!"!>}o!!"i!>,<"!!!>{"o!!!>>},<!!a<!i}}"!>,<"!>},<}!!o'!>{e">},{{<i!!!>!u<!!',e{>},{<!!!>',!!!>!eo{oe!>{>}},{{<!>!!!>i!!!><u!!!>!!!}'>,<o!>},<"o>},{},{{{<}a!!}!!}u!>,<oa"{"!!!>e'!!!>,<<!{!>,<>},<}!>!>},<!>!>},<,},o"u!!!!!'{!!!>>},{{{<!!!!i<}a!><a">,{{<{}'>}}},{{{<o!!!!!>u>},{{<>},{<{!>},<>}}},{{<!!!>!}!!!>!"!>},<"<<>,{<!>!},!!!>!>},<!!a'ao'i!>},<o!!!>>}},{{<a{"oi!!'!>},<<!>},<>,{<>}},{<o"o{{!>},<uo"!>},<!>,<}u>}}}},{<}'!>},<<"u!!!>!o!>a>,{<'{a>}}},{<<,!!{!!!>,!!,'ua!!!!!!!>,<!>,<!!,<!>},<'!!!!!!>,{}},{{<"e!o!!a,!>,<!ei!!!>!u{<>,<!>,<!>,<!>},<a!>,<<!!!>a!>},<!u!>,<}o>}}}}}},{{<!><'{!>,<}""!>,<!!!>!e"e>},{<!<!!!>>}}}},{{{<"!!!,u,!,!<}<!>,<!ao!>>},{}},{<!""!>,<!>,<}'{"!e'o!!a!!!>!!{}!!!!>,<ooi!>},<a<!>>},{}},{{{{},<!>!>,<i!!!>,<'e!!!>!!o!>!"!>},<!!!>},<"a!>,<'>},{<u<!>},<!!{>,{<'o!>!<!!e>}}},{{{<e!>},<!>,<,}i!>,<{!>},<o!>},<},<>},{{{{<!,!!{!>},<,,{!>,<!>},<',u"!o>},<e,>}},{<'i!>},<a!!ao!>,<u!!u'o!!">,{}},{{{{}}}}}},{{{{{}}}},{},{}}}},{{},{}}},{{<a'!>,<!!!>!!!>!!u'i!>!!!>!!!>u{!>},<!!!>!!!!!!!>>,{<!ao'i}!<>}},{{},{{{{},{<!!<!!i,}>}}}}},{<<!{>,<i!>!!!>'}eu<}!ii!>,<e!>,<'i}!>o>}}}}}} diff --git a/09/lib.scm b/09/lib.scm new file mode 100644 index 0000000..5eac027 --- /dev/null +++ b/09/lib.scm @@ -0,0 +1,70 @@ +(library (lib) + (export solve-part1 solve-part2) + (import (chezscheme)) + + ; Global state... a sin, but very convenient in this case! + (define chars '()) ; Characters still to be parsed + (define part1-total 0) ; Total score of groups in input + (define part2-total 0) ; Total non-escaped garbage chars + + ; Is the next character in the stream equal to `c'? + (define (peek? c) + (char=? c (car chars))) + + ; Blindly accept character and pop it. We do all detection + ; via `peek?', so we don't care what gets discarded here. + (define (next) + (set! chars (cdr chars))) + + ; Parse a "group". We can assume all input is well-formed, + ; which really helps keep this code as simple as possible. + (define (parse-group depth) + (next) ; Accept initial #\{ + (let loop () + ; Expect start of "group" or "garbage" + (cond + ((peek? #\{) + (parse-group (+ depth 1))) + ((peek? #\<) + (parse-garbage))) + ; Expect comma or end of current "group" + (cond + ((peek? #\,) + (next) ; Accept #\, + (loop)) ; Parse next "group"/"garbage" + ((peek? #\}) + ; Add current group's nesting depth to total score + (set! part1-total (+ part1-total depth)) + (next))))) ; Accept #\} and return + + ; Parse "garbage": everything until next non-escaped #\>. + (define (parse-garbage) + (let loop () + (next) ; Accept char (#\< at first) + (cond + ((peek? #\>) + (next)) ; Accept #\> and return + ((peek? #\!) + (next) ; Accept #\! + (loop)) ; Continue to escaped char + (else + ; Add this character to the total count + (set! part2-total (+ part2-total 1)) + (loop))))) + + ; Reset global parser state and parse the input string + (define (solve-puzzle str) + (set! chars (string->list str)) + (set! part1-total 0) + (set! part2-total 0) + (parse-group 1)) + + (define (solve-part1 str) + (solve-puzzle str) + part1-total) + + (define (solve-part2 str) + (solve-puzzle str) + part2-total) + +) diff --git a/09/main.scm b/09/main.scm new file mode 100644 index 0000000..b4b540a --- /dev/null +++ b/09/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 21037 for me +(printf "Part 1 solution: ~a\n" (solve-part1 input)) + +; Part 2 gives 9495 for me +(printf "Part 2 solution: ~a\n" (solve-part2 input)) diff --git a/09/test.scm b/09/test.scm new file mode 100644 index 0000000..6d232da --- /dev/null +++ b/09/test.scm @@ -0,0 +1,68 @@ +(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 (equal? 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) + +(test-part1 "part 1 example 2" + "{{{}}}" 6) + +(test-part1 "part 1 example 3" + "{{},{}}" 5) + +(test-part1 "part 1 example 4" + "{{{},{},{{}}}}" 16) + +(test-part1 "part 1 example 5" + "{<a>,<a>,<a>,<a>}" 1) + +(test-part1 "part 1 example 6" + "{{<ab>},{<ab>},{<ab>},{<ab>}}" 9) + +(test-part1 "part 1 example 7" + "{{<!!>},{<!!>},{<!!>},{<!!>}}" 9) + +(test-part1 "part 1 example 8" + "{{<a!>},{<a!>},{<a!>},{<ab>}}" 3) + +(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) + +(test-part2 "part 2 example 2" + "{<random characters>}" 17) + +(test-part2 "part 2 example 3" + "{<<<<>}" 3) + +(test-part2 "part 2 example 4" + "{<{!>}>}" 2) + +(test-part2 "part 2 example 5" + "{<!!>}" 0) + +(test-part2 "part 2 example 6" + "{<!!!>>}" 0) + +(test-part2 "part 2 example 7" + "{<{o\"i!a,<{i<a>}" 10) diff --git a/10/input.txt b/10/input.txt new file mode 100644 index 0000000..59db45c --- /dev/null +++ b/10/input.txt @@ -0,0 +1 @@ +31,2,85,1,80,109,35,63,98,255,0,13,105,254,128,33 diff --git a/10/lib.scm b/10/lib.scm new file mode 100644 index 0000000..11ad449 --- /dev/null +++ b/10/lib.scm @@ -0,0 +1,123 @@ +(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 commas into list of substrings + (define (string-split str) + (define (char-comma? c) (char=? c #\,)) + (map list->string (list-split char-comma? (string->list str)))) + + ; Reverse order of numbers in index range `[pos, pos+len)' in state + (define (reverse-range state-old pos len) + (define state-length (vector-length state-old)) + ; Initialize `state-new' as a copy of `state-old' + (define state-new (apply vector (vector->list state-old))) + (let loop ((i 0)) ; `i' is the offset from `pos' + (if (>= i len) + state-new + (begin + ; Copy `state-old[pos+i]' to `state-new[pos+len-i-1]' + (vector-set! + state-new + (mod (+ pos i) state-length) + (vector-ref + state-old + (mod (- (+ pos len) i 1) state-length))) + (loop (+ i 1)))))) + + ; Apply a single round of the (main phase of the) hash function + (define (single-round lengths0 state0 pos0 skip0) + (let loop ((lengths lengths0) + (state state0) + (pos pos0) + (skip skip0)) + (if (null? lengths) + ; Once we've exhausted `lengths', return the full internal state + (values state pos skip) + ; Call `reverse-range' for `(car lengths)', and update state + (loop + (cdr lengths) + (reverse-range state pos (car lengths)) + ; (We just let `pos' grow, ignoring circularity) + (+ pos (car lengths) skip) + (+ skip 1))))) + + ; Apply `single-round' `n' times, reusing the full internal state each time + (define (multi-round n lengths state-old pos-old skip-old) + (if (<= n 0) + state-old + (let-values + (((state-new pos-new skip-new) + (single-round lengths state-old pos-old skip-old))) + (multi-round (- n 1) lengths state-new pos-new skip-new)))) + + ; Initialize state and apply `n' rounds of knot-tying algorithm + (define (solve-puzzle n lengths) + (define state0 (list->vector (iota 256))) + (multi-round n lengths state0 0 0)) + + ; Convert "sparse hash" to "dense hash" as per part 2's description + (define (sparse->dense sparse) + ; At first, storing `state' as a vector was more convenient + ; because of all the indexing, but now a list seems better. + (let loop ((state (vector->list sparse)) + (dense '())) + (if (null? state) + (reverse dense) + (loop + ; Remove the first 16 elements from `sparse' + (cddddr (cddddr (cddddr (cddddr state)))) + (cons + ; XOR together the first 16 elements of `sparse' + (apply bitwise-xor + (list-tail (reverse state) (- (length state) 16))) + dense))))) + + (define (solve-part1 str) + (define lengths (map string->number (string-split str))) + (define state (solve-puzzle 1 lengths)) + (* (vector-ref state 0) (vector-ref state 1))) + + (define (solve-part2 str) + ; For part 2, `lengths' must be initialized differently + (define lengths + (append (map char->integer (string->list str)) + '(17 31 73 47 23))) + (define sparse-hash (solve-puzzle 64 lengths)) + (define dense-hash (sparse->dense sparse-hash)) + ; Convert `dense-hash' into lower-case hexadecimal representation + (let loop ((bytes dense-hash) + (final "")) + (if (null? bytes) + final + (loop + (cdr bytes) + (string-append final (format #f "~(~2,'0x~)" (car bytes))))))) + +) diff --git a/10/main.scm b/10/main.scm new file mode 100644 index 0000000..554b259 --- /dev/null +++ b/10/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 6952 for me +(printf "Part 1 solution: ~a\n" (solve-part1 input)) + +; Part 2 gives "28e7c4360520718a5dc811d3942cf1fd" for me +(printf "Part 2 solution: ~a\n" (solve-part2 input)) diff --git a/10/test.scm b/10/test.scm new file mode 100644 index 0000000..50a425d --- /dev/null +++ b/10/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 (equal? 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)))) + +; I've disabled part 1's test because it uses a 5-element list +; instead of 256 elements like the main problem and part 2, and +; I'm too lazy to structure my code properly to deal with that. + +;(printf "Part 1 tests:\n") + +;(define (test-part1 name input expected) +; (run-test name solve-part1 input expected)) + +;(test-part1 "part 1 example 1" +; "3,4,1,5" 12) + +(printf "Part 2 tests:\n") + +(define (test-part2 name input expected) + (run-test name solve-part2 input expected)) + +(test-part2 "part 2 example 1" + "" "a2582a3a0e66e6e86e3812dcb672a272") + +(test-part2 "part 2 example 2" + "AoC 2017" "33efeb34ea91902bb2f59c9920caa6cd") + +(test-part2 "part 2 example 3" + "1,2,3" "3efbe78a8d82f29979031a4aa0b16a9d") + +(test-part2 "part 2 example 4" + "1,2,4" "63960835bcdc130f0b66d7ff4f6a5a8e") |
