Daniel Ziltener e2a6188d9d | ||
---|---|---|
.dir-locals.el | ||
.gitignore | ||
README.org | ||
chicken-src.org | ||
chicken.org | ||
day3.scm | ||
day4.scm | ||
day5.scm | ||
day6.scm | ||
day7.scm |
README.org
Advent Of Code with Chicken Scheme
- Prelude
- Day 1: Trebuchet?!
- Day 2: Cube Conundrum
- Day 3: Gear Ratios
- Day 4: Scratchcards
- Day 5: If You Give A Seed A Fertilizer
- Day 6: Wait For It
- Day 7: Camel Cards
- Day 8: Haunted Wasteland
Prelude
I don't know why I am spending my time this way, but I am trying to get through this year's Advent of Code. I decided to use Chicken Scheme, and I am trying to use as few (if any) extensions, for an extra challenge.
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 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 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:
1abc2 pqr3stu8vwx a1b2c3d4e5f treb7uchet
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
(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)))
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:
two1nine eightwothree abcone2threexyz xtwone3four 4nineeightseven2 zoneight234 7pqrstsixteen
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
(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)))
Puzzle Input
Jump to day 2.
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
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:
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
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.
;; 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))
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.
;; 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))
Draw Processing
And as the last pre-processing step, I take apart the individual draws, and assign each amount to its respective colour keyword.
;; 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))
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.
;; 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))
Then, I put everything together in a main function, preprocessing the input and summing up all game
ids for which game-possible?
returns #t
.
;; 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)))
And now, everything can be put together:
(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)))
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:
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
- 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.
(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))))
And the main function gets modified to sum everything up.
(define (game-set-power input)
(let ((games (record-fold input)))
(foldl + 0
(map (lambda (game)
(powercalc (cdr game)))
games))))
The full thing put together:
(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))))
78375
Puzzle Input
Jump to day 3.
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
Day 3: Gear Ratios
Get the puzzle solution as tangled .scm file.
Part One
Quest
You and the Elf eventually reach a 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:
467..114.. ...*...... ..35..633. ......#... 617*...... .....+.58. ..592..... ......755. ...$.*.... .664.598..
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
(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)
Indexing the Input
(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))))))
Tokenizing the Indexed Input
(define (number-char? c)
(case (buffer-char-char c)
((#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9) #t)
(else #f)))
(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))))
(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))))))
(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))))))))
Checking for Part Neighbours
(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))))
Folding Everything Together
(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)))))
(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))
(let-values (((part-nums part-syms) (tokenize-indexed-input (index-input (string->list input)))))
(fold-part-numbers part-nums part-syms))
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:
467..114.. ...*...... ..35..633. ......#... 617*...... .....+.58. ..592..... ......755. ...$.*.... .664.598..
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
(define (gather-neighbours part-sym part-nums)
(foldl (lambda (output input)
(if (neighbours? input part-sym)
(cons input output)
output))
(list) part-nums))
Put Everything Together
(define (filter-gear-candidates part-syms)
(foldl (lambda (output input)
(if (eqv? '* (part-symbol-sym input))
(cons input output) output))
(list) part-syms))
(define (calc-gear-ratio gears)
(foldl (lambda (output input)
(if (= 2 (length input))
(+ output (apply * (map part-number-number input)))
output))
0 gears))
(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)))
75220503
Puzzle Input
Jump to day 4.
.....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..
Day 4: Scratchcards
Get the puzzle solution as 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 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:
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
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.
(define-record scratchcard id winning-numbers card-numbers match-numbers copies)
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.
(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))
The pattern is then used to extract every scratch card which is then being parsed in a fold statement.
(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))
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 !
.
(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)))
As a next step, I calculate the points for each card.
(define (card-points card)
(let ((match-nums (scratchcard-match-numbers card)))
(foldl (lambda (points num)
(if (= 0 points)
1
(* points 2)))
0 match-nums)))
And now, we can put everything together and sum up the points:
(foldl
(lambda (sum card)
(calc-card-matches card)
(+ sum
(card-points card)))
0 (input->cards input))
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:
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
- 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
(define (card-alist cards)
(foldl (lambda (alist card)
(calc-card-matches card)
(alist-update (scratchcard-id card)
card
alist))
'() (reverse cards)))
(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)))
(define (count-scratchcards cardlist)
(foldl + 0 (map (compose scratchcard-copies cdr) cardlist)))
(let ((cardlist (card-alist (input->cards input))))
(generate-copies cardlist)
(count-scratchcards cardlist))
5923918
Puzzle Input
Jump to day 5.
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
Day 5: If You Give A Seed A Fertilizer
Get the puzzle solution as 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 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 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:
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
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
:
50 98 2 52 50 48
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:
seed soil 0 0 1 1 ... ... 48 48 49 49 50 52 51 53 ... ... 96 98 97 99 98 50 99 51
With this map, you can look up the soil number required for each initial seed number:
- Seed number
79
corresponds to soil number81
. - Seed number
14
corresponds to soil number14
. - Seed number
55
corresponds to soil number57
. - Seed number
13
corresponds to soil number13
.
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
, soil81
, fertilizer81
, water81
, light74
, temperature78
, humidity78
, location82
. - Seed
14
, soil14
, fertilizer53
, water49
, light42
, temperature42
, humidity43
, location43
. - Seed
55
, soil57
, fertilizer57
, water53
, light46
, temperature82
, humidity82
, location86
. - Seed
13
, soil13
, fertilizer52
, water41
, light34
, temperature34
, humidity35
, location35
.
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
(define-record entity type id)
(define-record mapping-entry from-type to-type from-start from-end to-start to-end)
Data Extraction
Irregexes
(define seed-irregex
'(: (* whitespace)
"seeds: "
(submatch-named seed-numbers (+ (or numeric whitespace)))))
(define mapping-irregex
'(: (submatch-named mapping-from (+ alphabetic))
"-to-"
(submatch-named mapping-to (+ alphabetic))
" map:"
(submatch-named mapping-vals (+ (or numeric whitespace)))))
(define mapping-nums-irregex
'(: (* whitespace)
(submatch-named to-range (+ numeric))
(* whitespace)
(submatch-named from-range (+ numeric))
(* whitespace)
(submatch-named range-size (+ numeric))))
Data Reading
A list of seed numbers:
(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))))
And a mapping from input type (e.g. #:soil
) to the mappings to the next type:
(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))
Processing The Data
(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)))
(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)))
Solution
(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)))
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.
(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))))
After that, it is almost identical to part 1, but we have to replace the foldl
with a recursive
function that handles the promises.
(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)))
(let ((seeds (expand-seeds (input->seeds-list input)))
(mapping-alist (input->mapping-alist input)))
(fold-seeds seeds mapping-alist))
37806486
The Optimized Solution
For the optimized solution using ranges, a new record type is needed: ranged-entity
.
(define-record ranged-entity type from-id to-id)
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 themapping-entry
: the part lower has to be extracted into a 1:1-mapping for the next step type.
(define (extract-dangling-entity-part ranged-entity type mapping-entry)
(let ((mapping-entry-lower-bound (mapping-entry-from-start mapping-entry)))
(values (make-ranged-entity type
(ranged-entity-from-id ranged-entity)
(- mapping-entry-lower-bound 1))
(make-ranged-entity (ranged-entity-type ranged-entity)
mapping-entry-lower-bound
(ranged-entity-to-id ranged-entity)))))
- The beginning of
ranged-entity
is somewhere insidemapping-entry
: the part inside themapping-entity
's range has to be extracted and the ids shifted accordingly.
(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))))
- There is just
ranged-entity
left, with nothing else: then it gets a new type, and is otherwise passed on 1:1.
(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))
This behemoth determines which of the functions above to call.
(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)))))
Here, the mapping is being done.
(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)))
'()))
And here, it is all put together.
(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))))))
Puzzle Input
Jump to day 6.
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
Day 6: Wait For It
Get the puzzle solution as 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:
Time: 7 15 30 Distance: 9 40 200
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 traveled0
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 of1
millimeter per millisecond for6
milliseconds, reaching a total distance traveled of *=6 millimeters=. - Hold the button for
2
milliseconds, giving the boat a speed of2
millimeters per millisecond. It will then get5
milliseconds to move, reaching a total distance of10
millimeters. - Hold the button for
3
milliseconds. After its remaining4
milliseconds of travel time, the boat will have gone *=12= millimeters=. - Hold the button for
4
milliseconds. After its remaining3
milliseconds of travel time, the boat will have gone12
millimeters. - Hold the button for
5
milliseconds, causing the boat to travel a total of10
millimeters. - Hold the button for
6
milliseconds, causing the boat to travel a total of6
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.
(define-record race time-limit record-distance winning-distances losing-distances)
The solution starts with the usual data extraction using irregex
.
(define input-extraction-irregex
'(: "Time:"
(submatch-named time-vals (+ (or numeric whitespace)))
"Distance:"
(submatch-named distance-vals (+ (or numeric whitespace)))))
Next, the data is converted into race
records.
(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))))))
Race Calculations
(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)))))))
Getting The Result
(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)))))
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 kerning. There's really only one race - ignore the spaces between the numbers on each line.
So, the example from before:
Time: 7 15 30 Distance: 9 40 200
…now instead means this:
Time: 71530 Distance: 940200
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:
(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)))
And instead of keeping a list of all winning and losing distances, I use a counter.
(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)))))))
Race Variant Results
(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))))
41513103
Puzzle Input
Jump to day 7.
Time: 58 81 96 76
Distance: 434 1041 2219 1218
Day 7: Camel Cards
Get the puzzle solution as tangled .scm file.
Part One
Quest
Your all-expenses-paid trip turns out to be a one-way, five-minute ride in an 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 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 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:
32T3K 765 T55J5 684 KK677 28 KTJJT 220 QQQJA 483
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
andKTJJT
are both two pair. Their first cards both have the same label, but the second card ofKK677
is stronger (K
vsT
), soKTJJT
gets rank 2 andKK677
gets rank 3.T55J5
andQQQJA
are both three of a kind.QQQJA
has a stronger first card, so it gets rank 5 andT55J5
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 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.
(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))))
#<unspecified>
The hands are separated into types.
(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)
#<unspecified>
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:
(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)))))
#<unspecified>
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
;(get-type-for-cards #:A #:A #:A #:A #:A)
#:five-of-a-kind
((= 5 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:five-of-a-kind hand-types)))
Error: (#f) "unbound variable": (frequencies) Call history: <eval> (with-all-output-to-string (lambda () (call-with-values thunk (lambda v (set! result v))))) <eval> (with-output-to-string (lambda () (with-error-output-to-port (current-output-port) thunk))) <eval> (with-error-output-to-port (current-output-port) thunk) <eval> (current-output-port) <eval> (call-with-values thunk (lambda v (set! result v))) <eval> (eval form) <syntax> (begin ((= 5 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:five-of-a-kind hand-types)))) <syntax> (##core#begin ((= 5 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:five-of-a-kind hand-types)))) <syntax> ((= 5 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:five-of-a-kind hand-types))) <syntax> (= 5 (car frequencies)) <syntax> (car frequencies) <syntax> (hand-type-rec-set! hand (alist-ref #:five-of-a-kind hand-types)) <syntax> (alist-ref #:five-of-a-kind hand-types) <eval> ((= 5 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:five-of-a-kind hand-types))) <eval> (= 5 (car frequencies)) <eval> (car frequencies)
-
Four of a kind, where four cards have the same label and one card has a different label:
AA8AA
;(get-type-for-cards #:A #:A #:8 #:A #:A)
#:four-of-a-kind
((= 4 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:four-of-a-kind hand-types)))
Error: (#f) "unbound variable": (frequencies) Call history: <eval> (with-all-output-to-string (lambda () (call-with-values thunk (lambda v (set! result v))))) <eval> (with-output-to-string (lambda () (with-error-output-to-port (current-output-port) thunk))) <eval> (with-error-output-to-port (current-output-port) thunk) <eval> (current-output-port) <eval> (call-with-values thunk (lambda v (set! result v))) <eval> (eval form) <syntax> (begin ((= 4 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:four-of-a-kind hand-types)))) <syntax> (##core#begin ((= 4 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:four-of-a-kind hand-types)))) <syntax> ((= 4 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:four-of-a-kind hand-types))) <syntax> (= 4 (car frequencies)) <syntax> (car frequencies) <syntax> (hand-type-rec-set! hand (alist-ref #:four-of-a-kind hand-types)) <syntax> (alist-ref #:four-of-a-kind hand-types) <eval> ((= 4 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:four-of-a-kind hand-types))) <eval> (= 4 (car frequencies)) <eval> (car frequencies)
-
Full house, where three cards have the same label, and the remaining two cards share a different label:
23332
;(get-type-for-cards #:2 #:3 #:3 #:3 #:2)
#:full-house
((and (= 3 (car frequencies)) (= 2 (cadr frequencies))) (hand-type-rec-set! hand (alist-ref #:full-house hand-types)))
Error: (#f) "unbound variable": (frequencies) Call history: <eval> (eval form) <syntax> (begin ((and (= 3 (car frequencies)) (= 2 (cadr frequencies))) (hand-type-rec-set! hand (alist-ref #:full-house hand-types)))) <syntax> (##core#begin ((and (= 3 (car frequencies)) (= 2 (cadr frequencies))) (hand-type-rec-set! hand (alist-ref #:full-house hand-types)))) <syntax> ((and (= 3 (car frequencies)) (= 2 (cadr frequencies))) (hand-type-rec-set! hand (alist-ref #:full-house hand-types))) <syntax> (and (= 3 (car frequencies)) (= 2 (cadr frequencies))) <syntax> (##core#if (= 3 (car frequencies)) (and26474 (= 2 (cadr frequencies))) #f) <syntax> (= 3 (car frequencies)) <syntax> (car frequencies) <syntax> (and26474 (= 2 (cadr frequencies))) <syntax> (= 2 (cadr frequencies)) <syntax> (cadr frequencies) <syntax> (hand-type-rec-set! hand (alist-ref #:full-house hand-types)) <syntax> (alist-ref #:full-house hand-types) <eval> ((and (= 3 (car frequencies)) (= 2 (cadr frequencies))) (hand-type-rec-set! hand (alist-ref #:full-house hand-types))) <eval> (= 3 (car frequencies)) <eval> (car frequencies)
-
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
;(get-type-for-cards #:T #:T #:T #:9 #:8)
#:three-of-a-kind
((= 3 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:three-of-a-kind hand-types)))
Error: (#f) "unbound variable": (frequencies) Call history: <eval> (with-all-output-to-string (lambda () (call-with-values thunk (lambda v (set! result v))))) <eval> (with-output-to-string (lambda () (with-error-output-to-port (current-output-port) thunk))) <eval> (with-error-output-to-port (current-output-port) thunk) <eval> (current-output-port) <eval> (call-with-values thunk (lambda v (set! result v))) <eval> (eval form) <syntax> (begin ((= 3 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:three-of-a-kind hand-types)))) <syntax> (##core#begin ((= 3 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:three-of-a-kind hand-types)))) <syntax> ((= 3 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:three-of-a-kind hand-types))) <syntax> (= 3 (car frequencies)) <syntax> (car frequencies) <syntax> (hand-type-rec-set! hand (alist-ref #:three-of-a-kind hand-types)) <syntax> (alist-ref #:three-of-a-kind hand-types) <eval> ((= 3 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:three-of-a-kind hand-types))) <eval> (= 3 (car frequencies)) <eval> (car frequencies)
-
Two pair, where two cards share one label, two other cards share a second label, and the remaining card has a third label:
23432
;(get-type-for-cards #:2 #:3 #:4 #:3 #:2)
#:two-pair
((and (= 2 (car frequencies)) (= 2 (cadr frequencies))) (hand-type-rec-set! hand (alist-ref #:two-pair hand-types)))
Error: (#f) "unbound variable": (frequencies) Call history: <eval> (eval form) <syntax> (begin ((and (= 2 (car frequencies)) (= 2 (cadr frequencies))) (hand-type-rec-set! hand (alist-ref #:two-pair hand-types)))) <syntax> (##core#begin ((and (= 2 (car frequencies)) (= 2 (cadr frequencies))) (hand-type-rec-set! hand (alist-ref #:two-pair hand-types)))) <syntax> ((and (= 2 (car frequencies)) (= 2 (cadr frequencies))) (hand-type-rec-set! hand (alist-ref #:two-pair hand-types))) <syntax> (and (= 2 (car frequencies)) (= 2 (cadr frequencies))) <syntax> (##core#if (= 2 (car frequencies)) (and26693 (= 2 (cadr frequencies))) #f) <syntax> (= 2 (car frequencies)) <syntax> (car frequencies) <syntax> (and26693 (= 2 (cadr frequencies))) <syntax> (= 2 (cadr frequencies)) <syntax> (cadr frequencies) <syntax> (hand-type-rec-set! hand (alist-ref #:two-pair hand-types)) <syntax> (alist-ref #:two-pair hand-types) <eval> ((and (= 2 (car frequencies)) (= 2 (cadr frequencies))) (hand-type-rec-set! hand (alist-ref #:two-pair hand-types))) <eval> (= 2 (car frequencies)) <eval> (car frequencies)
-
One pair, where two cards share one label, and the other three cards have a different label from the pair and each other:
A23A4
;(get-type-for-cards #:A #:2 #:3 #:A #:4)
#:one-pair
((= 2 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:one-pair hand-types)))
Error: (#f) "unbound variable": (frequencies) Call history: <eval> (with-all-output-to-string (lambda () (call-with-values thunk (lambda v (set! result v))))) <eval> (with-output-to-string (lambda () (with-error-output-to-port (current-output-port) thunk))) <eval> (with-error-output-to-port (current-output-port) thunk) <eval> (current-output-port) <eval> (call-with-values thunk (lambda v (set! result v))) <eval> (eval form) <syntax> (begin ((= 2 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:one-pair hand-types)))) <syntax> (##core#begin ((= 2 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:one-pair hand-types)))) <syntax> ((= 2 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:one-pair hand-types))) <syntax> (= 2 (car frequencies)) <syntax> (car frequencies) <syntax> (hand-type-rec-set! hand (alist-ref #:one-pair hand-types)) <syntax> (alist-ref #:one-pair hand-types) <eval> ((= 2 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:one-pair hand-types))) <eval> (= 2 (car frequencies)) <eval> (car frequencies)
-
High card, where all cards' labels are distinct:
23456
;(get-type-for-cards #:2 #:3 #:4 #:5 #:6)
#:high-card
((= 1 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:high-card hand-types)))
Error: (#f) "unbound variable": (frequencies) Call history: <eval> (with-all-output-to-string (lambda () (call-with-values thunk (lambda v (set! result v))))) <eval> (with-output-to-string (lambda () (with-error-output-to-port (current-output-port) thunk))) <eval> (with-error-output-to-port (current-output-port) thunk) <eval> (current-output-port) <eval> (call-with-values thunk (lambda v (set! result v))) <eval> (eval form) <syntax> (begin ((= 1 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:high-card hand-types)))) <syntax> (##core#begin ((= 1 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:high-card hand-types)))) <syntax> ((= 1 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:high-card hand-types))) <syntax> (= 1 (car frequencies)) <syntax> (car frequencies) <syntax> (hand-type-rec-set! hand (alist-ref #:high-card hand-types)) <syntax> (alist-ref #:high-card hand-types) <eval> ((= 1 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:high-card hand-types))) <eval> (= 1 (car frequencies)) <eval> (car frequencies)
Hands are primarily ordered based on type; for example, every full house is stronger than any three of a kind.
(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))))
#<unspecified>
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.
(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)))))
#<unspecified>
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).
(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))
#t
To play Camel Cards, you are given a list of hands and their corresponding bid (your puzzle input). For example:
32T3K 765 T55J5 684 KK677 28 KTJJT 220 QQQJA 483
Better sample input from u/LxsterGames on Reddit:
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
(define camel-card-irregex
'(: (submatch-named cards (+ (or (/ #\A #\Z) (/ #\0 #\9))))
" "
(submatch-named bid (+ (/ #\0 #\9)))))
#<unspecified>
(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))
#<unspecified>
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.
(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))))
#<unspecified>
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
andKTJJT
are both two pair. Their first cards both have the same label, but the second card ofKK677
is stronger (K
vsT
), soKTJJT
gets rank 2 andKK677
gets rank 3.T55J5
andQQQJA
are both three of a kind.QQQJA
has a stronger first card, so it gets rank 5 andT55J5
gets rank 4.
(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)))))
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
.
(define (total-winnings hands)
(foldl (lambda (total hand)
(let ((bid (hand-bid hand))
(rank (hand-rank hand)))
(+ total (* bid rank))))
0 hands))
#<unspecified>
Find the rank of every hand in your set. What are the total winnings?
(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)))
#<unspecified>
251216224
Part Two
Quest
To make things a little more interesting, the Elf introduces one additional rule. Now, J
cards are
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
.
(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))))
#<unspecified>
In addition, the cardstr->cards
and, subsequently, input->hands
functions have to be adjusted
to use this new list.
(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))
#<unspecified>
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
.
(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)
#<unspecified>
Now, the above example goes very differently:
32T3K 765 T55J5 684 KK677 28 KTJJT 220 QQQJA 483
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
, andQQQJA
are now all four of a kind!T55J5
gets rank 3,QQQJA
gets rank 4, andKTJJT
gets rank 5.
We again take the Reddit example from above, since it covers corner cases.
(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)))))
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?
(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)))
#<unspecified>
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:
(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)))
((#:X . 5) (#:Y . 5))
(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))
((#:X . 0) (#:Y . 5))
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 day 8.
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