diff --git a/input/09.txt b/input/09.txt new file mode 100644 index 0000000..2f0b73d --- /dev/null +++ b/input/09.txt @@ -0,0 +1,100 @@ +7656767892349998765421234567898989212399998765436799323569876789876532345678934689439865434598764345 +7543456921498999887634345989987978901988999876545678912398945689998788756789323898929876545987652123 +5432346890987988998745677898766467899977899987656789101987934578999899967993212367895987856797543012 +6543467899896767899886788987654246997656789398977993219876523467899999878965601459994398767939652143 +7655678998765656899999899998762129898545691299899894498765412456789689989976542398989219878929854354 +8766989239954345999875979999874398765434592987698789987654301366789576597899743987878902989913996565 +9977898999965239876454567898765497664326789975432678998763212345689454376788959976567899997895987676 +6988987987891023994323467999986798553215678975321589999874345677794343234567998664356678956799998787 +5499976456789124989212356789697989432104567989432367899965457789893210134679876553234579997988989898 +4398765345678939875101289894598978943213479998543458999986567890999353256789965432123567989876578939 +5219833234599546954212678976899867899394989987654567898797778921298994345999876543234569879999489323 +6998621046788959894324569987920998988989894398896878997698989543987989456789989679765698768988995412 +9876543234567898795487678998931239877876789129987989989539898654976578997899998798976987657577894324 +4987654375678987679598789789546499856985679098998999876323789769894366789978999987897996545456789456 +3498765456799876599679894679697987643234589987659798765101556998743245678967899876799895432345679567 +2369897587901995478994913498989999832124599876545679543212348987654559799757899875478799321234589878 +1456998678919878367893201987878999751035678965434598764324456798765678967645698764365678944345678989 +2667899789998953256789219896567899862176989974323679876535897899878789656434988653234589975466789795 +3598919899987654348994398765489998943267899985434599987646789968989895432129876743123578986567898634 +4789329979998766856789499876579987654459939876798789498857895459798996543334985432035789987678976549 +5678998768989879987899989997799898767668921987899894359968954397656987654595696542126796598989987998 +6789987656979989998999876798998769879789410199998943239879543298787898969989987656789895459990199897 +7899986435867899989198765899019653989899321998987656545998961019899999898978998787895932349994298766 +8999865423456999871019886899998732194968939897998767699877892223964698776569899898954321098789349545 +9679854312567899853298987897899549013456798786899898988756789939943987665446789999985434989689959876 +9498766523898998764987698956797698924569987645799979876543457898899876543235678998976599876577899997 +7329878535799349765696569345689987895698798435678965997655568946789988932123789997997987676456789998 +5498989645678959876984321234579876789987655424567894398766789435699999894235699986789876532345678989 +6987899876789999989878540123698754678976543213568995459897894324567898799346789875679876543456789878 +9876543987899989998965432789799842567897654524567989567989989216678999678957998754567989655767899767 +8989632198998764767896543578921943458998965545689779979878978934569986567967896543456798786879957656 +7798993239898753456987764569990984569129298756789667899867867897698975456898997912569989997899742345 +6657989498765432345898987689989875678999349887892456988743457999987654348999879893698767898987631236 +5345678999986546456789998789978989799988956998921369879652345899998763237899768789987656789998543547 +3234569898698687867899899899865699899877897989432456965430456789879984456988656678999943499979765656 +2123498764579798989957789987654567998666789876576567986721278998769876569878234568998892567969876789 +3294987643469899994345678998963479876455699987687789998742389987654987698767123459877789678956987890 +4989875432356978921234567899874567943234569998798998987656569865432198797656012598765698789145798952 +9879999321247568910123478910997689876345678999899567898768678996543029986542123987654589894236999543 +6568998430123467892234589991298998765476789989923499989978789987655435998643354598765678975949987656 +5487987621545679943346799989349979876567899976312988975989892199796749879754456789976789299898998767 +4346798732356789765457899879959765987689999865209877894393921098987899869868767894987892098767899878 +3234569845467899876568998767898943198999987654398566789212492987898987654979878923598979987656789989 +2126979956578999987899987654567894239899998765987445678901589876789699843989989101239769878745679898 +4017898767679889998999899773489965398788999879876323789997678989897598764699998992348943965432589767 +3125679898789769879998759898567896987656799998765413456789989999976439975789876789457892987643498756 +4234567939897656567987545987678987986545678999876324698999799897655423989893985678998901297654989534 +5655678923998943467896434598989898995423789998987436789987689789543014599932124567899912398865978323 +9789789212349891234789323459998759876764799987698587899876565679642124598921013456799893569879965212 +9899892101239789645679219769896545989875678976559799998765434578963345997662124687899789978998754323 +9986989912398678986989398998785434596976789785439899129654323656794459876543236898987679899209865634 +8975767893987567899899976569654321245987898654323978998765612345689967987654347999996598789399979789 +7684556954597678998789895498776732356898989985454569439976843456996898998776788998765478679989998999 +6543347895698989987656789329887845456789679876785678923987754767895789209897899799654354589878767989 +6432123996799599987545678934998956567896563987897899212398875698934678999998997679932123499767656878 +7546236789989698776434789646799897678985432098998932101239876899324799989989894567891094987656346767 +8755445697679789654526998997989789789876543989999543312345987965456965679876743456989989998742125456 +9876756789568998543217896789874678991989659878987674523459998976789764599965432345678978999983012345 +8989887895459987654101245698963457890199878968898785789998999987899643489979874458999867899879123459 +7894998953312399767323349897652356789234999856799896899897894398978954569898965667998756899864234578 +6423469762101239898734567987643458994365987645879987998786899209567965798767896879876545799765349699 +4212356953212345998545678997656567895459876734568998987675678913457897987656789989975434578979998989 +2103969874323496987656789298767878999598765423459999996434569323467989877545678999865423467898887679 +3219899965434989898767892129898989998999996214567899876546778934579878965434567899976210158987776598 +4398788896549876789878999099999899987889989323679943987789889855698767894325678999854332345986656456 +5987656797698765699989998989998798765679878994589995699891998768989859899534789298765443599765432345 +9899777898987654678999987677897649854398766989691989789990989979878545788965690129876854987654321234 +8797998949998743989678996546789898764299745678910579899989876898765434567896789634988965798765210156 +7676789234998759898989987987993969875987656789323468919878765789654323478999896546799879989984321237 +6545678999899898787899998998932349976798777899434679109867454679875456989998987659893998769765632388 +8766789989799995656789879989659998987899888998946989998754323569989767897987898969912398759876545678 +9878999976678984645878965679998767898934999767897899897643212698799878956596789998923977645998668789 +7989998764589673234569894567899856999324989656789998765432101987643989543455899987899865734569799898 +6597986553499432123668789678987645689109875435893129876543219876532398921234599856799954323459892947 +5456795442988921012345678989999136789398765323989299989665423998541236932445689645989965434567901236 +3219986321567892335456899898998758999999876219876989898776567987632345893956789936979876545678994345 +4398765432348943545567895767999767989899987398985476789888789598745486789897899899765998676789789457 +5679876943959954656678943456789889876789999987674345699999893499876577898789998798943219987895696568 +8789998756767895798789432345698998765678999896543256789756902989989989945678976577895349998976789979 +9897898767899976899896541334567899954589998789652134595439899878593496434567895456789658959989899898 +3945699979999987912983210123458998765678967698931023469949798765432987565678954345689967945699998787 +2234987989989998909874321236769999986899654567892134567897689654321098676789321234567899896789987676 +0129876597879999598765432345679899899965743569943455678955569796432989787896543545678998789899996545 +3298765456767894329976543768798787778954532698956567889343478989569879898987654556789765678919865434 +4698984345656793219997654878987656569543210197897898993212345678979967959798875978897954599329876321 +6797653212347954397889965999996547459954329986799999654343478989998652345679996989976543458998983210 +7987654101459769976777896789985431347896498995678998765454567898998543458789987899995432567987654323 +8998543212467998765656789899876545456789597864578999876565878967987689569893498969876543878998965634 +9987654357898998754346999998987656567899986543568998998789989459998797678912399643988674599869987545 +3298767998999987643239899987898797678999875432349987659899992398999898989109987652399789678943987676 +4989988999998765432125788976799898989987654321238898743978901997899989393298899843999898789921098987 +9879999999987654321034567895678999694599775210126789654567899876789876459987679959878949999892149998 +8968999987598765432123678923489989543434986321545678965678988765899998698765589898765439879799234999 +7656889995459899543247789214999878962123997437656889996789876543457989799854345789978998767678949889 +6547679994345998765356789939898767893299898598789999989899987542349878998743236789989987653567898778 +2123456789559879965467897898765656789987769679891299878989876431239767987654347898890198842456789656 +1012897897698769878598946797654345678976659789910986563467986540997656698765467956789359321367899867 +3234789998799754989679239986543234767895549898929876452556898759876545569977568945678998410234999978 +6345678939987643498789198765752123456894323967998764341245998769987634456798679434567987321345789989 +5476789219876532569891097654321014567893212359876543210167899978998721237899789323459876532359891099 diff --git a/lib.rkt b/lib.rkt index 9e23ad2..bd00e31 100644 --- a/lib.rkt +++ b/lib.rkt @@ -4,7 +4,10 @@ threading (only-in data/queue make-queue - enqueue!)) + enqueue!) + (only-in racket/set + list->set + set->list)) (provide (all-from-out threading) (all-defined-out)) @@ -75,6 +78,11 @@ ;; convert it into the number it represents (define chars->binary (∘ string->binary list->string)) +;; char->number : char? -> number? +;; Convert a digit character into its integral value +(define (char->number c) + (- (char->integer c) (char->integer #\0))) + ;; string->vector : string? -> (vectorof char?) (define (string->vector str) (list->vector (string->list str))) @@ -258,6 +266,11 @@ (for-each (∂ enqueue! Q) lst) Q)) +;; unique : (listof a) -> (listof a) +;; Return a list of unique items; not guaranteed to be stable +(define (unique lst) + (set->list (list->set lst))) + ;; Vector helpers ;; diff --git a/src/09.rkt b/src/09.rkt new file mode 100644 index 0000000..5c91526 --- /dev/null +++ b/src/09.rkt @@ -0,0 +1,56 @@ +#lang curly-fn racket + +(require racket/set "../lib.rkt") + +(define input + (~>> (problem-input 9) + (map string->list) + (map #{map char->number %}))) + +(define rows (length input)) +(define cols (length (first input))) + +(define (grid-ref grid row col [default +inf.0]) + (if (or (< row 0) (>= row rows) + (< col 0) (>= col cols)) + default + (list-ref (list-ref grid row) col))) + +(define (neighbours row col) + (list (cons (sub1 row) col) + (cons (add1 row) col) + (cons row (sub1 col)) + (cons row (add1 col)))) + +(define (low? row col) + (andmap #{< (grid-ref input row col) + (grid-ref input (car %) (cdr %))} + (neighbours row col))) + +(define (highers row col) + (filter #{and (< (grid-ref input row col) + (grid-ref input (car %) (cdr %) -inf.0) + 9)} + (neighbours row col))) + +(define (basin unseen seen) + (match unseen + ['() (unique seen)] + [(list (and hd (cons row col)) tl ...) + (basin (append tl (highers row col)) + (cons hd seen))])) + +(define-values (part1 part2) + (for/fold ([risk 0] + [basins '()] + #:result (values risk (apply * (take (sort basins >) 3)))) + ([row (range rows)]) + (for/fold ([risk risk] + [basins basins]) + ([col (range cols)]) + (if (low? row col) + (values (+ (add1 (grid-ref input row col)) risk) + (cons (length (basin `((,row . ,col)) '())) basins)) + (values risk basins))))) + +(show-solution part1 part2) \ No newline at end of file