# Created 2023-12-10 Sun 23:58 #+title: Advent Of Code with Chicken Scheme #+author: Daniel Ziltener #+export_file_name: chicken.org #+property: header-args:scheme :session *chicken* :comments both :exports both :prologue ";; -*- geiser-scheme-implementation: chicken -*-" :eval no-export #+property: header-args:fundamental :eval no * Prelude I don't know why I am spending my time this way, but I am trying to get through this year's [[https://adventofcode.com/][Advent of Code]]. I decided to use [[https://call-cc.org][Chicken Scheme]], and I am trying to use as few (if any) extensions, for an extra challenge. /*This may or may not be the original document ([[file:./chicken-src.org][=chicken-src.org=]]) or its weave for reading ([[file:./chicken.org][=chicken.org=]]). Choose wisely.*/ * Day 1: Trebuchet?! ** Part One *** Quest Something is wrong with global snow production, and you've been selected to take a look. The Elves have even given you a map; on it, they've used stars to mark the top fifty locations that are likely to be having problems. You've been doing this long enough to know that to restore snow operations, you need to check all *fifty stars* by December 25th. Collect stars by solving puzzles. Two puzzles will be made available on each day in the Advent calendar; the second puzzle is unlocked when you complete the first. Each puzzle grants *one star*. Good luck! You try to ask why they can't just use a [[https://adventofcode.com/2015/day/1][weather machine]] ("not powerful enough") and where they're even sending you ("the sky") and why your map looks mostly blank ("you sure ask a lot of questions") and hang on did you just say the sky ("of course, where do you think snow comes from") when you realize that the Elves are already loading you into a [[https://en.wikipedia.org/wiki/Trebuchet][trebuchet]] ("please hold still, we need to strap you in"). As they're making the final adjustments, they discover that their calibration document (your puzzle input) has been *amended* by a very young Elf who was apparently just excited to show off her art skills. Consequently, the Elves are having trouble reading the values on the document. The newly-improved calibration document consists of lines of text; each line originally contained a specific *calibration value* that the Elves now need to recover. On each line, the calibration value can be found by combining the *first digit* and the *last digit* (in that order) to form a single *two-digit number*. For example: #+begin_example 1abc2 pqr3stu8vwx a1b2c3d4e5f treb7uchet #+end_example In this example, the calibration values of these four lines are =12=, =38=, =15=, and =77=. Adding these together produces =142=. Consider your entire calibration document. *What is the sum of all of the calibration values?* *** Puzzle Solution #+name: day1-solution-1 #+begin_src scheme (import (chicken string) (chicken irregex)) (let ((lines (string-split input "\n"))) (foldl + 0 (map (lambda (line) (let ((digits (irregex-extract '(/ #\0 #\9) line))) (if (= 0 (length digits)) 0 (let ((first-digit (car digits)) (last-digit (car (reverse digits)))) (string->number (string-append first-digit last-digit)))))) lines))) #+end_src ** Part Two *** Quest Your calculation isn't quite right. It looks like some of the digits are actually *spelled out with letters*: =one=, =two=, =three=, =four=, =five=, =six=, =seven=, =eight=, and =nine= *also* count as valid "digits". Equipped with this new information, you now need to find the real first and last digit on each line. For example: #+begin_example two1nine eightwothree abcone2threexyz xtwone3four 4nineeightseven2 zoneight234 7pqrstsixteen #+end_example In this example, the calibration values are =29=, =83=, =13=, =24=, =42=, =14=, and =76=. Adding these together produces =281=. *What is the sum of all of the calibration values?* *** Puzzle Solution #+name: day1-solution-2 #+begin_src scheme (import (chicken string) (chicken irregex)) (define (extract-digits input-string) (irregex-extract '(or (/ #\0 #\9) "one" "two" "three" "four" "five" "six" "seven" "eight" "nine" ; Duplicates "twone" "eightwo" "nineight" "eighthree" "threeight" "fiveight" "oneight" "sevenine") input-string)) (define (translate-code digit) (case (string->symbol digit) ((|0|) "0") ((|1| one) "1") ((|2| two) "2") ((|3| three) "3") ((|4| four) "4") ((|5| five) "5") ((|6| six) "6") ((|7| seven) "7") ((|8| eight) "8") ((|9| nine) "9") ; Again, duplicates ((twone) "21") ((eightwo) "82") ((nineight) "98") ((eighthree) "83") ((threeight) "38") ((fiveight) "58") ((oneight) "18") ((sevenine) "79") )) (let ((lines (string-split input "\n"))) (foldl + 0 (map (lambda (line) (let ((digits (string->list (foldl string-append "" (map translate-code (extract-digits line)))))) (if (= 0 (length digits)) 0 (let ((first-digit (car digits)) (last-digit (car (reverse digits)))) (string->number (string first-digit last-digit)))))) lines))) #+end_src ** Puzzle Input Jump to [[#headline-10][day 2]]. #+name: day1-input #+begin_src fundamental eightqrssm9httwogqshfxninepnfrppfzhsc one111jxlmc7tvklrmhdpsix bptwone4sixzzppg ninezfzseveneight5kjrjvtfjqt5nineone 58kk 5b32 1dtwo six7two7sixtwo78 mvhsixpptztjh13sixthree2 six1bqqvrxndt fourmk5grmqone944nbvtj twofiveqxfivezpkvfvxt5eightjhnpl fpfqp7three7 scmlf76ninegjzjkj97two fivetkhfnnx22 sevenxvbcbsvxr7eighttwo 1hvhqqmrs1bgttshthg6 4bvnccbdh4onefztdrpq62vvbnvpxxvgrngnfjgfk 653spgrvd sixctlhkjmmxh2fourfivenine37 229mjp3txmqsxxqdbnnnbrtrcctgzseven jfourdbpcjc39bhglgnine bvnltxdmsp7twoxzpdjdvkxeight4twothree jlvcdrkhzh8seven3 418oneeight 53flcrlvqdeight84frmdcsixchcbc 114sixone1eight2 xrbtzbklqsl11 bhfhszrhzgrhsfd2threeseventwosevenoneseven four9one 5p twovhjpdxmcxshnhv5vs qkkqeightcxcltnn7one9pmhlmvsxnine 4cbptmvp1 84xgm bzsmqhkrdtdmhhjgrjsdfour1ninetwo61 onetwoeightgflhlgksevennine7two6 mbjhkhfour6 8cvqk6eightonethree1 qhbllbnlkr3rcsmjvztgd 18eight4 hhc6onegvkgkqs5mvsone 66bnfj one99xvrhninefive eight96nxcjjddmseightxvgsixfiverrzpvmgnl rpgpczdsxpjgql39 855dnthhxld6eight four29twosspz1 sixfiveqvrbcdr9fourlrkpkmxphlsbone 341 mhqjjg9six9nine 7pvjctsgvsix64 75twotwothreegcvssgbvhpzcnbgteight 7keight8eight 52threerhfmklssxcptmnlr4hqc4 xndfqvgxn3five 974lknineseven rlnsix3 771m1 xvtjhq7six64threeeightgspmxgv 4sbqdxbmmzj6fiveone onesvvch4rvhmvncnk mkzsftp69six6 fiveptnn7 94lsgsjxrrghxxsr4 1grnvgpeightjthqmrfnszpfhfninefive9mbtf qtsdfour2 5mfhmskpcvqbxjzzxt4lq3sevenkv rbhjk1cdzjhtzkcbtvmfm nine4eightpmrptkb bfiveeight1lxzkzvbtkkgxxs38 mxcgbjqvhd1sevensevenrgp7two fourxrdzzmjfmtr62one sevenppqtlhvtwo7phlrbssxb dhbnjmxg3bsgbhmlfiveseventwo twoonemrbftgtzeightqjmjctmq55 ggk2lt586dfzqbjsvj1one jtgpzjjtwo86seventwo 37nine4onebqvsnmvg277 hmpnzmqsfour6 xzfhgzllmcbc56vpbpbbjffmgr3jrc 5lclone hjbvkdtmrgvpfive9sevenfive1nlzqlkfrg htwonetgxvjdkrvjsfjjbfmcthseven29 six89bdlssd 3eight6one vtbsix2twolzrhfr1 vhdcvtj5 167nsnmgxhtvn54fivedcbgrhm 4three1five82four 15eightonethreesixthree dvhtsccljt51 pbnfrxblk3sevenxjcmcvhlgrghpbgdnpl8xsr3fiveoneightq 242three8 2fivehgqfxgl8kpdknxhmk5bmmsbz fivejvjeight6fsqgtpvcb 1threelgkbhlhhlmrbvxqqgf klmqfgfg1gnine253psn8 47eight eight83mvdtsqppjhgjnsvngfive 7mcmzvsv6seven 56seven98three4three pfnbthreegthreefknjm4five 2nqgrdcshfpjfpqdrvnq1twoccpmxpxvv xtwo7threemxbtpsvjkgrfivethree2 9pkdfourfour1zjvczkhpbj 1three2 pkkbphkgqfivellrnvnkdxpql3 ppc62 one73ptfxsbbpqqgctdjhzjsjc91 nine7threefourvvk six59542xcxqcbnrvzfbshcxxddz2 ftsfj2ninesix1hdjsrpkonelklfpltv ninehmxgkqbmhvtlvdmdtvpeighttqfour1three frbnineeight4168ksmjstpqvzhnn rgnrntwohvqhgxxfkonefour4mfdr5ftgtjjv 3ninejbszdvdgznfourxpcxspqxnthlngkncvnineccq threemjglxtp5cqmtwotwo2seventwonerkl eightsevensevenlmbjzprggthree1eight 57nineninezdcf cqoneighteightjnrfkplvninefivemck18mnhszhkv4 tbvdcsjsvmxtshv3fourseven4kmxvvfour9 bxcsix19six8dnqsbx 7five81ncchkdk four4ck7rtjmjpccpeightone fivetwo6nine1tdczktmfninelrbnnine onetwo9twoeight5sevensix cvvtbmninebneightsix1dnnfkgmnm h7three3 tpnzsdm9sixtg5sixqvcqsq3 1sevenzmbcpgtfrjvq r8757 fournineseven6fourfour 798dpbrkfourtwoxdrgqkrkmfeight7 threebvqqjcldjx4nine5 3hbl twodndcfddkvfivermvkrfzsnqthree5 mhdcvsixmnqlvmvxmxfour3ct 25dpfsrbcllhtwothree2pthreezfhjx dcfggnine1onetwoone vtbmbpgffive2hdmzjzqqqc4one zg11 txrknhvhbv183 dlvscqszz82nvtpb7tktvtgjbml twofour5sevensmqfjrjcndmvcvqdfsrsix 446sixeight6rbrltdzf 132ncq1 4ninezdfzgvzf4four7qkzstcq 7rx5xntgxfpmvsevenzmzmbjlc3fivefive threeseven7tshthree gnbqhninecjnhlpcfivenine18 gjntwonenllmzgqsvq36lc45fourdrtzlctr 3tqgbfrk zldl3zxpfbpveight 2ninetgppcvqrq 7one1sixeighttxcnhltwooneeight bsm3hslqcr8xslndqnnvfpzvprlkt khvptwo7kkbznndpqsevensevenvlr sevenscneight8one4qnkc 2v 2threerjnineonev 68qhknonebtxvmqh 3btb kcxbqzbjqt3twofourfxdlprsxkzlmflbveight 9bmdcninecjdv7 ceightwoninelkbbfxgsv9fb5n ztwo2 7four9cpkclqxtrmpdgzxgtwo 8dghrmgprdjeight8knnb852one 2three36eightfournone2 6ztwofkzlhvjdrxtsmlbgczf knine6ninebpmzjbkg9tttkhtgcklbfive sevenv3 411one4483 88jvjggxqfour3zrbvbxjzmthree fivelqcnqfvgp18t fivejceightqlsdrmrnbzfbjskstzrllxrdlcxpjkvf1 832 sixfive77rhkjdhvbpdfjxpkmfdq66qqtfpfs fv6svkbnsgtpznblnvkvk5 sixsevenfoursixeight486 gsbfrjpngshpmlxf2 gbmmmvdhffbbcq3 5fivehxx28 snjxttwo1zd5sixklfl szsvdzsix3nine32nine onervkhknmnsix3four363 1btphrrvxdeightonekdhv8 gkphmq73lfhflk66xpfive2 611four3gnjsdkvksjdxfiveeight klbvb9zk4eightninetwo mreight59sevengqbhnspvhqcj2six hnvgkmljlpthsgjrzmsevensix6fcvtxddbnx5 ckfvkblhvv6gbsnlsevenktblt29three eightfoursevendnsghkfsg8fivextnnine 5hrdqmfjq twojcvkkjklzmfive2fourxqgdsdgzrjltwo7 onetwonvxnxnntxcthree3 threentwonine6 sprfmxlqvb9jnbzltskxppqzdscrvhpfvjjcqhxcf sixhfour95 41fourqhpjbztknqnfpxvzc two23sevenfgmmnszone113 one41seven57 oneninebqqklhk6gmdzddbhgzqcmxxfnmrvr 4mkpgv87eightckzjjfm vhgdmvncxn88ldbt7464 gcczfprplf7 6eightninesxthreefive99 two69fivecjxjhgjmgvttl9 mztbzjmgxnpkfrqnrbgkgfourjjfjtone8eight 63mggldkcprlz 6sevenfourfive 1zvmrdnpzcsqqmxscn five5tkgb8rrztmcfivebknjd 7pscpfive eight9sixgfvhvlcnineeight seven99fourtwojvxfrqmrdlthree sppcgnjzeight93j fivek7seventhree twornbhtrlnznpctrxhqtngzdtnvfb2 sevenfivefour63five38nlrxfcjpm qvtdcspc4zxmmhpklhcdlznqfg46lct5one 1bnndtnsfjdsevenfivetwo3k85 8five9six 3ltcc7trmmhbbbpjfive cmbchhhczmqlp3 nctz78twodljcqvplcqg nine4sevenpnbbztpvkbgztb zseven9eight fourktzscmnrvddnnzsqfnfctzpdvtwo9 nrtbgdjpm2ldcfdm5jjhx9 jq9two68kjttwo67 lnneightfourzqz6lgvxnthreeseven7 fiveglp85 ninefouronesix7k1three 3five5sevendhtmjhbh2 rbjhnmmgsvmtk8four vtrvvjsixhnctwocvskgzt3two3 kxfive5threezgtd2 2fivemcnngtzxsgbxmvbl eightlrlztkvhfivefour5 2twojcq7qrrbddmpsb 3twosixthreebqtoneone2 nine9six3vlmpqbgjjqdftldpq tgrglqfxxc2onetwo76oneonex one48one fivesgsnrzsms6one fiveseven1tzhxdknkseven4 3sprtonefivelxg47 twotwoseven3ninenqdvxgm nskjpvvqeightnine93fivecngkjcd3 ltfxscllxk9pjznpnmhfmrzmqbq 4nineeight6four7 fjtpj763 four6six73htbstbbpztwofj oneonetwo2five43three five8bgcjnlzcgqpfkn 11mcn 9twovhkltdpkqzc65six 8fkprfkg9xfjxspqpshlfkqpnrt 4sblrf7745 lblxmbzfour6187tggqllj dhdmlx71mbbxtvhszhsvcm six1qbqglfsssx 164tsthbb2 8nineldrtltqfivebqnrthrm sevenlsjbsklhxxfiveclbldxxtrdllxzthree6eight 18gnkrxfmnineone six4threetwoeightgcn vmknclnmnphb2czdbjmcone eightq67 eighthnzslhbblr85eight3 3457kdzhnppqz5four8two crcskvmhthree41 8pccnsbv8ln3 4eightonevd pdz9threenine 3sg5gkrncz 6dxnslkl3xqlnm965twonexxn 9nlhmmkzsdbpdctd7ninec 62eightnine7nine3lrd qbprlzczreight7threegqnrshrhc 3qlmr three1twojgptkzgxmf twosvdsfourone8 5sixfourzvjtkpk six418 five523fivecbs nineninesevenztfggvfkgkzfcm2 qnsix5dnv7three three5twofour hlmtnzsmlnjxdtwo6 9sixnglrctg onecrgfq5hdldpc nhzctlx94eight 19djvld tzp8zzv8six1 1nsnine5sixhqxfk 33sixtwojrdvksrfsnltglggxdhbsxf bbvtpxptrnvjqzl3rldseventhree6 2lcntfphb2lgpjbdeight fivetwo1jjgkt9kltwo1nc 7xnmrscpfkthreejqbhlrtf4sixrbfrone 3threetqfkv1twofive 95ninejlftlxrs1nxxfsqz hrsrszgrcl9seven8eightksdnhqsq7eight 5436ninefour one5five prcmxone8lhkblvr714three 92btgsllktgf7fivejhgsg2eight5 fourmm61nine558nine bxjx2 one6onetwotjxthreefour8 threedkpnpfvgt1one3nine1 bxfour3two2sb4twondmfdpsz 11sevennrpxftwooneeightmx6 9mqxcrjxnp7hdjgqktxm 2rnjlg7mbxstzbdh qmsixhckzone1 qzsnq6sixtwosixtwohhgbsrqgnine3 foureight7scksqtkmnfiveseven765 15oneckvshqd 41tzlxsfivebsckffdps threefivefournine7 5fiveonefour8lhqmltwoeighttwo four5six mhnrspfourmflmvkc52cjkvxheightsevendtddjdcnb vxrrlfnlqf1twoeightninesixonetwo 8xonetwo2 rveightwo79three onebjlr9sixldqrbtwo4 f1lhrbsix mbbkv7ffpk 8twofourmxqvkqfcjfoureightplgpmrtxm3 2rtrxjzqeighteightqtmsfnpdscpgqvxd7 nineqggljvzvxltwozsvsfournine9 ninexpmnnvqsfhnprqrqlcgfive9mtnflvttwoqlgphhb 11kbpmv1 htspdnh1xhbbh3lzcjjx1 five6fivefive5six sxtbktj7 ncvkgvgbeightfour89ttbrjthree xcgxzxbfnkxdqn73eight 5nine4fivesixtwotwo1 ffgzdfhn6 fourzvtfcczlxhnnx5three threednfntx4eightwovql sixtwoveightnine7twonineseven seveneightcclmgknrgninemnjsrsqsevenfftmlqkch7 pvqnltjs2hghkrphnine3scngkjfcsn 62vdnbzrcrjsndqqr2 5cxhscqpgdzbrnnq1m9b gnkclhmbjfourfivemmxpqx2qlxvsix sevenxcp4fourdlqgpxcl 8eighttwoone bjslbfrspcnffnine9rvnjjrvcsix2 six7tfive6hkllf56six km3 sixtjt2threefour2vqqcxj84 9vflltwo4five nineprprrcjt3eightmxfour 4twoninehvsbszqr dtdmkcsd41eightfourxppqzkjb xmdmghzdp9sevennine94 2bbjsdlxoneeight ninefivetwonine8 68four ninepdjpfmzxthree3dkxgttvncbr 52threesevenninefour6lfrlrsgzk ghkczjt86bdk3czvhcone cdjsd6jhnnnhzbzllqdjgpgnninevmcvbcxxltsix 1mxfsrninegfmgvnine14hbfnshgbprone 39four8 bxnnjqkninetwotwo58txgvrbxvq k4bftq68seven4nineseven seven97fivekxjnseven4fourfour drgttpqpsevenvrkxdlmvtctsc72seven eight298 2zsqmjskp six5bgdkhzqt fournlknxg35vqdqmnln6f 565rqtzdpqhlldxgnine7oneeight 3jfthree7vlkpfour1 fourgngnqtgd675vgrrjf 25nrfive kmlbnrm5dtvqndldh vgbzkpnltxrp5tpvb 5mbzzk3nine7cqkngz1mm sevenfive952 4pxk8four seven87fourlzlnineone zxllsctgqmsevensix72 9ggkqvsrhftwobndlt 8sixsfzlfpztjtwofourqvnptkgllxcf 5dvsjvtm 29dsvjrl3pvgjqncbgcxc 9mhvrb8fbtppbhm2s eightninel5 jltnzpcdr8one5szgf3nine88 8xzgs4chdkfour three7vgnbtqvhthree8sixq 2onesix354jj58 175rpdmxfeightwos gmngst7hpfvgmtfrqbb 9hd2lsxprdvtqxcv55 four13cjqkvgxvbseven8 1kqfrqsevenqgjttjrspd 7seveneight6zfmdbzdj2 9sixpfjbnthreedgbhblmr 7hdqqqkone6htzthree hmnxstkbzlhqjpdn3three2 dpbjgmnn1 ninefivecznsbttpcvkthreeoneeight1zqtxb 6hlxdlpgrl7six fourdhczrzd9mmmdthcngsmdqkq9fivetwofkb 7fbcrzcxjvxtqbfive168 sevenhlrkxgrggkqgd12 vzmpvhqvkpdfmthreetwo9 21cqxtjtwoljsixxbf3 bzzxkxtl3rhsrpnnzseven threevhdqqvtwothreenine48frqsfhgsgptbbn foureighteight3pgbcftjdbbsmcqjcrmt21 twovpfbsd42five 6foureightwofh 5185cbhgvkvpfzk1 1one3two5 seven3mdjks6kctnnchjgpnineeight sixfivecjfkx5 sccbfqfive28bhconexmztpcftrbz qfzhgl1nine5four59nbxhclpk mjrvgdz3nine6gkvznv83 mfxqslvpzeight2 ztwoneeightknnjh4nine onefivesevenfsmmhkbcplj6seven 2lfgzblvdflgxnsqfxtksbb blmvzczjs61fourmtds 5two2 jqppjfxfour2 3five2bcrn653 86five6bseven rzztlcbvteight135 1sjngcngjrsht3ninehninefive 81sixkrhvrhxqhn65 dkrgmnlcbjdjxblbfnp5 three85xrckdqtjqphjsjqflmt 5fmptvmz19fourmbzrttnxnk dptwonefbqhrxtljddtkhh6four23 xfvgkfive69 cbtfrbpxphj2sevenmmzrpccnine 5twotwoseven fivetwoeightonefive954 zxccrkvgdqtklbnhtdtdsghcseventwo6 three6vqmtchfdjxveightone onenine39twodksvrdsxflthree threesbpseven5zqtwobtmpgqjg1 326dgjmzzfivehkhsjrseven dgthreeeightthreefbhbltbdjnineseven3klvx 4xkcqeighttwo2 eightonerhlnchp17 2jcmzbczstsrmbpzxpftkmznzckhv7three 7foursixbrcc6twosixgnf 4lqxfourtvxhqtlhlx7xcfxhmqzbone 2sevenz6sixtwo nine1pv 95jzlkxn onerzfnqhmtjpqff93lrctjgqhseveneight 5eightrdjnine3 threetwo6fourrcrq9dfmbsznshkfqmpvcb five3hpjznhbtjonecvfgfsk9n9 2gkbqpqn31 sevenfivefgcvtpsxjprfh8nine lvfxml6992 5threexmjjgkv8985zzjqdbtwo eight3bkqdnbmrtb5 7sevenoneznpx 9hjg4eightrcsvdkbmldjclfqfm 9four2one4 koneightonecdfcrjkqtcsevennlvr8hbrc seven3lthbv8 ninexzznsix5nine ninentdd6qvkclninefivenine four11pgmxz7pnjfiveeight threeninefourpmtmlgllftnvxzn5twonine four46eight9sevenfive3three blztvfkqggcbshlzxppxgrxsr4three3 one9pvlnv 8l37 brjvlvjrhbfourxshh1vlclvrz2 5flqnkntnxkzhcftmzb9rlfzxlg sixfourseven77onekone 6xfmdgjfeight4qzrncxdpmb4four four28 seven74zrtpftdldc7fqlseven5 6gxjzskpkfvmmd zkoneight99jrrmgsfpsixfiveone 9jbbdtdxjsm8szxblgjppx4tpnvqvtlrj rsrlrcb32ngsixfourfivenine 6seven9one7threegrfqpncjthree onebjvpzzqhvlhg1pxkvmgqvxsrglb8fourptbjs 1fch njhs4p86n22 two1one6four1six fourphxjkjtwo8eight 3svqrzd1fourcmlcknhvninetddpbcmbtgqpcjms vkndzm684sixjlgkcvz4 25five pkzt2fivetwo2zffkjqrhgfive4jpsj sevenmpfcthreembjgbfpkdzqlr4 49four1mpldzb3 hdzddkxf1cxftflb73 zrmhdlhk2v7 25zcd 11eighteight5qcqzpvvk 38nine43 8lstwo 12sixnfbrgbhdpn1three3 8eightcd82rzkzlvthqnvhjvgfour 24jcbjplcnqbcrxs25 3fivebfkgpkglfchbmbfps pgmvbnhskgzdmz2sixeightcjq5 cdpmrlj1one 6hxqoneightjjv 34gxbjzrtg5 pvddskbslqnrfngmcjgsdthree3 6nkjjlknp9 hflkjhgjmeightc5n1 dmkeight1223 five9three8 eight7mqfsjplfprrfpkzctgtdvrmxphm phbs2fck4sixfourqvqbr 2bnvktn sfvkgzone83 2threetqnthdnq32ninetwo9 sixhdkvdcmp5three23j 8615four twosix54vrrbvzszk9 53671 threevklcphgkjsnine4eight4fmtffknglthree sixninethreeh4dj oneone1pmdthreesrfsssbkt8 7foureighteight3 srpvkzrqfive378 6twodnnrvfjrjv 4kpxlslqfbktwo bvzpgrc9twotqsvdztwoseven8 xkjdltjgzbjhxkjvtwo6 five27sixsevensixtwo9nine jk468qgkr fourtwo89 fourthreethreedtnzbmlfhmgjr5nineseven7 44seven two3psfive122jps sevensevenghzmpdvrffive9nine3eight 497ftdf9five gklfive6rnvpnvvkqheight 2hvdfiveprrdqspsix6 5m8nine bnctbninexsixonesix8five8 xkqqlmfmrveightsix4nine93nine 6k 3foursevensix6cksix5six 7twoone three73lfddzhd1fkxmjdzsix7twonex sthjlrjrhd741prcsqh3rmllvjmtvgfour 4dvffpjkn tpbttcslvz7twoneq fourtwoninej5snfxnqzthree n7cmsfsqd eightssrzkxj5 239 three8five7xxthreebqrbx zrlchvsevenfournine4ktvskhjgh3h 7fourfdjsnhdbgqjvnltzj6three mrjsndmzkz7rszqnbhxt3fvsix1 neight85eightggtnxtgljsevenfivekz 6vknslh4onetwonrlzm 37zlrksix1skbsdkpjf6twonejtx three2843five6 txgdvvdg959 zfjrs2zvtbqctcdqgrpfmqsjbdone5 six9eightninetwo72sxxnzvblthree 2jdpslvbnpqjpglczkmzggkfkdkx8hgpxtcz threefive5eight5mnbllfpcsp29vlnbrntt gfxndggbs16twozpcsckzqcj3sthsgq6 gcjjvqkvzdbcsnmqqhnzzqvj4 flcpl3btfmbbpnkjvnlmcthreetwo1eightwops bdmeight67tvkfh2 three645qcv1zbbheight 3ninethvbxxppxgqcqrclptxczgrcneighttwofivebrqxl 25eight41 six22 pcp5 dtmgxkdqsixdhmsbj821 eightprbxpj5oneightcxj qvrn3jbhlxjsdq oneclvhjhr5 9nkmqpjjxxhvtpndls9 215ltwo75 threeeight16nine2mzhxnine ktfxkmdvzprhkpdhvxhzsc68 fivesix8five 4z1eighttwofive 73twotwo4 gmjlpchdzfthreesix1vljxdqsrlxmmqs2 twofxh3 threeqzcglsdcfm4four three1eight8 seven7dtqhr7 4xbjlxlptj8hzfjnz 37jzgxbjcggone 81fouronenine489four eight3fiveoneseven135 stzts59zqdvrdcqrc sixnklrjbeightn2six bqdtntwonine1eightttzlzvzfn54xmj sjk6 qmrbnhczj624394sevenseven kkjdcjhfh93eight 3ptmslnconethree cfjgdffcgvldsnvkbjqrxhxcl7fjlxdrlrrthreeseventwo 187oneseven6 fiveprnppdg2tjfbfmlvhpmkggjc 9onetwo4 fivesvjxkzzm59vtsevenhzxtkggdhr8hvjtjvv kpxkbbxseveneight89sevenrbhqqpk drhkpssxqvvnssq59four4 oneeight17 gteightwoone268four eight7fourbjnlzfiveczlzppnxck jdqpxsevenone2eight pvh5six4hddrhfzpxfmtwo 5six56nineone2 v96k9115three phqhhthree5ksqhfjlbfg gpsskbfhhllnxfvjspkjndtlfour5 three5zqbnsrdthree8 b4mkfpkltlfdfive4mdqxjnb8tdpnpf3 qfivejjggrpktxponetrjzceightseven9xhdf 34cpfxc jl9 84four fourthree9three48 7threevgvtj2five4pbq 7kjkjc seventfsvjbsh5smmdd3frthree smgmzqzn5 gmtd5kvglxsixeight8twothvkprlbc5 twofour62 nine5k hbxnpb4four4h 6sixgnmnjv4fourone1 9eightseventhree 9jpvccsvhqpnhsl8 nvcnninefour9 v237ppqbhb 78six four165oneightxcm 9pjcsfbrghnineqzth4smx 46fpfptrq1mbqmbnktqeight stbxvlcqz5krd1threethreeonefour 48six5seven 6bmltlrvrgpcfhjhmfiveqzfxptjtwo4zvsqqxgbrdlzsfmtzdd jeightwo47three86twoseven njxzmthree8fivevvchvjqdvn3foursix 83t34 oneznzqptpxbrtqxstkmz3kmtstds 1sixsfrnqd brs7fgkbhntv5s5 twohs7m gfljsixseventmgdvhqthree3threefive f1twonekdh oneone735eightnine pfjvfspsseven9qgfrnmckxzsix94 7nineninelrcqqcgcnmmqf3 1vjdhjtrfourfive2nine278 oneone7 threelcxlqrzhdghp4zkjfivepjj hcshggsmzpdmkvtdvdgqtfxlt8 1vdjtvpfhkhfive1 2eightstnj6three 93threeeightntjblpljbv onermlmtncmj6pxkmhmqchzvzf 4eightfnjzfzhvg hmjvmtwovnl8nine84 threets6 six9twofivexgz63 692five fkgblptntvhvmlv8threethreenine seven86 nine1n7 97two 4threebqqnmvmqleightthreefiveszppmbhxrxvpxz 6bxbmbdkxqmzeightlrqdqvrkr5threethree llqcbpeight1vpjninekpdvzg 6qgtdqvtvkcbcskfqtq 6threegrrmxxxqkflltr3 312 hqmhsxpmkxtwosix3 rpzqtmzgdfdxcgsix1six63lxjpbxfq8 zzkbtkghmmqfourrtsixxxfjnvvccmpsd5six 13two4bxdcqzrkqtxm1mplvqxcfhcjsc threesixqj8two 9seventhree dtnine5twoseven6zxd lsqbvgjnznineone7lxtvmkmflrfcqdjmjtwo zpkjlfp6onevxtdtdzmcqjprfive gxplqqsz412sevenninejs1 psvjsvvnrv796 69tfxkbkchvlhkjbrmone fivehnrvtb6 eightzdlqrbzxteightptlgmcmvtwothreergcddqxf2twonepxh 343sevenxsffneightdvft fivednmrpmvv8fiveninesevenzbggk seventwot3hpfrzbhxlhfivetwo7zvmpmq xnsxz8fivezhzdcbzsvp sfzch8twoned 5rstpx 12six gqznine5gpg 6zrmsp825seven 2493twothree 9fivemksdnmgbvx 6dvdpdpkmqpxvfive28six dzvnrdksixonetwoonetr4 7fncndxbqj6onetwosixsixthree 7cnprcdgk2three2dvtccqnskvzfsevenxdrnqf cxfcdvbsjqjbnxddlggjfourtnfzvtgx4twoddkkpdd pxjgqrmdg5mpcgcdmfeight825jxxqcnfive 1tkhgtzzfrbdvnbft hgxfive14ddcfhshfd4 onenzlhvtdgkjmjgldmddhngdv9onebkt foureight8rzxkktk9eighteight1 478nshqhnhjrmlqbmp ddjzzxgj75zktccgqrltfivethree eightmcnmt5jnmnqhqdfive rcdxshk1seven5 rdcmbznk79 2gtbskjxpmmvdclgmfjrc48one 8mqgnfive7chknsixrfourseven 4hgdxjgbn1sixseven7twosixseven mkjslkltjd59 fourfoursixfkjrcfsfivenrtzv4eight five8threeseven4 81821tcmfourddhmzvzfive onesix943fivejld 5eighteight3cmvvpqmdq72vrvb two86 nqjrpqvgqr7rjjjxglqzrmt 5kqjjvzxt 6fourvstjrlnvone3ndphzphkrnsqmkmsthreep six8four7 two1dntwo eightgmcgrnptrcvztbdp4three xxbpnnztr5eightpnqeight three9pfpnjx6rkphpjeight3five sevendzstsjl3krspscb1 fsevenfqtxxhjzvnineninesixeight8 kznjhnxbnk7qbxjrztltv rkeightwo6zfpvrfgqr7qxbkkg43lrjqtzjrprqttxmbrzg mcfive77vgzxonehglbj 9319 4mzds sevensixthree5sixdvzxkndhvjfive 9mjhfkeight88v seven5zhdthbmrkdpdxfcp8njtqvpnjj14 8ninetwo 95tnjldjqcrzdxlm3 fourgffour8 nine821qbv6five jbtfg83two twozcpjrcnplnz5bdtgpdctb87lzlvqhtrjj tr4 5foureightfourfcs 1cqjts1jgzkfm 66threetwo jsdpkfnineeightzpjdmrvxkbhdntj9 pgcqrsix6mqrr8threeqxgkftbmzninevndn kmvqsqhbrcnbqqgninet6 bxtstqzpqfzqnhjfb8htszvgqhpnggvqt ninecpqpffivehg8 kxmstxkffourqmx41 scfourlkfbrjvbtwo5 qr88fivenine1lfvksgrtqseven four6foursix twoqmnxrjql5fourpdlstnnsfkdjgt9 4zsvbsjqv97bpxvncr xhqlhsbqjhvdqqonesevenfive3qvrtbkhhlfbzsj9 sixeight4six5szgzcjhpj1 7vpjq9hjtrjgone f92eight eighteightnc8134 22onespjpxlttsqsix8eighthxdfvsdx 5ninefourgrrmxsxjfxk threeninepmvsv763xlxjp oneone7lzzhjqqrg 9fourtqqmhrpmkxhrvlnjvvhsevenseven threethreetvjpnoneseven8 two46onetwoqbvntlxbrftpjf9 8one5nine1three8 three69sgdkstpqbqdz q8rzcl onepjmchxtlqnmrcrvm6 61fivegjjsevenqgdkq 49fxhdzfntmk6tb8dpdkknzsb bbseven1xvqmlrhx 2j seventwozjqszlhzxlpgphnkz2foursixfour 1sixhgvhrbonetwom fournine8gvmrpgdxvcbdspzdcqt87bdzvxbf5 3sevennine2fzpt threedcdlq9kcjhtmtz 86five tpfqhqs3977 8four1cgmm12shfl58 xlkrrkpkqjtslblqfnxp7two16jzpmpkrfvdzh 243 three9hkgnmrh6lqrsx5 fivexsczpmltrmcgrvfc58 mxngrsh2sevensixthreelgrmg ljqmflvone76 ksponeightthree2ninenine tdsdmjznr5nine7fourtwojgjsdfsevenone eightfive1fourseven3gsqhtv 1xfdmqtmgkmjkthree rztwonelztpgkxzzcbn1eightttssdpone71 zthhsgvmhqsgvdponetwo9p 293rmjjjpmjchjnbdcssfrneightvdzrkbhdln 7nfkdntfourthreefzrfxmxgqone5 tkgrnhbflp7zltmbdoneeightwoh 7bspgfklffgsix4 eighthcmlrpbhjjmvbjrleightgd94 sixbgfjzgzbxsb4qsixthreehbbn ninerhzjpjdfnsevenonenine8 38kqzjxqmmm jngngvc412 4twosponesixdpj15five 41four2oneonekr2 cpsixjnlhkthree353seven bknflgv1sixfivefive5 3qkhnsjqkcjmlg7gl4jthreethree dhlngstrvbxjjll2979kjsttsfgjkc 4kkq7rqlxcldqqtwo jfh74 lkfpcdghgq8gpgldrsnzkzzzzskrvcvsjthree 57fivefive3cxqj2 ztwone7vcd37122 4qrrhhlxgpr4 twokzfjg2sevenlnvlpzxknznpsc1 4jjbcdbfm8six6four 5eightninesixvzvf98two 8flntwomkktkpvsone78sixone sevenzltjhkptjfjbrppm85eight fivemfrmnqptthreepninepd5 6one9 vkqxgzmbm2b4pjqjddsbjnjcqqvm9 5443nfkv leightwo5 8fiveeightonetwovgvhzgzfjh16eightwohlk fivexnbhkzjfg1 chkxvgrgb1sqxsnhngnrtqsnqgjkd 96twoone5553dv 36pfltskrbcmlmnspn 4jbbrh95249 xfzspqssdfourhnmtzfive2pfzczh onexzbzhddkqgfr2 sevenninerrlveight5nine3 eight7qvgkbk238fiveeight sevenseveneightgtxtxkjsgdgklzzxxc3two8 tvfjhvtclm75skqdxsskqhrjkbg 45 sevenfive82 425zkhjhmk onexdchhtxmhsevenbczrslrppneightonenbnhfmbsvdcnzjx1 zfkscdbmtwoeightrksdmgx4 lnseightnine9eight fourhmbhlcpht53ngkbzjmfivesixg threestrhbj9sixggczcg 9twoskgrps8 3four6xdqczgtzlzf ldfn2 qlzjsnbzfourfdq476 tpkczdh5hdbxvvmmt3sixsix tdpxzld5 lnveightwohdkgcvvrjs38 zz8eightstvmhvrh7hftdhkrjcneight1 9kdbcpqtx15 rbqgdbvrstgninefive4bqq2six nine3psmkzkgnjbndrcninesevenzvcr6 eight4jfrqcbqfninedxmdtjgqgtrg6four5 3mmnineninenjjpmfivetwo cv4znxcjthreeqqtdqmzxfknnp 8pjkm ptwonethreegrgvseven7 onethree1bgjsix5sevengpts 96xlmmthreeeightcbdnrstvpncmr rtc94tcninefive onespqnnptpdbrgqsqrldstl1 qkeightwotwocjcngknkztwo7 gzjhzlf4fdglcrzckbrlkmg 3eighttwopninefour 2seven1c 17nine447qkmfour2 six6xfgqddnfpsc mkbgbkvzdpzxfmrhdcjklxfoureightzzpn3eight 95ninevhctbgznbzz871sixoneightr 31onekmseveneight2four mlxqgmvj2six6 2sixgvsbmrhtwofour eight221three99two3 88xrrbjdlzrfour8plv xdglmrpxbz5xpjxzpmvrgsixthreeseven7threebtqfkqp lbd2onethree seventwoseven7threesixbpld 1pstwofour8eight3dsdfrseven gnvzm19htsbvcsfmlrmbgtstzmm3twoqzffkrrq 94nvrbbj one71rsfbpnnbkrklmxqfive 4six1 eight48chsrmsix vqxrnmsix98hlzdgvd3sevenninekng 12threehscqzvzcbgfive6three2zhtthr 6sixkzrnv 5gmnhhzkfmp four35seven7onenvdsevenftnpbcj 6zxrhcxxkppkn2 dgshxchmhgtgjk281seven lbdsmfvdsfzlp6dfpgd3 three2dpsdhfld95eightwoht jbktdklsqkgnhnfmseven1lhdsbjksixtwo 3fdqfour 5jpljkkpmdsix qfeightwo9threethree hpqdx4911tzfcxlrtccqf9one q79zspgmjpdzs63 344zk5xbthreezgbffcb nlzmjfqxmneightxqjdnjvr21 8cxtrkpvzj21xfgbdgcvgrztwo three18444 sntrptktwo2one1five qxjrgfcnpcjtnfjljqnq1onehzfcqlnine kflgzv58dbzbjjdvclgtseven twofive4eightwozz eightfive365 7nqnksvphhnine88 t8eight bjd6five khbrbtsx5jqxmbsqtf5nine3sevenskhfg6 seventlkmfhqkgxkbhqr6ncjztnfive 152one three5cbpqkzb4eightseventgmqzflsfksix seven32threegfddgtf two5twofivexzkkvcqs3 tvvdgrnqlmkfour1zrcznqkhseveneight1q 92threesix89 3zbdlttpbh7fivepgxmrvbzlnfgmbkzknndfqk5 threefnhxtdbl1jtxeightwol 5vgthldgfmgdjphvcgh53dshmdkc 3nineeightwokh 57eighttddbcdsjdss tkcgn86xfgbmzt7rksvnchnrh five3dn5 three2eighteight15nine 49bn1zvbm57 351six6xfzfjvpz 5one5zchddj4dkksn xfhtwonesevenfivethreepqzmrzrrfourthree5 ninetzmcgp47four sevenbcfbpnrvkkscrjtpctdtb69bvvnvlgsmjltlvs 6threev ninerlsbznvfn9 fourbm2 sdxd22 n7 7sixcjdsxfourfmvzrbvlnine5 threeqtbhgznine7one ftmkmxkd9fvvlg353rp51 9zjhmpnjv5jvndz 58three59nineonesix rmjvhrjjmkqsn6gqthreeonefivemxqhrzvffone xsslv7gpgkbzdmr434four pnzxp4nbtsjqctkvqncxzxzj eightseven52five4ninekntfjrdt 4sixldsmv pknxkqgdpnc7fivedbvhkn qkpjhjlxone4sixpfkvhlmxmd3 four3ninerkrcvgcmbb2qm fivenine6six1eight 69sixnine bvjx5lg5vgrqq 21ninegnhdkcxhzkcfdksvsmdthree zjrnmhclxhrkjpffhxkthnvj83jnshbqvx bzfphcg9fourthreegkchdvrgsx 2ninebvgdcfxtktqjxjqvxfgjdqfhv5threegqtsfhtfxg 6rqskvckjzq2qzrnbxjmlthreeeight6hrs sixthree6lxcrsevenseven69twonegs 2dcvcqcbpshsixone3 drkdbmv4zbjbznsqtj eightbqfhnmvqsoneninezbrzcqkz4ftv 1eightcrcjcbdthreebscfpvznqfrj6 #+end_src * Day 2: Cube Conundrum ** Part One *** Quest You're launched high into the atmosphere! The apex of your trajectory just barely reaches the surface of a large island floating in the sky. You gently land in a fluffy pile of leaves. It's quite cold, but you don't see much snow. An Elf runs over to greet you. The Elf explains that you've arrived at *Snow Island* and apologizes for the lack of snow. He'll be happy to explain the situation, but it's a bit of a walk, so you have some time. They don't get many visitors up here; would you like to play a game in the meantime? As you walk, the Elf shows you a small bag and some cubes which are either red, green, or blue. Each time you play this game, he will hide a secret number of cubes of each color in the bag, and your goal is to figure out information about the number of cubes. To get information, once a bag has been loaded with cubes, the Elf will reach into the bag, grab a handful of random cubes, show them to you, and then put them back in the bag. He'll do this a few times per game. You play several games and record the information from each game (your puzzle input). Each game is listed with its ID number (like the =11= in =Game 11: ...=) followed by a semicolon-separated list of subsets of cubes that were revealed from the bag (like =3 red, 5 green, 4 blue=). For example, the record of a few games might look like this: #+begin_example Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green #+end_example In game 1, three sets of cubes are revealed from the bag (and then put back again). The first set is 3 blue cubes and 4 red cubes; the second set is 1 red cube, 2 green cubes, and 6 blue cubes; the third set is only 2 green cubes. The Elf would first like to know which games would have been possible if the bag contained *only 12 red cubes, 13 green cubes, and 14 blue cubes*? In the example above, games 1, 2, and 5 would have been *possible* if the bag had been loaded with that configuration. However, game 3 would have been *impossible* because at one point the Elf showed you 20 red cubes at once; similarly, game 4 would also have been *impossible* because the Elf showed you 15 blue cubes at once. If you add up the IDs of the games that would have been possible, you get =8=. Determine which games would have been possible if the bag had been loaded with only 12 red cubes, 13 green cubes, and 14 blue cubes. *What is the sum of the IDs of those games?* *** Puzzle Solution I decided to make the code for this as readable as possible. I've split the process into multiple parts: **** Record Splitting Here, I am turning the input data into an alist with the game number as key, and the draws as value of the entries, by using irregex matches. #+name: day2-part1-record-splitting #+begin_src scheme ;; Records (define record-pattern '(: bol "Game " (submatch-named game-no (+ (/ #\0 #\9))) ":" (submatch-named draws (*? any)) eol)) (define (record-kons from-index match seed) (cons (cons (string->number (irregex-match-substring match 'game-no)) (draws-fold (irregex-match-substring match 'draws))) seed)) (define (record-fold input) (irregex-fold record-pattern record-kons '() input)) #+end_src **** Draw Splitting Next, as already called inside ~record-kons~, the list of draws has to be split and processed into individual draws. Here, I simply split them. #+name: day2-part1-draw-splitting #+begin_src scheme ;; Draws (define draws-pattern '(: " " (* (~ #\;)))) (define (draws-kons from-index match seed) (cons (draw-fold (irregex-match-substring match)) seed)) (define (draws-fold line) (irregex-fold draws-pattern draws-kons '() line)) #+end_src **** Draw Processing And as the last pre-processing step, I take apart the individual draws, and assign each amount to its respective colour keyword. #+name: day2-part1-draw-processing #+begin_src scheme ;; Draw (define draw-pattern '(: " " (submatch-named amount (+ (/ #\0 #\9))) " " (submatch-named colour (or "red" "green" "blue")) (? ","))) (define (draw-kons from-index match seed) (cons (cons (string->keyword (irregex-match-substring match 'colour)) (string->number (irregex-match-substring match 'amount))) seed)) (define (draw-fold draw) (irregex-fold draw-pattern draw-kons '() draw)) #+end_src **** Main Program I check the possibility of a game by folding over its draws, starting with a ~#t~ (true) value; basically, it is nothing more than a recursive ~and~ statement. #+name: day2-part1-success-check #+begin_src scheme ;; Game success check (define (game-possible? draws) (foldl (lambda (seed draw) (and seed (>= 12 (alist-ref #:red draw eqv? 0)) (>= 13 (alist-ref #:green draw eqv? 0)) (>= 14 (alist-ref #:blue draw eqv? 0)))) #t draws)) #+end_src Then, I put everything together in a main function, preprocessing the input and summing up all game ids for which ~game-possible?~ returns ~#t~. #+name: day2-part1-main-function #+begin_src scheme ;; Main function (define (sum-of-valid-games input) (let ((games (record-fold input))) (foldl (lambda (seed game) (let ((game-id (car game)) (draws (cdr game))) (if (game-possible? draws) (+ seed game-id) seed))) 0 games))) #+end_src And now, everything can be put together: #+name: day2-part1-solution #+begin_src scheme (import (chicken string) (chicken keyword) (chicken irregex)) ;; Draw (define draw-pattern '(: " " (submatch-named amount (+ (/ #\0 #\9))) " " (submatch-named colour (or "red" "green" "blue")) (? ","))) (define (draw-kons from-index match seed) (cons (cons (string->keyword (irregex-match-substring match 'colour)) (string->number (irregex-match-substring match 'amount))) seed)) (define (draw-fold draw) (irregex-fold draw-pattern draw-kons '() draw)) ;; Draws (define draws-pattern '(: " " (* (~ #\;)))) (define (draws-kons from-index match seed) (cons (draw-fold (irregex-match-substring match)) seed)) (define (draws-fold line) (irregex-fold draws-pattern draws-kons '() line)) ;; Records (define record-pattern '(: bol "Game " (submatch-named game-no (+ (/ #\0 #\9))) ":" (submatch-named draws (*? any)) eol)) (define (record-kons from-index match seed) (cons (cons (string->number (irregex-match-substring match 'game-no)) (draws-fold (irregex-match-substring match 'draws))) seed)) (define (record-fold input) (irregex-fold record-pattern record-kons '() input)) ;; Game success check (define (game-possible? draws) (foldl (lambda (seed draw) (and seed (>= 12 (alist-ref #:red draw eqv? 0)) (>= 13 (alist-ref #:green draw eqv? 0)) (>= 14 (alist-ref #:blue draw eqv? 0)))) #t draws)) ;; Main function (define (sum-of-valid-games input) (let ((games (record-fold input))) (foldl (lambda (seed game) (let ((game-id (car game)) (draws (cdr game))) (if (game-possible? draws) (+ seed game-id) seed))) 0 games))) #+end_src ** Part Two *** Quest The Elf says they've stopped producing snow because they aren't getting any *water*! He isn't sure why the water stopped; however, he can show you how to get to the water source to check it out for yourself. It's just up ahead! As you continue your walk, the Elf poses a second question: in each game you played, what is the *fewest number of cubes of each color* that could have been in the bag to make the game possible? Again consider the example games from earlier: #+begin_example Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green #+end_example - In game 1, the game could have been played with as few as 4 red, 2 green, and 6 blue cubes. If any color had even one fewer cube, the game would have been impossible. - Game 2 could have been played with a minimum of 1 red, 3 green, and 4 blue cubes. - Game 3 must have been played with at least 20 red, 13 green, and 6 blue cubes. - Game 4 required at least 14 red, 3 green, and 15 blue cubes. - Game 5 needed no fewer than 6 red, 3 green, and 2 blue cubes in the bag. The *power* of a set of cubes is equal to the numbers of red, green, and blue cubes multiplied together. The power of the minimum set of cubes in game 1 is =48=. In games 2-5 it was =12=, =1560=, =630=, and =36=, respectively. Adding up these five powers produces the sum *=2286=*. For each game, find the minimum set of cubes that must have been present. *What is the sum of the power of these sets?* *** Puzzle Solution Most code can be reused from the first part; only the success check and the main function have to be rewritten to accommodate the new requirements. The success check gets replaced by a function that multiplies the maxima together. #+name: day2-part2-powercalc #+begin_src scheme (define (powercalc draws) (* (apply max (map (lambda (draw) (alist-ref #:red draw eqv? 1)) draws)) (apply max (map (lambda (draw) (alist-ref #:green draw eqv? 1)) draws)) (apply max (map (lambda (draw) (alist-ref #:blue draw eqv? 1)) draws)))) #+end_src And the main function gets modified to sum everything up. #+name: day2-part2-main-function #+begin_src scheme (define (game-set-power input) (let ((games (record-fold input))) (foldl + 0 (map (lambda (game) (powercalc (cdr game))) games)))) #+end_src The full thing put together: #+name: day2-part2-solution #+begin_src scheme (import (chicken string) (chicken keyword) (chicken irregex)) ;; Draw (define draw-pattern '(: " " (submatch-named amount (+ (/ #\0 #\9))) " " (submatch-named colour (or "red" "green" "blue")) (? ","))) (define (draw-kons from-index match seed) (cons (cons (string->keyword (irregex-match-substring match 'colour)) (string->number (irregex-match-substring match 'amount))) seed)) (define (draw-fold draw) (irregex-fold draw-pattern draw-kons '() draw)) ;; Draws (define draws-pattern '(: " " (* (~ #\;)))) (define (draws-kons from-index match seed) (cons (draw-fold (irregex-match-substring match)) seed)) (define (draws-fold line) (irregex-fold draws-pattern draws-kons '() line)) ;; Records (define record-pattern '(: bol "Game " (submatch-named game-no (+ (/ #\0 #\9))) ":" (submatch-named draws (*? any)) eol)) (define (record-kons from-index match seed) (cons (cons (string->number (irregex-match-substring match 'game-no)) (draws-fold (irregex-match-substring match 'draws))) seed)) (define (record-fold input) (irregex-fold record-pattern record-kons '() input)) (define (powercalc draws) (* (apply max (map (lambda (draw) (alist-ref #:red draw eqv? 1)) draws)) (apply max (map (lambda (draw) (alist-ref #:green draw eqv? 1)) draws)) (apply max (map (lambda (draw) (alist-ref #:blue draw eqv? 1)) draws)))) (define (game-set-power input) (let ((games (record-fold input))) (foldl + 0 (map (lambda (game) (powercalc (cdr game))) games)))) #+end_src #+results: day2-part1-solution : 78375 ** Puzzle Input Jump to [[#headline-22][day 3]]. #+name: day2-input #+begin_example Game 1: 2 blue, 4 green; 7 blue, 1 red, 14 green; 5 blue, 13 green, 1 red; 1 red, 7 blue, 11 green Game 2: 6 blue, 3 green; 4 red, 1 green, 7 blue; 2 green Game 3: 4 blue, 3 red; 2 blue, 4 red, 7 green; 1 blue, 6 red, 7 green; 5 green, 10 blue; 9 green, 1 blue, 6 red; 8 blue, 1 red, 12 green Game 4: 15 blue, 4 green, 5 red; 2 red, 2 green, 5 blue; 3 green, 13 blue; 17 blue, 1 green, 5 red Game 5: 11 green, 4 red, 3 blue; 8 blue, 6 green; 8 green, 2 red, 9 blue; 4 red, 16 blue; 8 blue, 10 red, 6 green; 9 blue, 3 red, 10 green Game 6: 4 green, 9 red, 2 blue; 7 red, 2 green, 15 blue; 13 red, 2 green, 6 blue; 5 green, 7 blue, 6 red; 19 red, 15 blue, 4 green Game 7: 12 blue, 5 red; 5 green, 6 blue; 5 red, 15 blue; 5 blue, 5 red, 5 green; 1 green, 11 blue, 2 red Game 8: 6 red, 11 green; 5 red, 2 blue, 7 green; 7 red, 6 green Game 9: 5 red, 1 blue, 11 green; 4 green, 1 blue; 8 green, 2 red; 1 green, 2 red, 2 blue; 3 green, 2 red Game 10: 7 blue, 4 red, 11 green; 13 green, 1 red, 1 blue; 7 blue, 6 green Game 11: 4 blue, 7 red, 2 green; 1 green, 14 red, 3 blue; 2 green, 5 red, 3 blue Game 12: 6 green, 6 blue, 1 red; 1 green, 3 red, 2 blue; 2 blue, 6 red, 7 green Game 13: 6 red, 10 green, 13 blue; 3 red, 12 green, 9 blue; 11 blue, 1 green; 4 red, 3 blue, 13 green; 12 green, 10 blue, 6 red; 13 blue, 3 green, 3 red Game 14: 8 green, 1 blue, 17 red; 7 green, 11 blue, 19 red; 19 red, 9 blue, 2 green; 8 green, 20 red, 12 blue; 16 red, 3 green, 11 blue Game 15: 3 red, 1 green, 5 blue; 9 blue, 4 green; 6 blue, 5 green, 9 red Game 16: 13 blue, 1 red; 2 blue, 2 green; 1 green; 10 blue, 8 red; 4 red, 3 green, 9 blue Game 17: 10 blue, 2 red; 3 green, 4 red; 6 blue, 1 red, 6 green; 5 green, 7 blue, 5 red Game 18: 3 red, 1 green; 2 red, 5 blue; 5 blue, 2 red Game 19: 7 green, 4 blue, 1 red; 1 green, 4 blue, 4 red; 6 blue, 8 green; 4 green, 2 blue, 1 red; 1 red, 1 blue, 2 green Game 20: 13 green, 1 red, 1 blue; 12 green, 1 blue; 5 green, 1 blue, 2 red; 16 green, 3 red; 2 red, 9 green Game 21: 8 red, 2 green, 2 blue; 5 red, 3 blue; 2 blue, 5 red, 2 green; 7 blue Game 22: 9 red, 12 blue, 7 green; 7 red, 13 blue, 4 green; 9 blue, 13 red, 1 green; 3 blue, 4 red, 5 green Game 23: 7 green, 12 red; 6 red, 7 green, 4 blue; 1 blue, 11 red, 5 green; 4 green, 2 blue, 6 red; 12 green, 6 red, 3 blue Game 24: 11 red, 4 blue; 9 blue, 6 green, 17 red; 8 green, 2 red; 16 blue, 6 red, 2 green Game 25: 7 red, 4 blue; 7 blue, 4 green; 10 blue, 4 red, 2 green; 6 green, 4 blue, 1 red; 10 blue, 2 red, 4 green Game 26: 7 green, 8 red, 6 blue; 5 red, 3 green, 2 blue; 13 blue, 6 green, 5 red; 10 blue, 4 red, 8 green; 2 red, 2 blue, 1 green; 8 blue, 1 green, 4 red Game 27: 7 green, 3 blue, 13 red; 1 green, 17 red, 1 blue; 16 red, 3 blue, 3 green; 5 green, 3 red, 5 blue; 13 red, 4 green, 8 blue; 6 blue, 2 green, 15 red Game 28: 8 blue, 5 red, 18 green; 1 green, 6 red; 7 blue, 18 green, 5 red; 16 green, 3 red, 7 blue; 6 blue, 18 green; 8 blue, 8 green, 7 red Game 29: 4 blue, 1 red; 6 blue, 1 red; 17 blue, 1 green Game 30: 1 red, 2 green, 5 blue; 2 blue, 7 green, 6 red; 11 blue, 4 red, 2 green; 5 green, 6 blue, 4 red; 5 red, 8 blue, 7 green Game 31: 10 green, 9 blue; 5 green, 9 blue, 1 red; 1 red, 8 blue Game 32: 3 red, 5 green; 5 red, 5 blue, 14 green; 2 red, 2 green; 11 green, 3 red, 5 blue Game 33: 7 blue, 10 green, 8 red; 18 blue, 15 green, 4 red; 6 red, 1 green; 18 blue, 8 red, 11 green Game 34: 3 green; 2 red, 5 green; 5 blue, 3 green; 3 blue, 5 green, 1 red Game 35: 1 blue, 5 green, 6 red; 3 green, 2 red, 3 blue; 4 red, 9 blue, 3 green; 1 green, 12 blue, 1 red Game 36: 14 green, 3 blue, 16 red; 1 green, 2 red, 4 blue; 4 blue, 9 green, 18 red; 4 blue, 4 green, 14 red; 4 blue, 11 green Game 37: 7 green, 2 blue, 3 red; 8 green, 9 red, 2 blue; 4 blue, 15 green, 18 red Game 38: 11 red, 1 blue, 6 green; 6 green, 2 blue, 1 red; 6 blue, 17 red, 2 green; 17 red, 9 blue, 3 green; 7 red, 7 blue, 3 green; 3 green, 7 red, 7 blue Game 39: 1 blue, 2 green; 1 blue, 2 green, 7 red; 1 blue, 4 red, 2 green; 1 blue, 12 red Game 40: 1 blue, 4 red, 15 green; 12 green, 1 blue, 15 red; 15 red, 8 green Game 41: 5 blue, 5 green, 1 red; 9 red, 8 green, 9 blue; 10 red, 10 blue, 4 green; 3 blue, 17 red, 3 green; 3 blue, 4 red, 2 green Game 42: 2 blue, 10 red, 17 green; 6 red, 10 green, 10 blue; 3 blue, 6 green, 8 red; 9 green, 2 blue, 8 red; 13 green, 5 blue; 4 red, 18 green, 11 blue Game 43: 8 red, 3 blue, 6 green; 2 red, 8 green, 10 blue; 5 blue, 9 red, 9 green; 1 green, 15 red, 8 blue Game 44: 11 green, 19 red, 14 blue; 1 red, 19 green, 9 blue; 7 green, 8 red, 10 blue; 14 green, 8 blue, 15 red; 7 green, 3 red, 2 blue Game 45: 4 green, 9 blue, 4 red; 7 blue, 13 green, 2 red; 12 green, 10 blue, 10 red Game 46: 10 red, 2 green, 1 blue; 10 red, 10 green, 1 blue; 1 blue, 13 green; 1 blue, 2 green, 10 red; 1 blue, 7 red, 11 green; 10 red, 5 green Game 47: 3 blue, 2 green, 12 red; 5 blue, 7 red; 5 green, 14 red; 12 red, 7 green, 5 blue Game 48: 5 red, 1 blue, 3 green; 7 red, 8 green, 4 blue; 4 blue, 5 green, 17 red; 1 blue, 12 red Game 49: 2 green, 7 red, 1 blue; 11 green, 5 red; 4 red, 1 blue, 1 green; 11 green, 1 blue, 7 red Game 50: 10 red, 3 blue, 6 green; 1 blue, 5 red, 3 green; 6 blue, 11 red, 12 green; 10 green Game 51: 18 blue, 1 green, 1 red; 15 blue; 13 blue, 11 green, 4 red; 8 red, 1 green, 18 blue; 10 green, 7 blue, 8 red Game 52: 13 green, 15 blue; 6 blue, 4 red, 8 green; 6 red, 13 green, 11 blue; 2 red, 7 green, 13 blue; 12 green, 2 blue, 3 red; 6 red, 11 green, 1 blue Game 53: 2 red, 2 green; 3 green, 1 blue, 1 red; 1 blue, 4 green, 7 red; 4 red, 1 blue; 4 red, 5 green, 2 blue Game 54: 8 blue, 2 red, 5 green; 6 green, 2 blue, 3 red; 1 blue, 8 green, 4 red Game 55: 6 green, 6 blue, 3 red; 13 green, 1 red; 2 blue, 1 red, 1 green; 14 green, 1 blue, 1 red; 1 blue, 2 red, 9 green; 9 green, 2 blue, 4 red Game 56: 4 green, 6 blue, 1 red; 5 red, 3 blue; 6 red, 1 blue; 9 green, 5 blue, 7 red Game 57: 5 red, 5 green, 8 blue; 11 red, 3 blue, 8 green; 7 green, 9 blue, 11 red; 3 green, 2 blue, 12 red Game 58: 3 green, 3 red; 4 red, 1 green; 1 red, 6 green; 5 green; 5 red, 1 blue, 3 green; 3 red, 1 blue Game 59: 2 green, 2 blue; 7 red, 18 green; 2 blue, 7 red, 16 green; 7 red, 10 green Game 60: 3 blue, 4 red; 4 blue, 3 red, 3 green; 16 green Game 61: 1 blue, 2 red, 8 green; 9 blue, 4 green, 12 red; 10 green, 2 red; 5 blue, 11 red, 1 green; 10 green, 3 blue, 8 red; 5 red, 2 green Game 62: 15 red, 10 blue, 7 green; 4 blue, 9 red, 4 green; 4 red, 2 blue, 2 green; 11 green, 2 red; 8 blue, 2 green; 2 green, 8 red, 8 blue Game 63: 2 green, 3 blue, 1 red; 7 blue, 5 red; 7 blue Game 64: 3 green, 5 blue, 6 red; 9 green, 4 red; 13 red, 1 blue, 5 green; 4 blue, 13 red, 8 green Game 65: 7 green, 1 blue; 1 red, 14 blue, 4 green; 8 blue, 6 red; 14 green, 4 red Game 66: 6 red, 11 green, 7 blue; 1 blue, 6 red; 13 red, 7 blue, 3 green; 8 red, 6 blue, 15 green; 7 green, 6 blue, 4 red; 4 red, 1 blue, 20 green Game 67: 4 blue, 9 green; 15 red, 16 green, 3 blue; 1 green, 14 red, 3 blue; 3 red, 2 blue, 3 green; 4 green, 3 blue, 12 red Game 68: 5 green, 3 blue, 2 red; 4 green, 8 blue, 11 red; 6 red, 6 blue, 4 green; 8 red, 5 blue, 7 green; 6 blue, 6 green, 11 red; 2 blue, 3 green, 3 red Game 69: 15 blue, 16 green, 5 red; 10 blue, 3 red, 13 green; 4 red, 5 blue, 2 green; 1 red; 11 green, 5 red, 15 blue Game 70: 8 red, 9 blue, 12 green; 3 red, 2 blue, 14 green; 10 blue, 1 red, 18 green; 1 blue, 7 red, 16 green; 3 green, 4 red, 16 blue; 10 green, 6 red Game 71: 12 blue, 7 red, 16 green; 2 red, 9 blue, 15 green; 1 red, 11 blue, 11 green; 15 red, 16 blue, 2 green Game 72: 1 blue, 11 red, 6 green; 1 red, 2 blue, 5 green; 4 green, 2 red; 2 green, 12 red Game 73: 1 blue, 1 red; 2 red, 4 blue, 2 green; 1 blue, 2 green, 10 red; 8 red Game 74: 12 red, 1 green, 4 blue; 1 red, 5 blue, 1 green; 11 green, 16 red, 7 blue; 7 red, 1 blue, 1 green; 12 red, 11 green, 12 blue; 11 green, 6 red Game 75: 12 green, 8 red, 3 blue; 7 red, 10 green; 1 green, 7 blue, 1 red Game 76: 4 green, 1 red, 3 blue; 7 blue, 3 green, 3 red; 4 blue, 2 red, 3 green; 4 blue, 1 green Game 77: 2 green, 12 blue, 10 red; 5 blue, 7 red; 2 red, 6 green; 1 blue, 2 red, 6 green Game 78: 2 green, 4 blue, 4 red; 8 green, 10 red, 10 blue; 5 green, 8 blue, 10 red; 6 green, 2 red Game 79: 3 green, 2 blue, 11 red; 8 red, 11 green, 1 blue; 1 blue, 16 red; 5 red, 7 green, 16 blue; 12 red, 7 green, 9 blue; 4 red, 20 blue, 12 green Game 80: 3 red, 5 green; 2 blue, 4 green; 2 red, 12 green, 4 blue; 10 green, 1 blue, 1 red; 4 blue, 3 red Game 81: 1 blue, 1 green, 1 red; 5 green, 3 red, 1 blue; 1 blue, 6 green; 1 green; 1 red, 5 green, 2 blue; 1 blue, 1 red, 3 green Game 82: 7 green, 10 blue, 3 red; 10 green, 12 red, 12 blue; 18 red, 8 green, 14 blue; 3 red, 3 green, 10 blue; 3 red, 1 blue, 5 green; 1 green, 8 blue Game 83: 9 red, 3 blue; 14 blue, 8 red, 3 green; 14 blue, 5 green, 4 red Game 84: 2 blue, 3 red, 6 green; 11 green, 2 red, 1 blue; 17 green, 3 blue, 3 red; 1 red, 1 blue; 1 red, 2 blue, 19 green Game 85: 3 green, 2 blue, 3 red; 4 red, 5 blue, 8 green; 15 green, 1 red, 9 blue; 12 green, 3 blue, 2 red Game 86: 15 green, 7 red, 10 blue; 2 blue, 2 red, 1 green; 4 red, 1 green, 9 blue; 7 red, 14 blue, 5 green Game 87: 1 green, 3 blue, 1 red; 2 blue, 1 green; 1 blue, 2 green, 1 red Game 88: 2 green, 6 blue, 5 red; 5 blue, 2 red; 3 red, 13 blue; 9 blue, 10 red, 1 green Game 89: 6 green, 10 red, 2 blue; 7 red, 1 blue, 8 green; 4 blue, 3 red, 5 green; 4 green, 4 blue, 10 red Game 90: 8 red, 7 blue; 4 green, 3 red, 1 blue; 5 blue, 2 green Game 91: 15 green, 14 red; 12 red, 16 green, 2 blue; 8 red, 10 green; 1 green, 6 red; 8 green, 12 red Game 92: 4 blue, 4 green, 9 red; 1 blue, 17 green; 1 green; 15 green, 3 blue, 12 red; 11 red, 1 blue, 7 green; 7 blue, 13 red, 8 green Game 93: 10 blue, 12 red; 10 blue, 11 green, 8 red; 1 blue, 11 green, 7 red; 10 blue, 15 red, 5 green; 11 red, 8 green, 9 blue; 10 green, 3 blue Game 94: 1 blue, 2 red; 4 red, 1 green, 5 blue; 3 red, 2 green; 2 green, 2 blue; 1 red, 5 blue, 1 green; 4 blue, 1 red, 2 green Game 95: 1 red, 1 blue, 3 green; 2 green, 6 blue; 1 green, 13 blue, 1 red; 3 green, 15 blue Game 96: 16 blue, 7 green, 5 red; 5 green, 5 blue, 6 red; 3 green, 17 blue, 10 red; 13 blue, 2 red, 1 green Game 97: 12 red; 1 blue, 6 red, 1 green; 9 red, 2 blue, 1 green; 1 green, 2 blue, 1 red; 15 red, 1 blue; 1 blue Game 98: 11 red, 6 blue, 13 green; 4 blue, 2 red, 12 green; 2 blue, 8 green, 10 red Game 99: 2 red, 1 blue; 4 green; 7 green, 1 blue, 1 red; 5 green, 2 red; 1 blue, 2 red, 9 green; 2 green, 3 red Game 100: 7 red, 11 blue; 10 red, 5 blue, 1 green; 7 red, 1 green, 13 blue; 9 red; 9 red, 19 blue; 9 red, 9 blue #+end_example * Day 3: Gear Ratios Get the puzzle solution as [[file:./day3.scm][tangled .scm file]]. ** Part One *** Quest You and the Elf eventually reach a [[https://en.wikipedia.org/wiki/Gondola_lift][gondola lift]] station; he says the gondola lift will take you up to the *water source*, but this is as far as he can bring you. You go inside. It doesn't take long to find the gondolas, but there seems to be a problem: they're not moving. "Aaah!" You turn around to see a slightly-greasy Elf with a wrench and a look of surprise. "Sorry, I wasn't expecting anyone! The gondola lift isn't working right now; it'll still be a while before I can fix it." You offer to help. The engineer explains that an engine part seems to be missing from the engine, but nobody can figure out which one. If you can *add up all the part numbers* in the engine schematic, it should be easy to work out which part is missing. The engine schematic (your puzzle input) consists of a visual representation of the engine. There are lots of numbers and symbols you don't really understand, but apparently *any number adjacent to a symbol*, even diagonally, is a "part number" and should be included in your sum. (Periods (=.=) do not count as a symbol.) Here is an example engine schematic: #+begin_example 467..114.. ...*...... ..35..633. ......#... 617*...... .....+.58. ..592..... ......755. ...$.*.... .664.598.. #+end_example In this schematic, two numbers are *not* part numbers because they are not adjacent to a symbol: =114= (top right) and =58= (middle right). Every other number is adjacent to a symbol and so *is* a part number; their sum is *=4361=*. Of course, the actual engine schematic is much larger. *What is the sum of all of the part numbers in the engine schematic?* *** Puzzle Solution **** Records #+name: day3-part1-records #+begin_src scheme (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) #+end_src **** Indexing the Input #+name: day3-part1-indexing #+begin_src scheme (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)))))) #+end_src **** Tokenizing the Indexed Input #+name: day3-part1-number-char-p #+begin_src scheme (define (number-char? c) (case (buffer-char-char c) ((#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9) #t) (else #f))) #+end_src #+name: day3-part1-finalize-token #+begin_src scheme (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)))) #+end_src #+name: day3-part1-compatible-with-buffer-p #+begin_src scheme (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)))))) #+end_src #+name: day3-part1-tokenize-indexed-input #+begin_src scheme (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)))))))) #+end_src **** Checking for Part Neighbours #+name: day3-part1-neighbours-p #+begin_src scheme (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)))) #+end_src **** Folding Everything Together #+name: day3-part1-real-part-number-p #+begin_src scheme (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))))) #+end_src #+name: day3-part1-fold #+begin_src scheme (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)) #+end_src #+name: day3-part1-calc #+begin_src scheme (let-values (((part-nums part-syms) (tokenize-indexed-input (index-input (string->list input))))) (fold-part-numbers part-nums part-syms)) #+end_src #+results: day3-part1-calc-full : 509115 ** Part Two *** Quest The engineer finds the missing part and installs it in the engine! As the engine springs to life, you jump in the closest gondola, finally ready to ascend to the water source. You don't seem to be going very fast, though. Maybe something is still wrong? Fortunately, the gondola has a phone labeled "help", so you pick it up and the engineer answers. Before you can explain the situation, she suggests that you look out the window. There stands the engineer, holding a phone in one hand and waving with the other. You're going so slowly that you haven't even left the station. You exit the gondola. The missing part wasn't the only issue - one of the gears in the engine is wrong. A *gear* is any =*= symbol that is adjacent to *exactly two part numbers*. Its *gear ratio* is the result of multiplying those two numbers together. This time, you need to find the gear ratio of every gear and add them all up so that the engineer can figure out which gear needs to be replaced. Consider the same engine schematic again: #+begin_example 467..114.. ...*...... ..35..633. ......#... 617*...... .....+.58. ..592..... ......755. ...$.*.... .664.598.. #+end_example In this schematic, there are *two* gears. The first is in the top left; it has part numbers =467= and =35=, so its gear ratio is =16345=. The second gear is in the lower right; its gear ratio is =451490=. (The =*= adjacent to =617= is *not* a gear because it is only adjacent to one part number.) Adding up all of the gear ratios produces *=467835=*. *What is the sum of all of the gear ratios in your engine schematic?* *** Puzzle Solution **** Gather Symbol Neighbours #+name: day3-part2-sym-neighbour-count #+begin_src scheme (define (gather-neighbours part-sym part-nums) (foldl (lambda (output input) (if (neighbours? input part-sym) (cons input output) output)) (list) part-nums)) #+end_src **** Put Everything Together #+name: day3-part2-filter #+begin_src scheme (define (filter-gear-candidates part-syms) (foldl (lambda (output input) (if (eqv? '* (part-symbol-sym input)) (cons input output) output)) (list) part-syms)) #+end_src #+name: day3-part2-fold #+begin_src scheme (define (calc-gear-ratio gears) (foldl (lambda (output input) (if (= 2 (length input)) (+ output (apply * (map part-number-number input))) output)) 0 gears)) #+end_src #+name: day3-part2-calc #+begin_src scheme (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))) #+end_src #+results: day3-part2-calc-full : 75220503 ** Puzzle Input Jump to [[#headline-37][day 4]]. #+name: day3-input #+begin_src org .....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.. #+end_src * Day 4: Scratchcards Get the puzzle solution as [[file:./day4.scm][tangled .scm file]]. ** Part One *** Quest The gondola takes you up. Strangely, though, the ground doesn't seem to be coming with you; you're not climbing a mountain. As the circle of Snow Island recedes below you, an entire new landmass suddenly appears above you! The gondola carries you to the surface of the new island and lurches into the station. As you exit the gondola, the first thing you notice is that the air here is much *warmer* than it was on Snow Island. It's also quite *humid*. Is this where the water source is? The next thing you notice is an Elf sitting on the floor across the station in what seems to be a pile of colorful square cards. "Oh! Hello!" The Elf excitedly runs over to you. "How may I be of service?" You ask about water sources. "I'm not sure; I just operate the gondola lift. That does sound like something we'd have, though - this is *Island Island*, after all! I bet the *gardener* would know. He's on a different island, though - er, the small kind surrounded by water, not the floating kind. We really need to come up with a better naming scheme. Tell you what: if you can help me with something quick, I'll let you *borrow my boat* and you can go visit the gardener. I got all these [[https://en.wikipedia.org/wiki/Scratchcard][scratchcards]] as a gift, but I can't figure out what I've won." The Elf leads you over to the pile of colorful cards. There, you discover dozens of scratchcards, all with their opaque covering already scratched off. Picking one up, it looks like each card has two lists of numbers separated by a vertical bar (=|=): a list of *winning numbers* and then a list of *numbers you have*. You organize the information into a table (your puzzle input). As far as the Elf has been able to figure out, you have to figure out which of the *numbers you have* appear in the list of *winning numbers*. The first match makes the card worth *one point* and each match after the first *doubles* the point value of that card. For example: #+begin_example Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53 Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19 Card 3: 1 21 53 59 44 | 69 82 63 72 16 21 14 1 Card 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83 Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36 Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11 #+end_example In the above example, card 1 has five winning numbers (=41=, =48=, =83=, =86=, and =17=) and eight numbers you have (=83=, =86=, =6=, =31=, =17=, =9=, =48=, and =53=). Of the numbers you have, four of them (=48=, =83=, =17=, and =86=) are winning numbers! That means card 1 is worth *=8=* points (1 for the first match, then doubled three times for each of the three matches after the first). Card 2 has two winning numbers (=32= and =61=), so it is worth *=2=* points. Card 3 has two winning numbers (=1= and =21=), so it is worth *=2=* points. Card 4 has one winning number (=84=), so it is worth *=1=* point. Card 5 has no winning numbers, so it is worth no points. Card 6 has no winning numbers, so it is worth no points. So, in this example, the Elf's pile of scratchcards is worth *=13=* points. Take a seat in the large pile of colorful cards. *How many points are they worth in total?* *** Puzzle Solution **** 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 #+begin_src scheme (define-record scratchcard id winning-numbers card-numbers match-numbers copies) #+end_src **** 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 #+begin_src scheme (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)) #+end_src The pattern is then used to extract every scratch card which is then being parsed in a fold statement. #+name: day4-part1-card-fold #+begin_src scheme (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)) #+end_src **** 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 #+begin_src scheme (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))) #+end_src As a next step, I calculate the points for each card. #+name: day4-part1-card-points #+begin_src scheme (define (card-points card) (let ((match-nums (scratchcard-match-numbers card))) (foldl (lambda (points num) (if (= 0 points) 1 (* points 2))) 0 match-nums))) #+end_src And now, we can put everything together and sum up the points: #+name: day4-part1-calc #+begin_src scheme (foldl (lambda (sum card) (calc-card-matches card) (+ sum (card-points card))) 0 (input->cards input)) #+end_src #+results: day4-part1-calc-full : 23441 ** Part Two *** Quest Just as you're about to report your findings to the Elf, one of you realizes that the rules have actually been printed on the back of every card this whole time. There's no such thing as "points". Instead, scratchcards only cause you to *win more scratchcards* equal to the number of winning numbers you have. Specifically, you win *copies* of the scratchcards below the winning card equal to the number of matches. So, if card 10 were to have 5 matching numbers, you would win one copy each of cards 11, 12, 13, 14, and 15. Copies of scratchcards are scored like normal scratchcards and have the *same card number* as the card they copied. So, if you win a copy of card 10 and it has 5 matching numbers, it would then win a copy of the same cards that the original card 10 won: cards 11, 12, 13, 14, and 15. This process repeats until none of the copies cause you to win any more cards. (Cards will never make you copy a card past the end of the table.) This time, the above example goes differently: #+begin_example Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53 Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19 Card 3: 1 21 53 59 44 | 69 82 63 72 16 21 14 1 Card 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83 Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36 Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11 #+end_example - Card 1 has four matching numbers, so you win one copy each of the next four cards: cards 2, 3, 4, and 5. - Your original card 2 has two matching numbers, so you win one copy each of cards 3 and 4. - Your copy of card 2 also wins one copy each of cards 3 and 4. - Your four instances of card 3 (one original and three copies) have two matching numbers, so you win *four* copies each of cards 4 and 5. - Your eight instances of card 4 (one original and seven copies) have one matching number, so you win *eight* copies of card 5. - Your fourteen instances of card 5 (one original and thirteen copies) have no matching numbers and win no more cards. - Your one instance of card 6 (one original) has no matching numbers and wins no more cards. Once all of the originals and copies have been processed, you end up with *=1=* instance of card 1, *=2=* instances of card 2, *=4=* instances of card 3, *=8=* instances of card 4, *=14=* instances of card 5, and *=1=* instance of card 6. In total, this example pile of scratchcards causes you to ultimately have *=30=* scratchcards! Process all of the original and copied scratchcards until no more scratchcards are won. Including the original set of scratchcards, *how many total scratchcards do you end up with?* *** Puzzle Solution #+name: day4-part2-card-alist #+begin_src scheme (define (card-alist cards) (foldl (lambda (alist card) (calc-card-matches card) (alist-update (scratchcard-id card) card alist)) '() (reverse cards))) #+end_src #+name: day4-part2-gen-copies #+begin_src scheme (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))) #+end_src #+name: day4-part2-count-scratchcards #+begin_src scheme (define (count-scratchcards cardlist) (foldl + 0 (map (compose scratchcard-copies cdr) cardlist))) #+end_src #+name: day4-part2-calc #+begin_src scheme (let ((cardlist (card-alist (input->cards input)))) (generate-copies cardlist) (count-scratchcards cardlist)) #+end_src #+results: day4-part2-calc-full : 5923918 ** Puzzle Input Jump to [[#headline-48][day 5]]. #+name: day4-input #+begin_src org 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 #+end_src * Day 5: If You Give A Seed A Fertilizer Get the puzzle solution as [[file:./day5.scm][tangled .scm file]]. ** Part One *** Quest You take the boat and find the gardener right where you were told he would be: managing a giant "garden" that looks more to you like a farm. "A water source? Island Island *is* the water source!" You point out that Snow Island isn't receiving any water. "Oh, we had to stop the water because we *ran out of sand* to [[https://en.wikipedia.org/wiki/Sand_filter][filter]] it with! Can't make snow with dirty water. Don't worry, I'm sure we'll get more sand soon; we only turned off the water a few days... weeks... oh no." His face sinks into a look of horrified realization. "I've been so busy making sure everyone here has food that I completely forgot to check why we stopped getting more sand! There's a ferry leaving soon that is headed over in that direction - it's much faster than your boat. Could you please go check it out?" You barely have time to agree to this request when he brings up another. "While you wait for the ferry, maybe you can help us with our *food production problem*. The latest Island Island [[https://en.wikipedia.org/wiki/Almanac][Almanac]] just arrived and we're having trouble making sense of it." The almanac (your puzzle input) lists all of the seeds that need to be planted. It also lists what type of soil to use with each kind of seed, what type of fertilizer to use with each kind of soil, what type of water to use with each kind of fertilizer, and so on. Every type of seed, soil, fertilizer and so on is identified with a number, but numbers are reused by each category - that is, soil =123= and fertilizer =123= aren't necessarily related to each other. For example: #+begin_example seeds: 79 14 55 13 seed-to-soil map: 50 98 2 52 50 48 soil-to-fertilizer map: 0 15 37 37 52 2 39 0 15 fertilizer-to-water map: 49 53 8 0 11 42 42 0 7 57 7 4 water-to-light map: 88 18 7 18 25 70 light-to-temperature map: 45 77 23 81 45 19 68 64 13 temperature-to-humidity map: 0 69 1 1 0 69 humidity-to-location map: 60 56 37 56 93 4 #+end_example The almanac starts by listing which seeds need to be planted: seeds =79=, =14=, =55=, and =13=. The rest of the almanac contains a list of *maps* which describe how to convert numbers from a *source category* into numbers in a *destination category*. That is, the section that starts with ~seed-to-soil map:~ describes how to convert a *seed number* (the source) to a *soil number* (the destination). This lets the gardener and his team know which soil to use with which seeds, which water to use with which fertilizer, and so on. Rather than list every source number and its corresponding destination number one by one, the maps describe entire *ranges* of numbers that can be converted. Each line within a map contains three numbers: the *destination range start*, the *source range start*, and the *range length*. Consider again the example ~seed-to-soil map~: #+begin_example 50 98 2 52 50 48 #+end_example The first line has a *destination range start* of =50=, a *source range start* of =98=, and a *range length* of =2=. This line means that the source range starts at =98= and contains two values: =98= and =99=. The destination range is the same length, but it starts at =50=, so its two values are =50= and =51=. With this information, you know that seed number =98= corresponds to soil number =50= and that seed number =99= corresponds to soil number =51=. The second line means that the source range starts at =50= and contains =48= values: =50=, =51=, ..., =96=, =97=. This corresponds to a destination range starting at =52= and also containing =48= values: =52=, =53=, ..., =98=, =99=. So, seed number =53= corresponds to soil number =55=. Any source numbers that *aren't mapped* correspond to the *same* destination number. So, seed number =10= corresponds to soil number =10=. So, the entire list of seed numbers and their corresponding soil numbers looks like this: #+begin_example seed soil 0 0 1 1 ... ... 48 48 49 49 50 52 51 53 ... ... 96 98 97 99 98 50 99 51 #+end_example With this map, you can look up the soil number required for each initial seed number: - Seed number =79= corresponds to soil number =81=. - Seed number =14= corresponds to soil number =14=. - Seed number =55= corresponds to soil number =57=. - Seed number =13= corresponds to soil number =13=. The gardener and his team want to get started as soon as possible, so they'd like to know the closest location that needs a seed. Using these maps, find *the lowest location number that corresponds to any of the initial seeds*. To do this, you'll need to convert each seed number through other categories until you can find its corresponding *location number*. In this example, the corresponding types are: - Seed =79=, soil =81=, fertilizer =81=, water =81=, light =74=, temperature =78=, humidity =78=, *location =82=*. - Seed =14=, soil =14=, fertilizer =53=, water =49=, light =42=, temperature =42=, humidity =43=, *location =43=*. - Seed =55=, soil =57=, fertilizer =57=, water =53=, light =46=, temperature =82=, humidity =82=, *location =86=*. - Seed =13=, soil =13=, fertilizer =52=, water =41=, light =34=, temperature =34=, humidity =35=, *location =35=*. So, the lowest location number in this example is *=35=*. *What is the lowest location number that corresponds to any of the initial seed numbers?* *** Puzzle Solution **** Mapping Record #+name: day5-part1-mapping-record #+begin_src scheme (define-record entity type id) (define-record mapping-entry from-type to-type from-start from-end to-start to-end) #+end_src **** Data Extraction ***** Irregexes #+name: day5-part1-seed-irregex #+begin_src scheme (define seed-irregex '(: (* whitespace) "seeds: " (submatch-named seed-numbers (+ (or numeric whitespace))))) #+end_src #+name: day5-part1-mapping-irregex #+begin_src scheme (define mapping-irregex '(: (submatch-named mapping-from (+ alphabetic)) "-to-" (submatch-named mapping-to (+ alphabetic)) " map:" (submatch-named mapping-vals (+ (or numeric whitespace))))) #+end_src #+name: day5-part1-mapping-nums-irregex #+begin_src scheme (define mapping-nums-irregex '(: (* whitespace) (submatch-named to-range (+ numeric)) (* whitespace) (submatch-named from-range (+ numeric)) (* whitespace) (submatch-named range-size (+ numeric)))) #+end_src ***** Data Reading A list of seed numbers: #+name: day5-part1-seeds-list #+begin_src scheme (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)))) #+end_src And a mapping from input type (e.g. ~#:soil~) to the mappings to the next type: #+name: day5-part1-mapping-alist #+begin_src scheme (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)) #+end_src **** Processing The Data #+name: day5-part1-map-entity-forward #+begin_src scheme (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))) #+end_src #+name: day5-part1-map-entity-forward-fully #+begin_src scheme (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))) #+end_src **** Solution #+name: day5-part1-calc #+begin_src scheme (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))) #+end_src #+results: day5-part1-calc-full : 1181555926 ** Part Two *** Quest Everyone will starve if you only plant such a small number of seeds. Re-reading the almanac, it looks like the ~seeds:~ line actually describes ranges of seed numbers. The values on the initial ~seeds:~ line come in pairs. Within each pair, the first value is the *start* of the range and the second value is the *length* of the range. So, in the first line of the example above: ~seeds: 79 14 55 13~ This line describes two ranges of seed numbers to be planted in the garden. The first range starts with seed number =79= and contains =14= values: =79=, =80=, ..., =91=, =92=. The second range starts with seed number =55= and contains =13= values: =55=, =56=, ..., =66=, =67=. Now, rather than considering four seed numbers, you need to consider a total of *27* seed numbers. In the above example, the lowest location number can be obtained from seed number *82*, which corresponds to soil =84=, fertilizer =84=, water =84=, light =77=, temperature =45=, humidity =46=, and *location =46=*. So, the lowest location number is *=46=*. Consider all of the initial seed numbers listed in the ranges on the first line of the almanac. *What is the lowest location number that corresponds to any of the initial seed numbers?* *** 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 #+begin_src scheme (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)))) #+end_src 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 #+begin_src scheme (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))) #+end_src #+name: day5-part2-calc #+begin_src scheme (let ((seeds (expand-seeds (input->seeds-list input))) (mapping-alist (input->mapping-alist input))) (fold-seeds seeds mapping-alist)) #+end_src #+results: day5-part2-calc-full : 37806486 *** The Optimized Solution For the optimized solution using ranges, a new record type is needed: ~ranged-entity~. #+begin_src scheme (define-record ranged-entity type from-id to-id) #+end_src 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. #+begin_src scheme (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))))) #+end_src - 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. #+begin_src scheme (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)))) #+end_src - There is just ~ranged-entity~ left, with nothing else: then it gets a new type, and is otherwise passed on 1:1. #+begin_src scheme (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)) #+end_src This behemoth determines which of the functions above to call. #+begin_src scheme (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))))) #+end_src Here, the mapping is being done. #+begin_src scheme (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))) '())) #+end_src And here, it is all put together. #+begin_src scheme (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)))))) #+end_src ** Puzzle Input Jump to [[#headline-63][day 6]]. #+name: day5-input #+begin_src org 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 #+end_src * Day 6: Wait For It Get the puzzle solution as [[file:./day6.scm][tangled .scm file]]. ** Part One *** Quest The ferry quickly brings you across Island Island. After asking around, you discover that there is indeed normally a large pile of sand somewhere near here, but you don't see anything besides lots of water and the small island where the ferry has docked. As you try to figure out what to do next, you notice a poster on a wall near the ferry dock. "Boat races! Open to the public! Grand prize is an all-expenses-paid trip to *Desert Island*!" That must be where the sand comes from! Best of all, the boat races are starting in just a few minutes. You manage to sign up as a competitor in the boat races just in time. The organizer explains that it's not really a traditional race - instead, you will get a fixed amount of time during which your boat has to travel as far as it can, and you win if your boat goes the farthest. As part of signing up, you get a sheet of paper (your puzzle input) that lists the *time* allowed for each race and also the best *distance* ever recorded in that race. To guarantee you win the grand prize, you need to make sure you *go farther in each race* than the current record holder. The organizer brings you over to the area where the boat races are held. The boats are much smaller than you expected - they're actually *toy boats*, each with a big button on top. Holding down the button *charges the boat*, and releasing the button *allows the boat to move*. Boats move faster if their button was held longer, but time spent holding the button counts against the total race time. You can only hold the button at the start of the race, and boats don't move until the button is released. For example: #+begin_example Time: 7 15 30 Distance: 9 40 200 #+end_example This document describes three races: - The first race lasts 7 milliseconds. The record distance in this race is 9 millimeters. - The second race lasts 15 milliseconds. The record distance in this race is 40 millimeters. - The third race lasts 30 milliseconds. The record distance in this race is 200 millimeters. Your toy boat has a starting speed of *zero millimeters per millisecond*. For each whole millisecond you spend at the beginning of the race holding down the button, the boat's speed increases by *one millimeter per millisecond*. So, because the first race lasts 7 milliseconds, you only have a few options: - Don't hold the button at all (that is, hold it for *=0= milliseconds*) at the start of the race. The boat won't move; it will have traveled *=0= millimeters* by the end of the race. - Hold the button for *=1= millisecond* at the start of the race. Then, the boat will travel at a speed of =1= millimeter per millisecond for =6= milliseconds, reaching a total distance traveled of *=6 millimeters=. - Hold the button for *=2= milliseconds*, giving the boat a speed of =2= millimeters per millisecond. It will then get =5= milliseconds to move, reaching a total distance of *=10= millimeters*. - Hold the button for *=3= milliseconds*. After its remaining =4= milliseconds of travel time, the boat will have gone *=12= millimeters=. - Hold the button for *=4= milliseconds*. After its remaining =3= milliseconds of travel time, the boat will have gone *=12= millimeters*. - Hold the button for *=5= milliseconds*, causing the boat to travel a total of *=10= millimeters*. - Hold the button for *=6= milliseconds*, causing the boat to travel a total of *=6= millimeters*. - Hold the button for *=7= milliseconds*. That's the entire duration of the race. You never let go of the button. The boat can't move until you let go of the button. Please make sure you let go of the button so the boat gets to move. *=0= millimeters*. Since the current record for this race is =9= millimeters, there are actually *=4=* different ways you could win: you could hold the button for =2=, =3=, =4=, or =5= milliseconds at the start of the race. In the second race, you could hold the button for at least =4= milliseconds and at most =11= milliseconds and beat the record, a total of *=8=* different ways to win. In the third race, you could hold the button for at least =11= milliseconds and no more than =19= milliseconds and still beat the record, a total of *=9=* ways you could win. To see how much margin of error you have, determine the *number of ways you can beat the record* in each race; in this example, if you multiply these values together, you get *=288=* (=4= * =8= * =9=). Determine the number of ways you could beat the record in each race. *What do you get if you multiply these numbers together?* *** Puzzle Solution **** Data Extraction First, we need to define the record for the race data. #+name: day6-part1-race-record #+begin_src scheme (define-record race time-limit record-distance winning-distances losing-distances) #+end_src The solution starts with the usual data extraction using ~irregex~. #+name: day6-part1-input-extraction-irregex #+begin_src scheme (define input-extraction-irregex '(: "Time:" (submatch-named time-vals (+ (or numeric whitespace))) "Distance:" (submatch-named distance-vals (+ (or numeric whitespace))))) #+end_src Next, the data is converted into ~race~ records. #+name: day6-part1-input--race-records #+begin_src scheme (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)))))) #+end_src **** Race Calculations #+name: day6-part1-get-distance #+begin_src scheme (define (get-distance race hold-time) (let ((time-remaining (- (race-time-limit race) hold-time))) (* time-remaining hold-time))) #+end_src #+name: day6-part1-calc-race-distances #+begin_src scheme (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))))))) #+end_src **** Getting The Result #+name: day6-part1-calc-fn #+begin_src scheme (import (chicken string) (chicken irregex)) (define input " Time: 58 81 96 76 Distance: 434 1041 2219 1218") (define-record race time-limit record-distance winning-distances losing-distances) (define input-extraction-irregex '(: "Time:" (submatch-named time-vals (+ (or numeric whitespace))) "Distance:" (submatch-named distance-vals (+ (or numeric whitespace))))) (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)))))) (define (get-distance race hold-time) (let ((time-remaining (- (race-time-limit race) hold-time))) (* time-remaining hold-time))) (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))))))) (define (calc-part-1) (foldl * 1 (map (compose length race-winning-distances) (map calc-race-distances (input->race-records input))))) #+end_src #+results: : 1159152 ** Part Two *** Quest As the race is about to start, you realize the piece of paper with race times and record distances you got earlier actually just has very bad [[https://en.wikipedia.org/wiki/Kerning][kerning]]. There's really *only one race* - ignore the spaces between the numbers on each line. So, the example from before: #+begin_example Time: 7 15 30 Distance: 9 40 200 #+end_example ...now instead means this: #+begin_example Time: 71530 Distance: 940200 #+end_example Now, you have to figure out how many ways there are to win this single race. In this example, the race lasts for *=71530= milliseconds* and the record distance you need to beat is *=940200= millimeters*. You could hold the button anywhere from =14= to =71516= milliseconds and beat the record, a total of =71503= ways! *How many ways can you beat the record in this one much longer race?* *** Puzzle Solution **** Code Changes The ~input->race-records~ function has to be rewritten: #+name: day6-part2-input--race-record #+begin_src scheme (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))) #+end_src And instead of keeping a list of all winning and losing distances, I use a counter. #+name: day6-part2-calc-race-distances #+begin_src scheme (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))))))) #+end_src **** Race Variant Results #+name: day6-part2-calc-fn #+begin_src scheme (import (chicken string) (chicken irregex)) (define input " Time: 58 81 96 76 Distance: 434 1041 2219 1218") (define-record race time-limit record-distance winning-distances losing-distances) (define input-extraction-irregex '(: "Time:" (submatch-named time-vals (+ (or numeric whitespace))) "Distance:" (submatch-named distance-vals (+ (or numeric whitespace))))) (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))) (define (get-distance race hold-time) (let ((time-remaining (- (race-time-limit race) hold-time))) (* time-remaining hold-time))) (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))))))) (define (calc-part-2) (race-winning-distances (calc-race-distances-with-counter (input->race-record input)))) #+end_src #+results: : 41513103 ** Puzzle Input Jump to [[#headline-76][day 7]]. #+name: day6-input #+begin_src org Time: 58 81 96 76 Distance: 434 1041 2219 1218 #+end_src * Day 7: Camel Cards Get the puzzle solution as [[file:./day7.scm][tangled .scm file]]. ** Part One *** Quest Your all-expenses-paid trip turns out to be a one-way, five-minute ride in an [[https://en.wikipedia.org/wiki/Airship][airship]]. (At least it's a *cool* airship!) It drops you off at the edge of a vast desert and descends back to Island Island. "Did you bring the parts?" You turn around to see an Elf completely covered in white clothing, wearing goggles, and riding a large [[https://en.wikipedia.org/wiki/Dromedary][camel]]. "Did you bring the parts?" she asks again, louder this time. You aren't sure what parts she's looking for; you're here to figure out why the sand stopped. "The parts! For the sand, yes! Come with me; I will show you." She beckons you onto the camel. After riding a bit across the sands of Desert Island, you can see what look like very large rocks covering half of the horizon. The Elf explains that the rocks are all along the part of Desert Island that is directly above Island Island, making it hard to even get there. Normally, they use big machines to move the rocks and filter the sand, but the machines have broken down because Desert Island recently stopped receiving the parts they need to fix the machines. You've already assumed it'll be your job to figure out why the parts stopped when she asks if you can help. You agree automatically. Because the journey will take a few days, she offers to teach you the game of *Camel Cards*. Camel Cards is sort of similar to [[https://en.wikipedia.org/wiki/List_of_poker_hands][poker]] except it's designed to be easier to play while riding a camel. In Camel Cards, you get a list of *hands*, and your goal is to order them based on the *strength* of each hand. A hand consists of *five cards* labeled one of =A=, =K=, =Q=, =J=, =T=, =9=, =8=, =7=, =6=, =5=, =4=, =3=, or =2=. The relative strength of each card follows this order, where =A= is the highest and =2= is the lowest. Every hand is exactly one *type*. From strongest to weakest, they are: - *Five of a kind*, where all five cards have the same label: =AAAAA= - *Four of a kind*, where four cards have the same label and one card has a different label: =AA8AA= - *Full house*, where three cards have the same label, and the remaining two cards share a different label: =23332= - *Three of a kind*, where three cards have the same label, and the remaining two cards are each different from any other card in the hand: =TTT98= - *Two pair*, where two cards share one label, two other cards share a second label, and the remaining card has a third label: =23432= - *One pair*, where two cards share one label, and the other three cards have a different label from the pair and each other: =A23A4= - *High card*, where all cards' labels are distinct: =23456= Hands are primarily ordered based on type; for example, every *full house* is stronger than any *three of a kind*. If two hands have the same type, a second ordering rule takes effect. Start by comparing the *first card in each hand*. If these cards are different, the hand with the stronger first card is considered stronger. If the first card in each hand have the *same label*, however, then move on to considering the *second card in each hand*. If they differ, the hand with the higher second card wins; otherwise, continue with the third card in each hand, then the fourth, then the fifth. So, =33332= and =2AAAA= are both *four of a kind* hands, but =33332= is stronger because its first card is stronger. Similarly, =77888= and =77788= are both a *full house*, but =77888= is stronger because its third card is stronger (and both hands have the same first and second card). To play Camel Cards, you are given a list of hands and their corresponding *bid* (your puzzle input). For example: #+begin_example 32T3K 765 T55J5 684 KK677 28 KTJJT 220 QQQJA 483 #+end_example This example shows five hands; each hand is followed by its *bid* amount. Each hand wins an amount equal to its bid multiplied by its *rank*, where the weakest hand gets rank 1, the second-weakest hand gets rank 2, and so on up to the strongest hand. Because there are five hands in this example, the strongest hand will have rank 5 and its bid will be multiplied by 5. So, the first step is to put the hands in order of strength: - =32T3K= is the only *one pair* and the other hands are all a stronger type, so it gets rank *1*. - =KK677= and =KTJJT= are both *two pair*. Their first cards both have the same label, but the second card of =KK677= is stronger (=K= vs =T=), so =KTJJT= gets rank *2* and =KK677= gets rank *3*. - =T55J5= and =QQQJA= are both *three of a kind*. =QQQJA= has a stronger first card, so it gets rank *5* and =T55J5= gets rank *4*. Now, you can determine the total winnings of this set of hands by adding up the result of multiplying each hand's bid with its rank (=765= * 1 + =220= * 2 + =28= * 3 + =684= * 4 + =483= * 5). So the *total winnings* in this example are *=6440=*. Find the rank of every hand in your set. *What are the total winnings?* *** Puzzle Solution Because the journey will take a few days, she offers to teach you the game of *Camel Cards*. Camel Cards is sort of similar to [[https://en.wikipedia.org/wiki/List_of_poker_hands][poker]] except it's designed to be easier to play while riding a camel. In Camel Cards, you get a list of *hands*, and your goal is to order them based on the *strength* of each hand. A hand consists of *five cards* labeled one of =A=, =K=, =Q=, =J=, =T=, =9=, =8=, =7=, =6=, =5=, =4=, =3=, or =2=. The relative strength of each card follows this order, where =A= is the highest and =2= is the lowest. #+name: day7-part1-cards #+begin_src scheme (define cards `((#:A . ,(make-card #:A 13)) (#:K . ,(make-card #:K 12)) (#:Q . ,(make-card #:Q 11)) (#:J . ,(make-card #:J 10)) (#:T . ,(make-card #:T 9)) (#:9 . ,(make-card #:9 8)) (#:8 . ,(make-card #:8 7)) (#:7 . ,(make-card #:7 6)) (#:6 . ,(make-card #:6 5)) (#:5 . ,(make-card #:5 4)) (#:4 . ,(make-card #:4 3)) (#:3 . ,(make-card #:3 2)) (#:2 . ,(make-card #:2 1)))) #+end_src The hands are separated into types. #+name: day7-part1-types #+begin_src scheme (define (calc-card-frequencies cardlist #!optional (frequencies '())) (if (eqv? '() cardlist) (sort (map cdr frequencies) >) (let* ((card-label (card-label (car cardlist))) (card-old-frequency (alist-ref card-label frequencies eqv? 0))) (calc-card-frequencies (cdr cardlist) (alist-update card-label (+ 1 card-old-frequency) frequencies))))) (define (calc-hand-type hand) (let ((frequencies (calc-card-frequencies (hand-cards hand)))) (cond ;; Insert the comparisons from below here )) hand) #+end_src For the sake of brevity, there is a shortcut function to get a type for a hand of cards, to be used in the following examples: #+name: day7-part1-type-sample-noweb #+begin_src scheme (define (get-type-for-cards #!rest card-labels) (hand-type-label (hand-type-rec (calc-hand-type (make-hand (map (cut alist-ref <> cards) card-labels) #f #f #f))))) #+end_src Every hand is exactly one *type*. From strongest to weakest, they are: - *Five of a kind*, where all five cards have the same label: =AAAAA=; src_scheme{(get-type-for-cards #:A #:A #:A #:A #:A)} =#:five-of-a-kind= #+name: day7-part1-five-of-a-kind #+begin_src scheme ((= 5 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:five-of-a-kind hand-types))) #+end_src - *Four of a kind*, where four cards have the same label and one card has a different label: =AA8AA=; src_scheme{(get-type-for-cards #:A #:A #:8 #:A #:A)} =#:four-of-a-kind= #+name: day7-part1-four-of-a-kind #+begin_src scheme ((= 4 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:four-of-a-kind hand-types))) #+end_src - *Full house*, where three cards have the same label, and the remaining two cards share a different label: =23332=; src_scheme{(get-type-for-cards #:2 #:3 #:3 #:3 #:2)} =#:full-house= #+name: day7-part1-full-house #+begin_src scheme ((and (= 3 (car frequencies)) (= 2 (cadr frequencies))) (hand-type-rec-set! hand (alist-ref #:full-house hand-types))) #+end_src - *Three of a kind*, where three cards have the same label, and the remaining two cards are each different from any other card in the hand: =TTT98=; src_scheme{(get-type-for-cards #:T #:T #:T #:9 #:8)} =#:three-of-a-kind= #+name: day7-part1-three-of-a-kind #+begin_src scheme ((= 3 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:three-of-a-kind hand-types))) #+end_src - *Two pair*, where two cards share one label, two other cards share a second label, and the remaining card has a third label: =23432=; src_scheme{(get-type-for-cards #:2 #:3 #:4 #:3 #:2)} =#:two-pair= #+name: day7-part1-two-pair #+begin_src scheme ((and (= 2 (car frequencies)) (= 2 (cadr frequencies))) (hand-type-rec-set! hand (alist-ref #:two-pair hand-types))) #+end_src - *One pair*, where two cards share one label, and the other three cards have a different label from the pair and each other: =A23A4=; src_scheme{(get-type-for-cards #:A #:2 #:3 #:A #:4)} =#:one-pair= #+name: day7-part1-one-pair #+begin_src scheme ((= 2 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:one-pair hand-types))) #+end_src - *High card*, where all cards' labels are distinct: =23456=; src_scheme{(get-type-for-cards #:2 #:3 #:4 #:5 #:6)} =#:high-card= #+name: day7-part1-high-card #+begin_src scheme ((= 1 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:high-card hand-types))) #+end_src Hands are primarily ordered based on type; for example, every *full house* is stronger than any *three of a kind*. #+name: day7-part1-hand-types #+begin_src scheme (define hand-types `((#:five-of-a-kind . ,(make-hand-type #:five-of-a-kind 7)) (#:four-of-a-kind . ,(make-hand-type #:four-of-a-kind 6)) (#:full-house . ,(make-hand-type #:full-house 5)) (#:three-of-a-kind . ,(make-hand-type #:three-of-a-kind 4)) (#:two-pair . ,(make-hand-type #:two-pair 3)) (#:one-pair . ,(make-hand-type #:one-pair 2)) (#:high-card . ,(make-hand-type #:high-card 1)))) #+end_src If two hands have the same type, a second ordering rule takes effect. Start by comparing the *first card in each hand*. If these cards are different, the hand with the stronger first card is considered stronger. If the first card in each hand have the *same label*, however, then move on to considering the *second card in each hand*. If they differ, the hand with the higher second card wins; otherwise, continue with the third card in each hand, then the fourth, then the fifth. #+name: day7-part1-hand-comparison #+begin_src scheme (define (card> card-a card-b) (> (card-weight card-a) (card-weight card-b))) (define (hand-cards> cards-a cards-b) (or (card> (car cards-a) (car cards-b)) (and (< 1 (length cards-a)) (= (card-weight (car cards-a)) (card-weight (car cards-b))) (hand-cards> (cdr cards-a) (cdr cards-b))))) (define (hands> hand-a hand-b) (let ((type-weight-a (hand-type-weight (hand-type-rec hand-a))) (type-weight-b (hand-type-weight (hand-type-rec hand-b))) (cards-a (hand-cards hand-a)) (cards-b (hand-cards hand-b))) (or (> type-weight-a type-weight-b) (and (= type-weight-a type-weight-b) (hand-cards> cards-a cards-b))))) #+end_src So, =33332= and =2AAAA= are both *four of a kind* hands, but =33332= is stronger because its first card is stronger. Similarly, =77888= and =77788= are both a *full house*, but =77888= is stronger because its third card is stronger (and both hands have the same first and second card). #+begin_src scheme (hands> (make-hand (map (cut alist-ref <> cards) '(#:3 #:3 #:3 #:3 #:2)) 0 (alist-ref #:four-of-a-kind hand-types) #f) (make-hand (map (cut alist-ref <> cards) '(#:2 #:A #:A #:A #:A)) 0 (alist-ref #:four-of-a-kind hand-types) #f)) #+end_src #+results: : #t To play Camel Cards, you are given a list of hands and their corresponding *bid* (your puzzle input). For example: #+begin_example 32T3K 765 T55J5 684 KK677 28 KTJJT 220 QQQJA 483 #+end_example Better sample input from [[https://old.reddit.com/r/adventofcode/comments/18cr4xr/2023_day_7_better_example_input_not_a_spoiler/][u/LxsterGames]] on Reddit: #+name: day7-part1-hand-input-example #+begin_example 2345A 1 Q2KJJ 13 Q2Q2Q 19 T3T3J 17 T3Q33 11 2345J 3 J345A 2 32T3K 5 T55J5 29 KK677 7 KTJJT 34 QQQJA 31 JJJJJ 37 JAAAA 43 AAAAJ 59 AAAAA 61 2AAAA 23 2JJJJ 53 JJJJ2 41 #+end_example #+name: day7-part1-data-regex #+begin_src scheme (define camel-card-irregex '(: (submatch-named cards (+ (or (/ #\A #\Z) (/ #\0 #\9)))) " " (submatch-named bid (+ (/ #\0 #\9))))) #+end_src #+name: day7-part1-data-extraction #+begin_src scheme (define (cardstr->cards cardstr) (map (compose (cut alist-ref <> cards) string->keyword string) (string->list cardstr))) (define (input->hands input) (irregex-fold camel-card-irregex (lambda (from-index match seed) (let ((cardstr (irregex-match-substring match 'cards)) (bidstr (irregex-match-substring match 'bid))) (cons (make-hand (cardstr->cards cardstr) (string->number bidstr) #f #f) seed))) '() input)) #+end_src This example shows five hands; each hand is followed by its *bid* amount. Each hand wins an amount equal to its bid multiplied by its *rank*, where the weakest hand gets rank 1, the second-weakest hand gets rank 2, and so on up to the strongest hand. Because there are five hands in this example, the strongest hand will have rank 5 and its bid will be multiplied by 5. #+name: day7-part1-hand-ranking #+begin_src scheme (define (rank-hands sorted-hands #!optional (index 1)) (when (not (eqv? '() sorted-hands)) (hand-rank-set! (car sorted-hands) index) (rank-hands (cdr sorted-hands) (+ index 1)))) #+end_src So, the first step is to put the hands in order of strength: - =32T3K= is the only *one pair* and the other hands are all a stronger type, so it gets rank *1*. - =KK677= and =KTJJT= are both *two pair*. Their first cards both have the same label, but the second card of =KK677= is stronger (=K= vs =T=), so =KTJJT= gets rank *2* and =KK677= gets rank *3*. - =T55J5= and =QQQJA= are both *three of a kind*. =QQQJA= has a stronger first card, so it gets rank *5* and =T55J5= gets rank *4*. #+begin_src scheme (let ((hands (input->hands input))) (map calc-hand-type hands) (rank-hands (reverse (sort hands hands>))) (append '(("Cards" "Hand Type" "Rank" "Bid" "Bid*Rank")) (map (lambda (hand) (let ((card-labels (map card-label (hand-cards hand))) (hand-rank (hand-rank hand)) (hand-bid (hand-bid hand)) (hand-type (hand-type-label (hand-type-rec hand)))) (list (apply string-append (map keyword->string card-labels)) hand-type hand-rank hand-bid (* hand-bid hand-rank)))) (sort hands hands>)) `(("Total" "" "" "" ,(total-winnings hands))))) #+end_src #+results: | Cards | Hand Type | Rank | Bid | Bid*Rank | | AAAAA | five-of-a-kind | 19 | 61 | 1159 | | JJJJJ | five-of-a-kind | 18 | 37 | 666 | | AAAAJ | four-of-a-kind | 17 | 59 | 1003 | | JAAAA | four-of-a-kind | 16 | 43 | 688 | | JJJJ2 | four-of-a-kind | 15 | 41 | 615 | | 2AAAA | four-of-a-kind | 14 | 23 | 322 | | 2JJJJ | four-of-a-kind | 13 | 53 | 689 | | Q2Q2Q | full-house | 12 | 19 | 228 | | QQQJA | three-of-a-kind | 11 | 31 | 341 | | T55J5 | three-of-a-kind | 10 | 29 | 290 | | T3Q33 | three-of-a-kind | 9 | 11 | 99 | | KK677 | two-pair | 8 | 7 | 56 | | KTJJT | two-pair | 7 | 34 | 238 | | T3T3J | two-pair | 6 | 17 | 102 | | Q2KJJ | one-pair | 5 | 13 | 65 | | 32T3K | one-pair | 4 | 5 | 20 | | J345A | high-card | 3 | 2 | 6 | | 2345A | high-card | 2 | 1 | 2 | | 2345J | high-card | 1 | 3 | 3 | | Total | | | | 6592 | Now, you can determine the total winnings of this set of hands by adding up the result of multiplying each hand's bid with its rank (=765= * 1 + =220= * 2 + =28= * 3 + =684= * 4 + =483= * 5). So the *total winnings* in this example are *=6440=*. #+name: day7-part1-total-winnings #+begin_src scheme (define (total-winnings hands) (foldl (lambda (total hand) (let ((bid (hand-bid hand)) (rank (hand-rank hand))) (+ total (* bid rank)))) 0 hands)) #+end_src Find the rank of every hand in your set. *What are the total winnings?* #+name: day7-part1-calc-fn #+begin_src scheme (import (chicken string) (chicken keyword) (chicken sort) (chicken irregex)) (define-record card label weight) (define-record hand cards bid type-rec rank) (define-record hand-type label weight) (define input " 3Q373 470 K53JT 351 A9JK9 856 2T333 515 867T4 541 58K22 253 5JA6J 994 K4A4K 865 94377 519 92J2Q 901 J7676 389 2KK36 938 JQ2KK 987 Q7A82 509 TTTA5 243 72J27 502 AKKKA 387 23222 674 55335 161 AA655 73 QKKQA 686 5J2T5 680 666AT 385 ATA3A 761 TTT8J 364 98A2T 282 59A44 260 6T9QJ 130 T7TKQ 721 9274T 656 T9AJ4 182 A2222 259 TQKJ7 67 4J844 560 AAATA 636 9J36J 546 QJQQQ 119 249TT 295 877J7 221 4KA23 116 929Q2 929 99JQQ 445 Q9QJ8 432 4Q7TJ 963 4J2J8 783 5J657 257 88788 183 KKK7K 909 KK396 637 J45AT 117 84448 806 A2698 820 A9AA5 320 A3934 19 Q45Q5 392 78686 254 A55A5 701 98A4K 655 5AJ88 95 AK3KK 55 773KK 33 J9J9J 356 2KAKK 563 655K5 287 55T56 475 54444 308 5J5QA 811 QKA76 792 2K288 42 JTKA2 694 88668 889 8TQ64 212 23QQ2 261 8K8K5 365 JKKAA 234 3J894 880 667Q2 817 888T4 599 T5Q83 315 3QK29 670 JK4KK 322 75T8T 144 AAA7K 291 7T333 495 A49K4 448 JJ3J3 251 5999J 278 38438 890 6K3Q9 122 TTT99 93 94775 240 K8QJ3 369 59674 107 267J4 355 QTQTQ 187 46J44 961 Q7AK2 580 69969 609 876A5 474 A3866 642 Q3QQA 526 JAA88 425 35Q9K 986 QQTQJ 550 54535 357 2J222 639 QK5J7 743 222Q2 191 T4T44 855 QTQQ2 338 JA7A2 300 AAAJ2 508 4J455 23 A77AA 339 5KK25 899 252J2 737 7QJ76 888 K46QK 795 A4T3J 640 8A8K8 176 AA5AA 41 J2Q24 958 58855 632 333J3 610 74474 807 K3AAA 78 JJ222 765 44224 688 76733 361 5845K 181 TT4T2 974 23J33 102 QQJ6Q 34 Q9AQQ 150 22747 717 KAA5A 121 7AA7J 286 J786T 780 3K8TT 32 A6KAA 25 9A362 166 A29Q2 499 6688K 57 KKQKA 947 999JJ 975 6A666 927 TTT3K 658 JQQ7T 467 8A247 934 7JK8J 712 KK39K 612 6666Q 17 77Q37 868 A66AJ 169 KKKKJ 535 7Q7JJ 591 K9848 646 46888 931 A86A8 326 743TA 527 QKK67 977 KKJ6K 471 AAJ7A 571 55292 330 3A222 390 6453J 109 JKKKA 403 4J9T5 21 K7A5K 486 6TT34 793 3479Q 60 44624 443 6KK3K 164 4447J 112 QQ27Q 452 JAK65 522 Q5Q5Q 354 J5Q6A 540 68999 711 3QJ4Q 155 A6AAA 314 222KK 767 55T9A 373 T5T57 913 TTTTA 794 8J258 190 3Q87J 489 AAQAQ 950 Q4JJ4 588 6T64T 9 636K5 228 AA222 248 7KJ35 616 26646 507 44A4J 829 23323 904 TA265 135 JJQT9 136 KATJ8 644 J2862 713 4JQ28 152 Q3K2T 56 6Q232 812 9A622 885 KJKKJ 773 3859T 374 99333 101 TKTTK 205 3333A 35 5A4AQ 548 T4944 967 43353 813 423JK 869 T99T7 219 3AAAA 394 T65Q6 740 J9243 352 6656J 496 444K4 574 Q8T6K 98 AQ55K 917 7QQJ7 605 TJ5TT 615 68JQ5 852 7A3J2 745 369AK 217 57755 343 A8844 61 Q76QQ 698 36333 774 237Q7 12 KT694 283 88286 154 4T552 990 Q9J54 759 K6697 350 A3A33 937 AA9AA 246 QQ7KK 748 TT4A6 380 4J992 845 A66AA 573 5QQ2Q 28 86J37 214 2A443 362 Q9QKK 654 44434 964 77773 74 44355 235 9QK75 863 3AJ33 766 T2TJT 53 44494 860 883A9 309 QQ59Q 360 A88A8 584 A83A4 395 7J9TA 299 55955 833 QJK35 188 4656A 514 8KTQ4 554 56J47 985 J272J 184 9J999 671 72295 31 53555 264 4A537 750 7A4JJ 875 QK834 463 88KKA 570 QQ9JK 906 6Q646 858 53336 359 QJ8QJ 587 424TJ 607 KTKK6 285 Q5AQQ 84 899A8 542 K8TKK 250 4JA4A 705 6J75J 896 888K8 312 5583J 660 6T335 614 Q757T 945 3AKKA 629 KK946 825 3393Q 406 7J288 367 49999 907 99729 837 66265 384 K47JQ 263 2AJ4K 566 TTKKA 186 8J877 418 56844 666 JTTTT 531 6TJ94 26 JQ5J5 344 7J772 85 33747 510 KJA2A 729 333TQ 578 JQAT4 955 75766 834 QQ6QQ 980 32K33 306 TTTJ6 231 2QTTT 213 999AQ 608 33353 202 Q8Q8Q 756 KK555 490 746K8 691 98A75 853 JQ858 816 KK9KK 536 9T999 933 TA8A8 39 8558J 919 J8KQK 15 73Q2K 503 2K2KJ 585 JK9K5 903 TJ7T7 545 J723T 453 KT895 583 TTTKT 123 39535 393 K4K88 893 43KK6 821 6AA8J 504 972TA 597 7J736 592 536A8 63 J23Q3 402 83K9Q 405 28337 396 9T558 776 7AA78 946 QTT24 441 26QT3 401 AJQAQ 953 6T6AJ 304 JK5KK 162 2JJ2J 484 73773 6 8J864 630 78782 557 6TJ52 424 487JQ 830 8J698 82 AJAAA 866 228J8 204 622J4 823 6J2QJ 79 22K22 232 A86A6 444 83K8Q 965 JK586 944 JA848 465 8888A 45 2T28T 803 73J73 450 27272 857 7A777 544 A998J 679 46466 458 KJ233 192 4453J 378 TQQJT 451 A3K5J 512 888Q6 968 6AA66 841 QQ222 883 3K5A3 233 JA4AA 379 62288 778 44456 51 4A644 862 55647 981 A77A7 327 KQ3A3 687 QQ7Q7 976 T4A2T 293 46226 628 Q59Q5 348 36AJ2 984 54433 532 JJQ24 831 7455J 381 78845 218 72AQ5 276 52T22 618 99399 68 36AA3 118 69669 839 33Q5J 785 TJ766 626 T28J4 556 T883Q 142 73928 932 TJ884 494 AJ36Q 485 9Q999 324 T725Q 267 22622 88 92364 685 97792 789 J673K 620 99943 625 77JJ7 921 8828Q 572 7777J 353 TAAJT 926 99T29 787 AQ4J4 520 9J559 5 J3T94 706 K9KK9 918 KK252 439 79925 97 TT47T 497 848T4 126 6TTT6 426 K8825 925 888J8 62 K5K85 972 AAKKA 449 J5555 663 89J99 27 4Q444 922 A9A99 397 5A555 163 8J3K8 662 29989 645 95222 751 Q4Q4Q 193 555K5 982 74AJ8 735 KKQ6K 668 7676Q 916 A28T7 784 K57KK 388 A4J4J 115 2K442 229 33TT3 956 TT6TA 741 TT782 131 TJ5JQ 238 TQ7T7 415 29KQQ 598 A8AAT 676 46A28 650 6698K 696 6J969 158 6694A 271 QTQ5T 498 Q2QQQ 613 2A7QJ 210 6T466 683 QJ575 799 Q63Q3 822 Q9J28 848 TTTT7 7 KA9AA 854 K2JJT 859 28228 179 K29KJ 429 JJ8JJ 222 A99A5 457 QQTTT 983 43KK2 134 984JJ 1 97J97 892 2AAA8 689 9Q77J 819 98TJK 517 56KA5 71 7J66J 294 55855 335 TTT8T 596 33663 407 7J774 911 3JQ55 564 QQQ7Q 329 85668 120 KK333 301 Q3553 867 7K557 988 Q8488 400 96J99 643 29224 714 T8ATA 346 99J93 462 K83J3 697 3KQJ4 653 5KJQ2 824 4JJ3A 897 56248 727 JJ666 702 355T5 245 45KAK 553 88AAA 236 K55J5 581 AJJ49 65 A8Q3J 197 AAAKQ 529 55976 707 77776 930 A9995 227 K7J7K 912 29K99 244 4Q464 80 22972 195 666JQ 189 26278 241 79288 601 5454A 427 JTAKQ 138 88833 549 84J54 215 AATAK 114 58959 145 8ATTJ 431 QJ26K 265 A3JA3 81 T8T4J 242 4T3A3 37 44777 871 JQ542 561 A97Q9 693 A76T4 412 28T4A 481 T485A 861 78286 303 K6776 52 T8TKQ 754 KJ938 957 Q444Q 840 25A89 455 58588 673 K8858 634 K8KJ8 170 K6KKK 851 53353 140 2T2K6 593 QQAQA 48 TT6J6 305 922J2 920 AA22K 22 J555Q 725 TTAAT 781 2244J 171 A95K7 436 2J299 651 78AAA 321 2KKK2 690 2J565 649 77J5K 77 T999T 762 J4445 879 J888Q 873 J884J 1000 98898 413 29299 442 QKQ3Q 678 A652A 993 55272 898 KA5K5 664 8KJAQ 147 Q56QJ 734 K77J3 739 J7677 661 T5569 206 2AA2J 757 TJTJT 342 T2TTT 682 88J82 363 9KK78 700 AT4T4 730 86968 736 99995 207 7A3J4 172 8KK87 991 TKKJJ 16 J7532 165 J9888 996 9AJTA 92 43T78 310 93J77 317 J4424 805 43J86 703 952TJ 127 54363 146 8T2J7 435 88848 832 TAAAQ 791 8228T 256 699QT 815 KQQQK 30 T82J3 49 36222 4 AK288 86 6792A 194 2Q22T 667 J3545 270 9QJK4 280 QQ22Q 371 K9247 446 A422A 943 765K3 469 9J5A6 874 4A4QA 775 8Q8Q8 124 T8Q62 850 8Q8Q5 747 6KT88 738 82888 722 3TQQQ 349 2J3TT 539 7TQ59 72 8998T 733 JQJT3 414 82428 589 92856 423 89833 54 79T4A 523 95839 979 TJJT5 936 33839 29 37433 511 TKJ2T 681 JT973 633 Q8Q8J 971 Q5555 440 K8886 24 Q75A4 43 3AQ33 298 T446T 719 577J5 753 KJTKT 167 52528 8 25222 641 QJ2T8 621 A8JQJ 316 7T7A7 772 KQQTQ 141 83734 758 6Q66Q 434 QJ6Q2 638 AAA7A 196 57555 203 4QJQ4 216 82J5Q 763 A73A3 940 46AJQ 559 T4936 103 89Q29 262 7872T 466 A5J58 274 AAAQA 290 37399 844 A759Q 328 TJ9TT 273 77887 268 64A2J 978 6T76Q 110 QQ467 742 9J7Q5 422 4K6Q3 91 336K3 826 6K63Q 382 23552 105 243AA 505 Q887J 764 2J92A 749 68A3Q 416 7T8T8 199 225J5 404 24774 153 T7T77 870 3J393 347 Q5Q8J 128 7Q777 796 QKKKK 617 86686 108 44KT4 75 56858 622 5AJK4 960 3245Q 311 36536 370 6644Q 11 JKAAA 104 T2426 579 J3399 83 33933 602 A299J 777 26J22 224 8666J 594 J3J38 669 3AJ84 239 52Q8T 877 QJQQK 779 QJ6T8 797 43339 399 9AJ74 476 T499Q 13 2TAKA 928 T3K78 809 2923K 201 J8858 798 T8888 818 98399 168 8T266 555 23A57 652 3KKK3 113 22T22 460 AJJAA 106 7QKA8 464 QQ8TQ 368 99A99 341 62Q5A 223 J9T47 568 Q7388 894 69662 744 96J2T 323 2A779 89 Q2874 269 77797 948 5359A 864 AJ9K4 482 Q3Q44 567 JT958 665 A38J3 438 J4666 296 428J5 501 38K8K 410 6T979 709 3533T 284 2285A 910 933T6 882 K6666 786 56Q32 992 5J752 198 AJJQJ 600 KK5KK 3 38T94 180 67QTJ 69 J6636 200 229J8 493 QJTQ3 247 5KQ5K 149 654AT 528 T84T4 878 Q23QQ 905 QQQ74 325 4JTQQ 408 T4T78 340 3T5T5 551 3J3J3 391 88844 631 TTT9T 810 57775 935 A777J 604 4555T 2 A5J8T 942 22AJJ 506 22323 997 A3323 624 84442 516 2T992 76 J7T76 828 J8552 995 KTKK3 886 33853 782 53233 129 44J4J 372 KQQT2 480 K5649 576 3J63K 760 2J666 827 6JT68 318 45Q64 849 49884 801 9KTTK 902 66737 952 5Q8J4 708 57Q92 724 627J7 331 K22J6 473 4T444 923 J4444 552 78J8J 491 4K328 477 4AA3A 808 7A34Q 437 AQ888 428 8TA99 768 AA9A9 143 9K5AT 211 77722 40 TQTTT 941 Q2A4K 492 236T9 677 J8686 746 J585K 64 TJKQT 582 T3TTJ 157 22266 38 KT5TK 692 QJQQJ 908 4K623 279 7JJJ7 173 64A66 524 J7AJ8 417 K43Q3 769 T662T 148 54J2J 488 K6485 44 J6666 970 J26J9 209 8337Q 334 A27A4 319 A7T78 132 K777A 842 KKK4K 249 99K9K 430 8745K 151 Q2QTJ 433 QKQ76 525 25Q2Q 533 5QK6J 800 77T77 558 5K323 939 33KK4 590 K8A52 111 ATQJ6 569 ATK89 50 4433A 836 3KKKQ 891 46TK4 538 5249Q 447 2462K 675 8JT6T 336 466J7 459 7K7KK 838 544Q4 959 58773 483 823J5 999 2TKA5 752 AKJ58 386 7T833 99 KQ88Q 659 KJ3A4 790 K9595 307 3K3J4 534 3838T 220 32522 720 366Q3 500 J8868 989 T7KTK 376 JQQQA 14 42555 409 5T5T5 648 4KK4Q 383 K7777 884 736A3 543 343Q3 366 TJ856 237 JJ555 46 K5QQQ 275 QAQQ7 672 8KTJQ 731 QQQ3Q 47 J257Q 575 6Q3QQ 87 QKK43 924 TTATJ 998 K44K5 771 37895 881 48823 521 KKK74 456 99J79 139 J4542 635 AJ96K 954 K8937 411 5J355 895 96967 185 333T3 562 TAJ77 755 J38A8 487 AAT79 313 A6Q73 398 386JA 10 J35Q8 623 27758 969 3K3KJ 966 7928Q 627 AAA4A 59 2AA52 478 848J8 133 55225 843 TTQT9 619 3Q79K 255 27AK8 58 TKTKK 272 KTTAT 333 55666 802 47748 454 Q3T56 699 63T3T 302 8754Q 723 4J86T 358 8TTQ9 226 5523J 125 88588 606 58AAA 208 TK273 137 4Q7KQ 160 29292 577 Q333Q 611 22TT2 716 A55AA 258 64822 468 22228 847 2242T 788 JA26Q 472 8JAAA 174 K5Q8A 175 Q5AT4 732 J4434 530 76666 337 9998Q 547 9T2J9 100 3Q982 90 7727Q 281 92944 973 K2597 814 K444K 36 26KJ6 292 34K38 962 5A378 225 636J9 375 TTTT4 420 A66TA 461 69QK5 345 76293 479 66966 804 A3383 297 T82TT 657 2QJJQ 156 K2JK3 94 K6K66 252 K58QJ 876 6J979 513 92647 718 QQ9Q9 586 862Q5 20 5465K 915 KQ44Q 595 T66T6 288 TJT7T 710 5JT8K 159 KJTK3 603 KKJTQ 949 67776 914 J4323 177 22229 704 96999 178 8AJKA 70 69T69 419 65556 770 87738 537 547J4 835 44766 421 3355J 684 2K266 647 5TTT5 266 3T3TT 332 88JJ8 96 QQ5K3 887 K7JKK 377 J8Q2Q 66 2KKJ6 230 TTKQT 277 22Q92 18 JTTTK 695 J993Q 846 88898 728 88T87 715 Q74J4 872 4T999 951 T997Q 289 92QA9 726 AJ394 900 TT2T2 518 JJJJJ 565") (define cards `((#:A . ,(make-card #:A 13)) (#:K . ,(make-card #:K 12)) (#:Q . ,(make-card #:Q 11)) (#:J . ,(make-card #:J 10)) (#:T . ,(make-card #:T 9)) (#:9 . ,(make-card #:9 8)) (#:8 . ,(make-card #:8 7)) (#:7 . ,(make-card #:7 6)) (#:6 . ,(make-card #:6 5)) (#:5 . ,(make-card #:5 4)) (#:4 . ,(make-card #:4 3)) (#:3 . ,(make-card #:3 2)) (#:2 . ,(make-card #:2 1)))) (define (calc-card-frequencies cardlist #!optional (frequencies '())) (if (eqv? '() cardlist) (sort (map cdr frequencies) >) (let* ((card-label (card-label (car cardlist))) (card-old-frequency (alist-ref card-label frequencies eqv? 0))) (calc-card-frequencies (cdr cardlist) (alist-update card-label (+ 1 card-old-frequency) frequencies))))) (define (calc-hand-type hand) (let ((frequencies (calc-card-frequencies (hand-cards hand)))) (cond ;; Insert the comparisons from below here ((= 5 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:five-of-a-kind hand-types))) ((= 4 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:four-of-a-kind hand-types))) ((and (= 3 (car frequencies)) (= 2 (cadr frequencies))) (hand-type-rec-set! hand (alist-ref #:full-house hand-types))) ((= 3 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:three-of-a-kind hand-types))) ((and (= 2 (car frequencies)) (= 2 (cadr frequencies))) (hand-type-rec-set! hand (alist-ref #:two-pair hand-types))) ((= 2 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:one-pair hand-types))) ((= 1 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:high-card hand-types))))) hand) (define hand-types `((#:five-of-a-kind . ,(make-hand-type #:five-of-a-kind 7)) (#:four-of-a-kind . ,(make-hand-type #:four-of-a-kind 6)) (#:full-house . ,(make-hand-type #:full-house 5)) (#:three-of-a-kind . ,(make-hand-type #:three-of-a-kind 4)) (#:two-pair . ,(make-hand-type #:two-pair 3)) (#:one-pair . ,(make-hand-type #:one-pair 2)) (#:high-card . ,(make-hand-type #:high-card 1)))) (define (card> card-a card-b) (> (card-weight card-a) (card-weight card-b))) (define (hand-cards> cards-a cards-b) (or (card> (car cards-a) (car cards-b)) (and (< 1 (length cards-a)) (= (card-weight (car cards-a)) (card-weight (car cards-b))) (hand-cards> (cdr cards-a) (cdr cards-b))))) (define (hands> hand-a hand-b) (let ((type-weight-a (hand-type-weight (hand-type-rec hand-a))) (type-weight-b (hand-type-weight (hand-type-rec hand-b))) (cards-a (hand-cards hand-a)) (cards-b (hand-cards hand-b))) (or (> type-weight-a type-weight-b) (and (= type-weight-a type-weight-b) (hand-cards> cards-a cards-b))))) (define camel-card-irregex '(: (submatch-named cards (+ (or (/ #\A #\Z) (/ #\0 #\9)))) " " (submatch-named bid (+ (/ #\0 #\9))))) (define (cardstr->cards cardstr) (map (compose (cut alist-ref <> cards) string->keyword string) (string->list cardstr))) (define (input->hands input) (irregex-fold camel-card-irregex (lambda (from-index match seed) (let ((cardstr (irregex-match-substring match 'cards)) (bidstr (irregex-match-substring match 'bid))) (cons (make-hand (cardstr->cards cardstr) (string->number bidstr) #f #f) seed))) '() input)) (define (rank-hands sorted-hands #!optional (index 1)) (when (not (eqv? '() sorted-hands)) (hand-rank-set! (car sorted-hands) index) (rank-hands (cdr sorted-hands) (+ index 1)))) (define (total-winnings hands) (foldl (lambda (total hand) (let ((bid (hand-bid hand)) (rank (hand-rank hand))) (+ total (* bid rank)))) 0 hands)) (define (calc-part-1) (let ((hands (input->hands input))) (map calc-hand-type hands) (rank-hands (reverse (sort hands hands>))) (total-winnings hands))) #+end_src #+results: : 251216224 ** Part Two *** Quest To make things a little more interesting, the Elf introduces one additional rule. Now, =J= cards are [[https://en.wikipedia.org/wiki/Joker_(playing_card)][jokers]] - wildcards that can act like whatever card would make the hand the strongest type possible. To balance this, *=J cards are now the weakest* individual cards, weaker even than =2=. The other cards stay in the same order: =A=, =K=, =Q=, =T=, =9=, =8=, =7=, =6=, =5=, =4=, =3=, =2=, =J=. #+name: day7-part2-cards #+begin_src scheme (define p2-cards `((#:A . ,(make-card #:A 13)) (#:K . ,(make-card #:K 12)) (#:Q . ,(make-card #:Q 11)) (#:T . ,(make-card #:T 10)) (#:9 . ,(make-card #:9 9)) (#:8 . ,(make-card #:8 8)) (#:7 . ,(make-card #:7 7)) (#:6 . ,(make-card #:6 6)) (#:5 . ,(make-card #:5 5)) (#:4 . ,(make-card #:4 4)) (#:3 . ,(make-card #:3 3)) (#:2 . ,(make-card #:2 2)) (#:J . ,(make-card #:J 1)))) #+end_src /In addition, the ~cardstr->cards~ and, subsequently, ~input->hands~ functions have to be adjusted to use this new list./ #+name: day7-part2-data-extraction #+begin_src scheme (define (p2-cardstr->cards cardstr) (map (compose (cut alist-ref <> p2-cards) string->keyword string) (string->list cardstr))) (define (p2-input->hands input) (irregex-fold camel-card-irregex (lambda (from-index match seed) (let ((cardstr (irregex-match-substring match 'cards)) (bidstr (irregex-match-substring match 'bid))) (cons (make-hand (p2-cardstr->cards cardstr) (string->number bidstr) #f #f) seed))) '() input)) #+end_src =J= cards can pretend to be whatever card is best for the purpose of determining hand type; for example, =QJJQ2= is now considered *four of a kind*. However, for the purpose of breaking ties between two hands of the same type, =J= is always treated as =J=, not the card it's pretending to be: =JKKK2= is weaker than =QQQQ2= because =J= is weaker than =Q=. #+name: day7-part2-types #+begin_src scheme (define (add-joker frequencies joker-freq) (let* ((joker-account joker-freq) (new-freqs (map (lambda (freq) (cond ((eqv? #:J (car freq)) freq) ((< 5 (+ joker-account (cdr freq))) (set! joker-account (- 5 (cdr freq))) (cons (car freq) 5)) (else (let ((newval (+ joker-account (cdr freq)))) (set! joker-account 0) (cons (car freq) newval))))) frequencies))) (alist-update #:J joker-account new-freqs))) (define (p2-calc-card-frequencies cardlist #!optional (frequencies '())) (if (eqv? '() cardlist) (let* ((joker-freq (alist-ref #:J frequencies eqv? 0)) (new-freqs (add-joker (sort frequencies (lambda (x y) (> (cdr x) (cdr y)))) joker-freq))) (sort (map cdr new-freqs) >)) (let* ((card-label (card-label (car cardlist))) (card-old-frequency (alist-ref card-label frequencies eqv? 0))) (p2-calc-card-frequencies (cdr cardlist) (alist-update card-label (+ 1 card-old-frequency) frequencies))))) (define (p2-calc-hand-type hand) (let ((frequencies (p2-calc-card-frequencies (hand-cards hand)))) (cond ;; Insert the comparisons from part 1 here )) hand) #+end_src Now, the above example goes very differently: #+begin_example 32T3K 765 T55J5 684 KK677 28 KTJJT 220 QQQJA 483 #+end_example - =32T3K= is still the only *one pair*; it doesn't contain any jokers, so its strength doesn't increase. - =KK677= is now the only *two pair*, making it the second-weakest hand. - =T55J5=, =KTJJT=, and =QQQJA= are now all *four of a kind*! =T55J5= gets rank 3, =QQQJA= gets rank 4, and =KTJJT= gets rank 5. /We again take the Reddit example from above, since it covers corner cases./ #+begin_src scheme (let ((hands (p2-input->hands input))) (map p2-calc-hand-type hands) (rank-hands (reverse (sort hands hands>))) (append '(("Cards" "Hand Type" "Rank" "Bid" "Bid*Rank")) (map (lambda (hand) (let ((card-labels (map card-label (hand-cards hand))) (hand-rank (hand-rank hand)) (hand-bid (hand-bid hand)) (hand-type (hand-type-label (hand-type-rec hand)))) (list (apply string-append (map keyword->string card-labels)) hand-type hand-rank hand-bid (* hand-bid hand-rank)))) (sort hands hands>)) `(("Total" "" "" "" ,(total-winnings hands))))) #+end_src #+results: | Cards | Hand Type | Rank | Bid | Bid*Rank | | AAAAA | five-of-a-kind | 19 | 61 | 1159 | | AAAAJ | five-of-a-kind | 18 | 59 | 1062 | | 2JJJJ | five-of-a-kind | 17 | 53 | 901 | | JAAAA | five-of-a-kind | 16 | 43 | 688 | | JJJJ2 | five-of-a-kind | 15 | 41 | 615 | | JJJJJ | five-of-a-kind | 14 | 37 | 518 | | KTJJT | four-of-a-kind | 13 | 34 | 442 | | QQQJA | four-of-a-kind | 12 | 31 | 372 | | T55J5 | four-of-a-kind | 11 | 29 | 319 | | 2AAAA | four-of-a-kind | 10 | 23 | 230 | | Q2Q2Q | full-house | 9 | 19 | 171 | | T3T3J | full-house | 8 | 17 | 136 | | Q2KJJ | three-of-a-kind | 7 | 13 | 91 | | T3Q33 | three-of-a-kind | 6 | 11 | 66 | | KK677 | two-pair | 5 | 7 | 35 | | 32T3K | one-pair | 4 | 5 | 20 | | 2345J | one-pair | 3 | 3 | 9 | | J345A | one-pair | 2 | 2 | 4 | | 2345A | high-card | 1 | 1 | 1 | | Total | | | | 6839 | With the new joker rule, the total winnings in this example are *=5905=*. Using the new joker rule, find the rank of every hand in your set. *What are the new total winnings?* #+name: day7-part2-calc-fn #+begin_src scheme (import (chicken string) (chicken keyword) (chicken sort) (chicken irregex)) (define-record card label weight) (define-record hand cards bid type-rec rank) (define-record hand-type label weight) (define input " 3Q373 470 K53JT 351 A9JK9 856 2T333 515 867T4 541 58K22 253 5JA6J 994 K4A4K 865 94377 519 92J2Q 901 J7676 389 2KK36 938 JQ2KK 987 Q7A82 509 TTTA5 243 72J27 502 AKKKA 387 23222 674 55335 161 AA655 73 QKKQA 686 5J2T5 680 666AT 385 ATA3A 761 TTT8J 364 98A2T 282 59A44 260 6T9QJ 130 T7TKQ 721 9274T 656 T9AJ4 182 A2222 259 TQKJ7 67 4J844 560 AAATA 636 9J36J 546 QJQQQ 119 249TT 295 877J7 221 4KA23 116 929Q2 929 99JQQ 445 Q9QJ8 432 4Q7TJ 963 4J2J8 783 5J657 257 88788 183 KKK7K 909 KK396 637 J45AT 117 84448 806 A2698 820 A9AA5 320 A3934 19 Q45Q5 392 78686 254 A55A5 701 98A4K 655 5AJ88 95 AK3KK 55 773KK 33 J9J9J 356 2KAKK 563 655K5 287 55T56 475 54444 308 5J5QA 811 QKA76 792 2K288 42 JTKA2 694 88668 889 8TQ64 212 23QQ2 261 8K8K5 365 JKKAA 234 3J894 880 667Q2 817 888T4 599 T5Q83 315 3QK29 670 JK4KK 322 75T8T 144 AAA7K 291 7T333 495 A49K4 448 JJ3J3 251 5999J 278 38438 890 6K3Q9 122 TTT99 93 94775 240 K8QJ3 369 59674 107 267J4 355 QTQTQ 187 46J44 961 Q7AK2 580 69969 609 876A5 474 A3866 642 Q3QQA 526 JAA88 425 35Q9K 986 QQTQJ 550 54535 357 2J222 639 QK5J7 743 222Q2 191 T4T44 855 QTQQ2 338 JA7A2 300 AAAJ2 508 4J455 23 A77AA 339 5KK25 899 252J2 737 7QJ76 888 K46QK 795 A4T3J 640 8A8K8 176 AA5AA 41 J2Q24 958 58855 632 333J3 610 74474 807 K3AAA 78 JJ222 765 44224 688 76733 361 5845K 181 TT4T2 974 23J33 102 QQJ6Q 34 Q9AQQ 150 22747 717 KAA5A 121 7AA7J 286 J786T 780 3K8TT 32 A6KAA 25 9A362 166 A29Q2 499 6688K 57 KKQKA 947 999JJ 975 6A666 927 TTT3K 658 JQQ7T 467 8A247 934 7JK8J 712 KK39K 612 6666Q 17 77Q37 868 A66AJ 169 KKKKJ 535 7Q7JJ 591 K9848 646 46888 931 A86A8 326 743TA 527 QKK67 977 KKJ6K 471 AAJ7A 571 55292 330 3A222 390 6453J 109 JKKKA 403 4J9T5 21 K7A5K 486 6TT34 793 3479Q 60 44624 443 6KK3K 164 4447J 112 QQ27Q 452 JAK65 522 Q5Q5Q 354 J5Q6A 540 68999 711 3QJ4Q 155 A6AAA 314 222KK 767 55T9A 373 T5T57 913 TTTTA 794 8J258 190 3Q87J 489 AAQAQ 950 Q4JJ4 588 6T64T 9 636K5 228 AA222 248 7KJ35 616 26646 507 44A4J 829 23323 904 TA265 135 JJQT9 136 KATJ8 644 J2862 713 4JQ28 152 Q3K2T 56 6Q232 812 9A622 885 KJKKJ 773 3859T 374 99333 101 TKTTK 205 3333A 35 5A4AQ 548 T4944 967 43353 813 423JK 869 T99T7 219 3AAAA 394 T65Q6 740 J9243 352 6656J 496 444K4 574 Q8T6K 98 AQ55K 917 7QQJ7 605 TJ5TT 615 68JQ5 852 7A3J2 745 369AK 217 57755 343 A8844 61 Q76QQ 698 36333 774 237Q7 12 KT694 283 88286 154 4T552 990 Q9J54 759 K6697 350 A3A33 937 AA9AA 246 QQ7KK 748 TT4A6 380 4J992 845 A66AA 573 5QQ2Q 28 86J37 214 2A443 362 Q9QKK 654 44434 964 77773 74 44355 235 9QK75 863 3AJ33 766 T2TJT 53 44494 860 883A9 309 QQ59Q 360 A88A8 584 A83A4 395 7J9TA 299 55955 833 QJK35 188 4656A 514 8KTQ4 554 56J47 985 J272J 184 9J999 671 72295 31 53555 264 4A537 750 7A4JJ 875 QK834 463 88KKA 570 QQ9JK 906 6Q646 858 53336 359 QJ8QJ 587 424TJ 607 KTKK6 285 Q5AQQ 84 899A8 542 K8TKK 250 4JA4A 705 6J75J 896 888K8 312 5583J 660 6T335 614 Q757T 945 3AKKA 629 KK946 825 3393Q 406 7J288 367 49999 907 99729 837 66265 384 K47JQ 263 2AJ4K 566 TTKKA 186 8J877 418 56844 666 JTTTT 531 6TJ94 26 JQ5J5 344 7J772 85 33747 510 KJA2A 729 333TQ 578 JQAT4 955 75766 834 QQ6QQ 980 32K33 306 TTTJ6 231 2QTTT 213 999AQ 608 33353 202 Q8Q8Q 756 KK555 490 746K8 691 98A75 853 JQ858 816 KK9KK 536 9T999 933 TA8A8 39 8558J 919 J8KQK 15 73Q2K 503 2K2KJ 585 JK9K5 903 TJ7T7 545 J723T 453 KT895 583 TTTKT 123 39535 393 K4K88 893 43KK6 821 6AA8J 504 972TA 597 7J736 592 536A8 63 J23Q3 402 83K9Q 405 28337 396 9T558 776 7AA78 946 QTT24 441 26QT3 401 AJQAQ 953 6T6AJ 304 JK5KK 162 2JJ2J 484 73773 6 8J864 630 78782 557 6TJ52 424 487JQ 830 8J698 82 AJAAA 866 228J8 204 622J4 823 6J2QJ 79 22K22 232 A86A6 444 83K8Q 965 JK586 944 JA848 465 8888A 45 2T28T 803 73J73 450 27272 857 7A777 544 A998J 679 46466 458 KJ233 192 4453J 378 TQQJT 451 A3K5J 512 888Q6 968 6AA66 841 QQ222 883 3K5A3 233 JA4AA 379 62288 778 44456 51 4A644 862 55647 981 A77A7 327 KQ3A3 687 QQ7Q7 976 T4A2T 293 46226 628 Q59Q5 348 36AJ2 984 54433 532 JJQ24 831 7455J 381 78845 218 72AQ5 276 52T22 618 99399 68 36AA3 118 69669 839 33Q5J 785 TJ766 626 T28J4 556 T883Q 142 73928 932 TJ884 494 AJ36Q 485 9Q999 324 T725Q 267 22622 88 92364 685 97792 789 J673K 620 99943 625 77JJ7 921 8828Q 572 7777J 353 TAAJT 926 99T29 787 AQ4J4 520 9J559 5 J3T94 706 K9KK9 918 KK252 439 79925 97 TT47T 497 848T4 126 6TTT6 426 K8825 925 888J8 62 K5K85 972 AAKKA 449 J5555 663 89J99 27 4Q444 922 A9A99 397 5A555 163 8J3K8 662 29989 645 95222 751 Q4Q4Q 193 555K5 982 74AJ8 735 KKQ6K 668 7676Q 916 A28T7 784 K57KK 388 A4J4J 115 2K442 229 33TT3 956 TT6TA 741 TT782 131 TJ5JQ 238 TQ7T7 415 29KQQ 598 A8AAT 676 46A28 650 6698K 696 6J969 158 6694A 271 QTQ5T 498 Q2QQQ 613 2A7QJ 210 6T466 683 QJ575 799 Q63Q3 822 Q9J28 848 TTTT7 7 KA9AA 854 K2JJT 859 28228 179 K29KJ 429 JJ8JJ 222 A99A5 457 QQTTT 983 43KK2 134 984JJ 1 97J97 892 2AAA8 689 9Q77J 819 98TJK 517 56KA5 71 7J66J 294 55855 335 TTT8T 596 33663 407 7J774 911 3JQ55 564 QQQ7Q 329 85668 120 KK333 301 Q3553 867 7K557 988 Q8488 400 96J99 643 29224 714 T8ATA 346 99J93 462 K83J3 697 3KQJ4 653 5KJQ2 824 4JJ3A 897 56248 727 JJ666 702 355T5 245 45KAK 553 88AAA 236 K55J5 581 AJJ49 65 A8Q3J 197 AAAKQ 529 55976 707 77776 930 A9995 227 K7J7K 912 29K99 244 4Q464 80 22972 195 666JQ 189 26278 241 79288 601 5454A 427 JTAKQ 138 88833 549 84J54 215 AATAK 114 58959 145 8ATTJ 431 QJ26K 265 A3JA3 81 T8T4J 242 4T3A3 37 44777 871 JQ542 561 A97Q9 693 A76T4 412 28T4A 481 T485A 861 78286 303 K6776 52 T8TKQ 754 KJ938 957 Q444Q 840 25A89 455 58588 673 K8858 634 K8KJ8 170 K6KKK 851 53353 140 2T2K6 593 QQAQA 48 TT6J6 305 922J2 920 AA22K 22 J555Q 725 TTAAT 781 2244J 171 A95K7 436 2J299 651 78AAA 321 2KKK2 690 2J565 649 77J5K 77 T999T 762 J4445 879 J888Q 873 J884J 1000 98898 413 29299 442 QKQ3Q 678 A652A 993 55272 898 KA5K5 664 8KJAQ 147 Q56QJ 734 K77J3 739 J7677 661 T5569 206 2AA2J 757 TJTJT 342 T2TTT 682 88J82 363 9KK78 700 AT4T4 730 86968 736 99995 207 7A3J4 172 8KK87 991 TKKJJ 16 J7532 165 J9888 996 9AJTA 92 43T78 310 93J77 317 J4424 805 43J86 703 952TJ 127 54363 146 8T2J7 435 88848 832 TAAAQ 791 8228T 256 699QT 815 KQQQK 30 T82J3 49 36222 4 AK288 86 6792A 194 2Q22T 667 J3545 270 9QJK4 280 QQ22Q 371 K9247 446 A422A 943 765K3 469 9J5A6 874 4A4QA 775 8Q8Q8 124 T8Q62 850 8Q8Q5 747 6KT88 738 82888 722 3TQQQ 349 2J3TT 539 7TQ59 72 8998T 733 JQJT3 414 82428 589 92856 423 89833 54 79T4A 523 95839 979 TJJT5 936 33839 29 37433 511 TKJ2T 681 JT973 633 Q8Q8J 971 Q5555 440 K8886 24 Q75A4 43 3AQ33 298 T446T 719 577J5 753 KJTKT 167 52528 8 25222 641 QJ2T8 621 A8JQJ 316 7T7A7 772 KQQTQ 141 83734 758 6Q66Q 434 QJ6Q2 638 AAA7A 196 57555 203 4QJQ4 216 82J5Q 763 A73A3 940 46AJQ 559 T4936 103 89Q29 262 7872T 466 A5J58 274 AAAQA 290 37399 844 A759Q 328 TJ9TT 273 77887 268 64A2J 978 6T76Q 110 QQ467 742 9J7Q5 422 4K6Q3 91 336K3 826 6K63Q 382 23552 105 243AA 505 Q887J 764 2J92A 749 68A3Q 416 7T8T8 199 225J5 404 24774 153 T7T77 870 3J393 347 Q5Q8J 128 7Q777 796 QKKKK 617 86686 108 44KT4 75 56858 622 5AJK4 960 3245Q 311 36536 370 6644Q 11 JKAAA 104 T2426 579 J3399 83 33933 602 A299J 777 26J22 224 8666J 594 J3J38 669 3AJ84 239 52Q8T 877 QJQQK 779 QJ6T8 797 43339 399 9AJ74 476 T499Q 13 2TAKA 928 T3K78 809 2923K 201 J8858 798 T8888 818 98399 168 8T266 555 23A57 652 3KKK3 113 22T22 460 AJJAA 106 7QKA8 464 QQ8TQ 368 99A99 341 62Q5A 223 J9T47 568 Q7388 894 69662 744 96J2T 323 2A779 89 Q2874 269 77797 948 5359A 864 AJ9K4 482 Q3Q44 567 JT958 665 A38J3 438 J4666 296 428J5 501 38K8K 410 6T979 709 3533T 284 2285A 910 933T6 882 K6666 786 56Q32 992 5J752 198 AJJQJ 600 KK5KK 3 38T94 180 67QTJ 69 J6636 200 229J8 493 QJTQ3 247 5KQ5K 149 654AT 528 T84T4 878 Q23QQ 905 QQQ74 325 4JTQQ 408 T4T78 340 3T5T5 551 3J3J3 391 88844 631 TTT9T 810 57775 935 A777J 604 4555T 2 A5J8T 942 22AJJ 506 22323 997 A3323 624 84442 516 2T992 76 J7T76 828 J8552 995 KTKK3 886 33853 782 53233 129 44J4J 372 KQQT2 480 K5649 576 3J63K 760 2J666 827 6JT68 318 45Q64 849 49884 801 9KTTK 902 66737 952 5Q8J4 708 57Q92 724 627J7 331 K22J6 473 4T444 923 J4444 552 78J8J 491 4K328 477 4AA3A 808 7A34Q 437 AQ888 428 8TA99 768 AA9A9 143 9K5AT 211 77722 40 TQTTT 941 Q2A4K 492 236T9 677 J8686 746 J585K 64 TJKQT 582 T3TTJ 157 22266 38 KT5TK 692 QJQQJ 908 4K623 279 7JJJ7 173 64A66 524 J7AJ8 417 K43Q3 769 T662T 148 54J2J 488 K6485 44 J6666 970 J26J9 209 8337Q 334 A27A4 319 A7T78 132 K777A 842 KKK4K 249 99K9K 430 8745K 151 Q2QTJ 433 QKQ76 525 25Q2Q 533 5QK6J 800 77T77 558 5K323 939 33KK4 590 K8A52 111 ATQJ6 569 ATK89 50 4433A 836 3KKKQ 891 46TK4 538 5249Q 447 2462K 675 8JT6T 336 466J7 459 7K7KK 838 544Q4 959 58773 483 823J5 999 2TKA5 752 AKJ58 386 7T833 99 KQ88Q 659 KJ3A4 790 K9595 307 3K3J4 534 3838T 220 32522 720 366Q3 500 J8868 989 T7KTK 376 JQQQA 14 42555 409 5T5T5 648 4KK4Q 383 K7777 884 736A3 543 343Q3 366 TJ856 237 JJ555 46 K5QQQ 275 QAQQ7 672 8KTJQ 731 QQQ3Q 47 J257Q 575 6Q3QQ 87 QKK43 924 TTATJ 998 K44K5 771 37895 881 48823 521 KKK74 456 99J79 139 J4542 635 AJ96K 954 K8937 411 5J355 895 96967 185 333T3 562 TAJ77 755 J38A8 487 AAT79 313 A6Q73 398 386JA 10 J35Q8 623 27758 969 3K3KJ 966 7928Q 627 AAA4A 59 2AA52 478 848J8 133 55225 843 TTQT9 619 3Q79K 255 27AK8 58 TKTKK 272 KTTAT 333 55666 802 47748 454 Q3T56 699 63T3T 302 8754Q 723 4J86T 358 8TTQ9 226 5523J 125 88588 606 58AAA 208 TK273 137 4Q7KQ 160 29292 577 Q333Q 611 22TT2 716 A55AA 258 64822 468 22228 847 2242T 788 JA26Q 472 8JAAA 174 K5Q8A 175 Q5AT4 732 J4434 530 76666 337 9998Q 547 9T2J9 100 3Q982 90 7727Q 281 92944 973 K2597 814 K444K 36 26KJ6 292 34K38 962 5A378 225 636J9 375 TTTT4 420 A66TA 461 69QK5 345 76293 479 66966 804 A3383 297 T82TT 657 2QJJQ 156 K2JK3 94 K6K66 252 K58QJ 876 6J979 513 92647 718 QQ9Q9 586 862Q5 20 5465K 915 KQ44Q 595 T66T6 288 TJT7T 710 5JT8K 159 KJTK3 603 KKJTQ 949 67776 914 J4323 177 22229 704 96999 178 8AJKA 70 69T69 419 65556 770 87738 537 547J4 835 44766 421 3355J 684 2K266 647 5TTT5 266 3T3TT 332 88JJ8 96 QQ5K3 887 K7JKK 377 J8Q2Q 66 2KKJ6 230 TTKQT 277 22Q92 18 JTTTK 695 J993Q 846 88898 728 88T87 715 Q74J4 872 4T999 951 T997Q 289 92QA9 726 AJ394 900 TT2T2 518 JJJJJ 565") (define p2-cards `((#:A . ,(make-card #:A 13)) (#:K . ,(make-card #:K 12)) (#:Q . ,(make-card #:Q 11)) (#:T . ,(make-card #:T 10)) (#:9 . ,(make-card #:9 9)) (#:8 . ,(make-card #:8 8)) (#:7 . ,(make-card #:7 7)) (#:6 . ,(make-card #:6 6)) (#:5 . ,(make-card #:5 5)) (#:4 . ,(make-card #:4 4)) (#:3 . ,(make-card #:3 3)) (#:2 . ,(make-card #:2 2)) (#:J . ,(make-card #:J 1)))) (define (add-joker frequencies joker-freq) (let* ((joker-account joker-freq) (new-freqs (map (lambda (freq) (cond ((eqv? #:J (car freq)) freq) ((< 5 (+ joker-account (cdr freq))) (set! joker-account (- 5 (cdr freq))) (cons (car freq) 5)) (else (let ((newval (+ joker-account (cdr freq)))) (set! joker-account 0) (cons (car freq) newval))))) frequencies))) (alist-update #:J joker-account new-freqs))) (define (p2-calc-card-frequencies cardlist #!optional (frequencies '())) (if (eqv? '() cardlist) (let* ((joker-freq (alist-ref #:J frequencies eqv? 0)) (new-freqs (add-joker (sort frequencies (lambda (x y) (> (cdr x) (cdr y)))) joker-freq))) (sort (map cdr new-freqs) >)) (let* ((card-label (card-label (car cardlist))) (card-old-frequency (alist-ref card-label frequencies eqv? 0))) (p2-calc-card-frequencies (cdr cardlist) (alist-update card-label (+ 1 card-old-frequency) frequencies))))) (define (p2-calc-hand-type hand) (let ((frequencies (p2-calc-card-frequencies (hand-cards hand)))) (cond ;; Insert the comparisons from part 1 here ((= 5 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:five-of-a-kind hand-types))) ((= 4 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:four-of-a-kind hand-types))) ((and (= 3 (car frequencies)) (= 2 (cadr frequencies))) (hand-type-rec-set! hand (alist-ref #:full-house hand-types))) ((= 3 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:three-of-a-kind hand-types))) ((and (= 2 (car frequencies)) (= 2 (cadr frequencies))) (hand-type-rec-set! hand (alist-ref #:two-pair hand-types))) ((= 2 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:one-pair hand-types))) ((= 1 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:high-card hand-types))))) hand) (define hand-types `((#:five-of-a-kind . ,(make-hand-type #:five-of-a-kind 7)) (#:four-of-a-kind . ,(make-hand-type #:four-of-a-kind 6)) (#:full-house . ,(make-hand-type #:full-house 5)) (#:three-of-a-kind . ,(make-hand-type #:three-of-a-kind 4)) (#:two-pair . ,(make-hand-type #:two-pair 3)) (#:one-pair . ,(make-hand-type #:one-pair 2)) (#:high-card . ,(make-hand-type #:high-card 1)))) (define (card> card-a card-b) (> (card-weight card-a) (card-weight card-b))) (define (hand-cards> cards-a cards-b) (or (card> (car cards-a) (car cards-b)) (and (< 1 (length cards-a)) (= (card-weight (car cards-a)) (card-weight (car cards-b))) (hand-cards> (cdr cards-a) (cdr cards-b))))) (define (hands> hand-a hand-b) (let ((type-weight-a (hand-type-weight (hand-type-rec hand-a))) (type-weight-b (hand-type-weight (hand-type-rec hand-b))) (cards-a (hand-cards hand-a)) (cards-b (hand-cards hand-b))) (or (> type-weight-a type-weight-b) (and (= type-weight-a type-weight-b) (hand-cards> cards-a cards-b))))) (define camel-card-irregex '(: (submatch-named cards (+ (or (/ #\A #\Z) (/ #\0 #\9)))) " " (submatch-named bid (+ (/ #\0 #\9))))) (define (p2-cardstr->cards cardstr) (map (compose (cut alist-ref <> p2-cards) string->keyword string) (string->list cardstr))) (define (p2-input->hands input) (irregex-fold camel-card-irregex (lambda (from-index match seed) (let ((cardstr (irregex-match-substring match 'cards)) (bidstr (irregex-match-substring match 'bid))) (cons (make-hand (p2-cardstr->cards cardstr) (string->number bidstr) #f #f) seed))) '() input)) (define (rank-hands sorted-hands #!optional (index 1)) (when (not (eqv? '() sorted-hands)) (hand-rank-set! (car sorted-hands) index) (rank-hands (cdr sorted-hands) (+ index 1)))) (define (total-winnings hands) (foldl (lambda (total hand) (let ((bid (hand-bid hand)) (rank (hand-rank hand))) (+ total (* bid rank)))) 0 hands)) (define (calc-part-2) (let ((hands (p2-input->hands input))) (map p2-calc-hand-type hands) (rank-hands (reverse (sort hands hands>))) (total-winnings hands))) #+end_src #+results: : 250825971 ** Thoughts About Today's Puzzle At first, when reading the description, I thought I'd miss not having extensions a lot for today's puzzle. But ultimately, I think it was fine witout. Sure, the code might have been a bit shorter here and there, but that's about it. I also came across the conscious realization about what feels intuitively right, but maybe is not; Scheme is not evaluating code depth-first. Consider the following two examples: #+name: day7-thoughts-a #+begin_src scheme (let ((A '((#:X . 5) (#:Y . 10))) (X-buf 5)) (alist-update #:X X-buf (map (lambda (a) (cond ((eqv? #:X (car a)) a) (else (let ((new-Y X-buf)) (set! X-buf 0) (cons (car a) new-Y))))) A))) #+end_src #+results: day7-thoughts-a #+name: day7-thoughts-b #+begin_src scheme (let* ((A '((#:X . 5) (#:Y . 10))) (X-buf 5) (new-A (map (lambda (a) (cond ((eqv? #:X (car a)) a) (else (let ((new-Y X-buf)) (set! X-buf 0) (cons (car a) new-Y))))) A))) (alist-update #:X X-buf new-A)) #+end_src The first example evaluates as =((#:X . 5) (#:Y . 5))= , because Scheme evaluates left-to-right, and only nested-first as soon as it encounters a list. But would it really be unintuitive if it was depth-first? In that case, the first example would evaluate to the same result as the second: =((#:X . 0) (#:Y . 5))= ** Puzzle Input Jump to [[#headline-83][day 8]]. #+name: day7-input #+begin_src fundamental 3Q373 470 K53JT 351 A9JK9 856 2T333 515 867T4 541 58K22 253 5JA6J 994 K4A4K 865 94377 519 92J2Q 901 J7676 389 2KK36 938 JQ2KK 987 Q7A82 509 TTTA5 243 72J27 502 AKKKA 387 23222 674 55335 161 AA655 73 QKKQA 686 5J2T5 680 666AT 385 ATA3A 761 TTT8J 364 98A2T 282 59A44 260 6T9QJ 130 T7TKQ 721 9274T 656 T9AJ4 182 A2222 259 TQKJ7 67 4J844 560 AAATA 636 9J36J 546 QJQQQ 119 249TT 295 877J7 221 4KA23 116 929Q2 929 99JQQ 445 Q9QJ8 432 4Q7TJ 963 4J2J8 783 5J657 257 88788 183 KKK7K 909 KK396 637 J45AT 117 84448 806 A2698 820 A9AA5 320 A3934 19 Q45Q5 392 78686 254 A55A5 701 98A4K 655 5AJ88 95 AK3KK 55 773KK 33 J9J9J 356 2KAKK 563 655K5 287 55T56 475 54444 308 5J5QA 811 QKA76 792 2K288 42 JTKA2 694 88668 889 8TQ64 212 23QQ2 261 8K8K5 365 JKKAA 234 3J894 880 667Q2 817 888T4 599 T5Q83 315 3QK29 670 JK4KK 322 75T8T 144 AAA7K 291 7T333 495 A49K4 448 JJ3J3 251 5999J 278 38438 890 6K3Q9 122 TTT99 93 94775 240 K8QJ3 369 59674 107 267J4 355 QTQTQ 187 46J44 961 Q7AK2 580 69969 609 876A5 474 A3866 642 Q3QQA 526 JAA88 425 35Q9K 986 QQTQJ 550 54535 357 2J222 639 QK5J7 743 222Q2 191 T4T44 855 QTQQ2 338 JA7A2 300 AAAJ2 508 4J455 23 A77AA 339 5KK25 899 252J2 737 7QJ76 888 K46QK 795 A4T3J 640 8A8K8 176 AA5AA 41 J2Q24 958 58855 632 333J3 610 74474 807 K3AAA 78 JJ222 765 44224 688 76733 361 5845K 181 TT4T2 974 23J33 102 QQJ6Q 34 Q9AQQ 150 22747 717 KAA5A 121 7AA7J 286 J786T 780 3K8TT 32 A6KAA 25 9A362 166 A29Q2 499 6688K 57 KKQKA 947 999JJ 975 6A666 927 TTT3K 658 JQQ7T 467 8A247 934 7JK8J 712 KK39K 612 6666Q 17 77Q37 868 A66AJ 169 KKKKJ 535 7Q7JJ 591 K9848 646 46888 931 A86A8 326 743TA 527 QKK67 977 KKJ6K 471 AAJ7A 571 55292 330 3A222 390 6453J 109 JKKKA 403 4J9T5 21 K7A5K 486 6TT34 793 3479Q 60 44624 443 6KK3K 164 4447J 112 QQ27Q 452 JAK65 522 Q5Q5Q 354 J5Q6A 540 68999 711 3QJ4Q 155 A6AAA 314 222KK 767 55T9A 373 T5T57 913 TTTTA 794 8J258 190 3Q87J 489 AAQAQ 950 Q4JJ4 588 6T64T 9 636K5 228 AA222 248 7KJ35 616 26646 507 44A4J 829 23323 904 TA265 135 JJQT9 136 KATJ8 644 J2862 713 4JQ28 152 Q3K2T 56 6Q232 812 9A622 885 KJKKJ 773 3859T 374 99333 101 TKTTK 205 3333A 35 5A4AQ 548 T4944 967 43353 813 423JK 869 T99T7 219 3AAAA 394 T65Q6 740 J9243 352 6656J 496 444K4 574 Q8T6K 98 AQ55K 917 7QQJ7 605 TJ5TT 615 68JQ5 852 7A3J2 745 369AK 217 57755 343 A8844 61 Q76QQ 698 36333 774 237Q7 12 KT694 283 88286 154 4T552 990 Q9J54 759 K6697 350 A3A33 937 AA9AA 246 QQ7KK 748 TT4A6 380 4J992 845 A66AA 573 5QQ2Q 28 86J37 214 2A443 362 Q9QKK 654 44434 964 77773 74 44355 235 9QK75 863 3AJ33 766 T2TJT 53 44494 860 883A9 309 QQ59Q 360 A88A8 584 A83A4 395 7J9TA 299 55955 833 QJK35 188 4656A 514 8KTQ4 554 56J47 985 J272J 184 9J999 671 72295 31 53555 264 4A537 750 7A4JJ 875 QK834 463 88KKA 570 QQ9JK 906 6Q646 858 53336 359 QJ8QJ 587 424TJ 607 KTKK6 285 Q5AQQ 84 899A8 542 K8TKK 250 4JA4A 705 6J75J 896 888K8 312 5583J 660 6T335 614 Q757T 945 3AKKA 629 KK946 825 3393Q 406 7J288 367 49999 907 99729 837 66265 384 K47JQ 263 2AJ4K 566 TTKKA 186 8J877 418 56844 666 JTTTT 531 6TJ94 26 JQ5J5 344 7J772 85 33747 510 KJA2A 729 333TQ 578 JQAT4 955 75766 834 QQ6QQ 980 32K33 306 TTTJ6 231 2QTTT 213 999AQ 608 33353 202 Q8Q8Q 756 KK555 490 746K8 691 98A75 853 JQ858 816 KK9KK 536 9T999 933 TA8A8 39 8558J 919 J8KQK 15 73Q2K 503 2K2KJ 585 JK9K5 903 TJ7T7 545 J723T 453 KT895 583 TTTKT 123 39535 393 K4K88 893 43KK6 821 6AA8J 504 972TA 597 7J736 592 536A8 63 J23Q3 402 83K9Q 405 28337 396 9T558 776 7AA78 946 QTT24 441 26QT3 401 AJQAQ 953 6T6AJ 304 JK5KK 162 2JJ2J 484 73773 6 8J864 630 78782 557 6TJ52 424 487JQ 830 8J698 82 AJAAA 866 228J8 204 622J4 823 6J2QJ 79 22K22 232 A86A6 444 83K8Q 965 JK586 944 JA848 465 8888A 45 2T28T 803 73J73 450 27272 857 7A777 544 A998J 679 46466 458 KJ233 192 4453J 378 TQQJT 451 A3K5J 512 888Q6 968 6AA66 841 QQ222 883 3K5A3 233 JA4AA 379 62288 778 44456 51 4A644 862 55647 981 A77A7 327 KQ3A3 687 QQ7Q7 976 T4A2T 293 46226 628 Q59Q5 348 36AJ2 984 54433 532 JJQ24 831 7455J 381 78845 218 72AQ5 276 52T22 618 99399 68 36AA3 118 69669 839 33Q5J 785 TJ766 626 T28J4 556 T883Q 142 73928 932 TJ884 494 AJ36Q 485 9Q999 324 T725Q 267 22622 88 92364 685 97792 789 J673K 620 99943 625 77JJ7 921 8828Q 572 7777J 353 TAAJT 926 99T29 787 AQ4J4 520 9J559 5 J3T94 706 K9KK9 918 KK252 439 79925 97 TT47T 497 848T4 126 6TTT6 426 K8825 925 888J8 62 K5K85 972 AAKKA 449 J5555 663 89J99 27 4Q444 922 A9A99 397 5A555 163 8J3K8 662 29989 645 95222 751 Q4Q4Q 193 555K5 982 74AJ8 735 KKQ6K 668 7676Q 916 A28T7 784 K57KK 388 A4J4J 115 2K442 229 33TT3 956 TT6TA 741 TT782 131 TJ5JQ 238 TQ7T7 415 29KQQ 598 A8AAT 676 46A28 650 6698K 696 6J969 158 6694A 271 QTQ5T 498 Q2QQQ 613 2A7QJ 210 6T466 683 QJ575 799 Q63Q3 822 Q9J28 848 TTTT7 7 KA9AA 854 K2JJT 859 28228 179 K29KJ 429 JJ8JJ 222 A99A5 457 QQTTT 983 43KK2 134 984JJ 1 97J97 892 2AAA8 689 9Q77J 819 98TJK 517 56KA5 71 7J66J 294 55855 335 TTT8T 596 33663 407 7J774 911 3JQ55 564 QQQ7Q 329 85668 120 KK333 301 Q3553 867 7K557 988 Q8488 400 96J99 643 29224 714 T8ATA 346 99J93 462 K83J3 697 3KQJ4 653 5KJQ2 824 4JJ3A 897 56248 727 JJ666 702 355T5 245 45KAK 553 88AAA 236 K55J5 581 AJJ49 65 A8Q3J 197 AAAKQ 529 55976 707 77776 930 A9995 227 K7J7K 912 29K99 244 4Q464 80 22972 195 666JQ 189 26278 241 79288 601 5454A 427 JTAKQ 138 88833 549 84J54 215 AATAK 114 58959 145 8ATTJ 431 QJ26K 265 A3JA3 81 T8T4J 242 4T3A3 37 44777 871 JQ542 561 A97Q9 693 A76T4 412 28T4A 481 T485A 861 78286 303 K6776 52 T8TKQ 754 KJ938 957 Q444Q 840 25A89 455 58588 673 K8858 634 K8KJ8 170 K6KKK 851 53353 140 2T2K6 593 QQAQA 48 TT6J6 305 922J2 920 AA22K 22 J555Q 725 TTAAT 781 2244J 171 A95K7 436 2J299 651 78AAA 321 2KKK2 690 2J565 649 77J5K 77 T999T 762 J4445 879 J888Q 873 J884J 1000 98898 413 29299 442 QKQ3Q 678 A652A 993 55272 898 KA5K5 664 8KJAQ 147 Q56QJ 734 K77J3 739 J7677 661 T5569 206 2AA2J 757 TJTJT 342 T2TTT 682 88J82 363 9KK78 700 AT4T4 730 86968 736 99995 207 7A3J4 172 8KK87 991 TKKJJ 16 J7532 165 J9888 996 9AJTA 92 43T78 310 93J77 317 J4424 805 43J86 703 952TJ 127 54363 146 8T2J7 435 88848 832 TAAAQ 791 8228T 256 699QT 815 KQQQK 30 T82J3 49 36222 4 AK288 86 6792A 194 2Q22T 667 J3545 270 9QJK4 280 QQ22Q 371 K9247 446 A422A 943 765K3 469 9J5A6 874 4A4QA 775 8Q8Q8 124 T8Q62 850 8Q8Q5 747 6KT88 738 82888 722 3TQQQ 349 2J3TT 539 7TQ59 72 8998T 733 JQJT3 414 82428 589 92856 423 89833 54 79T4A 523 95839 979 TJJT5 936 33839 29 37433 511 TKJ2T 681 JT973 633 Q8Q8J 971 Q5555 440 K8886 24 Q75A4 43 3AQ33 298 T446T 719 577J5 753 KJTKT 167 52528 8 25222 641 QJ2T8 621 A8JQJ 316 7T7A7 772 KQQTQ 141 83734 758 6Q66Q 434 QJ6Q2 638 AAA7A 196 57555 203 4QJQ4 216 82J5Q 763 A73A3 940 46AJQ 559 T4936 103 89Q29 262 7872T 466 A5J58 274 AAAQA 290 37399 844 A759Q 328 TJ9TT 273 77887 268 64A2J 978 6T76Q 110 QQ467 742 9J7Q5 422 4K6Q3 91 336K3 826 6K63Q 382 23552 105 243AA 505 Q887J 764 2J92A 749 68A3Q 416 7T8T8 199 225J5 404 24774 153 T7T77 870 3J393 347 Q5Q8J 128 7Q777 796 QKKKK 617 86686 108 44KT4 75 56858 622 5AJK4 960 3245Q 311 36536 370 6644Q 11 JKAAA 104 T2426 579 J3399 83 33933 602 A299J 777 26J22 224 8666J 594 J3J38 669 3AJ84 239 52Q8T 877 QJQQK 779 QJ6T8 797 43339 399 9AJ74 476 T499Q 13 2TAKA 928 T3K78 809 2923K 201 J8858 798 T8888 818 98399 168 8T266 555 23A57 652 3KKK3 113 22T22 460 AJJAA 106 7QKA8 464 QQ8TQ 368 99A99 341 62Q5A 223 J9T47 568 Q7388 894 69662 744 96J2T 323 2A779 89 Q2874 269 77797 948 5359A 864 AJ9K4 482 Q3Q44 567 JT958 665 A38J3 438 J4666 296 428J5 501 38K8K 410 6T979 709 3533T 284 2285A 910 933T6 882 K6666 786 56Q32 992 5J752 198 AJJQJ 600 KK5KK 3 38T94 180 67QTJ 69 J6636 200 229J8 493 QJTQ3 247 5KQ5K 149 654AT 528 T84T4 878 Q23QQ 905 QQQ74 325 4JTQQ 408 T4T78 340 3T5T5 551 3J3J3 391 88844 631 TTT9T 810 57775 935 A777J 604 4555T 2 A5J8T 942 22AJJ 506 22323 997 A3323 624 84442 516 2T992 76 J7T76 828 J8552 995 KTKK3 886 33853 782 53233 129 44J4J 372 KQQT2 480 K5649 576 3J63K 760 2J666 827 6JT68 318 45Q64 849 49884 801 9KTTK 902 66737 952 5Q8J4 708 57Q92 724 627J7 331 K22J6 473 4T444 923 J4444 552 78J8J 491 4K328 477 4AA3A 808 7A34Q 437 AQ888 428 8TA99 768 AA9A9 143 9K5AT 211 77722 40 TQTTT 941 Q2A4K 492 236T9 677 J8686 746 J585K 64 TJKQT 582 T3TTJ 157 22266 38 KT5TK 692 QJQQJ 908 4K623 279 7JJJ7 173 64A66 524 J7AJ8 417 K43Q3 769 T662T 148 54J2J 488 K6485 44 J6666 970 J26J9 209 8337Q 334 A27A4 319 A7T78 132 K777A 842 KKK4K 249 99K9K 430 8745K 151 Q2QTJ 433 QKQ76 525 25Q2Q 533 5QK6J 800 77T77 558 5K323 939 33KK4 590 K8A52 111 ATQJ6 569 ATK89 50 4433A 836 3KKKQ 891 46TK4 538 5249Q 447 2462K 675 8JT6T 336 466J7 459 7K7KK 838 544Q4 959 58773 483 823J5 999 2TKA5 752 AKJ58 386 7T833 99 KQ88Q 659 KJ3A4 790 K9595 307 3K3J4 534 3838T 220 32522 720 366Q3 500 J8868 989 T7KTK 376 JQQQA 14 42555 409 5T5T5 648 4KK4Q 383 K7777 884 736A3 543 343Q3 366 TJ856 237 JJ555 46 K5QQQ 275 QAQQ7 672 8KTJQ 731 QQQ3Q 47 J257Q 575 6Q3QQ 87 QKK43 924 TTATJ 998 K44K5 771 37895 881 48823 521 KKK74 456 99J79 139 J4542 635 AJ96K 954 K8937 411 5J355 895 96967 185 333T3 562 TAJ77 755 J38A8 487 AAT79 313 A6Q73 398 386JA 10 J35Q8 623 27758 969 3K3KJ 966 7928Q 627 AAA4A 59 2AA52 478 848J8 133 55225 843 TTQT9 619 3Q79K 255 27AK8 58 TKTKK 272 KTTAT 333 55666 802 47748 454 Q3T56 699 63T3T 302 8754Q 723 4J86T 358 8TTQ9 226 5523J 125 88588 606 58AAA 208 TK273 137 4Q7KQ 160 29292 577 Q333Q 611 22TT2 716 A55AA 258 64822 468 22228 847 2242T 788 JA26Q 472 8JAAA 174 K5Q8A 175 Q5AT4 732 J4434 530 76666 337 9998Q 547 9T2J9 100 3Q982 90 7727Q 281 92944 973 K2597 814 K444K 36 26KJ6 292 34K38 962 5A378 225 636J9 375 TTTT4 420 A66TA 461 69QK5 345 76293 479 66966 804 A3383 297 T82TT 657 2QJJQ 156 K2JK3 94 K6K66 252 K58QJ 876 6J979 513 92647 718 QQ9Q9 586 862Q5 20 5465K 915 KQ44Q 595 T66T6 288 TJT7T 710 5JT8K 159 KJTK3 603 KKJTQ 949 67776 914 J4323 177 22229 704 96999 178 8AJKA 70 69T69 419 65556 770 87738 537 547J4 835 44766 421 3355J 684 2K266 647 5TTT5 266 3T3TT 332 88JJ8 96 QQ5K3 887 K7JKK 377 J8Q2Q 66 2KKJ6 230 TTKQT 277 22Q92 18 JTTTK 695 J993Q 846 88898 728 88T87 715 Q74J4 872 4T999 951 T997Q 289 92QA9 726 AJ394 900 TT2T2 518 JJJJJ 565 #+end_src * Day 8: Haunted Wasteland Get the puzzle solution as [[file:./day8.scm][tangled .scm file]]. ** Part One *** Quest You're still riding a camel across Desert Island when you spot a sandstorm quickly approaching. When you turn to warn the Elf, she disappears before your eyes! To be fair, she had just finished warning you about *ghosts* a few minutes ago. One of the camel's pouches is labeled "maps" - sure enough, it's full of documents (your puzzle input) about how to navigate the desert. At least, you're pretty sure that's what they are; one of the documents contains a list of left/right instructions, and the rest of the documents seem to describe some kind of *network* of labeled nodes. It seems like you're meant to use the *left/right* instructions to *navigate the network*. Perhaps if you have the camel follow the same instructions, you can escape the haunted wasteland! After examining the maps for a bit, two nodes stick out: =AAA= and =ZZZ=. You feel like =AAA= is where you are now, and you have to follow the left/right instructions until you reach =ZZZ=. This format defines each node of the network individually. For example: #+name: day8-part1-example1 #+begin_example RL AAA = (BBB, CCC) BBB = (DDD, EEE) CCC = (ZZZ, GGG) DDD = (DDD, DDD) EEE = (EEE, EEE) GGG = (GGG, GGG) ZZZ = (ZZZ, ZZZ) #+end_example Starting with =AAA=, you need to *look up the next element* based on the next left/right instruction in your input. In this example, start with =AAA= and go *right* (=R=) by choosing the right element of =AAA=, *=CCC=*. Then, =L= means to choose the *left* element of =CCC=, *=ZZZ=*. By following the left/right instructions, you reach =ZZZ= in *=2=* steps. Of course, you might not find =ZZZ= right away. If you run out of left/right instructions, repeat the whole sequence of instructions as necessary: =RL= really means =RLRLRLRLRLRLRLRL...= and so on. For example, here is a situation that takes *=6=* steps to reach =ZZZ=: #+name: day8-part1-example2 #+begin_example LLR AAA = (BBB, BBB) BBB = (AAA, ZZZ) ZZZ = (ZZZ, ZZZ) #+end_example Starting at =AAA=, follow the left/right instructions. *How many steps are required to reach =ZZZ=*? *** Puzzle Solution **** Data Definition and Extraction #+name: day8-part1-records #+begin_src scheme (define-record node name left right) (define-record direction side) (define-record directions-ring entries entry length index) #+end_src #+name: day8-part1-irregex #+begin_src scheme (define alnum '(+ (or (/ #\A #\Z) (/ #\0 #\9)))) (define node-irregex `(: bol (* whitespace) (submatch-named node-name ,alnum) " = (" (submatch-named left ,alnum) ", " (submatch-named right ,alnum) ")" (* whitespace) eol)) (define directions-irregex '(+ (or #\L #\R))) #+end_src #+name: day8-part1-input--directions #+begin_src scheme (define (input->directions input) (let* ((directions-str (car (irregex-extract directions-irregex input))) (directions (map (compose make-direction string->symbol string) (string->list directions-str)))) (make-directions-ring directions (car directions) (length directions) 0))) #+end_src #+name: day8-part1-input--nodes-alist #+begin_src scheme (define (input->nodes-alist input) (irregex-fold node-irregex (lambda (from-index match seed) (alist-update (string->symbol (irregex-match-substring match 'node-name)) (make-node (string->symbol (irregex-match-substring match 'node-name)) (string->symbol (irregex-match-substring match 'left)) (string->symbol (irregex-match-substring match 'right))) seed)) '() input)) #+end_src **** Navigation #+name: day8-part1-move-forward #+begin_src scheme (define (move-forward directions-ring) (let ((entries (directions-ring-entries directions-ring)) (len (directions-ring-length directions-ring)) (index (directions-ring-index directions-ring))) (directions-ring-index-set! directions-ring (or (and (< index (- len 1)) (+ index 1)) 0)) (directions-ring-entry-set! directions-ring (list-ref entries (directions-ring-index directions-ring))) directions-ring)) #+end_src #+name: day8-part1-move #+begin_src scheme (define (move node direction nodes-alist) (let* ((side (direction-side direction)) (next-sym (if (eqv? 'L side) (node-left node) (node-right node)))) (alist-ref next-sym nodes-alist))) #+end_src #+name: day8-part1-navigate #+begin_src scheme (define (navigate nodes-alist directions start-sym target-sym #!optional (current-sym start-sym) (counter 0)) (if (eqv? current-sym target-sym) counter (let ((next-sym (node-name (move (alist-ref current-sym nodes-alist) (directions-ring-entry directions) nodes-alist)))) (navigate nodes-alist (move-forward directions) start-sym target-sym next-sym (+ counter 1))))) #+end_src **** Calculate The Route #+name: day8-part1-calc-fn #+begin_src scheme (import (chicken irregex) (chicken sort) (chicken string) (chicken type) (chicken format)) (define-record node name left right) (define-record direction side) (define-record directions-ring entries entry length index) (define alnum '(+ (or (/ #\A #\Z) (/ #\0 #\9)))) (define node-irregex `(: bol (* whitespace) (submatch-named node-name ,alnum) " = (" (submatch-named left ,alnum) ", " (submatch-named right ,alnum) ")" (* whitespace) eol)) (define directions-irregex '(+ (or #\L #\R))) (define (input->directions input) (let* ((directions-str (car (irregex-extract directions-irregex input))) (directions (map (compose make-direction string->symbol string) (string->list directions-str)))) (make-directions-ring directions (car directions) (length directions) 0))) (define (input->nodes-alist input) (irregex-fold node-irregex (lambda (from-index match seed) (alist-update (string->symbol (irregex-match-substring match 'node-name)) (make-node (string->symbol (irregex-match-substring match 'node-name)) (string->symbol (irregex-match-substring match 'left)) (string->symbol (irregex-match-substring match 'right))) seed)) '() input)) (define (move-forward directions-ring) (let ((entries (directions-ring-entries directions-ring)) (len (directions-ring-length directions-ring)) (index (directions-ring-index directions-ring))) (directions-ring-index-set! directions-ring (or (and (< index (- len 1)) (+ index 1)) 0)) (directions-ring-entry-set! directions-ring (list-ref entries (directions-ring-index directions-ring))) directions-ring)) (define (move node direction nodes-alist) (let* ((side (direction-side direction)) (next-sym (if (eqv? 'L side) (node-left node) (node-right node)))) (alist-ref next-sym nodes-alist))) (define (navigate nodes-alist directions start-sym target-sym #!optional (current-sym start-sym) (counter 0)) (if (eqv? current-sym target-sym) counter (let ((next-sym (node-name (move (alist-ref current-sym nodes-alist) (directions-ring-entry directions) nodes-alist)))) (navigate nodes-alist (move-forward directions) start-sym target-sym next-sym (+ counter 1))))) (define (calc-part-1) (let ((directions (input->directions input)) (nodes-alist (input->nodes-alist input))) (navigate nodes-alist directions 'AAA 'ZZZ))) #+end_src #+results: : 19631 ** Part Two *** Quest The sandstorm is upon you and you aren't any closer to escaping the wasteland. You had the camel follow the instructions, but you've barely left your starting position. It's going to take *significantly more steps* to escape! What if the map isn't for people - what if the map is for *ghosts*? Are ghosts even bound by the laws of spacetime? Only one way to find out. After examining the maps a bit longer, your attention is drawn to a curious fact: the number of nodes with names ending in =A= is equal to the number ending in =Z=! If you were a ghost, you'd probably just *start at every node that ends with A* and follow all of the paths at the same time until they all simultaneously end up at nodes that end with =Z=. For example: #+name: day8-part2-example1 #+begin_example LR 11A = (11B, XXX) 11B = (XXX, 11Z) 11Z = (11B, XXX) 22A = (22B, XXX) 22B = (22C, 22C) 22C = (22Z, 22Z) 22Z = (22B, 22B) XXX = (XXX, XXX) #+end_example =6= Here, there are two starting nodes, =11A= and =22A= (because they both end with =A=). As you follow each left/right instruction, use that instruction to *simultaneously* navigate away from both nodes you're currently on. Repeat this process until *all* of the nodes you're currently on end with =Z=. (If only some of the nodes you're on end with =Z=, they act like any other node and you continue as normal.) In this example, you would proceed as follows: - Step 0: You are at =11A= and =22A=. - Step 1: You choose all of the *left* paths, leading you to =11B= and =22B=. - Step 2: You choose all of the *right* paths, leading you to *=11Z=* and =22C=. - Step 3: You choose all of the *left* paths, leading you to =11B= and *=22Z=*. - Step 4: You choose all of the *right* paths, leading you to *=11Z=* and =22B=. - Step 5: You choose all of the *left* paths, leading you to =11B= and =22C=. - Step 6: You choose all of the *right* paths, leading you to *=11Z=* and *=22Z=*. So, in this example, you end up entirely on nodes that end in =Z= after *=6=* steps. Simultaneously start on every node that ends with =A=. *How many steps does it take before you're only on nodes that end with =Z=?* *** Puzzle Solution #+name: day8-part2-calc-next-sym #+begin_src scheme (define (calc-next-sym sym direction nodes-alist) (let ((side (direction-side direction)) (node (alist-ref sym nodes-alist))) (if (eqv? 'L side) (node-left node) (node-right node)))) #+end_src #+name: day8-part2-navigate #+begin_src scheme (define (p2-navigate nodes-alist directions start-sym #!optional (current-sym start-sym) (counter 0)) (if (eqv? #\Z ((compose car reverse string->list symbol->string) current-sym)) (begin (print "Found end point of " start-sym ": " current-sym ", steps: " counter) counter) (let ((next-sym (calc-next-sym current-sym (directions-ring-entry directions) nodes-alist))) (p2-navigate nodes-alist (move-forward directions) start-sym next-sym (+ counter 1))))) #+end_src #+name: day8-part2-find-start-points #+begin_src scheme (define (find-start-points sym-list) (foldl (lambda (start-points sym) (if (eqv? #\A ((compose car reverse string->list symbol->string) sym)) (cons sym start-points) start-points)) '() sym-list)) #+end_src #+name: day8-part2-lcm #+begin_src scheme (: p2-lcm ((list-of integer) integer -> integer)) (define (p2-lcm numbers #!optional (factor 2)) (let ((multiple (* (car numbers) factor))) (if (= 0 (foldl (lambda (x n) (+ x (modulo multiple n))) 0 numbers)) multiple (p2-lcm numbers (+ factor 1))))) #+end_src #+name: day8-part2-calc-fn #+begin_src scheme (import (chicken irregex) (chicken sort) (chicken string) (chicken type) (chicken format)) (define-record node name left right) (define-record direction side) (define-record directions-ring entries entry length index) (define alnum '(+ (or (/ #\A #\Z) (/ #\0 #\9)))) (define node-irregex `(: bol (* whitespace) (submatch-named node-name ,alnum) " = (" (submatch-named left ,alnum) ", " (submatch-named right ,alnum) ")" (* whitespace) eol)) (define directions-irregex '(+ (or #\L #\R))) (define (input->directions input) (let* ((directions-str (car (irregex-extract directions-irregex input))) (directions (map (compose make-direction string->symbol string) (string->list directions-str)))) (make-directions-ring directions (car directions) (length directions) 0))) (define (input->nodes-alist input) (irregex-fold node-irregex (lambda (from-index match seed) (alist-update (string->symbol (irregex-match-substring match 'node-name)) (make-node (string->symbol (irregex-match-substring match 'node-name)) (string->symbol (irregex-match-substring match 'left)) (string->symbol (irregex-match-substring match 'right))) seed)) '() input)) (define (move-forward directions-ring) (let ((entries (directions-ring-entries directions-ring)) (len (directions-ring-length directions-ring)) (index (directions-ring-index directions-ring))) (directions-ring-index-set! directions-ring (or (and (< index (- len 1)) (+ index 1)) 0)) (directions-ring-entry-set! directions-ring (list-ref entries (directions-ring-index directions-ring))) directions-ring)) (define (move node direction nodes-alist) (let* ((side (direction-side direction)) (next-sym (if (eqv? 'L side) (node-left node) (node-right node)))) (alist-ref next-sym nodes-alist))) (define (calc-next-sym sym direction nodes-alist) (let ((side (direction-side direction)) (node (alist-ref sym nodes-alist))) (if (eqv? 'L side) (node-left node) (node-right node)))) (define (p2-navigate nodes-alist directions start-sym #!optional (current-sym start-sym) (counter 0)) (if (eqv? #\Z ((compose car reverse string->list symbol->string) current-sym)) (begin (print "Found end point of " start-sym ": " current-sym ", steps: " counter) counter) (let ((next-sym (calc-next-sym current-sym (directions-ring-entry directions) nodes-alist))) (p2-navigate nodes-alist (move-forward directions) start-sym next-sym (+ counter 1))))) (define (find-start-points sym-list) (foldl (lambda (start-points sym) (if (eqv? #\A ((compose car reverse string->list symbol->string) sym)) (cons sym start-points) start-points)) '() sym-list)) (: p2-lcm ((list-of integer) integer -> integer)) (define (p2-lcm numbers #!optional (factor 2)) (let ((multiple (* (car numbers) factor))) (if (= 0 (foldl (lambda (x n) (+ x (modulo multiple n))) 0 numbers)) multiple (p2-lcm numbers (+ factor 1))))) (define (calc-part-2) (let* ((directions (input->directions input)) (nodes-alist (input->nodes-alist input)) (start-points (find-start-points (map car nodes-alist)))) (apply lcm (sort (map (cut p2-navigate nodes-alist directions <>) start-points) >)))) #+end_src #+results: : 21003205388413 ** Puzzle Input Jump to [[#headline-95][day 9]]. #+name: day8-input #+begin_src fundamental LRRLRRRLRLRLLRRLRLRLLRLRLRLLLLRRRLLRRRLRRRLRRRLLRLLRLRRLRLRLRRRLLLLRRLRLRRLRRLLRRRLRRLRLRRLRRLRRLRRLRLLRRLRRLLLLRLRLRRLLRRLLRRLRLLRLRRLRRLRRLRRRLRRLLLRRLRRRLRLRRRLLRLRRLRRRLRRLLRRRLRRLRLLRRLLRRLRRLRRRLRRLLRRLRRRLRLRLRLRLRLRRLRRLLRRRLRLRRLRRRLRLRLRLRLRLRRRLRRLRRRLLRRLRLLRRRLRRLRLLLLRRRLRRLRRRR DRM = (DLQ, BGR) PKD = (TNC, DKH) FSM = (LKS, KPG) NDS = (KGD, HNX) KQQ = (DPF, GKD) SBX = (DDL, MGH) GCV = (KMG, GLP) PCT = (JXN, XDR) KHR = (QPK, FPQ) FCK = (GLS, GGP) MKR = (XPQ, TJX) PFP = (RPR, LPS) XPC = (SSS, FRX) PTJ = (LSC, CND) GVJ = (NRL, SHV) QNF = (MBQ, GSR) TMK = (DVM, BJM) KTG = (QVG, LLX) JMK = (BKF, XDK) JQV = (DCM, RLT) VFH = (FDD, GML) XPN = (FKG, CXG) GDX = (GRV, BPP) GVP = (JLP, XNJ) TCB = (RVR, QXQ) DLP = (XDK, BKF) FQG = (RMH, QHR) XDD = (SMK, HMN) TLL = (TVV, FXX) NPT = (NGC, FQM) XQK = (PQG, QTK) DMQ = (RVS, KNQ) QKR = (SJD, PLH) XNV = (SJB, GCV) SRP = (CDK, JFK) FRP = (FFD, XPC) PVC = (XVD, MGD) DPP = (BFQ, XDD) CNV = (LQC, JJH) LLH = (CFP, BGF) XCK = (VDX, GFC) KGD = (LSF, FNK) MJA = (FXB, QVX) QLH = (KRM, KVD) QCR = (TKN, RNB) PSR = (FBL, HKJ) MGK = (BVC, HVL) PVK = (JRN, SMV) JTD = (VNS, FGJ) PMD = (HGN, NBM) DRF = (CPR, RTX) HJL = (CBR, VDR) PPB = (GDX, DXB) DVR = (LLT, GVJ) JRN = (RLD, RSL) NXM = (RBN, NVD) RLV = (FRM, FJB) SJB = (KMG, GLP) KJM = (XJH, LQX) GRB = (HHL, RGD) LQC = (BMC, XSH) NRB = (NQD, RFT) SQH = (QJT, JXX) JLX = (RJL, HHH) HVR = (XPN, JFM) FVD = (RXS, RHH) KSX = (TCB, GDK) GKJ = (TQF, HQJ) HQL = (BMR, PBX) QFP = (NJM, FSB) TPH = (NXT, RKN) SRL = (LSP, LFV) SDL = (MGL, PSK) MFX = (FSM, LQF) RFT = (FLV, GMS) BTG = (DRS, PVC) HLR = (DSB, DPP) DXB = (BPP, GRV) NHS = (HQG, GVP) GKK = (DCM, RLT) MJT = (JNR, PGC) KDS = (FFD, XPC) TSS = (BGX, QQX) FKC = (NBN, SJP) HHQ = (GVP, HQG) JKF = (QRR, GFD) CXG = (SDD, TMN) GCG = (TCC, TDT) NQX = (DMQ, DPM) GHX = (BJQ, CHJ) JQC = (HNQ, RJF) QBB = (GNH, XSC) BJG = (VMH, FCN) VMS = (KRX, VLQ) GSF = (NQM, KBH) JQQ = (PKD, GNB) KFG = (BGX, QQX) TTV = (SNB, JQF) CXJ = (CND, LSC) GGP = (PBH, XNG) FCV = (NLP, QJK) NSB = (KSX, SLL) JBH = (RGK, NSS) CQH = (HJL, FKR) VRX = (HKJ, FBL) HJZ = (QVX, FXB) RLD = (BJP, RLV) HHH = (PNJ, HPJ) LSC = (NRP, DCF) BVM = (RCG, QLL) KGN = (PRB, MLT) NTV = (MRQ, NHQ) VXT = (VFH, MBX) RLG = (MJQ, RNL) JVX = (HJQ, FNV) XGH = (HHK, JXT) NHC = (HPX, LGG) VPC = (XCL, HPQ) HKJ = (RQC, TMK) PGQ = (FTX, MNP) MPF = (KNM, BJG) MFT = (DRS, PVC) XNG = (RCS, JNH) RMH = (GHD, MPF) PFM = (PGQ, XHJ) TRN = (TCP, TCP) NHP = (JMG, VGP) JSK = (JBG, PVM) FSB = (MGK, HTD) BPR = (VFH, MBX) RHM = (LHD, PTF) PRV = (RJL, HHH) GNC = (HVR, PSV) PSV = (JFM, XPN) KMG = (KDR, RTV) RKL = (DPP, DSB) GLN = (QJT, JXX) FNK = (XXP, QDR) JDP = (HVR, PSV) HHD = (VPC, MDS) XHJ = (MNP, FTX) XVJ = (RGG, BCB) DRH = (CDK, JFK) BMC = (TTQ, KHR) TCT = (JQD, QBB) BCS = (HLV, MKR) LFV = (GTL, NSX) JCS = (JQC, NDG) SBJ = (PHS, QMN) HPZ = (DQD, PFP) BFM = (PMD, JGB) QBL = (KVC, TXK) RGD = (NXH, KQQ) PBX = (LBP, FPK) FDD = (TCX, CSN) RJT = (CQG, JSQ) BMR = (FPK, LBP) RBN = (DRF, VJB) PHB = (NXR, LPM) BPN = (PPX, PPX) KVC = (NSF, TQK) PXB = (GJH, JHM) BCB = (NTR, KKB) KXM = (NHS, HHQ) VTT = (NCB, HCR) SHP = (LQX, XJH) RCG = (CLL, TCT) LHG = (GSF, PRJ) XCL = (JLX, PRV) LXB = (RHH, RXS) FKZ = (TJS, BJB) NNH = (CFD, XMX) NTD = (NCX, PVK) DCF = (JHJ, VMN) GJH = (JTD, CJD) VBS = (CDQ, LFQ) MGL = (GGB, QNN) TXK = (NSF, TQK) HRX = (QFP, BJR) GMS = (GKJ, TNF) RGA = (PFP, DQD) KTS = (GSF, PRJ) TPP = (VPC, MDS) JNV = (BHV, XQK) DXL = (HDP, KTG) MBR = (GRS, GTG) KVJ = (LPH, NGG) HRG = (RNL, MJQ) XHL = (JXF, FVH) MMC = (FHM, HNF) HGC = (SHT, HBF) LPS = (NTV, CGR) FKR = (CBR, VDR) BHV = (PQG, QTK) BKF = (SRP, DRH) JMA = (BJB, TJS) MPT = (HRX, VSD) QHL = (NRB, HJG) PDG = (KJM, SHP) HFT = (HHQ, NHS) SJD = (GPM, PPB) NSF = (NRX, SRL) MXG = (JVJ, BMF) PHD = (BQK, VKV) VBH = (TXK, KVC) NJM = (HTD, MGK) TVV = (LLH, HFB) RPS = (GGQ, SNK) HPR = (LJS, DJR) FDR = (QKT, GRX) LLT = (SHV, NRL) VQC = (DPM, DMQ) MJQ = (CLD, FCV) BFG = (GJH, JHM) GFS = (PMP, VXL) LBP = (HRF, GRB) BXC = (MFS, NRM) CFD = (QMQ, HPR) HPN = (JQC, NDG) BBJ = (JTL, QQK) VVL = (CDN, STB) HFB = (CFP, BGF) NNG = (XVP, CQH) QKM = (KDS, FRP) VJB = (CPR, RTX) KQB = (XCK, BSF) LKS = (LDJ, MXG) GTL = (FVD, LXB) PJS = (BGV, MLM) KNM = (FCN, VMH) FCN = (VGR, KHV) RPJ = (XKD, BPM) GLP = (KDR, RTV) NXL = (VTS, SDL) XDX = (MPT, FXH) KRX = (DCD, DHH) CTP = (CRQ, DPL) SRG = (SKH, SLF) QVX = (NDC, NPL) XVK = (SNB, JQF) RBT = (NSD, SBJ) RXS = (FKC, JSS) SFX = (PRB, MLT) SRS = (FVH, JXF) NRL = (RLG, HRG) QKK = (PBX, BMR) DPL = (PTQ, DBH) PFD = (JQV, GKK) VGR = (KMX, DVR) FQX = (LHD, PTF) LXT = (RHM, FQX) JHV = (MBR, PHJ) JNN = (VKG, SLT) XDK = (DRH, SRP) JBR = (BDR, GFS) BNM = (VKG, SLT) CJD = (VNS, FGJ) FPK = (HRF, GRB) PBH = (JNH, RCS) FGV = (FDR, TMD) LSF = (XXP, QDR) RBM = (VHG, BDL) TNF = (HQJ, TQF) TRM = (JHT, BCG) GBH = (XMJ, JFF) DBH = (DSS, RQL) PGB = (BXR, DXL) QFR = (TDT, TCC) HHL = (NXH, KQQ) HGN = (BFG, PXB) PXC = (BPN, BPN) NDF = (VQC, NQX) GSK = (BVV, SBX) TCM = (VBS, HCN) HTD = (BVC, HVL) SHD = (MHG, HNG) LQX = (QVF, LBV) MSF = (FDF, VLP) NRP = (VMN, JHJ) TQF = (BXC, JCR) MBX = (GML, FDD) JCR = (MFS, NRM) NTR = (PCN, RNT) JHJ = (XMT, NPT) SQX = (CDN, STB) CSN = (GBJ, PGB) GDJ = (GBM, GCJ) XGL = (HJQ, FNV) PLD = (BFL, BFL) NRX = (LFV, LSP) TFF = (HGQ, MJT) JVJ = (TMS, HPK) BSF = (VDX, GFC) GML = (CSN, TCX) BFJ = (GFD, QRR) FGJ = (PGF, VMS) TQK = (SRL, NRX) GQD = (MDD, HLQ) TJX = (XCG, DJH) GRR = (LPM, NXR) PTQ = (DSS, DSS) HHK = (KLD, NNG) FBR = (KXM, HFT) RLT = (JMK, DLP) PHL = (QHR, RMH) DVM = (JTP, KDM) MNF = (RPJ, RMF) RMF = (BPM, XKD) GGQ = (MFT, BTG) CLD = (NLP, QJK) NMR = (FNL, LXT) CLX = (TRP, GMD) QMQ = (DJR, LJS) KDR = (PKC, NRF) KKG = (VHG, BDL) FBQ = (TPP, HHD) QVV = (LNR, GSK) VKV = (MFX, FDL) HJG = (NQD, RFT) XVD = (VXT, BPR) NCX = (SMV, JRN) QLN = (CDJ, TDK) GFC = (CKR, LNC) HGQ = (JNR, PGC) NDG = (RJF, HNQ) CBC = (NSD, SBJ) BQK = (FDL, MFX) VGV = (HGC, TQG) VGP = (RJT, KPK) VMN = (XMT, NPT) PSH = (NSS, RGK) PPL = (FXH, MPT) DCD = (SBR, DTS) MDD = (MQX, FQT) XCG = (XVK, TTV) LFQ = (SNS, VBL) JHT = (FMN, HMC) KNQ = (QKM, DPS) PVM = (CHL, GLT) JMG = (KPK, RJT) XKD = (GQJ, NXL) DGG = (CCB, CQX) HNF = (MNC, FKZ) QTL = (PSH, JBH) RNL = (CLD, FCV) BDR = (PMP, VXL) GKH = (KXM, HFT) RQC = (DVM, BJM) GSR = (PPL, XDX) JQD = (GNH, XSC) GRS = (RTN, MPH) BPP = (GBH, KQX) XVP = (HJL, FKR) PKZ = (NMR, KJK) SLT = (BVM, KMJ) XHA = (KJK, NMR) BQQ = (FDR, TMD) GGC = (CXJ, PTJ) NBM = (PXB, BFG) RQL = (BBH, NLT) KJK = (FNL, LXT) PSK = (GGB, QNN) FQT = (DRL, NDS) SJT = (VQC, NQX) QHT = (GFS, BDR) QJT = (PJS, DNG) SVT = (PDG, GSS) MBQ = (PPL, XDX) VHL = (PVM, JBG) QCJ = (JKK, JSR) NQH = (LKQ, FBG) XNJ = (QNF, LPL) PQV = (CKJ, JHV) FHM = (MNC, MNC) FPN = (DLQ, BGR) BJR = (NJM, FSB) HPQ = (PRV, JLX) KMJ = (QLL, RCG) FTX = (TSM, PDR) JXT = (KLD, NNG) DPS = (KDS, FRP) KKB = (RNT, PCN) XCB = (TDM, HXC) TCP = (PFP, DQD) CDK = (NDF, SJT) HCR = (HSP, PFD) SNK = (BTG, MFT) TKN = (QTL, HPL) GSS = (KJM, SHP) NRF = (SVT, RGV) FLV = (GKJ, TNF) QPK = (FPN, DRM) RNB = (QTL, HPL) HPJ = (XGL, JVX) NSD = (QMN, PHS) JXF = (DQV, XPX) PRJ = (KBH, NQM) XMT = (NGC, FQM) JLP = (QNF, LPL) RND = (HLV, MKR) QRR = (GPQ, GLL) LNR = (BVV, SBX) PQG = (TXR, NTD) JXX = (PJS, DNG) QQX = (VTT, XKV) RRJ = (GLS, GGP) MLM = (VCD, BTQ) QVG = (TMM, CTP) KRM = (MSF, HVT) XKV = (HCR, NCB) LJX = (RNB, TKN) CCB = (NXM, QSG) RJF = (FQP, VDH) XBN = (BJQ, CHJ) JHM = (JTD, CJD) SMV = (RSL, RLD) PDR = (GHX, XBN) JFK = (NDF, SJT) HCN = (LFQ, CDQ) SLL = (TCB, GDK) VBL = (JBR, QHT) SMK = (RBM, KKG) GDK = (QXQ, RVR) KQX = (XMJ, JFF) LKQ = (HLN, VTD) JSQ = (QXG, CLX) FFD = (FRX, SSS) NRM = (XBP, NQH) SBR = (PQQ, SRG) BKR = (MHG, HNG) QQK = (GQK, STS) HVL = (DLF, QLH) NHT = (PTJ, CXJ) GLL = (TLL, LRR) GLS = (PBH, XNG) NHB = (QQK, JTL) PFS = (KFG, TSS) PCN = (PFS, QFB) CJV = (BFL, PKZ) JFM = (FKG, CXG) GFD = (GLL, GPQ) MDS = (XCL, HPQ) FXH = (VSD, HRX) DQD = (RPR, LPS) HPX = (RRJ, FCK) JNR = (SQQ, SQQ) BGR = (PQV, DKS) BRN = (BSF, XCK) RVS = (QKM, DPS) PLH = (GPM, PPB) XSM = (QFS, GQD) TTH = (TQG, HGC) KBJ = (KTS, LHG) RKN = (PCX, NSB) TPK = (PFM, RFN) MNC = (BJB, TJS) PMM = (GRR, PHB) QKT = (BNK, QKR) HQG = (JLP, XNJ) RRD = (JGB, PMD) CPR = (TGM, VXS) GGM = (GCJ, GBM) HBF = (FQG, PHL) NXH = (DPF, GKD) TMD = (GRX, QKT) FBL = (RQC, TMK) GNB = (DKH, TNC) LQF = (LKS, KPG) BKN = (TRN, TRN) QJK = (BLT, XVJ) HLV = (TJX, XPQ) XPX = (TPK, HQN) BJP = (FJB, FRM) GHD = (KNM, BJG) XMX = (HPR, QMQ) FNV = (NHT, GGC) JGB = (HGN, NBM) PKH = (HHK, JXT) JXN = (VRR, VRR) CHJ = (TLF, QSN) XBP = (LKQ, FBG) QTK = (TXR, NTD) PKC = (SVT, RGV) JNH = (MGV, MPJ) FXB = (NDC, NPL) XHQ = (KTS, LHG) MFS = (NQH, XBP) FQM = (XJB, TXN) QNN = (JQQ, GBG) GBG = (PKD, GNB) TMN = (GRC, BCV) HMN = (KKG, RBM) DHH = (SBR, DTS) KPG = (LDJ, MXG) FDL = (LQF, FSM) FXX = (LLH, HFB) VSD = (BJR, QFP) HVT = (FDF, VLP) FRM = (CBB, GMX) GQK = (QVV, QBV) CKJ = (PHJ, MBR) JJH = (XSH, BMC) SQQ = (PLD, PLD) KPK = (JSQ, CQG) VLP = (HHT, MMC) NLP = (XVJ, BLT) VTS = (MGL, PSK) DTS = (SRG, PQQ) VCD = (GDJ, GGM) VRR = (HLR, RKL) VXS = (BKN, SRB) GMD = (PSR, VRX) PFK = (HXC, TDM) SJP = (VSM, NNH) TDK = (SRS, XHL) KRS = (GCV, SJB) MRQ = (CJK, PQD) XJB = (JRK, RPS) BGF = (QCR, LJX) MLT = (MMF, DGG) TCC = (MNF, KKL) QMN = (GLN, SQH) GQJ = (VTS, SDL) BFQ = (SMK, HMN) NSS = (JPQ, HXV) MHG = (VGV, TTH) KBH = (GPL, XCV) DRL = (KGD, HNX) HMC = (QDF, RGR) QSN = (FBR, GKH) SDD = (GRC, BCV) TGH = (BPN, SSQ) HNG = (TTH, VGV) RHH = (FKC, JSS) DQA = (MVV, LQJ) QFB = (KFG, TSS) TQG = (SHT, HBF) KDM = (QKK, HQL) XHV = (PLD, CJV) PQD = (TPH, PTN) SSS = (SQX, VVL) GPM = (DXB, GDX) KLD = (CQH, XVP) LRR = (FXX, TVV) HPL = (JBH, PSH) TMS = (BQQ, FGV) MMF = (CCB, CQX) DLQ = (PQV, DKS) PHJ = (GTG, GRS) TLF = (GKH, FBR) FJB = (CBB, GMX) PTF = (PSF, PHD) NPL = (RTG, QHL) XMJ = (XHQ, KBJ) PMP = (TRM, PJK) JPQ = (KLM, TCM) BCG = (FMN, HMC) DRS = (MGD, XVD) RGT = (PKH, XGH) TGM = (BKN, BKN) BPM = (GQJ, NXL) VDX = (CKR, LNC) XJH = (QVF, LBV) MGD = (BPR, VXT) RGR = (JSK, VHL) SNS = (QHT, JBR) SRB = (TRN, DVK) NRQ = (LQC, JJH) PSF = (BQK, VKV) BMF = (TMS, HPK) LGG = (FCK, RRJ) HPK = (FGV, BQQ) QBV = (GSK, LNR) FNF = (PHB, GRR) GLT = (JDP, GNC) DKS = (JHV, CKJ) RGV = (GSS, PDG) HQN = (PFM, RFN) GKD = (BFJ, JKF) HXC = (HPN, JCS) MGH = (BVB, FBQ) LBV = (XCB, PFK) LHD = (PHD, PSF) CDQ = (SNS, VBL) BTQ = (GGM, GDJ) HMS = (CBC, RBT) VTD = (CNV, NRQ) JBG = (GLT, CHL) LCB = (NGG, LPH) FKG = (SDD, TMN) BVV = (DDL, MGH) RGG = (KKB, NTR) FBG = (HLN, VTD) KMX = (GVJ, LLT) HRF = (HHL, RGD) DGM = (QFS, GQD) LPM = (QFR, GCG) QXQ = (BCS, RND) BGV = (BTQ, VCD) BGX = (XKV, VTT) XDR = (VRR, ZZZ) BJM = (JTP, KDM) RFN = (PGQ, XHJ) DDL = (FBQ, BVB) XCV = (JNN, BNM) TCX = (GBJ, PGB) QXG = (TRP, GMD) VKG = (BVM, KMJ) RSL = (RLV, BJP) CDN = (QLN, CNM) RVR = (BCS, RND) BBH = (BXJ, BXJ) BXR = (KTG, HDP) DJH = (XVK, TTV) DVK = (TCP, HPZ) SLF = (TFF, KQV) DJR = (SFX, KGN) HHT = (FHM, FHM) JSR = (JXM, JNV) DSB = (BFQ, XDD) DPM = (RVS, KNQ) HJQ = (NHT, GGC) ZZZ = (RKL, HLR) RJL = (HPJ, PNJ) BJQ = (TLF, QSN) HQJ = (BXC, JCR) FQP = (HMS, SRH) PGF = (VLQ, KRX) LQJ = (FNF, PMM) JXM = (BHV, XQK) PNJ = (JVX, XGL) STB = (CNM, QLN) BBS = (JXN, JXN) KKL = (RMF, RPJ) SHV = (HRG, RLG) FPQ = (FPN, DRM) GBJ = (DXL, BXR) QHR = (GHD, MPF) MDG = (JKK, JSR) CRQ = (PTQ, DBH) BVB = (TPP, HHD) GRC = (RGT, VDD) SKH = (TFF, KQV) DHZ = (LQJ, MVV) LSP = (NSX, GTL) MPJ = (QBL, VBH) TDT = (KKL, MNF) TXN = (JRK, RPS) HSP = (GKK, JQV) JTL = (STS, GQK) GBM = (QCJ, MDG) HDP = (LLX, QVG) GMX = (KQB, BRN) PJK = (JHT, BCG) NDC = (RTG, QHL) LPL = (GSR, MBQ) VLQ = (DCD, DHH) QLL = (CLL, TCT) RTV = (NRF, PKC) DKH = (BBJ, NHB) NGC = (XJB, TXN) CNM = (CDJ, TDK) XXP = (BSP, NHC) FNL = (RHM, FQX) NBN = (VSM, NNH) XSC = (BFM, RRD) VXL = (PJK, TRM) VSM = (XMX, CFD) NQM = (GPL, XCV) HLN = (CNV, NRQ) GCJ = (QCJ, MDG) FDF = (HHT, HHT) PQQ = (SKH, SLF) KVD = (MSF, HVT) QSG = (NVD, RBN) RGK = (HXV, JPQ) NXR = (GCG, QFR) QDR = (BSP, NHC) TDM = (HPN, JCS) MQX = (NDS, DRL) JRK = (GGQ, SNK) VMH = (VGR, KHV) RPR = (NTV, CGR) CFP = (LJX, QCR) CLL = (JQD, QBB) LLX = (CTP, TMM) PRB = (DGG, MMF) FVH = (XPX, DQV) JKK = (JNV, JXM) KLM = (VBS, HCN) NHQ = (CJK, PQD) BJB = (BKR, SHD) CQX = (NXM, QSG) KHV = (DVR, KMX) SRH = (CBC, RBT) DQV = (TPK, HQN) NQD = (GMS, FLV) PHS = (GLN, SQH) GPL = (JNN, BNM) JSS = (SJP, NBN) CGR = (MRQ, NHQ) PGC = (SQQ, XHV) GPQ = (LRR, TLL) HXV = (TCM, KLM) BFL = (KJK, NMR) PPX = (FXB, QVX) AAA = (HLR, RKL) DSS = (BBH, BBH) VDD = (PKH, XGH) NCB = (PFD, HSP) SSQ = (PPX, HJZ) DNG = (MLM, BGV) CDJ = (XHL, SRS) TNC = (NHB, BBJ) QDF = (VHL, JSK) GTG = (MPH, RTN) FRX = (SQX, VVL) MVV = (FNF, PMM) QFS = (HLQ, MDD) MNP = (PDR, TSM) LDJ = (BMF, JVJ) NSX = (FVD, LXB) RNT = (PFS, QFB) TJS = (SHD, BKR) HNQ = (VDH, FQP) BLT = (BCB, RGG) KQV = (HGQ, MJT) PTN = (NXT, RKN) VDR = (BBS, PCT) RCS = (MPJ, MGV) GRX = (BNK, QKR) JFF = (XHQ, KBJ) RTG = (NRB, HJG) CND = (DCF, NRP) DCM = (JMK, DLP) XPQ = (XCG, DJH) RTX = (TGM, VXS) DPF = (BFJ, JKF) LNC = (PXC, TGH) PCX = (SLL, KSX) BSP = (HPX, LGG) VHG = (LCH, NHP) GRV = (KQX, GBH) NGG = (DGM, XSM) XSH = (TTQ, KHR) MRH = (KVJ, LCB) TXR = (NCX, PVK) NVD = (VJB, DRF) TTQ = (FPQ, QPK) CKR = (PXC, PXC) BVC = (DLF, QLH) VDH = (SRH, HMS) JQF = (SKC, MRH) CBB = (BRN, KQB) FMN = (RGR, QDF) SHT = (FQG, PHL) NLT = (BXJ, DHZ) MPH = (KRS, XNV) BXJ = (MVV, LQJ) CHL = (JDP, GNC) TSM = (XBN, GHX) DLF = (KRM, KVD) BCV = (RGT, VDD) HNX = (FNK, LSF) LJS = (SFX, KGN) STS = (QBV, QVV) SKC = (KVJ, LCB) BNK = (SJD, PLH) RTN = (KRS, XNV) JTP = (QKK, HQL) LCH = (VGP, JMG) CBR = (BBS, BBS) VNS = (VMS, PGF) CQG = (CLX, QXG) HLQ = (MQX, FQT) TMM = (CRQ, DPL) BDL = (NHP, LCH) TRP = (VRX, PSR) MGV = (VBH, QBL) GNH = (BFM, RRD) NXT = (NSB, PCX) SNB = (SKC, MRH) LPH = (XSM, DGM) GGB = (GBG, JQQ) CJK = (PTN, TPH) QVF = (PFK, XCB) #+end_src * Day 9: Mirage Maintenance Get the puzzle solution as [[file:./day9.scm][tangled .scm file]]. ** Part One *** Quest You ride the camel through the sandstorm and stop where the ghost's maps told you to stop. The sandstorm subsequently subsides, somehow seeing you standing at an *oasis*! The camel goes to get some water and you stretch your neck. As you look up, you discover what must be yet another giant floating island, this one made of metal! That must be where the *parts to fix the sand machines* come from. There's even a [[https://en.wikipedia.org/wiki/Hang_gliding][hang glider]] partially buried in the sand here; once the sun rises and heats up the sand, you might be able to use the glider and the hot air to get all the way up to the metal island! While you wait for the sun to rise, you admire the oasis hidden here in the middle of Desert Island. It must have a delicate ecosystem; you might as well take some ecological readings while you wait. Maybe you can report any environmental instabilities you find to someone so the oasis can be around for the next sandstorm-worn traveler. You pull out your handy *Oasis And Sand Instability Sensor* and analyze your surroundings. The OASIS produces a report of many values and how they are changing over time (your puzzle input). Each line in the report contains the *history* of a single value. For example: #+name: day9-part1-example1 #+begin_example 0 3 6 9 12 15 1 3 6 10 15 21 10 13 16 21 30 45 #+end_example To best protect the oasis, your environmental report should include a *prediction of the next value* in each history. To do this, start by making a new sequence from the *difference at each step* of your history. If that sequence is *not* all zeroes, repeat this process, using the sequence you just generated as the input sequence. Once all of the values in your latest sequence are zeroes, you can extrapolate what the next value of the original history should be. In the above dataset, the first history is =0 3 6 9 12 15=. Because the values increase by =3= each step, the first sequence of differences that you generate will be =3 3 3 3 3=. Note that this sequence has one fewer value than the input sequence because at each step it considers two numbers from the input. Since these values aren't *all zero*, repeat the process: the values differ by =0= at each step, so the next sequence is =0 0 0 0=. This means you have enough information to extrapolate the history! Visually, these sequences can be arranged like this: #+begin_example 0 3 6 9 12 15 3 3 3 3 3 0 0 0 0 #+end_example To extrapolate, start by adding a new zero to the end of your list of zeroes; because the zeroes represent differences between the two values above them, this also means there is now a placeholder in every sequence above it: #+begin_example 0 3 6 9 12 15 B 3 3 3 3 3 A 0 0 0 0 0 #+end_example You can then start filling in placeholders from the bottom up. =A= needs to be the result of increasing =3= (the value to its left) by =0= (the value below it); this means =A= must be *=3=*: #+begin_example 0 3 6 9 12 15 B 3 3 3 3 3 3 0 0 0 0 0 #+end_example Finally, you can fill in =B=, which needs to be the result of increasing =15= (the value to its left) by =3= (the value below it), or *=18=*: #+begin_example 0 3 6 9 12 15 18 3 3 3 3 3 3 0 0 0 0 0 #+end_example So, the next value of the first history is *=18=*. Finding all-zero differences for the second history requires an additional sequence: #+begin_example 1 3 6 10 15 21 2 3 4 5 6 1 1 1 1 0 0 0 #+end_example Then, following the same process as before, work out the next value in each sequence from the bottom up: #+begin_example 1 3 6 10 15 21 28 2 3 4 5 6 7 1 1 1 1 1 0 0 0 0 #+end_example So, the next value of the second history is *=28=*. The third history requires even more sequences, but its next value can be found the same way: #+begin_example 10 13 16 21 30 45 68 3 3 5 9 15 23 0 2 4 6 8 2 2 2 2 0 0 0 #+end_example So, the next value of the third history is *=68=*. If you find the next value for each history in this example and add them together, you get *=114=*. Analyze your OASIS report and extrapolate the next value for each history. *What is the sum of these extrapolated values?* *** Puzzle Solution **** Data Extraction #+name: day9-part1-datalist #+begin_src scheme (define (input->list input) (map (lambda (x) (map string->number (string-split x))) (string-split input "\n"))) #+end_src **** Calculation #+name: day9-part1-diff #+begin_src scheme (define (diff input) (if (= 1 (length input)) '() (cons (- (cadr input) (car input)) (diff (cdr input))))) #+end_src #+name: day9-part1-extrapolate #+begin_src scheme (define (extrapolate data) (append data (list (if (foldl (lambda (out in) (and out (= 0 in))) #t data) 0 (+ (car (reverse data)) (car (reverse (extrapolate (diff data))))))))) #+end_src #+name: day9-part1-calc-fn #+begin_src scheme (import (chicken irregex) (chicken string) (chicken type) (chicken format)) (define (input->list input) (map (lambda (x) (map string->number (string-split x))) (string-split input "\n"))) (define (diff input) (if (= 1 (length input)) '() (cons (- (cadr input) (car input)) (diff (cdr input))))) (define (extrapolate data) (append data (list (if (foldl (lambda (out in) (and out (= 0 in))) #t data) 0 (+ (car (reverse data)) (car (reverse (extrapolate (diff data))))))))) (define (calc-part-1) (foldl + 0 (map (compose car reverse extrapolate) (input->list input)))) #+end_src #+results: : 2174807968 ** Part Two *** Quest Of course, it would be nice to have *even more history* included in your report. Surely it's safe to just *extrapolate backwards* as well, right? For each history, repeat the process of finding differences until the sequence of differences is entirely zero. Then, rather than adding a zero to the end and filling in the next values of each previous sequence, you should instead add a zero to the *beginning* of your sequence of zeroes, then fill in new *first* values for each previous sequence. In particular, here is what the third example history looks like when extrapolating back in time: #+begin_example 5 10 13 16 21 30 45 5 3 3 5 9 15 -2 0 2 4 6 2 2 2 2 0 0 0 #+end_example Adding the new values on the left side of each sequence from bottom to top eventually reveals the new left-most history value: *=5=*. Doing this for the remaining example data above results in previous values of *=-3=* for the first history and *=0=* for the second history. Adding all three new values together produces *=2=*. Analyze your OASIS report again, this time extrapolating the *previous* value for each history. *What is the sum of these extrapolated values?* #+name: day9-part2-calc-fn #+begin_src scheme (import (chicken irregex) (chicken string) (chicken type) (chicken format)) (define (input->list input) (map (lambda (x) (map string->number (string-split x))) (string-split input "\n"))) (define (diff input) (if (= 1 (length input)) '() (cons (- (cadr input) (car input)) (diff (cdr input))))) (define (extrapolate data) (append data (list (if (foldl (lambda (out in) (and out (= 0 in))) #t data) 0 (+ (car (reverse data)) (car (reverse (extrapolate (diff data))))))))) (define (calc-part-2) (foldl + 0 (map (compose car reverse extrapolate reverse) (input->list input)))) #+end_src #+results: : 1208 ** Puzzle Input Jump to [[#headline-104][day 10]]. #+name: day9-input #+begin_src fundamental 3 10 23 46 99 234 563 1310 2904 6131 12351 23745 43470 75464 123501 189097 268370 349700 418439 484617 669380 16 41 77 119 171 265 488 1017 2162 4417 8519 15515 26837 44385 70618 108653 162372 236537 336913 470399 645167 20 45 91 182 351 648 1157 2027 3543 6296 11556 22009 43088 85209 167316 322244 604526 1101399 1947905 3347136 5596837 24 50 87 141 223 341 487 621 653 420 -352 -2121 -5670 -12365 -24598 -46505 -85074 -151786 -264963 -453031 -758943 13 31 76 172 351 645 1075 1649 2399 3508 5604 10347 21558 47460 105396 232221 507493 1104469 2398816 5191706 11149877 11 26 41 56 71 86 101 116 131 146 161 176 191 206 221 236 251 266 281 296 311 15 29 51 84 133 204 310 490 840 1545 2898 5314 9419 16451 29509 56732 118481 262393 593397 1331440 2919341 15 25 37 52 92 226 605 1507 3400 7055 13792 26042 48618 91547 176291 349138 709201 1464905 3043603 6296140 12864564 7 10 18 37 73 132 220 343 507 718 982 1305 1693 2152 2688 3307 4015 4818 5722 6733 7857 15 38 84 178 356 676 1258 2368 4561 8898 17252 32718 60142 106784 183130 303868 489043 765406 1167972 1741802 2544024 6 1 -1 4 18 43 88 187 448 1186 3263 8896 23446 59130 142286 326871 718410 1514791 3073295 6017268 11401122 15 29 41 54 79 135 249 456 799 1329 2105 3194 4671 6619 9129 12300 16239 21061 26889 33854 42095 19 32 61 116 209 354 567 866 1271 1804 2489 3352 4421 5726 7299 9174 11387 13976 16981 20444 24409 6 20 44 78 122 176 240 314 398 492 596 710 834 968 1112 1266 1430 1604 1788 1982 2186 16 30 54 91 153 265 478 906 1811 3777 8045 17148 36139 75040 153808 312341 630150 1263728 2514908 4951321 9611313 13 38 88 174 309 517 845 1386 2334 4116 7690 15178 31151 65158 136598 283958 582099 1174186 2329820 4549050 8744617 24 34 44 54 64 74 84 94 104 114 124 134 144 154 164 174 184 194 204 214 224 9 13 27 63 139 273 489 854 1568 3142 6746 14925 33112 72770 157638 335518 699411 1423691 2823509 5448867 10228929 10 10 27 74 165 327 637 1304 2826 6271 13771 29395 60703 121520 236914 452294 850626 1586416 2955103 5536876 10493273 4 -2 1 20 72 195 466 1039 2234 4749 10146 21906 47613 103336 222285 471798 986484 2032184 4127207 8266676 16326242 26 37 48 59 70 81 92 103 114 125 136 147 158 169 180 191 202 213 224 235 246 22 29 39 66 134 284 585 1149 2150 3851 6669 11402 19995 37786 79284 181567 433019 1031652 2399292 5400601 11759053 15 30 58 119 247 501 993 1937 3727 7076 13313 25067 47809 93158 185649 376132 767743 1565630 3171448 6361747 12621939 3 6 9 15 33 80 178 345 578 825 942 630 -654 -3819 -10303 -22286 -42963 -76888 -130401 -212151 -333729 17 25 47 101 219 463 964 2011 4225 8871 18399 37384 74212 144276 276417 526495 1006445 1945905 3819619 7602107 15258621 18 29 46 68 95 128 169 221 288 375 488 634 821 1058 1355 1723 2174 2721 3378 4160 5083 7 14 23 38 77 194 511 1260 2835 5854 11231 20258 34697 56882 89831 137368 204255 296334 420679 585758 801605 22 38 69 135 264 494 877 1486 2430 3889 6192 9989 16665 29438 56335 117945 266418 629260 1504963 3562351 8239882 26 53 99 180 322 573 1030 1882 3470 6365 11465 20112 34230 56485 90468 140902 213874 317093 460175 654956 915834 15 23 35 61 122 257 543 1142 2402 5056 10594 21958 44885 90585 181120 360055 713057 1406833 2761469 5383323 10407444 10 8 4 13 68 227 585 1295 2609 4966 9184 16876 31349 59530 115990 231038 466366 944412 1903010 3799003 7512836 5 16 47 115 252 511 974 1776 3164 5606 9944 17535 30228 49864 76748 106236 122251 86280 -79663 -517365 -1464656 15 24 45 100 222 456 857 1485 2397 3636 5217 7110 9220 11364 13245 14423 14283 12000 6501 -3576 -19926 9 28 63 129 262 526 1024 1924 3520 6369 11584 21431 40508 78061 152598 301239 598775 1196146 2396433 4800625 9578422 9 8 16 61 188 456 945 1788 3243 5820 10478 18907 33910 59900 103527 174450 286269 457632 713532 1086809 1619872 17 36 59 89 150 315 760 1851 4280 9300 19180 38125 74110 142422 272337 519607 989951 1883736 3581545 6807641 12938466 7 20 46 97 195 378 708 1274 2191 3626 5945 10183 19205 40164 89187 199648 435935 915304 1841256 3552893 6595927 10 5 -5 -20 -40 -65 -95 -130 -170 -215 -265 -320 -380 -445 -515 -590 -670 -755 -845 -940 -1040 12 15 14 8 -5 -33 -80 -91 201 1614 6181 18353 47069 109209 235297 479044 933854 1762589 3253152 5924174 10725971 17 28 54 115 241 485 951 1856 3664 7364 15036 30992 64033 131772 268582 539580 1064191 2054280 3873614 7127525 12794077 3 18 41 76 144 297 646 1422 3108 6716 14355 30387 63785 132963 275685 569338 1172097 2405486 4917217 9995922 20165782 -2 -11 -18 -18 -9 20 110 363 996 2452 5649 12567 27667 61305 137695 312640 711010 1601959 3542704 7641380 16018623 10 26 64 139 273 495 841 1354 2084 3088 4430 6181 8419 11229 14703 18940 24046 30134 37324 45743 55525 14 24 44 81 144 259 502 1068 2419 5602 12910 29200 64433 138451 289794 591687 1180468 2305044 4410912 8279435 15253110 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 7 8 28 92 250 591 1258 2478 4629 8371 14868 26113 45312 77128 127213 199638 289163 362090 313624 -120434 -1536674 13 23 37 68 128 234 434 866 1882 4303 9920 22420 48995 102986 208023 404246 757331 1371199 2405455 4098788 6799762 12 20 25 36 65 121 199 260 198 -210 -1375 -3992 -9165 -18565 -34625 -60776 -101728 -163800 -255303 -386980 -572507 19 27 30 35 72 205 554 1345 3019 6463 13486 27773 56756 115227 232224 463967 917739 1795083 3468214 6612095 12427528 22 31 33 30 26 34 98 328 956 2458 5868 13557 30990 70339 157357 343649 727458 1487369 2934979 5594648 10321002 -2 -8 -10 11 87 272 656 1383 2671 4828 8253 13407 20738 30548 42801 56891 71420 84080 91792 91331 80761 -9 -10 -2 28 101 258 583 1236 2495 4806 8840 15556 26269 42722 67161 102412 151959 220022 311634 432716 590149 9 22 58 135 291 603 1213 2361 4425 7968 13792 22999 37059 57885 87915 130201 188505 267402 372390 510007 687955 11 16 36 88 195 396 773 1496 2887 5512 10331 18975 34281 61306 109164 194191 345147 611416 1075470 1871226 3210351 11 25 42 61 81 101 120 137 151 161 166 165 157 141 116 81 35 -23 -94 -179 -279 12 13 27 81 215 482 948 1692 2806 4395 6577 9483 13257 18056 24050 31422 40368 51097 63831 78805 96267 23 47 91 161 263 403 587 821 1111 1463 1883 2377 2951 3611 4363 5213 6167 7231 8411 9713 11143 22 40 68 119 215 382 647 1044 1639 2599 4375 8181 17211 39616 95503 232744 561299 1324998 3046759 6814429 14831782 5 8 13 32 102 306 802 1860 3907 7580 13787 23776 39212 62262 95688 142948 208305 296944 415097 570176 770914 24 34 52 87 143 225 368 713 1661 4151 10156 23609 52208 110966 229042 462397 916262 1783392 3406732 6378571 11692653 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 10 25 42 73 160 391 917 1966 3841 6888 11440 17797 26403 38542 58109 95332 173740 342203 694526 1399873 2748242 7 15 40 93 196 393 767 1475 2827 5458 10690 21284 43001 87846 180779 373417 771448 1588223 3247376 6576762 13174273 17 21 36 70 134 258 514 1042 2075 3959 7164 12282 20008 31100 46314 66310 91525 122009 157220 195774 235146 5 24 67 143 257 409 605 887 1384 2378 4378 8235 15481 29448 58482 123927 277779 638304 1456805 3235439 6924821 -4 -13 -31 -65 -116 -170 -189 -102 204 893 2189 4385 7852 13048 20527 30948 45084 63831 88217 119411 158732 9 3 -7 -13 14 145 522 1405 3256 6883 13661 25826 46797 81415 135892 217132 330915 478219 648689 809941 891008 19 26 42 77 157 335 694 1332 2321 3644 5135 6474 7319 7702 8947 15807 41799 122946 352368 962939 2513289 24 43 72 128 246 498 1023 2081 4170 8292 16532 33246 67397 137051 277976 560104 1119120 2217113 4358724 8512176 16525692 14 25 36 59 130 316 725 1526 2997 5655 10608 20453 41406 88013 192938 426237 931696 1993231 4154260 8432537 16713850 19 44 81 141 261 519 1064 2184 4456 9055 18341 36886 73134 141888 267766 489635 865785 1479206 2441737 3895019 6005051 22 27 31 48 113 303 773 1810 3906 7845 14799 26457 45305 75383 124229 207355 357574 642911 1198799 2282910 4364441 7 12 24 52 116 259 557 1127 2133 3790 6366 10182 15610 23069 33019 45953 62387 82848 107860 137928 173520 -1 6 29 91 228 492 956 1715 2874 4511 6600 8876 10621 10347 5349 -8902 -39559 -97428 -198265 -364383 -626614 22 27 43 86 173 322 552 883 1336 1933 2697 3652 4823 6236 7918 9897 12202 14863 17911 21378 25297 4 3 -4 -8 14 95 281 653 1380 2815 5646 11114 21310 39563 70931 122807 205652 333867 526816 810012 1216478 10 9 17 50 133 301 600 1088 1836 2929 4467 6566 9359 12997 17650 23508 30782 39705 50533 63546 79049 7 0 -9 -20 -21 30 229 772 2060 4936 11193 24608 52958 111845 231915 472723 950241 1893280 3761743 7495716 15035137 10 21 26 38 82 205 499 1145 2494 5204 10445 20164 37385 66582 114525 193166 329149 591406 1162719 2509549 5757819 10 25 54 96 157 254 412 662 1069 1849 3673 8304 19770 46342 103661 219442 440276 841153 1538440 2707168 4603611 23 38 61 112 231 499 1075 2262 4625 9194 17795 33562 61693 110523 192997 328636 546099 886454 1407281 2187740 3334747 13 24 59 145 330 706 1458 2953 5896 11603 22474 42792 80027 146887 264431 466642 806951 1367306 2270493 3696539 5904160 10 18 27 42 73 135 248 437 732 1168 1785 2628 3747 5197 7038 9335 12158 15582 19687 24558 30285 0 20 69 166 341 646 1172 2068 3551 5883 9275 13668 18357 21505 19801 8917 -13953 -43392 -52008 34010 375042 17 15 9 -5 -24 -12 147 721 2238 5664 12732 26593 53145 103800 201325 392204 772513 1540933 3104557 6284571 12706664 0 10 34 77 151 285 557 1156 2479 5267 10785 21054 39148 69576 118778 195775 313026 487560 742468 1108859 1628405 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 11 29 57 92 131 171 209 242 267 281 281 264 227 167 81 -34 -181 -363 -583 -844 -1149 -1 -1 3 23 82 226 539 1155 2271 4195 7529 13721 26479 55018 120964 272252 610107 1340413 2870991 5996513 12252244 9 6 -1 -16 -41 -72 -95 -73 97 692 2391 6721 16930 39768 89256 194718 417549 884978 1855267 3838446 7811229 6 5 4 13 52 160 422 1028 2379 5254 11059 22216 42852 80173 147371 269868 498718 939273 1812188 3582057 7224622 13 33 75 152 286 523 960 1788 3352 6226 11298 19857 33671 55042 86821 132363 195399 279799 389197 526446 692868 10 19 30 59 134 295 594 1095 1874 3019 4630 6819 9710 13439 18154 24015 31194 39875 50254 62539 76950 19 27 43 89 213 499 1078 2146 3995 7063 12009 19819 31949 50511 78508 120124 181075 269027 394087 569373 811669 -2 -3 -11 -28 -41 -2 197 748 1943 4177 7952 13966 23563 40276 74198 153035 348067 832077 2003716 4746046 10948462 19 30 60 123 242 466 905 1799 3642 7387 14763 28740 54183 98741 174022 297110 492485 794412 1249870 1922097 2894832 0 7 27 81 213 494 1027 1968 3587 6398 11380 20291 36062 63297 109090 184848 310794 526609 914641 1646749 3072763 17 32 58 111 237 524 1118 2263 4402 8395 15926 30177 56831 105418 190966 336018 573779 955502 1571274 2606855 4486445 15 20 35 78 181 404 862 1782 3631 7396 15165 31276 64500 132042 266623 528588 1025907 1946124 3605771 6524482 11532963 20 46 93 176 318 563 997 1767 3094 5303 8946 15186 26784 50386 101536 215309 468375 1024083 2223578 4768355 10082757 3 8 24 64 151 325 657 1282 2478 4835 9568 19016 37316 71128 130115 226735 375087 589848 890362 1324626 2047999 7 15 32 60 103 162 237 361 716 1925 5685 16012 41518 99340 221600 465601 929365 1774603 3259782 5786628 9964185 1 -7 -17 -33 -67 -146 -322 -676 -1284 -2080 -2510 -817 7300 31141 89649 220744 501079 1088781 2315289 4877757 10228491 12 27 59 115 218 416 793 1483 2697 4796 8487 15311 28807 57252 120069 262580 589026 1333781 3008755 6696087 14606600 24 40 71 124 198 282 369 512 975 2574 7361 19879 49309 112942 241541 487311 935370 1719812 3045675 5218374 8682432 17 18 13 -6 -37 -53 13 283 949 2288 4677 8608 14703 23729 36613 54457 78553 110398 151709 204438 270787 -1 2 12 38 91 184 332 552 863 1286 1844 2562 3467 4588 5956 7604 9567 11882 14588 17726 21339 23 39 66 122 249 520 1037 1931 3386 5729 9665 16795 30647 58615 115552 230558 460253 915439 1815044 3593968 7113449 -7 -2 9 33 88 203 418 784 1363 2228 3463 5163 7434 10393 14168 18898 24733 31834 40373 50533 62508 16 25 31 42 72 146 325 770 1883 4604 11028 25668 57977 127225 271612 564742 1144514 2262427 4365693 8231006 15178118 17 35 59 94 145 217 318 474 786 1597 3911 10355 27266 69022 166670 384444 850191 1809395 3717867 7395824 14276711 12 13 17 24 34 47 63 82 104 129 157 188 222 259 299 342 388 437 489 544 602 0 -1 -6 -19 -44 -85 -146 -231 -344 -489 -670 -891 -1156 -1469 -1834 -2255 -2736 -3281 -3894 -4579 -5340 5 16 32 70 173 428 985 2069 3988 7168 12293 20696 35238 62028 113480 213375 404799 762064 1407990 2538234 4454699 7 13 34 89 211 458 932 1814 3444 6520 12583 25131 52010 110221 235027 496322 1026725 2067887 4044160 7676197 14151365 10 22 35 46 52 50 37 10 -34 -98 -185 -298 -440 -614 -823 -1070 -1358 -1690 -2069 -2498 -2980 15 28 60 130 266 504 891 1497 2434 3877 6097 9579 15462 26884 52455 114159 263677 613630 1393790 3047140 6387030 28 36 49 85 173 364 756 1547 3145 6394 13039 26691 54844 113093 233903 484671 1004561 2078906 4288030 8801645 17953478 10 18 18 5 -11 9 153 589 1610 3694 7578 14343 25505 43105 69789 108867 164338 240866 343690 478449 650901 3 8 13 30 83 220 536 1207 2543 5096 9920 19187 37529 74714 150587 303628 605011 1180704 2244943 4149356 7453119 6 23 53 112 234 491 1028 2127 4326 8646 17029 33173 64095 123050 235114 448303 856506 1647425 3201837 6293946 12482396 13 34 69 132 260 532 1099 2246 4522 8985 17614 33936 63893 116917 207086 354152 584375 932072 1446071 2214064 3438654 13 30 52 89 161 302 580 1153 2402 5216 11564 25606 55842 119333 250156 516518 1055280 2140619 4317945 8659852 17246368 7 18 31 46 63 82 103 126 151 178 207 238 271 306 343 382 423 466 511 558 607 21 48 101 194 354 639 1161 2117 3836 6861 12108 21193 37129 65854 119643 224743 438199 883902 1827123 3822840 7999884 11 13 22 57 146 334 718 1536 3347 7361 16032 34149 70916 144028 287775 569230 1120532 2202854 4331783 8519402 16733123 -2 11 51 137 300 602 1181 2348 4786 9941 20756 42992 87522 174193 338136 639750 1179934 2122363 3724473 6377975 10657624 7 13 28 51 73 73 14 -154 -459 -781 -510 2274 12653 42918 121184 309218 738163 1677669 3664992 7737833 15840617 -9 -16 -23 -13 49 221 596 1330 2694 5150 9448 16766 29011 49657 86117 156061 303173 634244 1402195 3183669 7243449 20 35 56 83 116 155 200 251 308 371 440 515 596 683 776 875 980 1091 1208 1331 1460 7 1 4 39 141 367 815 1651 3143 5701 9922 16639 26973 42387 64741 96347 140023 199145 277696 380311 512317 24 45 72 111 185 351 727 1527 3112 6095 11590 21775 41076 78559 152743 301440 602189 1214813 2469043 5041085 10300040 -5 -4 2 13 38 109 306 798 1900 4149 8435 16316 30843 58592 114261 230351 476543 997368 2084774 4318733 8843090 12 18 27 47 95 215 513 1216 2769 5998 12388 24553 47010 87411 158436 280606 486338 825634 1373873 2242259 3591569 4 24 68 149 287 515 885 1474 2390 3778 5826 8771 12905 18581 26219 36312 49432 66236 87472 113985 146723 0 -10 -20 -25 -20 0 40 105 200 330 500 715 980 1300 1680 2125 2640 3230 3900 4655 5500 -8 -10 3 58 204 518 1123 2244 4337 8347 16210 31856 63266 126690 255089 514413 1033714 2058624 4042777 7798770 14739772 15 18 30 58 120 251 502 934 1613 2627 4196 7075 13729 31293 78265 198410 487727 1143860 2552398 5431564 11066378 8 15 48 121 259 521 1037 2071 4138 8229 16234 31705 61201 116694 220077 412042 770044 1444583 2730844 5205533 9978815 10 20 46 90 164 317 671 1465 3113 6296 12131 22494 40621 72173 127030 222177 386164 665764 1135620 1911866 3170930 18 23 24 32 80 243 671 1651 3722 7886 16006 31591 61405 118835 230952 453097 898238 1794181 3591256 7158078 14125706 29 51 92 167 309 595 1178 2335 4553 8686 16235 29845 54198 97633 175070 313184 559297 996161 1765722 3106111 5407527 12 12 4 -21 -76 -178 -348 -611 -996 -1536 -2268 -3233 -4476 -6046 -7996 -10383 -13268 -16716 -20796 -25581 -31148 0 9 35 98 232 488 936 1674 2877 4958 8966 17413 35803 75231 156529 316559 617390 1159247 2098285 3670420 6222642 13 21 32 49 85 182 447 1112 2635 5878 12439 25300 50113 97733 189126 364748 702329 1350459 2591722 4960343 9458373 9 19 39 86 189 395 789 1533 2933 5553 10424 19471 36446 68985 133049 262273 527277 1075055 2208489 4544904 9327119 19 36 72 149 295 545 946 1563 2481 3802 5652 8243 12077 18443 30510 55765 111767 240144 540160 1245849 2894059 15 29 72 172 384 804 1583 2941 5181 8703 14018 21762 32710 47790 68097 94907 129691 174129 230124 299816 385596 25 35 55 98 193 403 842 1697 3271 6073 10991 19594 34619 60709 105478 180989 305741 507271 825487 1316858 2059597 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 8 11 15 32 76 169 370 839 1956 4538 10240 22298 46904 95789 191261 376486 737120 1447065 2863661 5719920 11499172 -8 -2 13 45 122 303 686 1418 2735 5097 9533 18373 36617 74274 150096 297232 571434 1062560 1910237 3324669 5613700 13 23 33 43 53 63 73 83 93 103 113 123 133 143 153 163 173 183 193 203 213 18 43 77 122 190 318 594 1204 2519 5250 10708 21215 40721 75691 136335 238263 404656 669053 1078863 1699720 2620808 8 16 28 42 62 98 176 371 883 2196 5408 12934 30042 68225 152478 336535 733710 1577404 3336844 6934362 14147986 8 18 25 29 27 19 31 159 645 2027 5484 13657 32508 75226 169850 373203 794966 1637312 3257507 6263301 11653801 6 24 56 106 178 279 424 638 944 1313 1529 884 -2444 -12568 -37949 -94582 -209847 -424059 -779987 -1274723 -1714327 -2 13 45 110 245 522 1077 2173 4319 8468 16321 30775 56579 101338 177239 304520 519289 891865 1569433 2872703 5509044 17 26 47 86 160 319 683 1500 3231 6668 13091 24470 43718 75001 124111 198908 309837 470526 698471 1015814 1450220 -3 -1 8 31 81 182 388 841 1902 4409 10163 22832 49615 104267 212544 421952 819143 1560767 2927518 5416973 9898961 13 20 38 80 163 311 565 1001 1756 3062 5289 9000 15024 24557 39306 61697 95175 144632 217008 322120 473785 28 39 47 63 118 277 660 1478 3107 6261 12404 24678 49842 102075 210163 430999 875464 1759681 3509315 6974263 13868272 20 37 63 92 127 189 323 614 1250 2702 6132 14201 32571 72666 156840 328295 670484 1345532 2670978 5274306 10406489 12 14 31 87 219 479 939 1706 2953 4972 8273 13827 23743 43064 84079 175767 383139 845371 1850192 3980360 8406944 -8 -12 -15 -8 21 80 174 332 700 1782 4988 13797 36140 89197 208948 469000 1017273 2146494 4427414 8955718 17799720 9 20 36 52 63 64 50 16 -43 -132 -256 -420 -629 -888 -1202 -1576 -2015 -2524 -3108 -3772 -4521 22 38 71 131 225 358 542 820 1318 2363 4763 10452 23873 54719 123012 268101 564392 1149494 2277273 4423811 8507611 15 25 48 99 193 350 610 1062 1889 3437 6341 11804 22265 42999 85871 177948 380787 832437 1835974 4039605 8789881 -3 12 53 138 295 568 1034 1838 3254 5784 10314 18356 32418 56560 97213 164360 273203 446468 717531 1134582 1766081 9 18 48 126 296 625 1223 2292 4229 7838 14770 28423 55712 110379 218873 430309 832633 1577898 2920516 5273516 9289232 12 23 37 57 99 199 425 903 1868 3751 7323 13958 26187 48985 92882 181485 369228 781655 1702709 3754963 8254611 24 48 95 177 306 499 786 1221 1896 2958 4629 7229 11202 17145 25840 38289 55752 79788 112299 155577 212354 4 5 7 10 14 19 25 32 40 49 59 70 82 95 109 124 140 157 175 194 214 7 9 13 26 70 197 515 1225 2669 5389 10197 18256 31172 51097 80843 124007 185107 269729 384685 538182 740002 15 28 44 60 73 80 78 64 35 -12 -80 -172 -291 -440 -622 -840 -1097 -1396 -1740 -2132 -2575 17 38 65 108 202 432 975 2169 4632 9480 18737 36101 68345 127819 236819 435057 792171 1428238 2546689 4485974 7798892 20 30 44 71 137 292 617 1231 2305 4124 7316 13509 26907 57623 128106 284692 617246 1291102 2597120 5027743 9389545 9 14 29 68 169 402 877 1761 3321 6024 10750 19215 34763 63774 118054 218728 402353 730210 1302027 2275734 3895261 9 23 39 56 72 89 136 336 1061 3246 8987 22668 53123 117887 251707 523689 1071642 2169768 4358940 8690267 17165991 16 30 59 112 213 412 806 1582 3108 6124 12128 24119 47957 94734 184721 353659 662384 1210994 2158945 3752554 6361325 7 12 38 108 255 520 957 1664 2871 5128 9648 18872 37335 72924 138631 254916 452807 777876 1295242 2095764 3303599 3 10 35 103 265 612 1288 2502 4539 7770 12661 19781 29809 43540 61890 85900 116739 155706 204231 263875 336329 16 29 53 95 170 319 639 1343 2894 6296 13677 29364 61728 126168 249707 477790 884004 1583583 2751717 4647853 7647358 16 40 69 105 168 319 707 1653 3787 8255 17021 33324 62443 113114 200286 350512 612477 1077901 1924644 3509430 6572577 0 11 34 77 173 410 979 2241 4814 9681 18315 32806 55976 91537 144597 223435 344712 546499 917076 1652791 3165715 9 14 36 80 146 231 333 456 625 941 1740 3982 10126 26022 64897 155516 358321 796136 1710316 3559564 7187714 11 36 85 172 312 525 853 1393 2354 4170 7765 15200 31175 66259 143335 309641 658037 1362816 2737597 5325692 10036938 6 9 16 38 98 240 543 1150 2342 4719 9594 19762 40874 83726 167865 327018 616966 1126613 1993140 3422286 5714962 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 16 22 28 34 40 46 52 58 64 70 76 82 88 94 100 106 112 118 124 130 136 -3 0 10 37 93 197 388 759 1537 3240 6939 14638 29755 57639 105989 184948 306525 482848 722568 1024515 1367449 10 20 28 37 65 165 456 1173 2761 6065 12705 25772 51038 98940 187675 347830 629068 1109498 1908474 3203695 5253615 24 40 59 86 145 285 584 1165 2249 4287 8253 16271 32930 67962 141480 293768 602766 1213994 2389815 4587764 8581295 14 24 49 96 172 302 575 1237 2854 6572 14505 30286 59820 112282 201407 347123 577582 931648 1461905 2238252 3352156 -1 14 44 89 149 224 314 419 539 674 824 989 1169 1364 1574 1799 2039 2294 2564 2849 3149 14 15 17 21 40 117 357 989 2491 5837 12960 27569 56511 111931 214554 398493 718076 1257283 2142491 3559341 5774666 4 14 44 117 269 547 1003 1682 2609 3791 5262 7215 10313 16436 30590 65824 155350 380532 931308 2228761 5160433 12 9 6 3 0 -3 -6 -9 -12 -15 -18 -21 -24 -27 -30 -33 -36 -39 -42 -45 -48 20 35 54 78 121 218 424 801 1386 2126 2773 2790 1505 -770 1178 28420 145017 519925 1559927 4182072 10352394 #+end_src * Day 10: Pipe Maze Get the puzzle solution as [[file:./day10.scm][tangled .scm file]]. ** Part One *** Quest You use the hang glider to ride the hot air from Desert Island all the way up to the floating metal island. This island is surprisingly cold and there definitely aren't any thermals to glide on, so you leave your hang glider behind. You wander around for a while, but you don't find any people or animals. However, you do occasionally find signposts labeled "[[https://en.wikipedia.org/wiki/Hot_spring][Hot Springs]]" pointing in a seemingly consistent direction; maybe you can find someone at the hot springs and ask them where the desert-machine parts are made. The landscape here is alien; even the flowers and trees are made of metal. As you stop to admire some metal grass, you notice something metallic scurry away in your peripheral vision and jump into a big pipe! It didn't look like any animal you've ever seen; if you want a better look, you'll need to get ahead of it. Scanning the area, you discover that the entire field you're standing on is densely packed with pipes; it was hard to tell at first because they're the same metallic silver color as the "ground". You make a quick sketch of all of the surface pipes you can see (your puzzle input). The pipes are arranged in a two-dimensional grid of *tiles*: - =|= is a *vertical pipe* connecting north and south. - =-= is a *horizontal pipe* connecting east and west. - =L= is a *90-degree bend* connecting north and east. - =J= is a *90-degree bend* connecting north and west. - =7= is a *90-degree bend* connecting south and west. - =F= is a *90-degree bend* connecting south and east. - =.= is *ground*; there is no pipe in this tile. - =S= is the *starting position* of the animal; there is a pipe on this tile, but your sketch doesn't show what shape the pipe has. Based on the acoustics of the animal's scurrying, you're confident the pipe that contains the animal is *one large, continuous loop*. For example, here is a square loop of pipe: #+begin_example ..... .F-7. .|.|. .L-J. ..... #+end_example If the animal had entered this loop in the northwest corner, the sketch would instead look like this: #+begin_example ..... .S-7. .|.|. .L-J. ..... #+end_example In the above diagram, the =S= tile is still a 90-degree =F= bend: you can tell because of how the adjacent pipes connect to it. Unfortunately, there are also many pipes that *aren't connected to the loop*! This sketch shows the same loop as above: #+begin_example -L|F7 7S-7| L|7|| -L-J| L|-JF #+end_example In the above diagram, you can still figure out which pipes form the main loop: they're the ones connected to =S=, pipes those pipes connect to, pipes *those* pipes connect to, and so on. Every pipe in the main loop connects to its two neighbors (including =S=, which will have exactly two pipes connecting to it, and which is assumed to connect back to those two pipes). Here is a sketch that contains a slightly more complex main loop: #+begin_example ..F7. .FJ|. SJ.L7 |F--J LJ... #+end_example Here's the same example sketch with the extra, non-main-loop pipe tiles also shown: #+begin_example 7-F7- .FJ|7 SJLL7 |F--J LJ.LJ #+end_example If you want to *get out ahead of the animal*, you should find the tile in the loop that is *farthest* from the starting position. Because the animal is in the pipe, it doesn't make sense to measure this by direct distance. Instead, you need to find the tile that would take the longest number of steps *along the loop* to reach from the starting point - regardless of which way around the loop the animal went. In the first example with the square loop: #+begin_example ..... .S-7. .|.|. .L-J. ..... #+end_example You can count the distance each tile in the loop is from the starting point like this: #+begin_example ..... .012. .1.3. .234. ..... #+end_example In this example, the farthest point from the start is =4= steps away. Here's the more complex loop again: #+begin_example ..F7. .FJ|. SJ.L7 |F--J LJ... #+end_example Here are the distances for each tile on that loop: #+begin_example ..45. .236. 01.78 14567 23... #+end_example Find the single giant loop starting at =S=. *How many steps along the loop does it take to get from the starting position to the point farthest from the starting position?* *** Puzzle Solution **** Data Structures #+begin_src scheme (define-record tile goes-north? goes-east? goes-south? goes-west? start?) (define (char->tile c) (case c ((#\|) (make-tile #t #f #t #f #f)) ((#\-) (make-tile #f #t #f #t #f)) ((#\L) (make-tile #t #t #f #f #f)) ((#\J) (make-tile #t #f #f #t #f)) ((#\7) (make-tile #f #f #t #t #f)) ((#\F) (make-tile #f #t #t #f #f)) ((#\.) (make-tile #f #f #f #f #f)) ((#\S) (make-tile #f #f #f #f #t)))) #+end_src **** Load Data #+begin_src scheme (define (input->grid input) (map (compose (cut map char->tile <>) string->list (cut foldl string-append "" <>) string-split) (string-split input "\n"))) #+end_src **** Prepare Data #+begin_src scheme (define (get-tile grid x y) (list-ref (list-ref grid y) x)) (define (get-start-loc grid #!optional (x 0) (y 0)) (let ((tile (get-tile grid x y))) (if (tile-start? tile) (values x y) (if (= (+ 1 x) (length (car grid))) (get-start-loc grid 0 (+ y 1)) (get-start-loc grid (+ x 1) y))))) #+end_src #+begin_src scheme (define (update-start-loc grid x y) (let ((S (get-tile grid x y))) (when (and (< 0 y) (tile-goes-south? (get-tile grid x (- y 1)))) (tile-goes-north?-set! S #t)) (when (and (< (+ 1 y) (length (car grid))) (tile-goes-north? (get-tile grid x (+ y 1)))) (tile-goes-south?-set! S #t)) (when (and (< 0 x) (tile-goes-east? (get-tile grid (- x 1) y))) (tile-goes-west?-set! S #t)) (when (and (< (+ 1 x) (length grid)) (tile-goes-west? (get-tile grid (+ x 1) y))) (tile-goes-east?-set! S #t)))) #+end_src #+begin_src scheme (define x car) (define y cdr) (define (get-paths grid x y) `((#:e . (and (< (+ x 1) (length (car grid))) (tile-goes-west? (get-tile (+ x 1) y)))) (#:s . (and (< (+ y 1) (length grid)) (tile-goes-north? (get-tile x (+ y 1))))) (#:w . (and (< 0 x) (tile-goes-east? (get-tile (- x 1) y)))) (#:n . (and (< 0 y) (tile-goes-south? (get-tile x (- y 1))))))) (define (get-valid-paths paths #!optional (valid-paths (list))) (if (= 0 (length paths)) valid-paths (get-valid-paths (cdr paths) (if (cdar paths) (alist-update (caar paths) (cdar paths) valid-paths) valid-paths)))) (define (move-forward grid past-loc cur-loc) (let ((tile (get-tile grid (x cur-loc) (y cur-loc))) (delta-x (- (x cur-loc) (x past-loc))) (delta-y (- (y cur-loc) (y past-loc))) (valid-paths (get-valid-paths (get-paths grid (x cur-loc) (y cur-loc))))) (values cur-loc (cond ((= -50 (car past-loc)) (case (caar valid-paths) ((#:n) (cons (x cur-loc) (- (y cur-loc) 1))) ((#:e) (cons (+ (x cur-loc) 1) (y cur-loc))) ((#:s) (cons (x cur-loc) (+ (y cur-loc) 1))) ((#:w) (cons (- (x cur-loc) 1) (y cur-loc))))) ((and (tile-goes-north? tile) (alist-ref #:n valid-paths) (not (= (cdr past-loc) (- (cdr cur-loc) 1)))) (cons (x cur-loc) (- (y cur-loc) 1))) ((and (tile-goes-east? tile) (alist-ref #:e valid-paths) (not (= (car past-loc) (+ (car cur-loc) 1)))) (cons (+ (x cur-loc) 1) (y cur-loc))) ((and (tile-goes-south? tile) (alist-ref #:s valid-paths) (not (= (cdr past-loc) (+ (cdr cur-loc) 1)))) (cons (x cur-loc) (+ (y cur-loc) 1))) ((and (tile-goes-west? tile) (alist-ref #:w valid-paths) (not (= (car past-loc) (- (car cur-loc) 1)))) (cons (- (x cur-loc) 1) (y cur-loc))))))) #+end_src #+begin_src scheme (define (count-steps grid start-loc #!optional (last-loc (cons -50 -50)) (cur-loc start-loc) (count 0)) (if (and (> count 0) (= (car start-loc) (car cur-loc)) (= (cdr start-loc) (cdr cur-loc))) count (let-values (((cur-loc new-loc) (move-forward grid last-loc cur-loc))) (count-steps grid start-loc cur-loc new-loc (+ count 1))))) #+end_src **** Calculation #+name: day10-part1-calc-fn #+begin_src scheme (define (calc-part-1) (let ((grid (input->grid input))) (let-values (((start-x start-y) (get-start-loc grid))) (update-start-loc grid start-x start-y) (/ (count-steps grid (cons start-x start-y)) 2)))) #+end_src #+results: : 7145 ** Part Two *** Quest *** Puzzle Solution **** Calculation #+name: day10-part2-calc-fn #+begin_src scheme #+end_src ** Puzzle Input #+name: day10-input #+begin_src fundamental .F7FFJ7L-7.F-7.F7|F-L-7F7F|7.F7F7FJ.FLFF-77.FFF7-|FL-7LF-7F7FF--77.-777F-LJFFL7FJ.|-L7-FF-FJ77F7F7F-7F.|F7JF-L-J--|-F7|F-LF--77..J..F---.F7- |7LJJ-||.FF-7.|||J-|LL|-J7JFF77LFFJ.7J|L|LJ7F7J|-77||7LL7||L7L7FJFF|F-7|7-|FFJFJ|-|.L7.|.7.|F7-|F7J-JFFJFLJL|J7L|FF77J.-7LJF|LJ7||FFJF-JF-7J L7J|JJF-L|J.L7.LJF77.LF7JL-J|.L.7J-FF7|FJ7LF||LJLL.LJ-J|||L7L-JL7-J7JFL|L7FF--F-|.|F-L|F7-.L7J|L|.J.L||7||7.|.F7--J|J-|F|7||7-LF--JJ.L-JF-J- .LFF--|.|LFJ7||.||7-7||J.F|F|-J-|.|L|L-7L-J|.-77.|F.|.FFJL-JF---J7-FJL7L---J|J.JJFF77LJ-J.FFJ.-.|J7F.|L--J7-FJL-F-7J.|JLF7FL7|7F7LL----7J7|7 ..7JJFJF|J.L-7-F7JJL|-L.|F-FJ7J7L|7-L7FJ7L77J|JL--|FF7-L--7FJF7F7L7J-L-7|J|-L.FL-J.L|-J.L|7L-|LFJ|LF-FJLJ7FJ.|7LL-J-J77-L-|JL--J7JLF|-FJL--- FFJ.L7LJ7.|J|..LJ|FFLF--J|.JF7L|L-J.L||F-7F7JF7..7-|||-F7FJ|FJ||L-7LLL7FJ.F7|-|.FL|JL|F7.FJF-J-F-7FJ.L|.FF|7F|7L|||.F||7|LL7|.LLF7.L77|J.LL. 7J7|.F7.LJ|F7--J-L7J7.F|..F.7J-LFJ.F7|LJFJ||FJ|-||FF||FJ|L7||FJ|F-J7..J|F|.F7-|FLL|F-F-7F7||F|.J-L||7.L-J7LJ|J|.7JF7|7JL|LJ-L7L7|J-||JL|JJ-- LF-JFJ|LJJ|.F-F.|LL.|F77J.LJ||.FF7F||L-7|7|||FJ-F7F7||L7|F|||L7|L7F7-|LFF7FJL7F77|L--L7|||F-7JL7L|.F7-FL--JFLJFFFJL7LJ-FF-|-L77F77.JJ|FJJF.| LF7L7LF.||F.L-|77|.|LFL|7FF-|7-FJL7||F7|L-J|||F7||||||FJL-JLJFJ|FJ|L7J-FJ|L7FJ||7FJ||FJLJLJFJ|J7.F-J|.|F7|JLJJ|..FLFJL7JL7.-.|F.|F-JF-L..|F7 -LJ7||L-F7|7.FLJ-J.F77.77|7JF77L-7LJ||LJF7FJ|||||LJLJLJF-7F-7L7|L-JFJLFL7|FJL7|L77--7L-7F--JFF7-F77L|FFFJJ77|FFF77||-LL7F|.F7-J-FJ.LF-|-|7.| JFFL77|.L-|L-J-|7FLFJL7LFF7-||F-7L-7||F-JLJFJ|||L-7F7F7L7LJLL7||F--J|FF-J||F-J|FJ7|FF7FJL-7JFF7F777FF77||.F-7-FJL-77-F7F-7-LJ-|FF-L-|F77J|FJ FJ7L|L--F7|F7|7FJ-|..||.L||FJ|L7|F7|||L---7L7LJ|F7LJLJL-JF7-FJLJL7F7F7L7FJ||F7||JF-7||L7F-J-FJ|||F7F7JL77.L7|7L7F-J--LLL7L7FJLJ7|JJ.L|.7-FFJ L7|F7.|-|L-JLFF-JF-7FF--7|LJFJF|||LJLJF---JFJF-J|L7F--7F-JL7L7F--J|||L7|L-JLJLJL7L7|||FJL7-LL7||||LJL7F-7F7||F-JL7J|FJ|-|FJ7JFFF7FFF-|-|--L7 L-J-7-7-|JJL-JF-77F|7L-7LJF-JLFJ||F--7L-7F-JFJF7L7|L7FJL--7|FJL7F7|LJFJ|F-------JL|LJLJF7|F7L|||||F7FJL7LJLJ|L7F-JLF7F--J|F77F7||7JL7L.L7.JJ F..L|J.F|LJ.FF77-LF--7L|F7L7F7L7LJL-7L--JL-7L7|L7||FJL7.F7||L-7||||F-JL||F7F--7LF7L--7FJLJ|L-JLJ|LJ|L-7|F--7L7|L--7||L--7LJL7||||F7.--JJJJJ. -77JF--F--FLJF7.LFL-7|LLJL7LJ|JL-7F-JF7.F7FL7||FJ||L7FJFJLJL--J|||||F-7|||||F7|FJ|FF7||7F7L7F7F7L7FJF-JLJF7L7||F-7||L--7L-7FJ|||LJL7F|7||L77 L|7-|J.|.F--L|LJ-7F-J|F7|FL7FJF-7||F-JL7||F-J|||FJL-JL7L------7||LJ||FJ||||||LJL7L7||||FJL7LJLJ|FJ|FJF7F7|L7|LJ|F||L--7L7.|L-JLJF7FJFLFFJ|.F ..JJ||7LLJ.7--7|L-L-7|||-F-JL7L7LJLJF-7|||L-7LJ|L7F---JF--7F7FJ||F-J|L7|LJLJL7F7L7||||||F-J7F7FJ|FJ|FJ|||L7|L-7L7LJ-F7|FJFJF7F7FJLJF-.FJLL77 J.|.L.-7L|77-F7-77LFJ||L7L7F7L7L-7F-JJLJ|L7JL-7|FJ|F7F7L-7|||L7|||JFJFJ|F--7FJ||7|||||LJL7F7||L7|L7LJFJ||FJL-7L7L7F7|LJ|L|FJ||||JJLL77JFJ.77 |.FL|-LLFL---|.FF7.L7||FJ7LJL7L7FJL-77F7|FJF--J|L7LJ||L-7|LJL7||||FJFJF|L-7LJL||FJLJ||F--J||||FJL7L-7L7|||F--JJL7LJ|L-7L7|L7||LJJ.|-FJ-LF7FJ FFJ||--LFJ|JFLF7||F-JLJ|F7F-7L7||F--JFJLJL7L--7|FJF-JL-7|L--7LJLJ|L7|F7|F-JF7FJ||F-7LJL-7L||||L-7L7FJFJ|LJ|FF7F7L7FJF7|FJ|FJ|L7-7-F7F7.LJ7|. FL.J|JLF.FLFF7||||L---7||||FJFJLJL--7|F7F7L7F7|||FJF7F7||FF7L--7FJFJLJLJL--JLJFJLJ||F--7|FJ||L7FJFJL7|FJF7L7|LJL7|L7|LJL-JL7L-J7J|LLJ-7..F7- J-7-J-FF.|JFJLJLJL-7LFJ||LJL7L-7F--7|||LJL7||LJ|||FJ|||||FJL---J|||F----7F-7F-JF7F7||F7LJ|FJ|FJ|FJ7FJ|L-JL7||F--J|FJ|F---7FJF7F7-|.||J.7F-7J L-J-|.F|.L-L----7F7L7L7|L7F7|F7||F7LJLJLF7|||F-J||L7|||||L7F---7|FJ|LF-7LJ-LJ7FJ||||||L7-|L7||.||F7|FJ7F7L|LJL-7FJL-J|7F7LJ||||L-7-LJ|..|7|7 |FLFJF|J7L7|F7F7LJL7L-JL7LJ|LJ||LJL7F77FJLJLJL-7||FJLJ||L7LJJF-JLJFJFJFJF----7L7LJLJ||FJFJFJ|L7|LJLJL7FJL7|F-7FJL7F--JFJL--7|||F-JJ|.F7F|-F7 LL.|F7JLFF7FJ|||F--JF7F7L--JF-JL-7FJ||FJF---7F-J|||F7FJ|FJ|F7L---7L7|FJF|F---JFJF7F-J|L7L7L7L7|L--7F-JL-7LJ|-||F-JL7FFJF---J|||L7F7-FJL7LFLF .|-F---FFJ|L7|||L---JLJL---7|F7F7|L-J|L-JF--JL-7|LJ|LJFJL-7|L7F--JFJ|L--J|F-7FJFJ||F7L7L-JFJFJL7F7|L-7FFJF7L7LJL--7L7L7|F7F7||L7LJL7|F-J7L-J -JF7|-7JL7L-JLJL-----------J|||||L7F-JF-7L7F-7FJL-7|F7L7F-J|FJL--7L7L7F--J|FJL-JFJ||L-JF--J|L7FJ|||F-JFJFJL-JF7.F7|FJF|LJ|||||F|F--J|L-7JJ-. FLF-J7L7LL---7F---7F7F7F7F-7LJLJL7|L-7|FJLLJFJ|F7FJ||L7||F7||F7F7|FJFJL-7FJ|F7F-JFJL-7FJFF77FJL7|||L7FJFJF--7||FJLJ|F7|F-J|LJ|FJL-7.|F-JJJ.L F|LJ|FJL-|JF7LJF77LJLJ|||||L-7F-7LJF7|||-F-7L7|||L7|L7||||||LJLJ||L-JF7FJ|FJ|||F7L--7||F7|L7L-7||LJFJL7L-JF-J||L-7FJ||||F7L7FJ|F-7L-JL----7| LJ|JFJ||FFFJL-7||F7F-7LJLJF--J|FJF7|LJ||FJFJFJ||L-J|7|||LJ||F--7LJF--JLJFJL7||LJL-7FJ|||||FJF7||L-7L7FJF--JF7|L7J|L-JLJ||L-JL-JL7|F7F7F-7FJJ F----JL|7LL--7LJLJ|L7|F-7LL--7|L7|||7FJ|L7L7L7|L--7|FJLJF-JLJF7|F7|F--7FJF-J||F--7||FJ||||L7||||F7L7||FJF7FJLJFJFJF-7F7LJF-7F7F-J||LJ||FJL7J F77FJ.LLF7F--JF--7L-JLJFJF7F-J|7LJ|L7L7L7L7L7|L7F7|LJF7FJ|F7J||||LJL-7|L7|F7||L7FJ|||FJ||L7|||||||J|LJ|J|LJF--JFJFJFJ|L7FJ|LJ|L-7|L-7LJL-7|| --L77FJ|||L-7FJF-JF-7F7L7||L--JF7FL7|FJFJFL7LJFJ|||F7|LJF7|L-J||L7F7FJL7||||||FJL7|||L7|L7|||||LJL7|F7L7|F-JF--JFJ-L7L7|L7F7||F7|L-7L7LJ-||7 .L|LF..FJL7FJL7L--J|LJL7LJL----J|F-J|L7|FF7|F-JL||LJ||F7||L-7FJ|FJ||L-7|||||||L7FJ|||FJ|FJ|||||F--JLJ|FJ|L--JF7FJ-F7L-JL-J|L7LJ|L-7L-J.FLLJ. |L7-J7-L-7LJF-J|F-7F7F-JF--7F7F7LJF7L7|L7||||F7FJL7FJ||LJ|F7||FJL7||F7|||||||L7|L7||||FJ|FJLJ||L-7F7FJL7|F--7|||F7|L--7F77|FJF7L--JJF7-L.|J7 77LJ.-.L-|F7|-F7L7||LJF7L-7LJLJL--JL7|L7LJ|||||L7FJL7|L7J|||||L-7||||||||||||FJ|-|||||L7|L7F-JL-7||LJF7LJL-7LJLJ||L-7FJ|L-JL7||F7F7L||F|7|-| |F--JJ7|F||LJFJL7||L--JL--JF---7F7F-JL-JF7||LJL7|L7FJL7|FJ|||L7FJ||||||||||||L7L7|||||FJL7|L-7F7|LJF7||F---JF---JL7FJL7|F---J|LJLJL-J|JLL77J FLJLL7FJL||JFJF7LJL--------JF-7LJ|L---7FJ||L7F7|L7|L7LLJ|FJ||FJ|FJ|LJLJLJLJ|L7L7|||||||F-J|F-J|LJF-JLJ|L---7|F----JL7FJ|L----JF7F----J|F.L77 -J|JJL.LF|L7L-JL7F7F7F--7F-7|FJF7L---7LJFJL7LJ|L7|L7|F--JL7||L7|L7L-------7|FJFJ|||||||L--JL-7L-7L---7L---7LJL---7F-JL-JF----7||L--7.L-L77L7 JF|7..FF7L-J7F-7||||||F-J|FJ|L-J|F--7L7FJ|FJF7|FJL7LJ|F7F-J||FJ|FJF7F7F7F-J|L7|FJLJ|||||F----JF7L7F--JF7F7L--7F7FJL7F7F7L-7F7LJL---JJ77L-7J. |J|L-7-|L-7F7L7LJ|||||L7FJ|FJF--J|F-JFLJF7|FJ||L7FJF-J|LJF-J|L7|L7||||||L7FJFJ|L-77|||L7|F-7F7||FJ|F-7|LJL--7LJLJF7||LJL-7LJL-7F7F-7.|7JF|JL L-|..L7L-7LJL-JF7||||L7||FJ|-L---JL-----J||L7LJL|L7L7FJ-FJF7L7LJFLJ||||L-J|FJFJF7L7||L7|||FJ|||LJF|L7||F----JF7|FJLJL7-F7L-7F-J||L7L7.|7FJ.L |-7-7FJ|LL-7F7FJ|||||FJLJL-JF---7F7F--7F7|L7||F-JFJFJL-7L7||FJ7F---J||L--7|L7|FJL7|||7LJLJL7|||F--JFJLJL-----JL-JF7F7L-JL-7LJF7||FJFJ-JLJ777 JFL-F|.|J.LLJ||FJ|||LJF7F---JF-7LJ|L-7LJ|L7|L7L7FJ-L7F-JFLJ|L7FJF-7FJ|F7FJ|FJ|L-7||LJF7F7F-J||||F-7L7F-7|F7F7F7F7|LJ|F-7F7L--JLJLJFJJ7.7|F77 LJJ7J|F|..L|7LJL-JLJFFJ|L--7FJLL-7L-7L-7L-JL7|LLJFF-JL--7F-JFJ|FJJ|L7||LJFJL7L7FJLJF-JLJLJF-J||LJ.L-JL7L-JLJLJ||||F7LJF|||F-7F7F7FJFL|-L|JJ| LJ7L.7-FF77F7-F-7F7F7L7|F--J|F-7FL-7|F7|F-7JLJF7F7|F-7F7|L-7|FJL7FJFJ|L-7L7FJFJL--7|F7F--7|F7LJ-F7F7F7L--7F--7LJLJ|L--7||LJFJ||||L77F7.L|7|| |.FL.LF---7||-L7LJLJL7||L---JL7L---JLJLJ|FJF7FJLJ|||FJ||L7FJ|L7FJL7L7|F7L7|L7L7F--J||||F-J||L--7|LJ|||F7|LJF7|F---JF--JLJF7|FJLJL7L-J|7.||L- ..FJ.FL7F7LJL7|L----7LJ|-F7|F7L--------7|L-JLJF--JLJL7|L-JL7|FJL-7|FJ|||FJL7L7|L7F7LJLJL--JL--7|L-7LJLJL7F-JLJ|F---JF----J|LJF7F7L-7FJ7FF77L F-|-7F|LJL7F-JF-7F--JF-JFJ|FJL--------7LJF--7FJF---7FJ|F---J|L7F7||L7||LJF-JFJL7LJL7F---------J|F7L-7F-7|L----JL----JF7F--JF7|LJL77LJLJ-LJJ| F-|--LF---J|F7L7|L--7L-7L7|L---------7LS7L-7LJL|F--JL-JL-7F7|FJ||||FJ|L-7L-7L-7|F7FJL--7F7F---7LJ|F-J|FJL-7F--7F-7F-7||L---JLJF-7|7F|.|FLJL7 -7.|FLL7F-7|||FJ|FF7L-7L7|L--77F----7L-7L--JF7FJL-----7F7LJ|||FJ|||L7L-7|F-JF7|||||J|F7LJLJF--JF7LJF7||F-7LJF7|L7|L7|||F7F---7|JLJLFJ|LL77LF FLL-||LLJFJLJLJFJFJL-7|FJL--7L7L---7L--JF7|FJLJF-7F--7LJ|7FJ|||FJ||FJF-J|L--J||LJ|L-7|L--7FJF7FJ|F7|LJLJFJF7||L-JL7|LJ||LJF-7|L--7---LF-L77| F|FFLJ-F-JF---7|JL--7LJ|F7F7L7|7F-7L---7|L-JF7FJJLJF7L-7|FJFJ||L7|LJ7L-7L--7FJL-7|F7|L7F7LJFJLJL|||L7F-7L-JLJ|LF-7|L-7|L77|FJL---JJ.||.||7-L F|777F-L--JF7|||F--7L-7||LJL7||FJFJF---J|F--JLJF7F7|L7LLJL7L7||FJL----7L7F7|L7F-J||LJ-LJL7FJF7F7LJL-JL7|F----JFJFJL7FJL7L-JL----77.F|7-F7|J| |.|FF77|F--JL-J||F7L--J|L--7LJ|L7|.L----JL-----JLJLJFJF--7L7|||L7F7F-7L7|||L7LJ|.LJF-7F--JL7|LJL7F7F7J||L-7F7L|FJF7LJF7L7F--7F--J7F7JJ||J77| L--FL-F-JF----7|LJL-7F7L---JF7L7|L7F7F7F7F7F-7F-----JFJF-JFJ|||FJ|||.|FJLJL7L-7777|L7LJF---JL7F7LJLJL-JL--J|L7||7||F-JL7|L-7LJJJFFJ||.||FLFL F-LL7-L-7|7F--JL7F7JLJ|F7F--JL7||FJ||||||||L7LJF7F7F7L7L-7L7|LJ|FJLJFJL7.F-JF-J7-F7-L--JF--7.LJ|F-7F7F7F-7LL7LJL7|LJF7FJL7FJF-7|L---7FJF-7LL L7|FLJ..LJ-L---7|||F7FLJ||F---JLJL-JLJLJ||L7L--JLJLJL-JF-J-LJF7|L-7LL-7|FJF7|J-L|||-F7F-JF7L---JL7LJ||||FJF7|F--JL7FJ|L7||L-JFJ7|J-J7LL|JL-7 L7-F.LJ.FFLF---JLJLJL---J|L----7F7F7F--7LJLL-7F-------7L77FLFJLJF-J7-LLJL-JLJF-.F|L-J|L--JL---7F-JF-J|LJL-JLJL----JL7L7L7L--7|F777-L|7J.L|F7 LFJ|L.|-F|FL----7F7F----7|FF7F-J|||||F-JF---7LJJF----7L7L77.L--7L7J|.|.|J7FJJJLFFJF-7L7|F-7F--JL7FJF7|F---7F7F7F7F--JFL-JF-7|LJL7J.L|.77FFF| ||-FJ--.|JF-----J|||F7F7LJFJLJF7|||LJL--JF--J|F7|F--7L7L-JF7|-L|FJ-|-|.L7F|L|L7|L-JLL7L7L7|L--7FJL-JLJL--7LJLJ|||L-------JFJL---J-FFJ.-|-JJ| 7L7L-JFFJ-L---7F7||||LJL7-L7F-JLJLJF7F7F7L7F7FJLJL7-L-JJF7|L7.FLJJFL.F.LLF7-J|F-7F7F7L7L-J||F7LJ7F-7F77F7L--7|LJL---7F----J.F7F--7J.L7JLLFJF |FLJLF-|JLF7F7||LJ||L7F7L--J|F-----JLJLJL7LJLJF--7L7FF-7||L7|-L-J-|7F77-FJ-F77L7|||||F|F-7L-JL--7L7LJL-J|F-7L7F7F7F7LJF7F7F7||L7FJ7FL77.F|-L |--|FJ|L|-|LJ|LJF7LJJLJL7F--JL--------7F7|F7F7L-7L7L7L7LJL-JL77FJJ|7-J|.LJLF---JLJLJL-J||L7F---7L7L----7LJ7L7LJ||LJ|F7|||||||L-JL-7F7JL-|JL| |.|L|LLF|7L-7|F-J|F7-F7FJ|F--7F7F----7LJ|||LJ|F7L7L7L-JF7F7F7|-LJ.|---F-LJFL---7F-7F-7FJF7LJF7FJFJFF--7L---7|F7LJF-J|||LJLJLJF---7LJ|77.||F| F777L|.|J-F-JLJF7LJ|FJ||FJ|F7LJLJF--7|F-J|L-7||L7|FJF7FJLJLJLJJ|FJ-J7|JFFF7|JLFJL7LJJLJL|L-7||L7|F7L7FJF---JLJ|F7|F7|||F--7F-JF-7L--J-L.--F| LJ-FFJ-L|LL----JL7FJL7|LJ.LJL--7FJLFJ|L-7L7FJLJL||L7||L-7F7F77-77L|7-7--7F7J-FJF-JJF---7L-7LJL7||||7|L7L-----7|||LJ||||L-7LJF-JFJJF7J||F|-|| L---JLL.-J|F7F7F7||FFJ|F7F7F---J|F-JLL--JLLJF7F7LJ.LJ|F7LJLJL77JF-J|LJ7F7.||F|FJ7|.L--7|F7L--7LJLJL-JFJF-----J|||F-J||L7FJF7L7FJF7|L7F777FF| -7FJF77-|FFJLJLJLJL7L7||||LJF7F-JL-7JF-7F7F7||||F7F-7LJL---7FJ|.JJ77JLF|77|FLLJLF7-F7FJLJL---JF7F7F-7|FL---7F7LJLJF7|L-JL-JL7||.|||FJ|L77FL7 F--J-F----JF--7F--7L7||||L--JLJF---JFJFJ|||LJLJLJ||FJ7F-7F7LJJ7F|FL-77LL|--L.L|FJL7||L7F-7F7F7|||LJFJ|F7F-7LJL7F7FJLJF7F----J|L-JLJL7L7L7JLJ J7L--L----7L-7LJF-JFJ||||F7F--7L----JFJJ||L7F----J||F7L7||L7F7J-F7L|.--F|.FJFFFJF7LJL7LJ7LJLJLJ|L7FL7|||L7|F--J|||F--J|L-----JF----7L-JFJJ7J FL-..F----JF-JF7L-7L-JLJLJ|L-7|LF-7F-JF7||FJL---7L|LJ|-|||FJ|||F77-|L..-JFL7FFL-J|F-7|F7F7F7F--JFJF7||||L||L---JLJL-7|L-7F--7FJF--7L-7FJJ||7 FJ.LFL----7|F-J|F-JF7F-7F7L--JL7L7|L--JLJLJF----JFJF7|FJ|||L|L7|L7-||F-J.J.-FJ.|FJ|FJLJLJLJ|L---JFJLJLJL-J|F---7F7F7L--7|L-7|L-JF7L-7|L-7F7J ..77||F|J7|||F7LJF7||L7LJL----7L-J|F-------JF77F7L7|LJL7LJL-JFJ|FJ-|-JJ|.L7.|FF-JFJL-7F7F-7L----7L---7F7F7LJF7F||LJL---JL--J|F-7|L7FJ|F7LJ|| 7.LF|LFJ-FLJLJL--JLJ|FJF7LF7F7L--7LJ7F------JL-JL7|L7F7|F----JFJL77J.|.L--|-JFL7FJF-7LJLJFJF7F-7L----J|LJL-7|L7LJF7F7F7JF--7|L7||.||.|||F-JJ ....|-L7FLF---7F----J|FJL-JLJL---JF7FJF7F7F-7F7F7LJFJ||||7F7F-JF-JF77J|.JF|L7J.LJFL7L---7L-JLJ-L---7F7|F---JL7|LFJ||||L-JF7||FJLJFJL7|||L7JJ 7.FF|7J.F.L-7FJL-7F--JL-7F7F---7F-JLJFJLJ|L7|||||F7|FJLJL7|||F-JF-J|-F77J|LF7.-L|F7L---7L--7F------J|||L-----JL7L7||LJF--JLJLJF7LL7FJ||L7||L F--7JF7FF---JL--7LJF---7LJ||F--J|F---J7F7|FJ|||||||LJF7F7LJ||L--JF-J7||J7J.|L7..FJL77F7L-7FJ|F-7F-7FJLJF---7F-7L-JLJF7|F7F7F--JL-7||7LJJLJ77 JJF|||F-L7F7F-7FJF7L--7|F7LJL-7FJL-7F--J||L7LJ|||||F7||||F7LJF--7L-7FJ||F-7-F7FFJF7L7||F-JL7LJFJ|FLJF7LL--7|L7|F7F7FJ|LJLJLJF-7F7|LJF|L-7|-7 J7-7.FF|-LJLJFJ|FJ|F7FJLJL7F7FJ|F-7LJF7FJL-JF7LJ||||||LJLJ|F7L-7L7FJ|FJFJFJJ|L7L7|L7LJ|L-7FJF7|FJF--JL----JL-JLJ||||FJF-----JFLJLJ7LF-7J-7.| LJF|-FJL.|LF7L7|L7|||L--7FJ|LJFJL7L--JLJF---JL-7LJLJ|L--7FJ|L--J7LJ7|L-JFJF-JFJJLJ7L-7L77|L-J|LJ.L-------------7LJ||L7L----7F-7JF-77|FJJLF.F .LJ|..7--F-JL-JL-J|||F--JL7L--JF7L------JF----7L7F7FL--7|L-JF7-F-7F7L--7|7L-7|F-7F--7L7L-JF--JF7F7F------------JF7LJ.L7F7F7LJFJFJFJFJL77FL-J LF-|7FF7-L-------7LJ|L---7|.F7FJL--------JF7F7L-J|L-7F7LJF7F|L7L7||L7F-JL7LFJ|L7|L-7L-JF-7||F-JLJLJF-7F-------7FJL7FF7LJ|||F-JFJFJFJF-J-L-J. L7J||.|.FF7F7FF--JF7L7F--JL-JLJF------77F7|LJL7F-JF-J|L7FJ|FJFJFJ||FJL--7L7L7L7|L77L-7FJFJL7L------JFLJF7F----J|F-JFJL-7LJ||LFJFJFJFJ|J|JL7. LJF|J.77FJLJL-JF7FJL7LJF7F-----JF7|F-7L-JLJF-7LJF7|F7L7||FJ|FJFJFJ|L7|F7L7L7|FJL7L7F7LJFL7FJF--7F77F7|FJLJ|F7F7|L7FJF--JF7LJFJFJLL7|F777..|. |7F|J|.-L----7FJ|L-7L--J||F-----JL-JLL-----JFJF-JLJ|L7|LJL7|L7L7L-JFJFJL-JFJ|L-7L7||L--7FJ|-L-7LJL-JL-JF---JLJ||FJL7L---JL7FJFJF7FJLJL-7--77 L7FJF7F-FF---JL7L7FJF---J|L7F7F-7F-7F--7F7F7L-J-F7L|FJL-7FJL7L7|F7FJ-L7F-7L-JF-JFJLJF--JL7L7F7L-----7F7|F--7F7LJL--JF7F---JL7|.|LJF7F--J|-|J L||-L7-JL|F7F7FJFJ|FJF7F7|FJ|LJ.LJJLJF7LJLJL7-F7|L-JL--7|L-7L7|||LJLF7||FL7F-JF7|F-7L---7L7LJL------J|LJL-7|||F-----JLJF7F7FJL-JF7||L-7J-7F7 ||LFLJ.F-LJLJ||FJFJL7|LJLJL-JF7F7F7F7||F-7F7L-JLJF7F---J|F-JFJLJL--7||LJF-JL-7||LJ|L7F--JFJF---7F7F7FJF-7FJLJ|L--7.F--7|LJ||F---J||L--JJJFFL L|J...FF----7LJL-JF7LJ|F7LF7FJLJLJLJLJ||FJ||F7F7FJLJF7F7||-FJF-----J|L7FJF7F-J|L7JF7||F7F|FJFF-J|||LJJL7LJF-7L--7L-JF-JL-7||L--7LLJF7|F77FJ| LL7F-7FL-7F7|F7F7FJL--7||FJ|L--------7|||FJLJLJLJF7FJ||||L7|FJ7F--77|FJL-J|L7|L7|FJ||LJL7LJF7L--J||F---JF-JFJ-F7L---JF7F7|LJF--JF7FJL-JL-7JJ ..|7.||FLLJ|LJLJ|L---7LJ|L7|F--7F----JLJLJF---7F-J||FJ||L7|||F7|F-JFJL77F7L7|F7||L7|L--7L--J|F7F7LJL----JF-J-FJL-----JLJLJF7L-7FJ||F-----JJ. F-7-FJ|F--FL7F-7L---7L-7L-J|L-7|L------7F-JF--JL-7LJL7|L-J||LJ||L-7L7FJFJL-JLJ||L7|L--7L-7F7LJLJL7F7F7JF-J-F7|F-7F-7F7F-7FJL-7LJFJ||FF---7-| J7|7||L7JFF7|||L7F-7L-7L7F7L--JL-------J|F7L---7FJF--JL-7FJL7FJ|F-JFJ|.L----7FJL7||F-7|F7LJ|F-7F7LJLJL7L---JLJL7LJFJ|||FJL--7L-7L-JL7|F--JL7 .7LFF-L|J-||LJF-JL7|F7L7LJL7F7F7F7F77F7|LJ|F---JL7|F-7F-JL7FJ|FJ|F7L7L7|F7F-JL--JLJL7LJ|L-7|L7LJL---7FJF7F-7F-7L-7L-JLJL7F-7|JFJF7F7LJL--77| -J-||FFF-7||F7L---JLJL7L7F7||LJLJLJ|FJL7F7|L7F-7FJ||FJL-7FJL7|L7|||FJFJFJ||F----7F--JF7L7FJL-JF77F--JL-JLJFLJJ|F7L-7JF--JL7||FJFJLJL7F--7|FJ LJF|F--JFJ||||F7F7LF7|L7LJ|LJF7F7F7LJF7LJ|L7LJFJ|FJ||F7J||F7|L-J||LJFJFJFJLJF---JL-7FJ|FJL7F7FJL7L-7F7F7F----7LJ|F7L7L7F-7|LJL7L--7FJL-7||JJ FF-FL--7L-J||||||L-J|F-JF7L--JLJLJL--JL--J.L-7L-JL7|||L7|LJ|L--7||F-JFJFJ.F7L7F7F7FJ|FJ|F-J|LJF7|F-J|LJLJF7F-JF7|||FJFJL7|L7F7|F-7|L-7FJLJJ7 --7|-F-JF-7|||||L--7|L--JL-----7F---7F7F7F7F-JF-7FJ|||FJL-7|F7FJ|||F7L7|F7||-LJLJ||FJL7|L-7|F-JLJL-7|F---JLJF7||LJLJLL7FJ|FJ|LJ||LJF-J|F77F7 .L77.L--JFJLJLJ|-F7||F7F------7||F--J|||LJ|L-7||LJF||||F77|||||FJ||||FJ|||||F-7F-JLJF-JL-7LJL--7F7.LJL------JLJL-7F7F7LJ-|L7|F7L7.L|F7LJL-J| 7.L-|JJF-JF---7L-JLJLJ|L7F-7F7LJ|L---JLJF7|F-JL7F7FJ|||||FJ|||||FJ|||L7||||||FJL---7|F7.FJF---7||L-7-F------7F---J|LJL7JFJFJLJL7L-7LJL7F7F7| |-|JJLFJF7|F--JF-7F7F7L-J|LLJL7FJF7F7F--JLJL-7FJ||L7|||||L7LJ||LJFJ||FJ||||||L-7F7J|LJ|FJFJF7JLJL-7L7|F7F--7LJF---JF-7L7|FJF---JF7L--7|||||| FJJ|JF|FJLJL7F7L7LJLJ|F--JF7F7LJFJLJ||F7F7F7FJL7||FJ||||||L-7||F-JFJ||FJ|||LJF7|||FJF-J|FJ.|L-7F7FJFJLJLJF-JF7|F--7L7|FJ||JL--7FJ|F7FJ||LJ|| 77FJ-JLJF|F-J|L7|F7F-J|F-7|LJL--JF-7LJ||||||L7FJ|||FJ||||F7|||||F7L7|||7||L7FJLJ||L7|F7||F7L7FJ|||FJF7FF7L--JLJL-7L-JLJFJL-7LFJ||||LJFJ||||| J-7JJFF---JF7|.LJ||L--JL7|L---7F7|7L7FJ||||L7|L7|||L7|LJ||L7|||||L7|LJL-JL7||F7FJ|FJLJ||||L7||FJ|||FJ|FJL7F-7F7F7L----7L--7|FJFJFJL-7L-J7FLJ L-77F-|F--7|||F--JL---7FJ|F7F7LJ|L-7|L7||||FJ|FJ||L7|L-7||FJ|LJ|L7|L7F--7-||LJ|L7LJF7FJ||L7||LJFJ||L7||F-JL7||LJL--7F7L7F7LJL7L7L--7|7JL7-JJ |FL||FLJ|LLJLJ|F-----7|L7LJLJL--JF7||FJ|||||FJL7|L7||F-J||L7L7J|FJL7||F7L-JL-7L7L--J|L7|L7||L-7|FJL7|LJL-7FJ|L--7F7LJL-J|L7JLL-J7J|LJ-7-F77| FF-JF|F|-.F7F7|L7F---J|||F7F7F-7FJ||||FJ||||L-7|L7|||L-7LJFJFJFJL-7LJLJ|F7F7FJF|F---JFJL7|||F7|||LFJL7F7FJ|F|F-7LJL7F7F7|FJJLFJ-J-|J|FJ.|L-J -F-F-L-F--|LJLJFJL---7L-J|||||FJL7LJLJ|FJ||L7FJL7|||L7FJF7L7L7L7F7|F---J||||L7FJL--7JL7FJ||||LJLJFJF7LJ|L7|FJL7|F7FJ|LJLJL--77J7.-.|L7LFL-|J ||--77FL-LL-7F-JF----JF7FJ||||L7FJF--7LJ|LJFJ|F-J||L7||FJL-JFJ-||||L-7F7|LJ|FJL7F--JF-J|-LJ|L---7|FJ|F7L7||L7FJLJ||||F----7FJ|FJFLF-7|.LFJJ. -FJ-F7|.LFLFJ|F7L--7F7||||LJ||FJL-JF7L---7LL7||F7|L7|||L-7F7|F-J|||F-J||L-7|L7||L-7LL--JF--JF---JLJ||||FJLJF|L-7FJL7||F--7||LL7-7L7LF-7LJJ.. FF7.||JF-7JL-J||F7FJ||||L--7LJL--7FJL--7FJF7LJLJ|L7||||F-J|||L7FJ||L-7|L-7||FJFJF7L7JF-7L7F7L-7JF---J|||LLF-JF-JL-7LJLJF-JLJ7|FJ|7LJL-J7JL-7 LLJ7-L-|J.FF--JLJLJFJ|||F--JF7F--JL---7|L7|L----JFJ||LJ|F7|||7|||||F-J|F7|||L7|FJL7|FJFJ7LJ|F7|FJF7F7||L7FJF7L---7|F-7FJF7JJLJJ7L-7FLJ7|7.77 LLLFJ-FJ-FJL---7F-7L7LJ|L7F-JLJF7F7F--JL7||F7F7F7L7|L-7||LJ|L7|L7||L--J|LJ|L7||L-7|LJFJ|F7FJ||||FJ||||L-JL-J|F-7FJLJFJL-JL77FLJJ7.F--7-||FF7 |FJF7.J-FF7FF--JL7L7|F-JFJL--7FJ|||L---7||LJLJ|||FJ|F-JLJF-JFJ|FJ||F---JF7L7|||F7||F7L-7|LJFJ|||L7|||L----7FJL7|L--7L7F7F7L7JJ7LLL-JFLJFF|-J F|F|J-|--7|-L7F7FJFJ|L7FJ|F--J|7LJ|F-7FJ||F---J|||FJL-7F7L-7L7||FJ|L7F-7|L7|||||LJLJ|F-JL-7L7||L7|LJ|F----J|F-J|F-7L7||LJL-J.L7..L|.LL7-FLJ7 -7-|F7L7J|F7|LJLJ7L7L7LJF7L7F7L7F-J|JLJFJ|L-7F7|||L-7FJ|L--JFJ|||FJ|LJFJL7LJ|||L-7F-JL-7F7L-JLJFJ|F-J|F----JL-7||FJFJ|L-7F7.F.|-7-|-LJJF-7|| ||JL||FJFLF--------JFJF-JL-J||FJ|F7L--7L-JF-J|||LJF-JL7L---7|.LJ|L-7F-JF7L-7LJ|F-JL-7F7LJL---7|L7||F-JL7F-7F7FJ||L-JFJF7LJL7JLL-77F-7JF-J--- 7.L-J-L-L7L7F7F7F7F-JFJF-7F7||L7LJ|F--JF7LL7FJLJ-FJF-7L-7F-JL-7FJF-JL--JL7FJFFJL-7F-J|L---7F7L7FJ||L-7FJL7||||FJL--7L7||F--J-JF|JJ|LJ7|JLLJJ L7.FJJJ|L-7LJLJ||||F-JFJFLJ|||FJLFJL---JL7L|L--7FJFJLL7FJ|F7F-JL-JF------JL-7L7F7|L-7L--7JLJL-JL7||F-J|F7|||||L-7F-JFJ||L---7-JL|77FL|JF7-|. |L7JL|-L---J-|-LJ||L7FJF7F-J|||F-JF------JFJF-7|L7L--7||FJ||L---7FJF-7F7F7F-JFJ|||F-JF-7L---7F-7LJ||F7LJ||LJ||7FJL-7L-J|F---J-JFL|-F-|LJJ--7 J7L7-7..|.L.---J-LJ-||FJLJF7|LJ|F7L---7F7FJFJFJ|FJF-7|||L7|L7F7FJL7|FJ|LJ|L-7|FJLJL7FJFJF---JL7L7FJLJL7FJ|F-JL7L7F7L--7|L-77L7FF7|.J7LFJL7FJ FF7|7L7-|.|FJL7FFJ|.LJL--7|LJF-J|L7F-7LJ|L-J7L-JL7|FJ|||F|L7|||L7F||L7|F-JF7||L7F--JL7L7L-7.F-JFJL7F7FJL-JL7F7|JLJ|F--JL--JJJ--F7|FL7|LF-FJJ F|FFJ7LL--F7F--.|F7F-----JL7FJF7|FJL7L-7L---7F---J|L-J||FJFJ||L-JFJ|7LJL7FJLJL-JL7F--J||F-JFJF7L-7LJ|L-7F--J||L--7|L77LL-|J-|F-7LJ7.L7|L-7FJ LLJL777FJLLJJ7|LFJ|L------7||FJ||L7FJFFJF7F7||F--7|FF-J|L7L7||F7-L7|F---JL--77F--J|F---JL--JFJ|F7L7FJF7||F-7||F7FJ|FJJLJ.L|.L7.|J|L|JFJ7F.77 J.7J777L-J.|FJ-LL7L-------J||L7LJFJL-7L7|LJ||||F-JL7L-7L7|FJ|LJ|F-J|L-7F7F-7|FJF7FJL-7F-7F7FJ.||L7|L7|||LJFJ||||L7LJJJ.|.JJ|7L-F.|.J-7-|JFJ7 FFJ|FJ-|..FJ7|.|L|F-7F---7FJ|FJLFJF7FJFJL7.LJLJ|F-7|F7|FJ|L7|F-JL-7|F-J||L7||L-J||JF-JL7||||F7LJ7LJ-LJ|L-7L-J|||FJJJ|LF77|7F77J|L77L7JFJ-FJ| L|.F|-LJ.FJF7LJJ|LJFJ|.F-J|||L-7|FJLJFJF7L--7F-JL7|||LJL7L7||L-7JJLJL7FJL7|LJFF-JL7L7F7||||LJL--7-LF--JF-JJ-FJ||L7-LL7|L-|-JJ7F|J.7.-77|F|JJ FJ-7.-7--|FL--7F|.|L-JFJF7|FJF7||L7-FJFJ|F--JL-7FJLJ|F-7L7||L--JFFFJF||-FJ|FF-JF7FJ|LJ||LJL7F---JJ|L---J7|77L-JL-J77|J|7LL77LJ|.|-|F|.F-JJ|. |JJFJJ.FLL.|.LL-JFF7|LL7|LJ|FJ||L7|FJFJFJL--7F-J|7.L||F|FJ|L--7JJ-L-LLJJL7|FJF-J||F7JFJL7F-JL7JL|.7LF|-LJ-7-FJJLL|.7JLLJ7.F7-FF77-LF|FFJ-777 ||JL7|F-JLF77J|.L-.F-F-J||FJ|7LJ7||L7|FJF-7FJ|F7L-7.LJ-||FJF-7|.|JJ.L|7LL|||FJF-JLJL7|F7|L-7FJJ7F-|--JFL|LL7L|F-FF7L77L7--LF7LLF|JFL|7|--7JJ JJ--J7-L-7JL|J|-..7|FL--J-L7|7J|FJ|FLJ|FJFJ|7LJ|F-J-7F-J|L7|-LJ-|J|7F|--LLJLJFJF-7F-JLJ||F-JL7-L--L-JL|.7FLJF||.-JJ7.|JL|.LJJ.F|.F7LF-J.FJ.. .|L-J|7|L7.|L-J.LJLJLJL|L||LJ7-LL-J-LLLJ7L7L7L|LJ.|7F|F7|JLJFL|.F.F-LLJ-LLLLJL7|FJL---7LJL-7FJJ.L77.F7|FL-JL|-J7|JF7F|7.F7LJ.--.F||LL.--F-|7 .-7J7LF7-|--JLF-.|7.FFFJF-FJL|F||L77L7|FJ-L-JF|J|-|-FJ|LJ|LL7-FLL.--7F-7.|7|.LLJL7F--7|||LFJ|J.|7FF-J-J7JL.||||-LL|JLJL|.J.LF.F7JL7|L|J.|.|L |FJ.|.|--.LJJF-LFJJ7FLJ.7LJJF|-|J||7FJJF7F||.||.-7LFL-JJL-F.F.-JL.J-77|77.LL-7|-|||JLLJ-7-|FJJ7.L.|FJ-||LL-F-7F-77FJL.FL7J77F7FJJ.F--JJ-J7FJ F--J..L-|FF.LFLL.|J-7J7F--|JL7|LL7.F|F-LJF|77||FL--7J|JL.L|7F-.L|7-F.--JL77FLL7|F||J7|LL|.LJ|L.77.-|.|L7F-.|LLF7|-77|.JJ|.F-JL|JFLF|F7|7F7J| 7|FJ.|.F|--J.F7L7JL-J.-FF-77.LF7|JF-J77FL|L-7J.F.L-JL-.|.7-|..7|.|||.|F--FFJJ.F7LLJF-|-.LFJJ||F|FF7|-|-|7F-|JJ.F77FF--7.LL|-JFLJL-L7|J-FF-F7 L7J.F|-7|J|-F|7L-77-L-7LL7FJF.J-|-----LJ-J||J7LF77|.FF-7|J-|F7.J-|7||77--7|||.L|.LL|-J.7-||.L-L7L|-7JL-||J-J.FFFL7LJ-L|-FJ.LF|7FJ--J|77L7.|| FJ-L--7J--J-LL--LL77-LL.L7J.JJJJL-|J..J----7L-JL|-J-|J-LJF-|.L-LJ..|JL-JLLLJJJ--7LJL-J.|L--FFJ.|JL-J.J-L|---F--|L|..7.L|.F|L-J--JJ.-.FJLL7JJ #+end_src