Code sanitising (don't use detangle!)

This commit is contained in:
Daniel Ziltener 2023-12-08 10:17:29 +01:00
parent 2758e25e2c
commit e2a6188d9d
Signed by: zilti
GPG Key ID: B38976E82C9DAE42
6 changed files with 10534 additions and 0 deletions

7581
chicken.org Normal file

File diff suppressed because it is too large Load Diff

375
day3.scm Normal file
View File

@ -0,0 +1,375 @@
;; Puzzle Solution
;; [[file:chicken-src.org::*Puzzle Solution][Puzzle Solution:1]]
;; -*- geiser-scheme-implementation: chicken -*-
(import (chicken string)
(chicken format))
(define input "
.....664...998........343...............851............................2............414.....................3....................948.164....
......*..................*617....885...*....................-......250.........536..........470...#..................../4......=.....*......
...407...570..218................-.....654........776.....920.........*753...........566......*..347.....61.-979..786........935...42.......
.......%....*...$..311.102..........................*.907.....723...............622-....*..354..............................................
.....266..............*....987.554...........&....288...#......#.......................69......41..........486..-...........................
.849................................&........781...........978......724*..196..../767................725..../...892.....*355.....815.390....
....*......@.....*988......%........704...............*......&...........*...................826.....................243.......#....*.......
...796......729.9.........490..721....................438.=....272..54&...926..481..............*..523......&.785...........766.......*493..
........281.........706...........=.666.......505.........579.*................./...669.........73...*...639...*.......479.........514......
...........*...386.......375..................................525.926..$120............&.580.........457........325.......*829..............
.....758..662.......937....%...661.24......749*323...444.............*.............583....*.........................................223.....
.......*........665....*...........*................@.................154......965..*....119.......620*............347.................*470.
........391.........183.........75..783../....................209.312............*...362........./.....667..........*....77.................
...379=..........................$......261..228........907......*.......+591...178.........227.704........@771..667..........268......543..
.......................#.....................*..........*....................................-........*581...........101........*.....*.....
................471...545..135........432..178....$225..143...973#..322............2.................................*...........239...985..
......728*612...*.........*.....65....................................*...........*................&..............527....255+../............
..255.........435.304....854...................-............=........261......&...749....+......196....694......................779..271.374
......604.........*.....................708.....922.......76..82*554......991..19........456............*..582.........597@.................
.................374..*........*707........................................*....................609...52....%.................483...........
..../..................739......................$..........649...973.*511.861..20%.................=.....................148....*......343..
...978.................................282&...401......961....-.*.........................................499%.........../.....347..........
.................+..174..315.-819.................841.....*66......820.836......8....60....456........*........434..........................
....62%.......908......./.................770....../..................*.....852......&.....*........317...%......@.......+.......691........
........793......../......411......963.......*594..................@........@......*.......45.............729...........306.148....*..@.....
626.......$......35..........*........*...........................77.134........584.....23....35................589........./...482..853....
.......................366..668.........................238...........*..265.........*..........*...........&......*...471..................
..741.............679.................@.807...76....185*...........211..%.........507....178..583....*.561...521..620...*....865.$247.494...
.....*.....383.....%..183..876......179..$..................254.........................$..........697.*..............935...*...............
...50..390..*.........*.........917.........904/..50+.........................96...............960......701...............464....*.......947
.........*..53........270..........*647.342......................778............$..$684..+279...*....#.........................393..........
......151.......490...........352*.........*........................#............................594.732.........11....#....................
........................$.........306....805..................832...................859..../.#53.........953*228...*....217.................
......37....349....391.739.......................................*286..........558......516.......647........................%........847...
..346.../....*......&.......855.........732....586...353.................43....*..............598.&...798.719.........671.....881...........
..........561................=..........................*..........52....*.....727............./.....$....*..........*......................
999*..........746...158........534............927.....587.....521......511...........448%...89...........52..557......211..356.344...116....
........*.....................%........732....*..............*...............................*..................*806.......$.....*..*.......
.....575.515.......922..........410.......*................564...............+503...........297................................132.667......
.../.............-..#.....69*82....*.......842......248..&.......630.@........................................500...........................
..916.........944...................586.................647.......*...21....&419..........=....699.......766...%.......152.......315*101....
......*436...........987#.....*....................188.............81.............87..-..109......*.........-..........*....349.............
...553..........570-.......442.197.......115...590....*.......284.......478...459..#.6.........946...............945-..192............292...
22.......+..............................%......../...865........*......*........*..........900......950.......................*449...$......
.......780..........435...*................................371...588...727.....213.....496.............-.845*..../173......688..............
713........923..../.*......289....38.....408.552.141*476..*..................................619....6........238...................633......
...*821.......*..57.8............../..46*......*..........38.........%..................$...*.......*....201......=.............61...-..%86.
...........361......../12..39.51............903..................380..659........905+.28....256.............*......215.....=.../............
...-..577.......553...............749.246.........34....................................................311..282........894.................
.960.....@...........661.....558...&......239*..........482......574=..269..........289..../...............*.................323............
...........292................%.................#........../............*......452/.-......132.....=..342.721..335.....426....*.....516.....
................967.......=.......900...........925..........476.252/...861.....................891.....*.........*315.&.....130...=........
..955..........=........584.......*...-................600............$..........940.=348...............733...754...........................
.....*..123.....................76...36...430-......&...............524.........*............706..............#.....*.....849*......162*129.
..543.....*........903..290.........................42.......................649...$............+...78.*648......180.979......353...........
...........91.642.../....*........443/.........206...........#.......219............134............*..............................798..344..
......759................144..............................455........*...906...............195......924....502.405....802.400.......*.......
.812..............-..........394.............$771.245..............116........................*.+.........#....../...*.....*...448...883....
..................784................................*.....&.................809.......616..109.496.................89.....592...*..........
...596........671......527..483.197......-965.231.918.......921.452-.538.......*..763.........................162............../..479../685.
......*....46...#......*......*.@.............................................839.*......172.....................*374........927............
.....383............649.....783..........=981.........44..159.....94...............769......*..............#..........*.............748*993.
..................................................607.+...*......*.......................755..810........539.......728.98.....425...........
......32......35....99...233..............275.337.&......437..630...........423.84...........-............................163........578....
................+.....*.....+.....334.......*.-................................*..................110.....358....115..566....*648.......*...
....................471............*......384....81...190.606..=714....673.198.......57..#761........=..........*.....*..................618
..........847.755..................963..........*........*................*......251*....................#592.222....107...991..557.........
....236-.....*.................569.....311....584.............*958..........923%........................................./.......*....=.....
................../.835...................*........157*324.840......../415...................408...........212......-..573.549.770.995......
............312.34..............&.377...287.461..................+.................33*555...*................@.315.720......%...............
.......614.*.................309.....*........*..758............811..........................259.................+..................-627....
.........*.....*.....757.................684.527..*.......408.........999...............524..............570...............995..............
...835..415.345.822...............495.....*.......138...........966....*..................#...............*....560.........*................
...#.................806..954......*.......51...........+.......*.....910..436.477..............*150.....510...*.....#....537...........434.
......................*...-........871.743.........643...234...844............*....705..959..360................454..402..........984.......
....................491.................+..675...........................$........*........-................................487...*...876...
....191........%559.......................*........250..................965......556..&...........521.......365.......994%.%....923.....$...
.....*........................238..257...631..........*....*.....&...........346......366...150....*........*...............................
.....532....584....800.......*.................603.452..155.42..272..267.295*.....52...........*....672..743...830.....395.......862........
...............#....*.....347...................*......................@.......................487...................................671*973
......=340.......&..667...................*......413.........................576*888......706.......487..502..........22....................
................649..........&./426....286.............149........690..............................&..........765.....*..............321....
389........304/............200...................660...*.............*253...........129..#30.........................710.../................
...@..............408.............258*246....136.....614..531..-.....................*.........253&..........421...........939.....+.357....
.....%..............*...........................*............*..313..+418.47...931...329............974.........=...847..........166.*......
834..6.............346....505....164............833........66.....................*.......367..95......*211..............-............888...
.........535....=......+.....$.......770......+....................................5.......*.....*36..................547...+...............
.....115.*...471......863.............#.....75..364...........=842..974......722........581............$..........588.......557....760......
987..=...780...............$...................*......................................+......869.......591.......&................-.........
........................15.484..........640...768.@710.353.......=.585......&91....996..712..=...............548...680........661...939.....
...630...........186=...*......575.....*................#.....662..$.................................+......*.........+........../.....*....
.........116*235........138...*....................644....................*853...............210...719......503.....................453.....
.....................=.........480..%................=...........429...478.....695.....789..$..........19&............216...................
......506.........101...189.........232....951.........706....43...*.......943.........%...........935.......160..........+20..152.16.......
..............789...........654...............*648.............*...........*....=.............398...*........*................*.............
..............*.........509...@.....$...............746.....645...........607..336.................488....285....$..944......298.$..........
..........23...642.374.............913................*.327....................................................263.....*182......822........
......94....*......*.......942*.............596....285.....*..............177...........86...................................477......702...
..243..+.....220.838.637.......481....301..+...............717...................394......................782/.......*..........%.872.*.....
.........../.........%...../...........$...........239...........209......*........-...............153............100.700...........*..708..
............499.........235..........................*....939*......*..227.293.-.....805.785.........#..250.................423....954......
.......570........................................837..@......748..56..........782.....*....*..........*......552...........................
872%..*......%.......88*484....805....178...704........282............387...........562....614..559...750..*...........@.....417......762...
......745.....3...98....................*..*...............................@....329........................130.......134....$...........*...
.814.............%......829.268........220...441.316.............*740......607........*831..............*......................529.......410
......=...687...........*.....*................*...*..........369.....332..........798...............956.932......................=.........
.....856.*............858....283.........43.594...292................*....*.604*.........217....................44*.....676*.........752.571
..........489....................951...................83...........262.243........681....*.................373....493...........-...@......
349................................*..................@.....................444.......*......../951..810.......#.......184....227...........
.................958..574....313...312...909....204/....................674*...........146...........=...=..................................
.....*.438...512*.....*.....*...........*.............484&.25..........................................851...........534@.$720.719..........
...254.*...........167..@...7............22....681...........*684........7.696.135.207.......177............749*670............*.....681....
..........733...........659.........527............645*215.........850.....*..........*.........*....822........................787.........
..37*58.....*.................562....*........232..........610.321*.....148.......416............514.....703......54...................310..
..........638....223.........*........296............452....................152....#...678..........................*...+...692.........*...
..911...........*.........594.......*......589........*..........186........................219...........344.927.324.525..*............753.
.....*..144.247.493...............351.........*....994...........*......738..107.......235...*....937.......-.*...........171....634........
....756..*..../.....626..131+.@..............770..........70...11........*...............*..533...*...181......861..................*.......
.........755...................637./15.....................=.........217..407......146...........402.#..................11...436..535.......
..........................&592.............367.636...........830........*..........*..........................................+.........%...
..........420*.27....954..........314.............=...........*......791...$.......718........828.....9@..449...................868...110...
..................*..........835...&...417*...........895......747..........785.........128....*..80........*.....................*.........
........475@...285...700.............*.....846....561...*.723.............................&.436...*......728................&....389........
....................*.............610.266...........@.351.*..........308...931...490...............50........*487.....958.500...............
..................335...736.....................285.......294..510*....*........*.....103.....139.........920...........=...................
.............*...........*..........343............*..692..........57.741.....@..314...*.....*......*835......738.=............582.....295..
...437....215..........185...............58.......654...&.....603..........505.......97...224..@..........766.....508.....+317....#.........
...............................52.............1...........777........704........372.............23....652...=...........@...............620.
............83..481..917......*........36$...../......=...=.............*...471*.....171.680.............*.......635...28...127.....272.....
...262.183..*......*..=..56*.72...................812.317.......454.....1.............*.............................*.........*.......*.....
....*........299..246...........190#...........%...+..............*.224..............664......897....407.155*....407...........406..581.....
......691.................869..........439.....385....@.........26.....*........863.......402*.........-.............*28...332..............
........*.......159*638......*....38....*..209......578.963........592..875......*...................*.....$......596........-..............
......90................424.640.....*.272.................$..........*.........134...........624..158.907..964.................291..........
................410....&..........972.......................$..305..683..743........551.338.&..................................*............
...........................%..........213.................164.....*.......+..........*........751..............................10....710.387
......%................&....314........-..376.......833*.......494..821...........829......%.....#........582..............&............*...
......87...318......472...........%449.....=............720.........%.................257...29...........*.........-.....656................
..666........*....*.....920.....................................................&......*........................759..........875$...........
......138....366..797...........584.......247.........................427..206..843...618.....530......................................172..
")
;; Puzzle Solution:1 ends here
;; Records
;; #+NAME: day3-part1-records
;; [[file:chicken-src.org::day3-part1-records][day3-part1-records]]
;; -*- geiser-scheme-implementation: chicken -*-
(define-record part-number number line start-col end-col)
(define-record part-symbol sym line start-col end-col)
(define-record buffer-char char line col)
;; day3-part1-records ends here
;; Indexing the Input
;; #+NAME: day3-part1-indexing
;; [[file:chicken-src.org::day3-part1-indexing][day3-part1-indexing]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (index-input input #!optional (indexed-input '()) (line-index 0) (col-index 0))
(if (= 0 (length input))
(reverse indexed-input)
(let ((next-char (car input))
(new-rest-input (cdr input)))
(if (eqv? #\newline next-char)
(index-input new-rest-input
indexed-input
(+ line-index 1)
0)
(index-input new-rest-input
(cons (make-buffer-char next-char line-index col-index)
indexed-input)
line-index
(+ col-index 1))))))
;; day3-part1-indexing ends here
;; Tokenizing the Indexed Input
;; #+NAME: day3-part1-number-char-p
;; [[file:chicken-src.org::day3-part1-number-char-p][day3-part1-number-char-p]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (number-char? c)
(case (buffer-char-char c)
((#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9) #t)
(else #f)))
;; day3-part1-number-char-p ends here
;; #+NAME: day3-part1-finalize-token
;; [[file:chicken-src.org::day3-part1-finalize-token][day3-part1-finalize-token]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (finalize-token buffer)
(let* ((rev-buffer (reverse buffer))
(line (buffer-char-line (car buffer)))
(start-col (buffer-char-col (car buffer)))
(end-col (buffer-char-col (car rev-buffer))))
(if (number-char? (car buffer))
(make-part-number (string->number
(apply string (map buffer-char-char buffer)))
line start-col end-col)
(make-part-symbol (string->symbol
(apply string (map buffer-char-char buffer)))
line start-col end-col))))
;; day3-part1-finalize-token ends here
;; #+NAME: day3-part1-compatible-with-buffer-p
;; [[file:chicken-src.org::day3-part1-compatible-with-buffer-p][day3-part1-compatible-with-buffer-p]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (compatible-with-buffer? buffer char)
(and
(not (eqv? #\. (buffer-char-char char)))
(or (= 0 (length buffer))
(and (number-char? (car buffer))
(number-char? char))
(and (not (number-char? (car buffer)))
(not (number-char? char))))))
;; day3-part1-compatible-with-buffer-p ends here
;; #+NAME: day3-part1-tokenize-indexed-input
;; [[file:chicken-src.org::day3-part1-tokenize-indexed-input][day3-part1-tokenize-indexed-input]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (tokenize-indexed-input indexed-input #!optional (token-buffer '()) (part-nums '()) (part-syms '()))
(if (= 0 (length indexed-input))
(values (reverse part-nums)
(reverse part-syms))
(let ((next-char (car indexed-input)))
(cond
((compatible-with-buffer? token-buffer (car indexed-input))
(tokenize-indexed-input (cdr indexed-input)
(cons (car indexed-input) token-buffer)
part-nums part-syms))
((= 0 (length token-buffer))
(tokenize-indexed-input
(cdr indexed-input)
(if (eqv? #\. (buffer-char-char (car indexed-input)))
token-buffer (list (car indexed-input)))
part-nums part-syms))
(else
(let ((token (finalize-token (reverse token-buffer))))
(tokenize-indexed-input
(cdr indexed-input)
(if (eqv? #\. (buffer-char-char next-char)) '() (list (car indexed-input)))
(if (part-number? token) (cons token part-nums) part-nums)
(if (part-symbol? token) (cons token part-syms) part-syms))))))))
;; day3-part1-tokenize-indexed-input ends here
;; Checking for Part Neighbours
;; #+NAME: day3-part1-neighbours-p
;; [[file:chicken-src.org::day3-part1-neighbours-p][day3-part1-neighbours-p]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (neighbours? part-num part-sym)
(let ((part-num-line (part-number-line part-num))
(col-min (- (part-number-start-col part-num) 1))
(col-max (+ (part-number-end-col part-num) 1)))
(and (>= (part-symbol-line part-sym) (- part-num-line 1))
(<= (part-symbol-line part-sym) (+ part-num-line 1))
(>= (part-symbol-start-col part-sym) col-min)
(<= (part-symbol-start-col part-sym) col-max)
(>= (part-symbol-end-col part-sym) col-min)
(<= (part-symbol-end-col part-sym) col-max))))
;; day3-part1-neighbours-p ends here
;; Folding Everything Together
;; #+NAME: day3-part1-real-part-number-p
;; [[file:chicken-src.org::day3-part1-real-part-number-p][day3-part1-real-part-number-p]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (is-real-part-number? part-num part-syms)
(and (< 0 (length part-syms))
(or (neighbours? part-num (car part-syms))
(is-real-part-number? part-num (cdr part-syms)))))
;; day3-part1-real-part-number-p ends here
;; #+NAME: day3-part1-fold
;; [[file:chicken-src.org::day3-part1-fold][day3-part1-fold]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (fold-part-numbers part-nums part-syms)
(foldl (lambda (output input)
(if (is-real-part-number? input part-syms)
(+ output (part-number-number input))
output))
0 part-nums))
;; day3-part1-fold ends here
;; #+RESULTS: day3-part1-calc-full
;; : 509115
;; [[file:chicken-src.org::*Folding Everything Together][Folding Everything Together:5]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (calc-part-1)
(let-values (((part-nums part-syms) (tokenize-indexed-input (index-input (string->list input)))))
(fold-part-numbers part-nums part-syms)))
;; Folding Everything Together:5 ends here
;; Gather Symbol Neighbours
;; #+NAME: day3-part2-sym-neighbour-count
;; [[file:chicken-src.org::day3-part2-sym-neighbour-count][day3-part2-sym-neighbour-count]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (gather-neighbours part-sym part-nums)
(foldl (lambda (output input)
(if (neighbours? input part-sym)
(cons input output)
output))
(list) part-nums))
;; day3-part2-sym-neighbour-count ends here
;; Put Everything Together
;; #+NAME: day3-part2-filter
;; [[file:chicken-src.org::day3-part2-filter][day3-part2-filter]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (filter-gear-candidates part-syms)
(foldl (lambda (output input)
(if (eqv? '* (part-symbol-sym input))
(cons input output) output))
(list) part-syms))
;; day3-part2-filter ends here
;; #+NAME: day3-part2-fold
;; [[file:chicken-src.org::day3-part2-fold][day3-part2-fold]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (calc-gear-ratio gears)
(foldl (lambda (output input)
(if (= 2 (length input))
(+ output (apply * (map part-number-number input)))
output))
0 gears))
;; day3-part2-fold ends here
;; #+RESULTS: day3-part2-calc-full
;; : 75220503
;; [[file:chicken-src.org::*Put Everything Together][Put Everything Together:5]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (calc-part-2)
(let-values (((part-nums part-syms) (tokenize-indexed-input (index-input (string->list input)))))
(let ((gear-candidates (map (lambda (x) (gather-neighbours x part-nums)) (filter-gear-candidates part-syms))))
(calc-gear-ratio gears))))
;; Put Everything Together:5 ends here

404
day4.scm Normal file
View File

@ -0,0 +1,404 @@
;; Puzzle Solution
;; [[file:chicken-src.org::*Puzzle Solution][Puzzle Solution:1]]
;; -*- geiser-scheme-implementation: chicken -*-
(import (chicken string)
(chicken irregex))
(define input "
Card 1: 33 56 23 64 92 86 94 7 59 13 | 86 92 64 43 10 70 16 55 79 33 56 8 7 25 82 14 31 96 94 13 99 29 69 75 23
Card 2: 61 66 75 1 27 38 93 90 34 43 | 94 46 62 49 35 88 45 70 15 22 20 86 56 38 64 98 50 6 79 11 13 93 92 60 16
Card 3: 57 7 33 56 85 6 88 34 80 8 | 92 42 7 60 61 51 40 6 67 35 3 25 87 2 98 75 97 54 10 68 73 83 4 62 56
Card 4: 79 85 94 74 15 62 84 88 76 56 | 56 9 22 57 4 92 62 79 84 64 72 55 34 88 66 15 45 18 76 73 85 94 8 78 74
Card 5: 57 94 99 25 52 67 69 31 26 78 | 94 52 31 83 70 45 40 67 89 11 81 24 25 61 26 72 50 12 27 69 91 57 55 34 78
Card 6: 5 96 3 19 98 25 13 59 94 8 | 36 55 22 76 86 19 10 8 59 9 87 40 2 71 13 98 12 77 3 70 5 25 34 41 88
Card 7: 35 52 84 36 72 53 76 88 41 14 | 57 34 14 39 44 71 51 1 67 30 16 77 23 66 45 74 37 55 38 69 33 31 98 72 36
Card 8: 7 70 72 13 23 1 48 18 40 94 | 48 70 93 99 20 23 17 40 72 35 21 7 71 3 42 59 87 55 18 41 94 1 13 22 90
Card 9: 40 2 46 38 86 16 62 78 29 13 | 26 46 47 29 99 51 25 57 66 86 62 2 22 70 41 3 78 13 74 15 16 90 43 40 38
Card 10: 35 71 99 87 81 58 5 83 55 73 | 90 34 71 10 96 38 39 29 69 93 35 51 86 12 76 91 80 36 17 59 64 68 58 15 82
Card 11: 35 89 27 73 65 46 39 86 81 90 | 86 90 50 35 73 31 92 65 18 81 30 37 21 76 89 56 64 71 49 12 27 82 16 32 29
Card 12: 15 77 35 41 38 93 63 30 39 18 | 90 69 65 93 13 4 64 51 72 57 96 91 75 14 58 94 28 38 63 97 86 84 50 15 21
Card 13: 10 82 16 85 74 38 95 51 54 94 | 66 29 85 73 54 8 51 14 56 74 46 42 10 67 16 59 23 7 95 48 94 6 82 68 88
Card 14: 77 53 62 72 97 7 36 96 67 28 | 30 24 28 44 39 77 15 88 92 4 60 66 11 21 20 42 55 53 6 12 95 87 37 58 85
Card 15: 89 74 36 8 27 73 90 60 48 56 | 56 45 74 78 39 7 15 6 89 88 8 76 90 16 22 36 17 10 99 79 71 59 46 96 49
Card 16: 82 64 99 10 32 65 20 78 29 31 | 49 59 4 78 22 18 95 82 54 72 39 41 35 14 98 1 84 92 58 64 28 83 50 7 65
Card 17: 25 1 40 66 84 24 19 17 10 46 | 22 40 8 87 17 38 6 95 36 51 15 93 18 73 56 9 13 57 63 10 78 37 48 1 84
Card 18: 18 14 27 40 80 47 9 65 22 5 | 90 59 72 36 33 31 93 55 75 3 56 37 27 87 10 23 47 19 99 85 35 48 18 62 69
Card 19: 63 16 71 14 1 89 61 55 62 44 | 32 5 64 82 94 77 11 90 54 47 49 29 97 78 57 68 92 33 44 28 59 30 72 18 8
Card 20: 60 21 85 8 35 66 70 36 2 58 | 10 37 36 64 72 98 60 19 55 45 30 33 31 94 90 49 71 57 81 17 91 29 68 86 39
Card 21: 4 25 18 6 56 62 97 1 83 30 | 42 66 83 75 14 50 26 24 90 36 46 87 49 84 53 65 80 17 92 70 19 95 9 27 32
Card 22: 53 91 82 19 43 83 65 46 4 85 | 97 67 90 39 16 1 54 64 10 77 99 71 28 94 30 45 84 95 21 35 13 61 29 11 33
Card 23: 65 66 83 69 23 16 13 3 29 68 | 6 54 27 65 16 68 13 69 29 14 91 23 37 61 39 74 66 77 83 11 26 40 92 3 49
Card 24: 43 97 61 35 69 20 65 3 23 79 | 3 69 20 80 98 92 18 61 91 96 86 88 19 25 43 97 17 79 47 55 11 35 23 77 65
Card 25: 94 30 47 27 2 80 76 75 82 67 | 28 12 96 27 2 20 4 29 58 18 93 75 62 38 30 72 94 80 76 91 47 14 67 82 46
Card 26: 51 47 45 64 9 53 16 80 61 94 | 88 28 84 45 61 51 70 18 4 21 94 62 5 53 32 10 20 86 47 46 43 9 66 83 80
Card 27: 31 5 15 38 10 61 33 92 26 47 | 60 49 54 69 1 99 85 29 95 34 84 81 36 11 57 67 14 55 90 51 17 7 37 35 48
Card 28: 25 69 85 59 82 16 6 17 49 62 | 80 17 62 69 16 46 87 29 59 64 97 85 45 30 6 82 47 75 25 43 72 14 2 23 49
Card 29: 58 97 36 33 62 27 74 38 68 23 | 51 20 85 47 44 67 48 25 39 36 17 61 52 22 79 6 64 57 95 56 71 33 98 34 42
Card 30: 74 96 56 34 64 54 26 22 62 59 | 32 74 61 7 34 47 83 94 27 26 66 54 87 75 56 65 49 13 64 70 96 62 53 22 59
Card 31: 26 6 14 82 12 60 16 4 92 87 | 16 33 76 55 54 39 27 26 17 83 6 18 94 77 3 40 81 92 1 69 25 19 71 99 2
Card 32: 15 3 33 16 13 65 8 44 40 96 | 22 15 46 89 16 50 6 33 53 24 96 40 8 35 97 13 3 55 43 14 65 66 34 60 44
Card 33: 41 61 28 60 85 69 87 62 91 18 | 49 88 84 73 20 45 75 99 27 25 3 65 66 30 50 54 97 57 76 96 2 6 39 5 18
Card 34: 12 72 20 48 49 77 38 86 68 92 | 6 56 30 68 95 87 42 16 59 10 7 22 82 74 2 71 19 48 50 1 40 37 24 80 72
Card 35: 97 86 21 45 10 30 63 8 36 91 | 33 31 67 77 29 24 10 79 21 25 12 71 30 1 68 56 46 94 51 64 8 14 45 4 41
Card 36: 90 75 80 95 49 87 2 88 50 42 | 77 85 53 76 52 72 32 42 79 65 50 25 19 14 37 11 35 63 29 75 49 98 96 54 95
Card 37: 19 84 30 59 86 49 31 40 14 50 | 20 92 36 43 82 18 86 47 73 30 84 19 99 5 48 34 68 63 61 46 53 75 16 28 45
Card 38: 39 47 28 13 75 89 76 93 15 14 | 36 94 51 97 49 16 66 60 72 30 52 5 3 17 23 7 58 14 63 87 54 8 56 13 35
Card 39: 70 22 9 80 89 51 43 64 57 37 | 23 39 5 27 98 11 29 73 72 10 63 79 59 58 46 96 2 86 50 19 67 41 95 66 82
Card 40: 94 95 1 39 64 63 54 19 17 38 | 44 53 12 92 11 34 42 67 93 36 6 3 29 60 7 62 85 4 33 83 2 9 10 82 51
Card 41: 69 12 36 48 67 7 52 89 63 73 | 11 61 81 93 47 20 27 31 66 64 45 38 2 59 46 5 73 7 87 22 6 52 36 10 54
Card 42: 17 93 3 90 91 59 6 57 54 65 | 22 17 99 16 6 77 38 46 43 59 41 47 12 2 86 4 40 56 80 82 11 98 23 20 85
Card 43: 1 68 36 70 24 83 86 94 52 7 | 38 9 64 12 10 60 92 81 77 98 59 23 79 91 65 28 13 15 6 69 24 40 19 16 99
Card 44: 3 45 25 7 57 67 62 36 40 44 | 51 23 88 52 68 11 89 84 59 54 10 77 73 96 46 44 17 85 91 12 80 74 5 27 39
Card 45: 14 68 88 27 44 83 37 22 65 7 | 78 61 91 48 92 21 52 49 77 74 46 24 33 28 36 89 53 39 93 23 72 95 2 63 67
Card 46: 20 59 75 43 98 38 85 46 74 57 | 3 34 11 7 98 64 52 89 43 41 87 57 19 56 37 68 20 2 99 91 23 17 74 48 78
Card 47: 87 20 73 47 82 37 3 68 29 65 | 15 53 58 25 62 13 31 59 11 63 2 89 30 71 35 36 82 37 75 67 17 12 34 90 19
Card 48: 63 11 55 53 44 7 3 41 60 40 | 73 61 87 91 46 60 51 31 11 32 7 44 41 78 55 14 59 3 63 53 74 94 62 65 40
Card 49: 30 62 35 9 40 51 68 55 79 97 | 53 87 77 97 63 11 52 67 51 35 68 79 99 98 5 9 40 37 19 49 30 16 55 75 62
Card 50: 66 80 74 99 63 84 35 26 83 67 | 43 92 52 67 63 84 16 21 88 23 31 22 24 49 59 99 75 47 66 80 1 83 91 95 70
Card 51: 68 99 70 39 79 10 81 27 46 80 | 70 17 46 68 61 50 43 48 79 81 12 32 65 1 27 39 80 99 58 8 19 10 41 4 73
Card 52: 37 86 40 43 66 14 63 2 19 50 | 96 50 27 43 64 83 13 92 63 86 37 19 2 40 58 66 3 31 59 14 62 61 67 54 53
Card 53: 78 33 11 45 12 22 19 38 87 74 | 2 50 63 33 97 8 58 99 48 22 4 45 11 60 74 21 69 78 87 29 12 39 19 18 38
Card 54: 11 51 64 21 19 87 70 80 55 95 | 11 69 53 94 24 96 87 59 95 76 23 19 68 47 51 74 70 55 32 77 80 64 21 36 78
Card 55: 92 99 88 93 1 26 13 4 61 11 | 71 92 99 61 76 56 46 89 4 67 3 45 22 81 19 33 50 26 93 28 13 72 1 11 88
Card 56: 11 65 76 35 97 63 16 57 92 53 | 96 30 65 82 76 59 63 97 35 40 16 98 86 79 41 11 78 95 10 88 29 28 64 5 74
Card 57: 32 5 1 8 43 15 25 79 96 71 | 25 49 31 90 39 77 27 83 15 56 41 5 1 26 58 33 34 79 62 8 96 32 92 43 71
Card 58: 65 20 54 93 18 31 97 99 94 86 | 89 46 12 27 23 42 43 88 75 73 35 49 95 9 37 66 50 62 51 48 11 17 26 1 41
Card 59: 62 38 28 4 59 53 16 89 52 35 | 27 47 52 12 35 86 59 8 39 31 81 55 95 79 37 89 58 14 30 80 68 87 43 84 56
Card 60: 8 89 16 22 75 94 34 67 78 62 | 84 81 29 51 10 70 91 95 32 34 46 12 67 66 68 99 74 87 92 78 90 13 76 18 27
Card 61: 27 92 80 94 87 2 75 26 22 79 | 36 34 76 84 22 48 52 86 79 46 81 80 87 78 27 95 70 51 35 49 9 89 75 8 67
Card 62: 89 10 56 52 80 76 46 31 69 24 | 73 6 53 98 17 65 44 16 83 45 92 41 94 3 81 99 26 61 43 67 2 93 36 28 29
Card 63: 38 74 68 99 88 4 42 87 58 31 | 39 99 22 11 16 50 52 53 85 34 67 76 55 42 45 8 89 43 2 20 75 4 97 28 70
Card 64: 22 38 75 7 35 62 49 30 10 32 | 1 54 59 40 12 74 46 51 37 21 72 57 97 82 31 25 87 47 29 43 67 88 19 9 8
Card 65: 21 69 41 76 88 73 4 77 34 93 | 92 53 25 78 81 84 8 49 77 41 28 70 12 88 91 45 29 15 86 46 32 96 57 34 54
Card 66: 42 60 7 35 31 50 13 61 9 19 | 53 18 80 69 78 88 24 56 29 62 49 95 64 81 11 42 17 40 34 28 6 98 70 54 91
Card 67: 36 50 47 89 18 54 9 25 92 91 | 87 59 85 42 62 37 26 21 52 4 90 19 75 23 67 33 35 49 69 79 14 80 46 97 98
Card 68: 92 43 44 34 29 75 6 1 8 31 | 88 85 55 9 1 95 14 97 67 42 22 72 89 19 90 35 74 96 58 5 57 51 47 37 69
Card 69: 59 43 21 14 5 85 20 12 1 7 | 40 11 63 87 72 34 83 86 94 31 66 3 24 98 82 39 65 35 51 77 67 18 2 47 90
Card 70: 24 83 87 85 3 48 99 11 21 33 | 76 92 16 81 61 86 83 14 57 44 74 41 98 63 96 38 89 65 32 11 48 51 53 23 19
Card 71: 57 77 65 66 16 50 49 39 55 87 | 3 45 97 44 31 14 25 70 13 72 16 41 2 66 88 69 57 26 54 95 80 10 65 28 86
Card 72: 3 80 44 10 43 90 71 20 17 85 | 86 53 46 72 74 3 91 99 19 55 94 2 65 4 36 26 29 16 95 48 11 24 90 76 78
Card 73: 71 11 88 6 54 78 97 30 91 92 | 52 86 23 91 78 54 97 66 11 44 30 8 93 71 16 92 21 83 84 88 34 6 33 26 9
Card 74: 87 88 97 95 33 72 21 39 60 66 | 65 68 95 84 97 32 72 21 43 74 23 55 1 96 92 87 25 66 60 16 33 59 39 98 88
Card 75: 40 81 51 37 56 61 25 84 82 4 | 82 84 43 7 23 61 14 38 63 5 27 85 48 71 56 99 30 96 29 40 18 37 77 13 16
Card 76: 40 46 25 27 39 47 33 37 36 7 | 13 39 9 80 34 38 8 7 60 48 92 71 5 40 10 41 37 21 67 29 25 43 69 28 2
Card 77: 25 10 9 74 66 52 6 22 41 3 | 32 24 86 5 47 22 6 23 3 69 56 40 28 52 54 17 95 53 68 39 60 74 71 99 4
Card 78: 59 18 58 51 88 8 92 27 82 79 | 97 86 8 11 79 28 88 70 48 80 42 37 87 2 92 95 55 59 82 40 50 27 51 68 63
Card 79: 51 97 54 22 64 44 80 27 96 47 | 93 72 29 23 96 1 54 66 51 24 22 62 87 97 35 27 44 77 79 64 3 37 47 45 80
Card 80: 64 67 54 24 8 4 35 89 15 23 | 67 12 13 77 45 15 54 92 89 9 96 95 25 24 99 4 81 52 46 35 69 64 23 79 8
Card 81: 34 25 84 7 23 12 54 30 20 1 | 49 26 82 7 13 75 89 58 53 67 93 46 8 97 32 86 11 72 28 54 98 56 1 45 55
Card 82: 87 24 17 63 67 65 43 97 38 95 | 8 40 49 43 15 36 88 11 83 29 46 7 62 31 51 23 69 67 66 39 54 72 35 80 65
Card 83: 12 57 85 81 48 97 45 5 72 11 | 68 98 58 29 8 22 9 30 49 51 67 47 74 13 40 65 94 44 91 34 92 82 14 33 61
Card 84: 95 33 18 64 24 92 27 29 57 53 | 56 19 14 79 60 36 6 12 75 71 26 87 4 58 54 16 52 31 98 17 85 40 61 41 77
Card 85: 42 71 23 49 53 96 88 48 60 95 | 66 18 98 88 58 7 12 11 89 37 13 1 6 28 45 47 30 31 55 57 17 97 77 99 4
Card 86: 44 31 35 2 49 88 26 98 43 42 | 19 46 70 1 92 12 3 11 30 74 33 38 95 17 24 75 9 28 83 32 40 65 62 10 29
Card 87: 98 23 88 50 4 73 92 5 11 24 | 85 14 59 94 41 69 5 99 46 22 27 61 77 7 60 95 58 6 30 24 44 92 10 88 23
Card 88: 39 61 4 84 2 6 33 53 85 42 | 3 77 16 69 11 76 48 80 95 15 12 10 83 78 19 57 30 56 52 46 58 88 55 35 13
Card 89: 27 97 32 38 46 3 62 40 58 89 | 6 91 80 72 21 56 24 50 82 54 74 97 60 73 47 96 13 38 84 12 9 69 14 3 41
Card 90: 80 50 8 55 93 29 3 87 84 27 | 38 83 96 69 76 28 18 87 32 45 89 48 82 91 70 6 25 24 73 42 19 49 34 51 93
Card 91: 10 40 8 20 83 79 47 2 69 12 | 31 79 74 71 87 57 41 36 7 22 76 42 82 72 16 78 3 67 43 52 26 85 39 25 14
Card 92: 72 76 71 8 20 13 48 25 81 47 | 33 94 7 85 64 93 53 31 10 21 92 50 70 23 1 99 2 12 18 97 66 45 57 51 55
Card 93: 50 21 56 54 41 32 77 19 93 13 | 36 88 97 56 53 99 68 26 13 21 9 86 77 41 50 3 16 75 98 48 24 62 8 32 93
Card 94: 52 39 66 88 19 43 80 53 33 3 | 66 34 43 41 65 92 80 50 72 86 94 69 52 53 39 67 83 16 25 19 99 93 11 33 6
Card 95: 22 38 17 63 68 51 79 72 81 61 | 79 63 38 71 81 1 78 13 68 33 21 51 12 57 53 67 97 22 62 72 61 2 9 17 73
Card 96: 83 96 2 47 21 68 50 78 19 29 | 77 66 37 59 36 96 74 16 80 84 65 87 90 58 89 48 42 47 68 85 35 49 56 40 19
Card 97: 72 8 69 10 3 33 79 4 99 65 | 26 99 96 10 31 33 8 58 38 4 40 69 6 97 80 79 98 65 20 57 73 3 81 5 72
Card 98: 43 67 24 40 95 3 27 1 89 39 | 24 87 37 1 26 72 19 95 43 89 32 3 27 5 55 40 25 71 69 67 39 74 56 93 35
Card 99: 68 24 93 30 34 20 27 89 37 50 | 93 77 86 17 4 30 60 37 98 24 68 34 14 39 8 31 18 50 48 10 20 12 27 78 70
Card 100: 68 45 61 38 58 50 27 87 9 96 | 3 23 52 54 76 49 34 8 81 78 11 38 33 15 26 40 37 67 94 51 24 5 30 97 31
Card 101: 23 16 99 80 29 13 81 67 27 22 | 94 53 95 19 66 31 96 3 60 28 38 30 35 47 44 68 75 82 56 18 5 50 36 78 64
Card 102: 17 2 85 30 78 23 93 46 88 92 | 18 44 84 92 13 62 48 46 53 31 52 17 93 78 29 51 99 39 30 23 91 5 81 2 33
Card 103: 35 21 66 81 40 75 50 88 14 6 | 16 25 61 81 13 6 17 77 38 66 98 41 45 54 23 19 99 21 49 32 51 35 8 47 65
Card 104: 29 37 46 77 92 53 81 20 9 96 | 94 81 75 8 24 78 68 48 4 5 98 16 30 57 3 10 14 70 36 33 91 64 47 18 87
Card 105: 15 2 31 71 99 30 26 61 79 32 | 21 49 58 16 67 94 5 75 4 69 96 51 28 53 17 89 25 85 1 12 83 82 10 33 6
Card 106: 51 24 14 80 10 38 53 55 41 32 | 69 66 91 73 65 12 36 75 45 90 46 58 80 57 74 28 39 37 95 22 30 62 7 32 1
Card 107: 26 78 66 42 54 69 51 95 17 52 | 64 69 20 75 87 30 11 42 60 47 85 46 80 36 40 7 94 68 33 21 31 83 89 10 82
Card 108: 82 2 99 56 80 38 54 47 20 29 | 23 56 40 97 5 81 37 4 69 48 91 64 58 73 32 61 54 78 77 43 67 14 17 68 15
Card 109: 97 80 18 44 73 53 15 50 47 48 | 30 41 82 36 43 86 95 56 33 4 89 47 28 59 27 31 92 12 93 32 60 74 99 26 75
Card 110: 4 58 43 91 66 59 69 73 37 94 | 35 3 65 27 77 52 44 38 86 79 2 32 56 84 10 60 18 24 49 64 61 78 93 99 22
Card 111: 52 86 22 5 18 14 7 92 65 56 | 50 86 28 52 14 48 56 93 5 22 80 76 65 25 92 2 78 7 45 49 70 47 18 15 53
Card 112: 10 36 28 87 20 7 93 15 65 53 | 27 93 36 83 87 46 24 1 86 43 28 7 89 4 32 20 38 14 15 67 57 29 69 40 10
Card 113: 27 38 49 70 32 56 22 11 43 10 | 25 75 85 29 63 83 35 95 65 15 84 49 87 27 74 43 11 13 46 10 72 56 22 70 57
Card 114: 91 82 29 32 44 84 51 67 94 11 | 51 69 55 28 89 74 8 96 93 35 42 33 73 44 3 31 36 68 38 11 94 46 29 12 82
Card 115: 88 46 87 97 52 18 20 96 2 3 | 17 36 23 42 67 93 72 24 10 89 87 8 66 48 25 50 61 32 59 52 84 2 35 99 65
Card 116: 50 23 72 60 40 77 97 90 98 70 | 3 76 97 92 72 11 28 60 30 29 35 45 70 62 84 55 57 87 22 14 38 69 51 25 86
Card 117: 31 4 58 33 86 7 47 25 62 87 | 44 36 7 4 73 84 25 58 65 14 23 96 55 31 27 87 77 17 9 15 47 22 98 69 62
Card 118: 71 33 83 75 28 82 56 94 21 42 | 1 21 43 28 13 86 19 82 58 48 89 94 71 91 41 95 27 79 73 93 75 31 66 30 83
Card 119: 38 69 51 58 93 60 13 66 90 71 | 44 94 98 53 49 69 9 74 24 57 71 45 12 78 18 56 88 68 85 42 35 1 47 17 2
Card 120: 44 82 72 71 73 16 39 5 93 81 | 57 21 8 33 3 69 54 47 26 70 53 10 5 44 77 31 29 87 24 19 93 37 80 65 84
Card 121: 90 63 79 82 91 85 98 70 14 28 | 66 71 82 27 2 29 44 73 76 18 47 3 55 64 34 25 6 88 81 8 30 19 75 1 31
Card 122: 80 4 6 16 18 20 23 35 50 90 | 50 25 27 1 70 12 60 19 96 37 57 82 69 89 45 87 23 26 75 90 48 42 30 78 54
Card 123: 32 6 8 96 56 86 73 18 71 92 | 35 64 83 21 15 95 49 80 33 93 11 45 29 78 68 5 60 63 86 67 57 91 42 51 97
Card 124: 72 84 64 25 99 28 40 98 96 59 | 31 50 67 35 94 3 10 95 85 38 46 45 80 42 6 62 97 52 7 92 83 44 55 65 21
Card 125: 13 63 2 53 48 38 88 14 5 58 | 49 50 91 75 40 66 34 71 24 52 28 26 55 19 25 73 98 56 11 41 96 21 85 67 29
Card 126: 55 36 33 58 17 53 39 6 21 52 | 88 30 68 84 61 14 17 97 7 19 99 54 45 56 52 35 92 50 85 36 24 70 27 29 75
Card 127: 96 37 56 99 84 12 10 70 93 55 | 85 77 82 60 74 20 51 27 92 12 59 98 91 81 56 31 6 53 4 10 89 84 90 69 55
Card 128: 63 44 56 61 88 65 33 85 81 55 | 58 28 88 75 33 89 20 8 61 37 6 9 19 92 46 17 35 94 29 62 76 41 55 57 80
Card 129: 86 99 43 13 11 17 67 9 50 33 | 47 67 6 69 11 5 13 98 96 89 57 40 61 79 33 80 15 42 62 92 59 86 10 65 44
Card 130: 4 71 54 22 81 7 25 19 29 50 | 91 16 36 54 51 19 50 80 83 7 81 64 61 30 85 72 79 9 13 12 67 59 4 31 20
Card 131: 87 91 50 20 3 77 14 47 97 76 | 71 87 8 34 78 27 32 61 33 89 62 52 72 17 60 16 42 51 64 49 66 86 22 30 59
Card 132: 68 17 4 26 8 14 41 57 21 31 | 98 31 75 47 9 48 30 65 36 40 70 57 77 72 76 3 21 42 68 24 96 7 23 17 10
Card 133: 46 32 98 75 52 49 80 60 9 47 | 87 3 69 96 29 80 54 98 53 49 66 88 35 75 58 40 93 73 42 2 30 90 1 76 22
Card 134: 23 8 93 17 5 21 9 19 13 82 | 71 37 95 91 65 43 27 44 36 24 98 99 2 74 20 88 49 17 76 80 46 57 79 94 81
Card 135: 81 28 19 5 22 75 18 74 51 13 | 32 66 55 62 17 60 96 70 23 37 34 67 14 84 24 76 16 47 94 56 38 65 25 97 98
Card 136: 72 8 16 42 50 75 57 39 82 41 | 86 82 57 11 62 92 79 78 1 41 3 64 15 12 46 31 89 45 63 91 81 47 96 27 10
Card 137: 64 70 10 41 33 73 22 62 9 21 | 25 47 90 79 14 97 80 34 33 40 4 6 64 28 83 91 73 63 37 44 98 42 5 12 62
Card 138: 87 14 61 6 27 82 35 8 54 56 | 95 36 51 60 98 78 30 83 19 58 72 4 88 10 77 69 96 8 87 74 27 92 65 75 35
Card 139: 4 16 59 44 74 86 33 5 95 60 | 14 2 34 29 44 26 12 70 66 47 67 52 85 71 95 7 11 4 30 77 40 96 36 98 6
Card 140: 12 86 6 69 88 43 13 55 81 10 | 19 71 6 51 72 46 2 97 3 67 56 74 90 42 86 28 32 52 98 17 38 76 77 49 10
Card 141: 29 72 27 68 17 7 45 64 49 26 | 35 11 29 26 66 14 41 52 6 42 92 5 99 39 24 59 75 12 83 51 78 58 28 81 93
Card 142: 41 63 11 16 15 59 97 34 40 23 | 39 85 37 84 30 20 77 60 36 19 42 61 11 67 10 21 99 87 32 66 48 1 28 5 9
Card 143: 47 14 63 53 73 40 7 50 15 21 | 69 96 26 94 38 9 10 79 78 48 82 66 59 57 12 37 74 1 92 98 88 42 31 39 23
Card 144: 36 88 96 60 86 29 1 57 37 46 | 99 47 22 57 3 60 29 87 86 36 58 30 40 37 1 33 88 49 46 11 96 80 9 8 82
Card 145: 54 66 15 59 79 52 73 14 23 8 | 50 8 20 14 92 72 98 80 85 77 42 49 59 58 18 91 90 17 21 97 1 19 53 84 2
Card 146: 36 80 57 90 97 28 76 52 77 45 | 41 14 46 8 84 91 20 57 52 99 37 67 3 55 10 87 25 18 43 77 97 80 78 85 74
Card 147: 64 12 80 55 49 67 78 28 20 10 | 20 43 1 78 83 39 80 38 24 54 75 49 94 22 26 67 71 97 64 28 12 45 10 55 89
Card 148: 57 96 75 17 53 63 60 8 95 27 | 8 60 2 82 19 5 24 98 27 93 80 86 63 97 17 53 99 59 70 14 78 96 95 57 75
Card 149: 50 95 82 20 27 47 80 48 13 49 | 87 77 20 82 88 74 94 48 13 99 30 65 47 27 11 49 80 61 71 50 34 62 85 18 95
Card 150: 52 14 22 54 43 3 1 99 73 39 | 42 97 89 92 58 8 60 80 82 5 28 17 35 79 40 50 61 56 53 75 95 25 83 31 15
Card 151: 44 9 3 78 73 55 32 59 70 24 | 75 23 91 37 81 66 24 59 70 38 25 55 54 9 3 73 32 44 89 39 78 64 83 12 7
Card 152: 37 29 16 15 24 41 40 99 21 87 | 37 78 68 17 95 60 69 44 55 21 66 96 82 65 87 29 23 36 4 20 15 52 94 75 74
Card 153: 72 80 39 77 71 29 83 10 7 93 | 10 51 52 12 1 22 65 62 33 32 34 11 13 55 72 57 76 96 85 95 90 3 64 47 31
Card 154: 89 66 34 86 8 75 50 98 56 71 | 74 39 16 68 56 27 5 2 58 97 75 34 90 91 8 71 95 66 50 98 60 92 6 9 35
Card 155: 23 84 27 71 33 15 96 25 14 57 | 11 31 46 14 77 88 27 60 59 93 3 96 48 71 33 15 5 6 23 79 89 82 57 25 84
Card 156: 10 25 83 53 73 33 56 29 95 24 | 22 29 11 32 41 74 4 43 46 38 78 16 91 12 73 54 62 10 25 47 52 65 7 28 63
Card 157: 97 31 12 42 32 23 29 72 98 99 | 64 41 3 57 25 76 46 80 75 47 73 87 91 95 82 55 31 35 51 60 16 8 78 77 66
Card 158: 90 46 61 13 33 59 12 25 30 49 | 29 57 31 46 1 64 93 43 94 21 87 83 23 67 91 52 92 85 71 78 36 79 62 5 58
Card 159: 75 92 63 61 69 53 1 74 51 27 | 3 87 65 74 10 59 54 42 22 95 26 24 67 91 33 55 92 77 98 79 43 82 13 12 27
Card 160: 50 38 97 82 73 27 91 79 74 41 | 69 71 34 94 55 40 23 84 10 25 14 67 7 46 48 6 37 91 12 66 16 17 26 22 9
Card 161: 57 19 25 38 12 76 89 95 10 33 | 31 63 68 46 42 79 94 60 7 44 36 56 91 23 35 85 41 87 71 58 82 54 11 9 81
Card 162: 17 54 37 84 85 46 99 51 86 7 | 32 38 4 66 49 7 9 23 76 35 51 85 52 30 45 19 89 6 82 5 58 91 87 72 50
Card 163: 44 4 10 46 38 87 52 83 85 16 | 79 42 21 58 75 3 25 56 7 50 69 57 27 84 38 39 89 70 59 78 93 85 8 96 72
Card 164: 76 26 66 23 89 37 87 9 34 81 | 84 43 14 21 13 20 95 97 3 33 18 88 81 78 16 86 58 48 90 6 61 11 68 62 64
Card 165: 15 54 48 34 18 25 85 23 82 43 | 79 49 95 24 9 96 58 27 2 8 77 3 90 71 86 78 31 80 28 81 26 69 57 29 17
Card 166: 23 94 29 56 27 33 51 55 79 98 | 85 7 89 74 69 15 19 2 97 5 27 88 43 80 86 62 78 76 67 63 30 20 65 1 37
Card 167: 69 37 95 7 53 80 16 82 11 27 | 22 75 5 93 47 62 76 49 2 89 9 50 21 85 34 90 38 86 45 42 18 25 33 98 99
Card 168: 95 12 30 74 21 24 80 64 17 67 | 86 8 98 19 37 48 75 56 16 31 20 40 29 83 79 73 71 27 59 43 65 61 57 78 81
Card 169: 80 8 4 83 15 47 93 2 41 25 | 69 80 93 30 75 16 25 74 61 15 56 67 47 4 85 44 2 87 19 92 70 95 41 94 81
Card 170: 91 25 44 98 29 80 63 26 72 88 | 7 57 3 38 17 44 70 75 88 92 54 14 80 26 8 40 98 55 39 32 72 29 61 63 86
Card 171: 74 37 39 87 31 6 8 38 76 32 | 67 83 34 96 68 64 69 82 54 74 63 12 25 85 9 35 50 87 59 33 60 11 20 32 84
Card 172: 45 96 3 16 97 2 98 27 51 34 | 63 82 10 95 6 5 14 24 57 69 98 23 51 3 43 91 79 35 20 36 48 44 90 84 70
Card 173: 83 69 34 6 8 44 42 33 28 5 | 86 32 56 57 3 19 91 43 80 29 78 8 93 47 73 34 85 77 48 65 83 11 2 15 26
Card 174: 22 30 18 86 72 57 26 29 38 69 | 37 21 80 26 61 68 52 33 15 74 69 9 66 81 17 40 99 78 23 65 43 1 95 79 24
Card 175: 91 47 88 2 62 39 21 4 48 49 | 14 65 12 4 51 21 42 6 79 17 57 10 7 55 98 70 47 49 5 90 18 67 58 62 54
Card 176: 76 7 72 24 57 19 70 41 67 87 | 37 59 36 95 90 28 8 58 93 97 40 57 18 80 69 66 13 54 87 27 86 62 76 84 19
Card 177: 61 23 95 38 1 85 28 51 49 53 | 6 34 38 33 16 39 64 57 10 11 80 78 60 18 12 27 5 75 28 36 25 63 88 74 8
Card 178: 22 69 42 55 54 52 58 11 89 70 | 54 75 5 88 74 97 64 59 94 82 16 76 58 20 23 90 28 47 67 38 66 51 42 83 52
Card 179: 51 45 20 68 69 24 54 52 73 89 | 88 3 64 5 72 1 39 17 53 79 97 8 83 49 50 77 70 76 90 18 59 15 29 61 10
Card 180: 68 10 39 93 62 32 1 20 90 99 | 40 31 38 23 63 27 94 85 87 36 53 67 56 5 72 13 22 6 89 25 35 64 41 57 65
Card 181: 43 76 19 35 75 71 27 13 23 5 | 56 21 87 50 30 46 2 47 85 16 44 73 3 68 38 59 92 17 65 48 22 32 42 52 83
Card 182: 77 3 61 97 96 84 27 48 52 40 | 9 54 65 43 7 20 29 86 73 67 87 82 42 14 55 33 39 71 1 81 69 31 92 74 75
Card 183: 10 52 76 84 82 14 93 34 60 73 | 81 34 75 67 23 82 68 47 73 1 52 45 25 10 6 37 84 93 21 60 79 89 76 14 18
Card 184: 39 91 94 34 71 86 36 2 65 74 | 46 37 91 79 74 59 65 66 34 30 40 73 36 16 64 57 92 71 2 78 94 89 77 86 39
Card 185: 76 22 70 57 85 51 44 43 84 14 | 80 22 29 66 75 1 97 72 21 38 76 13 27 33 69 65 74 7 11 84 53 98 77 17 82
Card 186: 59 49 71 34 66 23 52 79 32 28 | 59 2 32 93 70 96 86 71 1 3 10 28 49 51 66 79 61 24 23 19 46 52 7 34 42
Card 187: 3 31 77 49 45 15 47 6 20 25 | 25 67 88 20 49 6 46 45 9 98 24 2 59 70 77 99 22 13 31 53 91 15 3 74 47
Card 188: 84 19 66 65 53 61 38 25 83 91 | 24 64 43 66 11 72 53 94 86 39 28 97 18 70 68 52 5 7 30 55 38 9 85 34 31
Card 189: 86 22 88 18 87 28 63 92 5 16 | 33 90 71 18 88 39 28 22 26 14 68 1 52 93 56 87 49 77 92 19 86 63 5 16 72
Card 190: 67 83 94 44 66 25 9 98 21 51 | 55 97 76 81 85 68 40 94 66 41 51 45 69 44 50 37 63 83 87 39 2 96 98 95 13
Card 191: 92 89 36 65 6 72 46 23 84 19 | 94 51 99 1 3 88 77 35 90 68 72 87 44 25 69 37 2 42 59 22 58 73 61 43 33
Card 192: 52 49 74 40 2 89 54 87 21 79 | 50 58 54 24 79 27 74 72 62 67 46 89 52 38 83 40 49 29 26 77 87 12 5 21 2
Card 193: 32 59 96 29 80 7 54 3 39 83 | 83 21 80 98 13 54 87 43 29 96 62 75 53 68 88 65 59 33 3 32 67 39 10 77 7
Card 194: 40 12 79 91 84 54 1 74 56 38 | 31 78 38 9 25 46 10 99 54 11 2 97 5 84 37 77 27 1 50 91 43 72 12 96 56
Card 195: 80 34 51 81 55 65 49 71 8 44 | 81 71 83 92 8 51 80 53 30 55 44 2 43 16 24 69 18 57 31 49 65 47 91 79 3
Card 196: 12 22 77 95 49 1 48 8 84 47 | 61 64 63 42 55 13 96 70 73 41 92 10 58 6 86 30 14 23 91 66 87 72 9 27 51
Card 197: 90 30 14 35 11 20 99 79 56 2 | 75 59 40 15 80 36 97 44 17 77 20 10 50 29 33 39 55 32 85 71 43 26 35 24 82
Card 198: 92 98 86 34 64 32 74 17 26 53 | 32 75 97 22 66 89 74 17 8 31 69 52 41 53 34 77 45 46 68 2 96 86 95 93 21
Card 199: 32 31 52 80 2 47 1 13 89 9 | 28 32 87 9 96 7 20 12 73 60 46 78 24 69 55 58 64 14 38 97 16 92 52 79 82
Card 200: 1 8 31 4 53 15 45 22 73 13 | 22 10 73 9 81 74 83 2 11 53 15 45 46 21 62 43 69 50 32 67 41 48 5 25 24
Card 201: 45 37 26 53 80 1 20 35 68 33 | 6 51 77 11 41 53 56 18 25 27 13 42 48 14 79 16 81 59 99 29 86 78 3 15 17
Card 202: 86 56 57 83 11 19 52 69 36 17 | 65 72 11 95 73 49 25 75 15 5 84 35 18 71 44 99 26 52 9 60 45 22 14 19 94
Card 203: 76 23 26 70 12 48 60 11 72 64 | 90 56 99 59 64 62 15 84 71 11 85 93 98 33 46 86 53 39 5 60 81 43 3 78 14
Card 204: 23 75 70 14 95 84 61 9 66 77 | 79 8 1 64 50 41 32 93 58 15 33 10 28 72 82 16 77 65 25 43 39 49 13 23 83
Card 205: 2 99 53 15 32 6 16 69 21 14 | 96 98 24 66 6 47 4 54 45 46 42 13 75 11 80 18 34 35 93 79 65 37 40 92 91
Card 206: 74 30 29 66 68 2 3 34 79 87 | 63 45 88 78 98 27 97 32 38 75 9 11 71 93 55 69 56 20 12 82 81 41 80 23 94
")
;; Puzzle Solution:1 ends here
;; A Record For The Start
;; Records are always useful, so let's create one to represent an individual card. We want to store the
;; card's id (it might be useful in part 2), the winning numbers, and the card's numbers.
;; Since it could potentially be relevant, I also add a slot for the matches.
;; /UPDATE: I also added a slot for the number of copies of the scratch card - relevant for part 2./
;; #+NAME: day4-part1-scratchcard
;; [[file:chicken-src.org::day4-part1-scratchcard][day4-part1-scratchcard]]
;; -*- geiser-scheme-implementation: chicken -*-
(define-record scratchcard id winning-numbers card-numbers match-numbers copies)
;; day4-part1-scratchcard ends here
;; Parsing The Input
;; We know the drill by now, we have to take apart the input strings, and parse them into an easy
;; format for us - in our case, this is the ~scratchcard~ record.
;; For that, I first create the pattern for a card.
;; #+NAME: day4-part1-card-irregex
;; [[file:chicken-src.org::day4-part1-card-irregex][day4-part1-card-irregex]]
;; -*- geiser-scheme-implementation: chicken -*-
(define card-irregex
'(: bol
(* whitespace)
"Card"
(+ whitespace)
(submatch-named card-no (+ numeric))
": "
(submatch-named winning-numbers-str (+ (or numeric whitespace)))
" | "
(submatch-named card-numbers-str (+ (or numeric whitespace)))
eol))
;; day4-part1-card-irregex ends here
;; The pattern is then used to extract every scratch card which is then being parsed in a fold
;; statement.
;; #+NAME: day4-part1-card-fold
;; [[file:chicken-src.org::day4-part1-card-fold][day4-part1-card-fold]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (input->cards input-str)
(irregex-fold card-irregex
(lambda (from-index match seed)
(cons
(make-scratchcard
(string->number (irregex-match-substring match 'card-no))
(map string->number
(string-split (irregex-match-substring match 'winning-numbers-str)))
(map string->number
(string-split (irregex-match-substring match 'card-numbers-str)))
'() 1)
seed))
'() input-str))
;; day4-part1-card-fold ends here
;; Processing The Cards
;; I compare every card number with every winning number on a card, and put every card number
;; with at least one match into the special slot of the record. Note that this is a non-functional
;; operation, and thus modifies the original record! That is also the reason why the procedure
;; name ends with an ~!~.
;; #+NAME: day4-part1-card-matching
;; [[file:chicken-src.org::day4-part1-card-matching][day4-part1-card-matching]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (calc-card-matches card)
(let ((winning-nums (scratchcard-winning-numbers card))
(card-nums (scratchcard-card-numbers card)))
(for-each (lambda (card-num)
(when (foldl (lambda (matches? winning-num)
(or matches?
(= card-num winning-num)))
#f winning-nums)
(scratchcard-match-numbers-set!
card (cons card-num (scratchcard-match-numbers card)))))
card-nums)))
;; day4-part1-card-matching ends here
;; As a next step, I calculate the points for each card.
;; #+NAME: day4-part1-card-points
;; [[file:chicken-src.org::day4-part1-card-points][day4-part1-card-points]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (card-points card)
(let ((match-nums (scratchcard-match-numbers card)))
(foldl (lambda (points num)
(if (= 0 points)
1
(* points 2)))
0 match-nums)))
;; day4-part1-card-points ends here
;; #+RESULTS: day4-part1-calc-full
;; : 23441
;; [[file:chicken-src.org::*Processing The Cards][Processing The Cards:5]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (calc-part-1)
(foldl
(lambda (sum card)
(calc-card-matches card)
(+ sum
(card-points card)))
0 (input->cards input)))
;; Processing The Cards:5 ends here
;; Puzzle Solution
;; #+NAME: day4-part2-card-alist
;; [[file:chicken-src.org::day4-part2-card-alist][day4-part2-card-alist]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (card-alist cards)
(foldl (lambda (alist card)
(calc-card-matches card)
(alist-update (scratchcard-id card)
card
alist))
'() (reverse cards)))
;; day4-part2-card-alist ends here
;; #+NAME: day4-part2-gen-copies
;; [[file:chicken-src.org::day4-part2-gen-copies][day4-part2-gen-copies]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (generate-copies cardlist #!optional (index 1))
(let ((index-card (alist-ref index cardlist)))
(if index-card
(let* ((matches (scratchcard-match-numbers index-card))
(copies (scratchcard-copies index-card))
(copy-indexes (foldl (lambda (indexes match)
(cons (+ 1 index (length indexes))
indexes))
(list) matches)))
(for-each (lambda (card-id)
(let ((target-card (alist-ref card-id cardlist)))
(scratchcard-copies-set!
target-card
(+ (scratchcard-copies target-card) copies))))
copy-indexes)
(generate-copies
cardlist
(+ index 1)))
cardlist)))
;; day4-part2-gen-copies ends here
;; #+NAME: day4-part2-count-scratchcards
;; [[file:chicken-src.org::day4-part2-count-scratchcards][day4-part2-count-scratchcards]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (count-scratchcards cardlist)
(foldl + 0 (map (compose scratchcard-copies cdr) cardlist)))
;; day4-part2-count-scratchcards ends here
;; #+RESULTS: day4-part2-calc-full
;; : 5923918
;; [[file:chicken-src.org::*Puzzle Solution][Puzzle Solution:6]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (calc-part-2)
(let ((cardlist (card-alist (input->cards input))))
(generate-copies cardlist)
(count-scratchcards cardlist)))
;; Puzzle Solution:6 ends here

543
day5.scm Normal file
View File

@ -0,0 +1,543 @@
;; Puzzle Solution
;; [[file:chicken-src.org::*Puzzle Solution][Puzzle Solution:1]]
;; -*- geiser-scheme-implementation: chicken -*-
(import (chicken fixnum)
(chicken sort)
(chicken string)
(chicken keyword)
(chicken irregex))
(define input "
seeds: 364807853 408612163 302918330 20208251 1499552892 200291842 3284226943 16030044 2593569946 345762334 3692780593 17215731 1207118682 189983080 2231594291 72205975 3817565407 443061598 2313976854 203929368
seed-to-soil map:
2069473506 3732587455 1483883
3235691256 2348990120 6550341
3547561069 1392195671 747406227
3264251584 3734071338 283309485
391285622 257757572 195552540
1645243555 3166958320 377191689
335002083 512210869 56283539
3242241597 897735089 22009987
77244511 0 257757572
989159646 4172023334 122943962
605476380 3544150009 188437446
0 568494408 18343754
2700122696 4050276683 121746651
2022435244 2139601898 47038262
2227672101 919745076 95840269
1112103608 2633818373 533139947
826809686 2186640160 162349960
3100147259 762191092 135543997
18343754 453310112 58900757
2323512370 1015585345 282396986
2605909356 1297982331 94213340
2821869347 2355540461 278277912
793913826 4017380823 32895860
2070957389 605476380 156714712
soil-to-fertilizer map:
2700214958 2743391193 363795571
1484584575 1440072796 24660284
927520818 435059068 191969051
1588488926 1434420334 5652462
1423277199 141187887 5443857
1594141388 1350997453 83422881
1986188257 3933008893 120750463
1509244859 146631744 79093544
3712482038 4220862006 74105290
3948206286 1986188257 277570873
291046304 281588807 153470261
1119489869 918224946 303787330
1677564269 1321192605 29804848
2309878676 2336743687 390336282
3079951473 3306332300 449116691
444516565 1222012276 99180329
543696894 1464733080 383823924
3895169406 3771389935 53036880
3529068164 4053759356 167102650
0 627178642 291046304
3696170814 2727079969 16311224
3855550220 3824426815 39619186
2106938720 3107186764 199145536
1428721056 225725288 55863519
1707369117 0 64378064
1771747181 64378064 76809823
3064010529 3755448991 15940944
2306084256 2332949267 3794420
4225777159 2263759130 69190137
3786587328 3864046001 68962892
1588338403 627028119 150523
fertilizer-to-water map:
2299879115 39069388 7889905
514481680 504392888 101474410
3448524168 0 25428313
13641075 1832356728 472401611
0 25428313 13641075
1842445520 108629584 395763304
486042686 3445513487 28438994
2307769020 2304758339 1140755148
2238208824 46959293 61670291
615956090 605867298 1226489430
water-to-light map:
1318826171 2010420436 223477535
2278894745 2233897971 671603259
988189854 447584401 27746374
2132052210 300741866 146842535
0 1279660741 97125596
3531244480 3147213622 507810286
257581844 3816963790 101424269
1298609589 3918388059 20216582
3317726838 1072550929 21856732
3065323607 1254863909 4121973
97125596 1094407661 160456248
359006113 1057194484 15356445
374362558 1636971609 104335413
4039054766 475330775 9209679
1038424317 1376786337 260185272
878530050 3938604641 109659804
1784016098 3738041092 78922698
3152462764 0 165264074
1862938796 1741307022 269113414
497536930 676201364 380993120
3069445580 3655023908 83017184
2950498004 165264074 114825603
1015936228 1258985882 1835900
478697971 1260821782 18838959
1017772128 280089677 20652189
1542303706 2905501230 241712392
3339583570 484540454 191660910
light-to-temperature map:
2827696039 489007811 183207687
1480301347 3744628626 306791400
695239418 130668965 358338846
1297125534 2232912413 183175813
3979319170 1917264287 315648126
3010903726 948848843 968415444
130668965 2663473525 564570453
1053578264 4051420026 243547270
2303677395 672215498 276633345
1787092747 3228043978 516584648
2580310740 2416088226 247385299
temperature-to-humidity map:
4161466647 3871737509 133500649
2423686895 2864370860 72123408
1983529997 0 320533964
3184295196 2695571092 41928210
0 822932241 605870242
3557076981 3267347843 604389666
3226223406 2936494268 330853575
2495810303 2737499302 126871558
1108268519 1428802483 491674128
605870242 320533964 502398277
2622681861 2423686895 271884197
2894566058 4005238158 289729138
1599942647 1920476611 383587350
humidity-to-location map:
2945628300 1864953738 334378942
3467273713 3579654586 715312710
975015905 1356290883 508662855
1483678760 2498980024 1080674562
3443998409 2199332680 23275304
3280007242 2222607984 163991167
4182586423 2386599151 112380873
2564353322 975015905 381274978
")
;; Puzzle Solution:1 ends here
;; Mapping Record
;; #+NAME: day5-part1-mapping-record
;; [[file:chicken-src.org::day5-part1-mapping-record][day5-part1-mapping-record]]
;; -*- geiser-scheme-implementation: chicken -*-
(define-record entity type id)
(define-record mapping-entry from-type to-type from-start from-end to-start to-end)
;; day5-part1-mapping-record ends here
;; Irregexes
;; #+NAME: day5-part1-seed-irregex
;; [[file:chicken-src.org::day5-part1-seed-irregex][day5-part1-seed-irregex]]
;; -*- geiser-scheme-implementation: chicken -*-
(define seed-irregex
'(: (* whitespace)
"seeds: "
(submatch-named seed-numbers (+ (or numeric whitespace)))))
;; day5-part1-seed-irregex ends here
;; #+NAME: day5-part1-mapping-irregex
;; [[file:chicken-src.org::day5-part1-mapping-irregex][day5-part1-mapping-irregex]]
;; -*- geiser-scheme-implementation: chicken -*-
(define mapping-irregex
'(: (submatch-named mapping-from (+ alphabetic))
"-to-"
(submatch-named mapping-to (+ alphabetic))
" map:"
(submatch-named mapping-vals (+ (or numeric whitespace)))))
;; day5-part1-mapping-irregex ends here
;; #+NAME: day5-part1-mapping-nums-irregex
;; [[file:chicken-src.org::day5-part1-mapping-nums-irregex][day5-part1-mapping-nums-irregex]]
;; -*- geiser-scheme-implementation: chicken -*-
(define mapping-nums-irregex
'(: (* whitespace)
(submatch-named to-range (+ numeric))
(* whitespace)
(submatch-named from-range (+ numeric))
(* whitespace)
(submatch-named range-size (+ numeric))))
;; day5-part1-mapping-nums-irregex ends here
;; Data Reading
;; A list of seed numbers:
;; #+NAME: day5-part1-seeds-list
;; [[file:chicken-src.org::day5-part1-seeds-list][day5-part1-seeds-list]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (input->seeds-list input)
(let ((seeds-str (irregex-match-substring
(irregex-search seed-irregex input)
'seed-numbers)))
(map string->number (string-split seeds-str))))
;; day5-part1-seeds-list ends here
;; And a mapping from input type (e.g. ~#:soil~) to the mappings to the next type:
;; #+NAME: day5-part1-mapping-alist
;; [[file:chicken-src.org::day5-part1-mapping-alist][day5-part1-mapping-alist]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (input->mapping-alist input)
(irregex-fold mapping-irregex
(lambda (from-index match seed)
(let ((map-from-key (string->keyword (irregex-match-substring match 'mapping-from)))
(map-to-key (string->keyword (irregex-match-substring match 'mapping-to)))
(mapping-vals-str (irregex-match-substring match 'mapping-vals)))
(cons
(cons
map-from-key
(irregex-fold mapping-nums-irregex
(lambda (from-index match seed)
(let ((from-start (string->number
(irregex-match-substring match 'from-range)))
(to-start (string->number
(irregex-match-substring match 'to-range)))
(range-size (string->number
(irregex-match-substring match 'range-size))))
(cons
(make-mapping-entry
map-from-key map-to-key
from-start (fx- (fx+ from-start range-size) 1)
to-start (fx- (fx+ to-start range-size) 1))
seed)))
'() mapping-vals-str))
seed)))
'() input))
;; day5-part1-mapping-alist ends here
;; Processing The Data
;; #+NAME: day5-part1-map-entity-forward
;; [[file:chicken-src.org::day5-part1-map-entity-forward][day5-part1-map-entity-forward]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (map-entity-forward entity mapping-alist)
(let ((maplist (alist-ref (entity-type entity) mapping-alist)))
(if maplist
(let ((default-target-type (mapping-entry-to-type (car maplist))))
(or
(foldl (lambda (new-entity mapping-entry)
(if (and (fx>= (entity-id entity)
(mapping-entry-from-start mapping-entry))
(fx<= (entity-id entity)
(mapping-entry-from-end mapping-entry)))
(make-entity (mapping-entry-to-type mapping-entry)
(fx+ (mapping-entry-to-start mapping-entry)
(fx- (entity-id entity)
(mapping-entry-from-start mapping-entry))))
new-entity))
#f maplist)
(make-entity default-target-type (entity-id entity))))
#f)))
;; day5-part1-map-entity-forward ends here
;; #+NAME: day5-part1-map-entity-forward-fully
;; [[file:chicken-src.org::day5-part1-map-entity-forward-fully][day5-part1-map-entity-forward-fully]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (map-entity-forward-fully entity mapping-alist)
(let ((new-entity (map-entity-forward entity mapping-alist)))
(if new-entity
(map-entity-forward-fully new-entity mapping-alist)
entity)))
;; day5-part1-map-entity-forward-fully ends here
;; #+RESULTS: day5-part1-calc-full
;; : 1181555926
;; [[file:chicken-src.org::*Solution][Solution:3]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (calc-part-1)
(let ((seeds (map (cut make-entity #:seed <>) (input->seeds-list input)))
(mapping-alist (input->mapping-alist input)))
(apply min (map (compose
entity-id
(cut map-entity-forward-fully <> mapping-alist))
seeds))))
;; Solution:3 ends here
;; Puzzle Solution
;; All that is needed is to "expand" the seed numbers before continuing. Since we are dealing with such
;; a huge number of seeds, I use ~delay-force~ to delay calculation of the later ones until they're
;; actually needed.
;; #+NAME: day5-part2-expand-seeds
;; [[file:chicken-src.org::day5-part2-expand-seeds][day5-part2-expand-seeds]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (expand-seed existing-seeds start size)
(let ((max (- (+ start size) 1)))
(do ((seedlist (cons start existing-seeds)
(cons (+ (car seedlist) 1)
seedlist)))
((< (- max 2) (car seedlist))
seedlist))))
(define (expand-seeds seed-nums #!optional (existing-seeds '()))
(if (< 2 (length seed-nums))
(expand-seeds (cddr seed-nums)
(delay-force (expand-seed existing-seeds
(car seed-nums)
(cadr seed-nums))))
(expand-seed existing-seeds (car seed-nums) (cadr seed-nums))))
;; day5-part2-expand-seeds ends here
;; After that, it is /almost/ identical to part 1, but we have to replace the ~foldl~ with a recursive
;; function that handles the promises.
;; #+NAME: day5-part2-fold-seeds
;; [[file:chicken-src.org::day5-part2-fold-seeds][day5-part2-fold-seeds]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (fold-seeds seeds mapping-alist #!optional (minimum most-positive-fixnum))
(let* ((seeds (if (promise? seeds) (force seeds) seeds))
(seeds-available? (not (eqv? '() seeds))))
(if seeds-available?
(let ((location-entity-id ((compose entity-id
(cut map-entity-forward-fully <> mapping-alist)
(cut make-entity #:seed <>))
(car seeds))))
(fold-seeds (cdr seeds)
mapping-alist
(min minimum location-entity-id)))
minimum)))
;; day5-part2-fold-seeds ends here
;; #+RESULTS: day5-part2-calc-full
;; : 37806486
;; [[file:chicken-src.org::*Puzzle Solution][Puzzle Solution:5]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (calc-part-2)
(let ((seeds (expand-seeds (input->seeds-list input)))
(mapping-alist (input->mapping-alist input)))
(fold-seeds seeds mapping-alist)))
;; Puzzle Solution:5 ends here
;; The Optimized Solution
;; For the optimized solution using ranges, a new record type is needed: ~ranged-entity~.
;; [[file:chicken-src.org::*The Optimized Solution][The Optimized Solution:1]]
;; -*- geiser-scheme-implementation: chicken -*-
(define-record ranged-entity type from-id to-id)
;; The Optimized Solution:1 ends here
;; To map the ~ranged-entity~ onto the next step, it has to be split up according to the
;; ~mapping-entry~ ranges.
;; There are different types of splitting, and when they apply:
;; - The beginning of ~ranged-entity~ lies lower than the ~mapping-entry~: the part lower has to be
;; extracted into a 1:1-mapping for the next step type.
;; [[file:chicken-src.org::*The Optimized Solution][The Optimized Solution:2]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (extract-dangling-entity-part ranged-entity type mapping-entry)
(let ((mapping-entry-lower-bound (mapping-entry-from-start mapping-entry)))
(values (make-ranged-entity type
(ranged-entity-from-id ranged-entity)
(- mapping-entry-lower-bound 1))
(make-ranged-entity (ranged-entity-type ranged-entity)
mapping-entry-lower-bound
(ranged-entity-to-id ranged-entity)))))
;; The Optimized Solution:2 ends here
;; - The beginning of ~ranged-entity~ is somewhere inside ~mapping-entry~: the part inside the
;; ~mapping-entity~'s range has to be extracted and the ids shifted accordingly.
;; [[file:chicken-src.org::*The Optimized Solution][The Optimized Solution:3]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (extract-matching-entity-part ranged-entity type mapping-entry)
(let* ((mapping-entry-lower-bound (mapping-entry-from-start mapping-entry))
(mapping-entry-upper-bound (mapping-entry-from-end mapping-entry))
(mapping-entry-target-start (mapping-entry-to-start mapping-entry))
(ranged-entity-lower-bound (ranged-entity-from-id ranged-entity))
(ranged-entity-upper-bound (ranged-entity-to-id ranged-entity))
(start-offset (- ranged-entity-lower-bound mapping-entry-lower-bound))
(first-index (max ranged-entity-lower-bound mapping-entry-lower-bound))
(last-index (min ranged-entity-upper-bound mapping-entry-upper-bound))
(range-size (- last-index first-index))
(matches-mapping? (= ranged-entity-upper-bound mapping-entry-upper-bound))
(exceeds-mapping? (> ranged-entity-upper-bound mapping-entry-upper-bound)))
(values (make-ranged-entity type
(+ mapping-entry-target-start start-offset)
(+ mapping-entry-target-start start-offset range-size))
(if exceeds-mapping?
(make-ranged-entity (ranged-entity-type ranged-entity)
(+ mapping-entry-upper-bound 1)
ranged-entity-upper-bound)
#f))))
;; The Optimized Solution:3 ends here
;; - There is just ~ranged-entity~ left, with nothing else: then it gets a new type, and is otherwise
;; passed on 1:1.
;; [[file:chicken-src.org::*The Optimized Solution][The Optimized Solution:4]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (map-dangling-entity ranged-entity type)
(values (make-ranged-entity type
(ranged-entity-from-id ranged-entity)
(ranged-entity-to-id ranged-entity))
#f))
;; The Optimized Solution:4 ends here
;; This behemoth determines which of the functions above to call.
;; [[file:chicken-src.org::*The Optimized Solution][The Optimized Solution:5]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (map-ranged-entity-forward ranged-entity type level-mappings)
(let ((processed-ranged-entity #f)
(remaining-ranged-entity #f)
(retry? #f))
(cond
((eqv? '() ranged-entity) '())
((eqv? '() level-mappings)
(let-values (((processed-ranged-entity* remaining-ranged-entity*)
(map-dangling-entity ranged-entity type)))
(set! processed-ranged-entity processed-ranged-entity*)
(set! remaining-ranged-entity remaining-ranged-entity*)))
((and (>= (ranged-entity-from-id ranged-entity)
(mapping-entry-from-start (car level-mappings)))
(<= (ranged-entity-from-id ranged-entity)
(mapping-entry-from-end (car level-mappings))))
(let-values
(((processed-ranged-entity* remaining-ranged-entity*)
(extract-matching-entity-part ranged-entity type (car level-mappings))))
(set! processed-ranged-entity processed-ranged-entity*)
(set! remaining-ranged-entity remaining-ranged-entity*)))
((> (ranged-entity-from-id ranged-entity)
(mapping-entry-from-end (car level-mappings)))
(set! retry? #t))
(else
(let-values
(((processed-ranged-entity* remaining-ranged-entity*)
(extract-dangling-entity-part ranged-entity type (car level-mappings))))
(set! processed-ranged-entity processed-ranged-entity*)
(set! remaining-ranged-entity remaining-ranged-entity*))))
(if retry?
(map-ranged-entity-forward ranged-entity type (cdr level-mappings))
(if remaining-ranged-entity
(cons processed-ranged-entity
(map-ranged-entity-forward remaining-ranged-entity type (cdr level-mappings)))
(list processed-ranged-entity)))))
;; The Optimized Solution:5 ends here
;; Here, the mapping is being done.
;; [[file:chicken-src.org::*The Optimized Solution][The Optimized Solution:6]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (map-ranged-entity-forward-fully ranged-entity mapping-alist)
(let ((mappings (alist-ref (ranged-entity-type ranged-entity) mapping-alist)))
(if (and (not (eqv? '() mappings))
mappings)
(let* ((mappings-alist (map (lambda (x)
(cons (mapping-entry-from-start x) x))
mappings))
(sorted-mapping-ids (sort (map car mappings-alist) <))
(sorted-mappings (map (cut alist-ref <> mappings-alist) sorted-mapping-ids))
(new-type (mapping-entry-to-type (car sorted-mappings)))
(new-entities (map-ranged-entity-forward ranged-entity new-type sorted-mappings)))
(foldl append '() (map (cut map-ranged-entity-forward-fully <> mapping-alist)
new-entities)))
(list ranged-entity))))
(define (seeds-list->ranged-entities seeds)
(if (<= 2 (length seeds))
(cons (make-ranged-entity #:seed (car seeds)
(- (+ (car seeds) (cadr seeds)) 1))
(seeds-list->ranged-entities (cddr seeds)))
'()))
;; The Optimized Solution:6 ends here
;; And here, it is all put together.
;; [[file:chicken-src.org::*The Optimized Solution][The Optimized Solution:7]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (calc-part-2-optimized)
(let ((seeds (seeds-list->ranged-entities (input->seeds-list input)))
(mapping-alist (input->mapping-alist input)))
(foldl min most-positive-fixnum
(map ranged-entity-from-id
(foldl append '()
(map (cut map-ranged-entity-forward-fully <> mapping-alist)
seeds))))))
;; The Optimized Solution:7 ends here

184
day6.scm Normal file
View File

@ -0,0 +1,184 @@
;; Puzzle Solution
;; #+NAME: day6-part1-imports
;; [[file:chicken-src.org::day6-part1-imports][day6-part1-imports]]
;; -*- geiser-scheme-implementation: chicken -*-
(import (chicken string)
(chicken irregex))
;; day6-part1-imports ends here
;; #+NAME: day6-input-scm
;; [[file:chicken-src.org::day6-input-scm][day6-input-scm]]
;; -*- geiser-scheme-implementation: chicken -*-
(define input "
Time: 58 81 96 76
Distance: 434 1041 2219 1218")
;; day6-input-scm ends here
;; Data Extraction
;; First, we need to define the record for the race data.
;; #+NAME: day6-part1-race-record
;; [[file:chicken-src.org::day6-part1-race-record][day6-part1-race-record]]
;; -*- geiser-scheme-implementation: chicken -*-
(define-record race time-limit record-distance winning-distances losing-distances)
;; day6-part1-race-record ends here
;; The solution starts with the usual data extraction using ~irregex~.
;; #+NAME: day6-part1-input-extraction-irregex
;; [[file:chicken-src.org::day6-part1-input-extraction-irregex][day6-part1-input-extraction-irregex]]
;; -*- geiser-scheme-implementation: chicken -*-
(define input-extraction-irregex
'(: "Time:"
(submatch-named time-vals (+ (or numeric whitespace)))
"Distance:"
(submatch-named distance-vals (+ (or numeric whitespace)))))
;; day6-part1-input-extraction-irregex ends here
;; Next, the data is converted into ~race~ records.
;; #+NAME: day6-part1-input--race-records
;; [[file:chicken-src.org::day6-part1-input--race-records][day6-part1-input--race-records]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (input->race-records input)
(let ((match (irregex-search input-extraction-irregex
input)))
(map (lambda (time distance)
(make-race time distance #f #f))
(map string->number (string-split (irregex-match-substring match 'time-vals)))
(map string->number (string-split (irregex-match-substring match 'distance-vals))))))
;; day6-part1-input--race-records ends here
;; Race Calculations
;; #+NAME: day6-part1-get-distance
;; [[file:chicken-src.org::day6-part1-get-distance][day6-part1-get-distance]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (get-distance race hold-time)
(let ((time-remaining (- (race-time-limit race) hold-time)))
(* time-remaining hold-time)))
;; day6-part1-get-distance ends here
;; #+NAME: day6-part1-calc-race-distances
;; [[file:chicken-src.org::day6-part1-calc-race-distances][day6-part1-calc-race-distances]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (calc-race-distances race
#!optional (hold-time 1) (winning-distances '()) (losing-distances '()))
(let* ((record-distance (race-record-distance race))
(new-distance (get-distance race hold-time))
(is-new-record? (> new-distance record-distance)))
(cond
((= new-distance 0)
(begin
(race-winning-distances-set! race winning-distances)
(race-losing-distances-set! race losing-distances)
race))
(else
(calc-race-distances
race (+ hold-time 1)
(if is-new-record? (cons new-distance winning-distances) winning-distances)
(if is-new-record? losing-distances (cons new-distance losing-distances)))))))
;; day6-part1-calc-race-distances ends here
;; Getting The Result
;; #+NAME: day6-part1-calc-fn
;; [[file:chicken-src.org::day6-part1-calc-fn][day6-part1-calc-fn]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (calc-part-1)
(foldl *
1 (map (compose length race-winning-distances)
(map calc-race-distances (input->race-records input)))))
;; day6-part1-calc-fn ends here
;; Code Changes
;; The ~input->race-records~ function has to be rewritten:
;; #+NAME: day6-part2-input--race-record
;; [[file:chicken-src.org::day6-part2-input--race-record][day6-part2-input--race-record]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (input->race-record input)
(let* ((match (irregex-search input-extraction-irregex input))
(time-val ((compose string->number
(cut foldl string-append "" <>)
string-split
(cut irregex-match-substring <> 'time-vals))
match))
(distance-val ((compose string->number
(cut foldl string-append "" <>)
string-split
(cut irregex-match-substring <> 'distance-vals))
match)))
(make-race time-val distance-val #f #f)))
;; day6-part2-input--race-record ends here
;; And instead of keeping a list of all winning and losing distances, I use a counter.
;; #+NAME: day6-part2-calc-race-distances
;; [[file:chicken-src.org::day6-part2-calc-race-distances][day6-part2-calc-race-distances]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (calc-race-distances-with-counter race
#!optional (hold-time 1) (winning-distances 0) (losing-distances 0))
(let* ((record-distance (race-record-distance race))
(new-distance (get-distance race hold-time))
(is-new-record? (> new-distance record-distance)))
(cond
((= new-distance 0)
(begin
(race-winning-distances-set! race winning-distances)
(race-losing-distances-set! race losing-distances)
race))
(else
(calc-race-distances-with-counter
race (+ hold-time 1)
(if is-new-record? (+ 1 winning-distances) winning-distances)
(if is-new-record? losing-distances (+ 1 losing-distances)))))))
;; day6-part2-calc-race-distances ends here
;; Race Variant Results
;; #+NAME: day6-part2-calc-fn
;; [[file:chicken-src.org::day6-part2-calc-fn][day6-part2-calc-fn]]
;; -*- geiser-scheme-implementation: chicken -*-
(define (calc-part-2)
(race-winning-distances
(calc-race-distances-with-counter (input->race-record input))))
;; day6-part2-calc-fn ends here

1447
day7.scm Normal file

File diff suppressed because it is too large Load Diff