chore: simplify structure + multiple years of advent of code possible

This commit is contained in:
theoludwig committed 2025-02-20 08:59:13 +01:00
1 parent 31bcb54699
commit f34d6208bd
84 files changed
+305 -3186

No files matched your search

+3
View File
@@ -0,0 +1,3 @@
# Advent of Code 2023
Source: <https://adventofcode.com/2023>
+7
View File
@@ -0,0 +1,7 @@
[package]
name = "puzzle_2023_day_1"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
[dependencies]
+50
View File
@@ -0,0 +1,50 @@
# - Day 1 of 2023: Trebuchet?! -
Source: <https://adventofcode.com/2023/day/1>
## Instructions - Part 1
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](https://adventofcode.com/2015/day/1) ("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](https://en.wikipedia.org/wiki/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:
```txt
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?**
## Instructions - Part 2
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:
```txt
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?**
+1000
View File
@@ -0,0 +1,1000 @@
eighttkbtzjz6nineeight
5knjbxgvhktvfcq89onefive
hnjcrxeightonejnlvm4hstmcsevensix
trsdgcxcseven39dpmzs
oneninesixtwo26
dppthreeh32twobhrqzks
1cxklgfbvhsnccfive4
foursgjsevenseven5five19
nrrk87
63ntkjbvcv3ntdcptmvheight78
7xv3one
3tzjcrfbvhtqctfmqmdcbjhxln9eightnqbcqztmxcthree
sevensszlgdrlrhnptonethree3qvrxkbgfxtthree
3nckzkpkjsvztqkgvm99
fourthreeonesevencqdv2gnvblhr
528ksdcbx
six342
3twozrfrtljql9eightgcqrgmbzz7dlcr5
6five2threesevenone65
4onejrg23sevensxfive
fourthreecszzvhzfsevensix916
spqzvdxxjeightninejzbpzone7
cfivesevensix332lfpcffmld
ninesevenhrdvmzj24bcxxz6
khpn3fourvhqmntjxfhsvrlnvc
bfzxhzftwo2czsrv
mmblpnnineseven4gtfvqscghfour
1zjgqlz
five1ninetjjtfxqpdkgrxtgxrcsevenkfdzlh
s8twoned
8fiveone53nineeightthree7
926xrfcjzvpd7
3sevenqnzjsqh6fnssjdsbv3nine
rjbbsevenvzkghzsixsbjchs59
221fsnxtbstone1
seven9fourpdseven1four2eight
two1nine4nine7
9seven7
fourcjmdgjsfive2l
twokvhrdldggn15twoxfivenine
mmjtldgmvq157hchsnvpbjvrvtvnineeight
cgzeight3sjmhdcvlnthree5vkgfmx
8sevenfourgnxdpp62xx5
jgdk3z7mmkkjkm
9xrdltttpqznsljbvcdvtz
62zthreethree6
sjbxq9ptsvjhpzmxfoureightmdbnlsckfqlqr
91xrnsbxxsvk6brxfftpttsevencszfhsnrfive
two9ljdfskpfive
1seven384
xbfkhfvlts8dhtnxhxgn93three7one1
3xkjrnqnqhgcfgjvfmxhghp15
nine9844
5onepczqjfcgfrbmtstbqbktphkvqcmbbvhpld
eightsixhnsbnine1twonevrs
eightcmbm2zbxsixone34
five99qccjbklfivevqskhpxzd
seven9four2kzkjbrp
ttdbhd4gqzdlqldnm
9cqcztfourrsfskdjf
njttzmcrchfd4
r414tzqnfddrbf
4tzbfcjksjsn7eightonelvkjzkch
ls7four
6eightsixrtkcrcbmqq6eight3nine
onesix5five7six1
dvrqseven5ninegqthree4two9
fourgdkmbrlgc8
three7nine
sixqrpzqvxd7xnbkftn5seven
oneonerbpgk5ljpqh5threevtpkpfxtsv2
ljttxthreefour3three4gxzgsfm
sixttjvhdggbk357
eightlb4
fourtwo4twonekzb
8one2cdsnrbfxbsixztcfour1
ldveight19lg
seventpd84dscfmxj
one34flpg6eight76
cfninepkscscc5
flqv5v6twooneprlprlkcbk
qsqlrvmkq5457ninetwosevenm
xlvvtxgspct4gmrgeight
hpbbkqthree4gzbq768five
5dqfsixeightonenine
seven4nfshmhvgqm4
rhfgvzxtfckbtmxtt9rqms9one
3gsgfbrnkhqrjddvlx59four2jfz
fdl4two
9sevennine158
five9eight49
3mfsixnkxdbpdxqdgfdqnk
six9fivefive
fourjdmvlvkrp5seventhreejnqncmktwonev
8cjfqkkgtzlnine
3nnsevenjdbjfp1
ghthree1mhgtklfqdkqthree7seven4
4mqsstftj
sixprblqsevendsxvqnk5
four45one
dxhvj23188xz4
dcmnr2
xfoneightsixnine6fiveseven
6cxbbxkrxphsix
5ckkzlzjngvssfx
223zgb
six4qsf
hfxgsfhfhpjlvb329eightone
9zjkckhxoneightbnj
xsdp23seven3four7
8five53eightthreenljbtgcnfive
fnjn36
eightkpkxrvssix2lhctc
6ninebqcksevensevenhk
2one98rrtlncrxhllbgthreelgvkdf
sixzdnlfrvvd4
lltjs8sixqbblmfdhctwo
6twonclq98sscjn
six3niners7eightwokjj
sixeighttwo1onerxrvvbfxxqmxnq9
conetfpbsrm81sixsgkfqk8six
jbqs5277
kjbncjlqthxzlznld89bgqgkxfzpqsptwo
onefive1
pchlnspk52one4sgqj
zd3
43fsfplhgxtjthree7gs4npllqvll
eight8sixeightone6onexr
six6hqltskzpkgbggjktlzlpktdqhzdbnine9
eightnpfbmfninevgpjsleightxh3mz
rninenine7nine
fourbbjnjrbzdvshfeight62
3hzpfsfsdm
2vzhjbv6
27bpninejhbcjrmz7zfqf4
ppflreightpmztvhvonetnjmrxdd31one
threeseven7
srf5hcxvhsmn5five
onersvqvqgkfiveeightqxgrjgfcqj5ntgdzxp3zxdcmbsjqn
mcb643fivetwo
onermbkvmkc9pfvlpdhkzj
3oneeight64
qtnptg5two36nine2tprkbtb
15lbhtcqfnj1qgjk
eightkzrnlrrnlltdmxlbxfourpbpghtgkb9nvlvsm
26kmmkz
jhnldxdtpseven46oneightnb
4lfftjtbzvppxsix17nxpgvjkxd
vszsbxdzjfourhlxldrthdzpqg6slnj8four
nineone2njsfpcb
5sevenone6five
jrmdhdvrb53onelgvlkd29seven
qqqg7eightseven
sevenm9
3dfcfcdb9twoqbvxjgt56six
xq88jjmv83pspctxthree
38five5
six7rbrvjb
eightlvqn335nine
rgmfflzxzd9hs3foureight5
qm6qvmrone4
fournine8
two688qqdtdfbmzn5
8joneonefourljvbjntkngtskcgfnszpgxt
ninethree5pjzcvntl984five
mfgqzcjbglx7
ninemxnfcqrbjonek1nineggj
8dcfkfdtwo
4cltttbrlzpgzbdbqsevendtwosspqk
8eight9klmcbninetwozdcznsv
six85pjqldfbqvclntpnqgv
1dgprzx53
4sixthreeh3fjqpggtjzq
fourone8fiveseven4kgbs7
seven64npxthreeonefour
xvntvgxv9twotlgcsbgsix4
hcqtdzthfour2xvqmnmgrncjt51
qhlpksvnntjq8
3rtmfngqccktwovpppqfqdlxmk2
sixfoureight9tqpdln3eightbjnqfldblnine
eight2sixthree
3plpm
6two3two2
1cfszpnxgtk5fivefive8one
lxrdvls2
sevenfqszrfhone5dxcqsq
42
3dmpsix9nhgzhbmknfour19oneightlng
six2dfglxszbjone
eightone88
9hffzxl7five4
seven8fknjk
fivefoursevenllljzrvjf7
eightmsxfkbszh2
6fiveqhkttbsthreefghn4
3eight98vsnzbkvzcjfive
spmzsdztzgcfbhvbzqlv5
fourtwozlsst9sevenjjmbmqk4
jtmlgrjcpkone2twockgc5four
one35five4
four8tltpxqfour
57sevenbmhceightbhttrzxfvt
qlvrrlnxgvjgnine1four2two
sixoneseven3sevenm
fivejxfghfp81two
rkp3zbzfnrrqfour4eight
eightnine7tpflkbqpz
28fourlmxlhdzctxkrsix
2fiveeightnineninexhfourseven7
mnlrszkr18tfive7l
3eight639
gqpbkntddpeight22lxqjqqone
txxrdbx4bvsfxd
343nsctfvndmp93four2
9lqjvtjcrrtthree
bsffrmtwo2fivesix
qltdtgl3eighttwo91mjq
rh4rddsfr
fourfive7seven
pbqmx7twoqdk
6onesixclklzfzsq992
kzxkxvqzjffourdtm4onefive6xoneightsnl
k4snine4three39
sevenone2xcnscqhcdplnonekcxmgt
seven7ninepmeighthqr8
xpspdx3twoqpc3881
5two5four8eightfive
sevenseven2bcbsf
1sevenrjstpdxfiveseven
2zsxfivefivesix43
eightone5j99nhvbfqhzbvrv5
onefive35m
2kfnqftkkcxtskj
twoeight8
1one8bzzsmgvj2kmqcnqjrz4
1one4sixsixbzbcglm
fiveqqhbmnjgz5ninerlrxkl2seven
4eight4two1xgkb91fdzgxlp
nine8onefive5scxlfrf
gbrqllhnine9
1fouronesixfiveseven95
7qjrprpseightshfzfxvn
2vkbbxfrthreenineeight
58three4
lmfsgdzxnqfdbxtjsnp9
zlbqglfseventprsqvsmt1one9
fmksmtlc8dvhbtdvpfgdz
3six1
mkdthree67jkprftqhdzvjxxftthree8
bstlpptcfghsrrnine7bz
5m1qfscxncvkqgtf
62four16threeoneightg
twoxlrhpc8n9nine
q5sixfour
ninesix2ninepzvxxlpcbxsfpz28hxtccfzmdq
sevenccq4npgpkkb
k79four9fp
ssqptjqvld1pjfdjnkvsevenkjdzks
2bgpbgqfournine614
16threeeightwot
five68jnhzdfqp2qlqbmnjmjdtfbj
vplnzg4545seven
two3two
zcbhzsvc68cnppjpqhfl5
nine68seventwo8pfzgfzbsh
onethreethreeknngnmzhpmlnsd7
46two
sixhdg748blmlkbdtjbtwobgpzzlhzqrbvl
2smcthmql84seveneighthnmdkmfg
5fourrpscd3
sppzzjbckgsixone1sixfour
ltkzb3v3ltwo
four61nineeightdkgtcjfvds
eightd5nfcvvdxhkkddhb
four6q7thbpnz
5rknhshlhgnzz7sixone1six
327rkthreesixeight
cnbqtvptwo1qnsevenpzqh
threeqthreepmhgcqhseven2sevenggmpjcldz
ninedlvlgnglqf3
4two993ninetwo
eightzpfournine72oneseven7
ninejdfkznz62kflbvgpblcgchpzz
448
6rktvxxjpfpqtntbsonefive
6lngttwodshgtworkvvsrnfhjmvpvvbseven
eight43gpssneight
6seven3threefourninesevenrnxx
three22rblfvqjr1four5six6
xtdsqqbv43cxxvfpvtwoklhnqgjlkrrg
threevpvxgddmhl576
3cxccdsevenmvzhqvpfn3btldbhbmfg
kklcmgptl931threenineeight
vj42ntvkrcjtq7sk6
llsvqthreefive5
xspgshknq3kpld2lfour6mhzrzvqf
4bfl38onesix9
seven1vjzjmcrrvnh
7sixsevensix
gqnkgzmvpsnnzcvldlftrzhnpcbq6hzvbqbmnqvsix
5jvbldxsh
jrmvplfive7mfpbsmklzfivefivelsm
8seven5nppxjfjsevenbxrmzmdjnine
seveneightnrkconeqgjfkxjr532
m9seven7
vdn5hdghzvphfour
cpceightwo3
sixtdxhninesevenmmzrpdqcp24
tghjrkhltwojgrcnnbbq1
cfrqlvsevengkthnsbtwo4twovffpv5six
two6pcxj4eightgbctk71
five93nrqpshmxpbdnzssb2
jnxjdzm2xcfhnzkxxz948twonejv
sixfive4four5nkdxzvd
twoqvnxzgcg883fivejgvltjq4
7mzsqvrxlf6kpfjgvdpvj
tzhkjn813six7
5qjbtklseven
rddmfnjgdlnkx5fourzkxlttqdfourrrjfdd
qtr2qrrqvhrkvmtqgbkdq
five56ninesschfzxone
lkb3
3zmbbqdqqnineeightlvlfqqxleighttloneightv
7threetwofive168
njxgnsqcpnine2
zthreerfnvvone7
three4one8
8ppmjj983seveneight9
p4
8tshsgmkb516three6four
7seven8
twosixthreenine6three
gvqz9
n89ninethreesix8
ptqrhhvztxsjbxfour81lncqpkjt
8flvhqljqpmlf6fivenine28
zhbsl7seightwoczd
four1pspgxdvtbzdcd7vsbkzmt
fourj9sdnqtwotwonine3ftzrbzckqk
1fourkkfnndsdxnklrl
zpcdvrszc4ggjcpngkqeight
6twonxhgzcsrgxtwosixvblddxgfmsmqtfcthree
6pltsptthreefive5jjqtzncslmxrmbv7
sixfourqfxtfour9onefivehsgdvpmdsfive
ksevensevenonebdxdxffive5threeeight
zztvdjzlnqtbrfccctsknppmx5seventhree9
soneight716
1fqnntfjhcj2threekmcpzqnbzlqps
twopcftkx8twofourcsixfour
8six2sixgxzzhpkv
four9nine4tgq
htfmtchrx634four5zsmkmdv
45dltlvdvv
dtl848three36
nine7sixonetwo8vsix
twobxctmqvdnt96mnljbpxtsptjpznrjctgtwooneightqv
peightwosixeightseven4
1seven8ds4five6pone
zjftdkvpkpfrhzj97nine56
4sdcdr53beightwocjc
onezxmtfive7ttbbttjeighttwo
rlcjone3sixonezvbmzcgpk4eightwotnm
5ddmcsfzhntpnzntlllthreevqvct
twoeight9
tfhmxsbf2foursqrrfourmfrzjffive6
dhhnlbkjmfourthree6
dxtkbxjlphpqcbmhpdfpqlmreight775bh
sixklvmtjgsevennine33qgvplfourb
gkjmcxsmhtwopkcszlrjd1onesevenseven
8xxvzzqvzszcn1onevmdfsrrtbbjgeighttgpmhh
eightpndprhrf7
three7fpxtxghx
fivenssevengrrlntzldl87
484sixjsxcmmtvbftrfive
t8onesevenvqsfc2k
sevenoneoneeightsevenfive71
sevennvnvbtzsnqggrsrgq35sevenfive7
feightfive12
twoc846cf
1mtvlxhhxlsdbphgltlgzpl
xddrlslrdl9
fiveqvfjvcqlcfour27
9fjqp9rrkqbtpv3
23fqccxsvsix94tkzsqmrhsg
6lvrsqnz
9four7hvlfl9
gbgsnmkrxjxpgnj828
56grzmb6onekf9six
87bjn4
sjdzmqkrlkbsmxzsmn3
seven91eightsix
svhfnxzdzqczc2
vbnz92chjjfqftxfourqzzxseven
seventwofour5jbqvlmqknbznfbhtonefour
dqdmntkfsnbmjqxxgmkvm6vqpgpnnreight
one1431
1five4
twoone8thtxlrrdxbone
qftpltmjd1zpxckthreeeight
9xg
pjpdjrkltnrkkmd9five75rdctppdhjtghrffczdx
mtvbhnpzjfive7nine
thlzdgxcqvsknczrdslsh7
eighteight4kkt7four5
71ninekzfntxtjthreeone3
gzseven2fssqrgmbj
52j
nsv16seven
stwone1
twodbqgfivegsrrvxvone3
jckhqbdlvgbgn7vtx3vggrdm
ntzftfhfeighteight2
48eight6
flzfqonezvskbf1668one6
sevensix864eightfour3
dnsdrsxvcxnsevengxrszqxfnd4fmnine
tjjngfourhdfzpfkh24
foursmgvlqjxsqmz8ninekthktdhz
three435
tkfqhpz8zjmcqbxcb46
mmvstlmln3kxnkvjcmxtrdxp4seven
rmfour13vkgnnmbzbzgd
three6nnbljchmzthreeg
68onep9five1one2
rbvzvgmkbmdrnmvone7kqtxtrtbone
three13six4
qksfrmvgztsfournnvp66nine
34three
11fourpzkmqnfmjqkdgrlgqbsixsixcqtgdggbdx
nineone2seven4twoninesix
ninez6qpnnbpmcdhcr
sixbdbkhgntpsevencpn3
1fivehvlrzpninemkfbfgtvfivesix3
7kpeightzlvqsgkfjznpfpfsseven66
c7hxrgkglfivebfctxk
5rfdxgshzmnzqscpqzlbnrhbg9strxdthree8kntkhdpdll
4gfzcjcjsm63fvxpvflv
nine8526
6scslfpnrveight1seven5bdllknjj
seven94hnxddjv26s
two48seven3four58four
fourseven1smh5
1zzdzmbjpjfzlhsvzgxf61gvtnklgx6
ninefour63
nine3nrfzn
gthreeseventwonine1eights
sdonejzdmtxtpl9onerzztvqr8
eight15kqnjrggpblhsbdz1
lkkxnzjrgsixsixthreeeighteight4twonem
d17two44
6seveneight1fourthreesevenbdpvg
cjgchvhq4386five8
1threefive426rsxmthree8
sixnztppjtn9twossfjrdkzkrldztfbbv
threesevenlqrdmvzdcphmqj3four5three
fivethreepcfxdxmc3vdbprghd5sevenszprlbzrbn
threethree88xcgdmrcssevenrlflv39
eightonezchscllpfone9
zreight6sevennine
fmrhqrxr7
sixnlqccjchpxpqg86five5
sdpxjrxtk4sevenfivetmddbpqgtqffive2
hrvrgjgvxt7vrsr
2zj8
35fourspthreeseven3zgddrmbxmsz
four8kkxmtsscf
4six98
five9four
four5one7pjbninefourbmss
4sixsixt138seven
fourxsevenseveneighthsgmmpdx5
tonexhgcjxbjn8
chbkd2183
six8fivefourglszgngfgqthree
pghkzrftwo6
fourpfx572
62zfvzp
sixsixnzvtxdgsixzxsgmpz1zvtwo4oneightpg
425twothreebv4twoxbx
8nineeight55eightflkpggltsr4spl
seven45clkrkrxj
65six594twofive
4ktvpfjeight
nnslpmkqc5five5four
nineonetzmft8jcxqzrk
fivefivethree99
2l2
4mhdj
3eight7fivejqhvrszgh3
5four7mbfz8
one8sevenmltbgqcbq22
1zgfnfvt9seven
2lhbfrndhmfiveone
fivekzgch424zbpgxhtkbjdljxkxvnz
1vd6vpmzjmnhhn
vlqcbhskb5onerqbql6
six3tplqcxthreethreefoureightzldgvgxrthree
4fourtwo4
cvznvxbxlszjpxvzbqn7gt2fjtxddzmjv
kjqthree67twosixfour4nine
dmjrhflfzslhkjmthreemfgqvzcpm9bcnfbpz
nfpcsevenone3two58
eight4kdqczz96five1four
1mzfour
57tdcmtmns4
bdxeightrjvkrddrm3nftmzxlftthree
2three2kvfourgrtvxmrzgdninecseven
threemxpfnthree5onehjdxfntvtzlxhr
8onelqtjpkmtwotwoseven91
rzhzg1fouronecqkdpfkgdkkftsixhllvphvtjv
vxgrlptk48one14two
kqncz3znmkppxs3hlggbmsfj81
ddrp3
three8hjdccgthrtbd6lvhnbfivemzh
twomptzvkqmssix7bjvpsix6nine
phrdjxmzj3xxkmfour7dsix
5threeshtmlsjbmfzgdq
96eight
three6rqqxgzthreejphvs
69seven52kmnpbqmjdhtjvxcnlxfgldbs
veightwozbbcmqrdxv6hxxpdknf
nxbtwone1vktdvlbbhnfour
4five864
2dn1fiveeightthree
two4twofoureight43
1eight51
71fourhjrnqssxqvf
sevenqxkccdxndfgqhctsfsx6
xqgsjvdmnb31sixfourtksqshz5
4ghkqfzxceighteight2eightfiveeightwotf
ninelsnldgslfxfqfsrc24six
3seven3ctbf9eightmshd
mbqpfourfive44sixbnmqrmkgxt
flgdrvjj4dks
oneqslfbjgfx8
jmmssm2
hjfbzsix1
bvjdxseven8
fivenhfccvg9
four5sevengkvslppponerhlvfms
b9one
89znlhgbnkmmxsix3two
sixsqtjcdfbs87ninejvznvmeightfvst1
sevenktnzdkcsrzzdqtb9jnbtwotgxsptxcd5
6mqvbhsddnmb21sixskg8
threenb2four74five1lcmdzrvq
ftvone7
5msevenpdqgzncvzxeight
foursixpshnbrpm64
six2twotwordzf
nine7lbnxsfjtbb1seven4ggt4
zlnfkkconept36
9sevenfqlxjmts94xpcxqseven
foursevenseven15ninedqff1kmzfgvnks
xktjdhb115
threeeightcnlpzrb8
91six
376kkgmlblrcbthree7jgxvgfcdv
9xpz3
rrcvpkgtwo2one6vjfone24
sevenhfour3three
pxfvzltqrg9twotwogqdtzbp
lrgseveneight5pmxvppjdhtwoone
97six
four8bjdhpmszdeightprkgone
mb6lfcdkcn
8fbvxnjone
z9vdthreethreesbsrkzgnsxp8
sevengftjmm1onegqhpninesnr3
f4fourrbbngrdm37five
ninerbmdqfvkfx9eightone8eight2
rxdvclfr714
oneggchmt2dgh7
tvbfour9four
four474fourgmdtm
nffourpbxtlcs7ninethree3
bpjlrztwo2sdttcghc
hfflhmdc18
4ninepsrmtbqrfeightk3xxxf
433hdvcggkr1xjcntvtnvsc
7nine2nine6
9zctwo
9vvfjvctgtzpjh7jtdjcrh
qrtgcd5six31khd5
fourbjshrq845zg
ghconeight35jljdqgtg4fjdtxtsfiveone4
one7kxscgcxnsx
43threethree54four
vmninetwo2onetqgblrsgcpfkrreightwokg
threefour38
fivesixeights26three
jtmzzxvmxone2four9jgtxjrvpcthree
fdqgczkq8sevenvcnhpseven8three88
7ninezone3
frj4eighttwobgx1threesjckzsvvxlone
oneseven2cspzhqfsix4
ljmnbbcnxffkmdn5
tmzlnl8oneseven86ninelbrzjgqn
fthree3seven6sixtwo34
6two8fivexteight
89seven5twosix63
63pzsjcjzvbhseven
msqvppsgnfbjrjmdrrhbfxrjqdlkpfourjbrjks3dthree
eight6twoklkdfgvxzteighttctqz
4gjpfmqs233six
onefourninenxcnkgfour8rmmrzln
1sptlpstqb6eightqgfhzzgpgp24
eightlrjlhqfoureightjvj937
595oneighthpt
44five
two2sevenbtwo
7fivefivepxonebbrlthreefive
klxnlfjlsrgjcd7eightninefive
threeqzpptnzhjnkqfsixpvk3xxlrpl
mqkhsdtbqqzgjb7149ninesix
1dbrrvjsx34cbdxhqpzbfhtgpm9three
3onesix6eight
five34
6qcv9nzngtsjv
9lttthreegttzjstt
four47
95onetwoftdzmhsfmhbnblnine
chcsqhnp72qjdqtjxzc8fourfourfour
fourfive28
81eighttwoqdjkmnleightdbmzz
vzzqpjx8
qq1six
qbktqgrjcqq75
772
njvnhnzdz6threefivetwonelt
pcfzzjfhqkxhfpztpv7
fivemztfourqjrtngrkpcbfc3qq
bfjhbm6ghtdpsmlvb86eight
94883
6onegbxmcqmdfive
sevenonesixcngsrgcz9
sevenzhxktd22fourgnr9
tdxpzvggnlpdxxrcpsp3threexjrldrkmp
34kjtbsxppmxfoursixlbzgqxbltv
fivethreezfive2
7seven1seven
4fhvxbg58eighteightone
631gqtwosix
xqn1chrcjjrqxp4threezjcd
jtssvppxlnsix49rfvjdzntwoone
sevencmpmdnczcfdprgfdbjnzzkgnine26
hkbnggqfk7mfmfsone68sxpdmf
fourtlhsmksvzg4foursixseven
pprkj3sixseven
kzxjpdczxhxckxtgbbtwothreethree5dztmdfrlfivedgcfmmrt
hjvrdhnckspl5eight3three9
74two95eightfourdkzzlkxszm
one7tbfour1cpjtrxsqgvbjtpbcct2
fivefour4hsix8hjsxrmpqqxnkhmjseven
nine8fivehvmnxsfour7four75
sjfrjr2ds
fivefourqt95vbndnzns665
sixssbznthreethree6f8lnzcgpprl
ninepfbpfnflrfnpzhq9
nh9fvrldpkjmq7six5p
75zsixnqbhrcbpmddshjfqthtq
sevennine377fourfrtvpqrseven6
97eightnine
52fiveonetrq5
threehgjqt7rvfsljtzkfour
tjkxc1
jthreerqbpzpzmeightntjlrhdmfour2
fourmgv2three4one
four91
9bone
oneseven1sevenpdvdqhlq
xlhbqxcpfp7
twothreefive43
1ctjmfn9one2
htfivesixcdkjrjbr45eightseven
onefour8rrhltfl897
37ljvmcnjhonevxkqpjk
3891sevencfgjhh45
twoone5tbznkdmv1fourpltvnnsvk19
55bcnzbfggd2
17zpskbgeight2dx3
vbdshtdkxllttwo65
tzvmcmltfphztpplrxjxpbnine3qvktlctfrpxncb
1sixppzlfvkbnm
eight1gdvlzrfkc
four74fivefseven
hlzlvnjrp9312jxeightnine1
sixsevenkjpbz5sevencksb2
9rtvlgdpfnmgzdzcjggsq7sevendxglftncmbninefive
eight8gxkrbkgcvbxbbxlonefivesevenjnffhjsk
99twobdmcnfthreevr
sevenlpjbbthree58
eightthree32
14fhxsqshmjbngrhdzvxvvhxgvqnlxnnvrsgsheightninenine
6twotwo
kr573eightseven78
9six18
2seven8six1qdvf
ones9three1lcqj2
sixbfour6gbd
tfpvtbbjtwormxz6
49eighttwoonesixeighteight
fcrhntggdvseventhreeeight9foureightxjxqvtb
oneone3rnngppxj8fzpsncjmzn
9fiveonejjdpthreetwo9
sixsixjzckvmbbszsl1nrrfphj5
zgjvnttth7sbmtxczggxbbqpzq467
3mhslltk
9six16three79three
fxprlhbm3zljzd49gdsrtt
6eightoneseveneightfourrfive
fourfive11six
6gmrfxnsmnnljf8ninenlctx
seven5threehninecnhbkgbnvqbsfx
pxzccjqz8
xgzpzljnfour7threethrxskjlz9
fourseveneight292eightone
5bjpzjseven21four
xbtf88nine
6nfjllxh4
67five4c8
1qbzdkvmlrzgj3rzqczz4
mjjzblg3
x3five
jrpxsrqgr9hqsddmscmsrsbhkdc63eightxfscd
6eightsixone
5dggfbgclz7htvpcx1
onethree46psdlfpgbsix
lqbnine978
7nrrdzfksbtjlnbgfxttzfourstqkd
mtfptwo9six23hctpbrxtbx
eightfznvmmp7cllpkggknttwoxbbv
rggdrlsgcm2hdljxzjhjrfour83
vhtmhvjdzzkzmzqgr7fourfourfourgzbqqpz
dfjctmlnkqzzjhhltpvhfmhsixvclfive7vgm9
nine642sevenseven9mblrhxxktfhdhbcztvx
4rzrdfmtvlpthree86
qkdoneighttwo1one3
dnnvkvpcmn2cltbzc6five59s
sixsnzpnfplrn38hthhbfive4
tsrxkzfxcdgckxrgzkmrctqvrngfnvdscnpc6jgszldglnhsg
vvtfhtgxjbdgznjjzqjjclfg1lvpdcpjsevenseven3
xrhbrpg8zb8
4nine5qfxlhmvzsjsbznmklseven
lffl2six733jtrfrs3
7nbvpkdpzjtc8qckhbqfsqqgz
cfljnthreecninedt2xldzbgl5six
nrggf7four
hbkpxrxonetwo969fivethreegspmzcfr
jjpmzlzfvqbvbzqcz2eightninepfqjkjrkfivebzcthgrpqx
xsccsbmcninefive4kkrvrht
sgnzzschtwotwofzjt9seven
8tworpzncglnmninenjmf368
2one1zjtgllvsone
7nine4nqqxnvvnsbsevenvddcvfdr
three117
shcjhvrfourpthree12
1zxcxninegpdfrfhzlbzg
7eight9gkkfbdhplnmjkksbqzp6htmbhg
sixeight76sixfive
5twonemt
three86
4three52psgzhnlhgvgcsbzbleight5oneightkj
cnztwone1
six9sgx
79clrpmeightninepkh39
rmfplpsixsixlvrdbqgpljgl5onetwo3
7ninelznqjxjgtwohhk6five
1659two7onefive
rskpnrmfbbghttvklkg773fourczdqeight
xftwo4
2nine5ccrgsmfcseven9seven52
8sixseven
k33threehgqtljcdqxkl
hfgdvngttzfivecflmcc31three
eightninethreensjxxlzhgk9b51x
ninejktfhnnphkkgm2dms5dpxrbcd
eight7skzllgxgmkd1three4thhdpsjtvnq
7ninehhhdngbxjvvxldvbrhzrbvntl2
pxgsixone75llslx
31tgrvtvvlbhnshjfgnqc
knzgkjfckf2sevendfive
bmxcnznineeight9dvkbngzmxz
gzqdjfsxq9pbseven
212
h3
9sixfourbrfsfivekttxzhrmdsppps
3vxtbtrzqzxfhgsksbvqd
9lbxdjmckrhfgjqlnsrrfzqxktqkrmmjshfnine
7pjmmxdcffxgspeightgpdcftjtdxjgdrfthree
t84ninefive4
fgfour63sevendmtrrc9
64three
btjnc3g6f3one
pm9
threefourvjmsx5four
14one2rtcccqc
jhcckpv84xntpzdn
rpjrhgddzfvrzpqnfg5twoseven3threehvcmnkreightwotl
74one
six4ninesnbxlonesix5three
kfxjzjone76xppxgddstgfhxphpffrjlone
sixthreedsdccpqff4
4951
zszgqjxbx7
three4pqqvfzf622
vc77threetd
sixlbglxqhn52
1sgktgvxp
bdsonekxsevenpgssslcq3fgp7
pvnxnhdjmndnhthreefive49
kgvkszsixone4
3mjvqjpglzhphg67ninehnnine
one6xvvnvkxp4dfcxv
eightfour7threesevenp
7ggdl1
ztwonethree427ninetnmzntj4
fttwone258seventwotwo
75sixseven59
7kmfzqgjpqkpdhthjlseven674xdgmphfk
eighttwo6five7
3eightwoxg
22434five
khjmcpzvfpr9
3rrzqzlrljgcvdnxj6four8six
63qrgqklszpgthreefkpzx
574htclbtzfivetwo
jtwofqfpkflzt9
xnjzxpmmdln4lzlmlk41
6jdzjjmz7jt7seven8fourkgttztbsktwoneps
72s166zpslq5
3553lhkdcxvhqbddrfdbc5two
4gktbmone
fouronefives3qhglmzttwoeightone
one87rxkkhfrjfrpdjjt485
one437nine
119one
5lseven87nmxxqvhmn
pphfmcfhxlsevensqdmtvtpvq1
18eightfivefour
three98
4onephzhtq4qc5four
26zglkpjvz3twoeight
7mxkdrbpnk29
ppeight15
9jnprvtmscsixbbpsixfivecktgvdpf5
lbftvcngvkvxf5cmmrqljjb471
eight3knrvtwo
one6pvbpkqkpdsixbv
eight2onethree6eight
5rztcbtfjkb2twoeight39hxppvpxqg
8threemlllncmfourthree
vhtsmncssixbmlpggvmlzdxbczgc1fxrgvsbhsrbs
ninebnpv7575three
4mthree
fourtwo1qrbfourjrjmlxjr
3jbkcsrqznc8
pcgrxgf4eight54
seven5mjk
ninenine6vmcmlxmcrbvq1nine8
sixone2ninesixrdqfgpxddzthreetcheight
899lfbzhgn151
46nineone
7one2qthree
nine2hjnfourninesixvblnqbgctwoeight
qkggsnnthrxnrccbgs583
351zkxqtmbd9sixthreegjjxt
zrchlhmqcthreeninesmxz9
219fivejrxgbjvvcxkjtwoseven
8threebzzsxdx
nine249ninefmlhj8rfour
16zfljhfdcmkthree
7sixjvdqgpvhmndpmhhzsphceight
two2zjqc4nfd6732
41threeseven1fourseven
296fourgnq7three
tbzdhbhs7ntshptcgrbkjspjdz
55qcrmclmcck9
25mhmtb3dscmjbhgv3four
bjmhkxsffourhnxkxv1
jvntlbn5fivegjdcjl
7gndbbbneight
357623chktvtfzvf
169plhsshseven
nhgsrxcdfktpbzf9vpppxzkznine9
xrdnlbmtdeightone3threeeighttwo
bnnqzcfoneeight2hhdfkrrqzt
342tlmjgtfcnine
47rvtfqlzgmjlqbqthree
7gnmxplrjbvfour6
mcgbldbhlh1eightnine
two9eightxnpdj61kzcdpnpnpfgsdrbcflh
6541fourpkdplksnkpvkjxpdnvfttlfdflz
kfour7
x4tpbnnvnjlseven
55nineninesevenzttsztwo9nlcqjq
1drhjrzsbvpl
mpknzhj9vmqckrpznqthreesj9
211zqgpdlmpn
4jxzrztg5onehnzvdbtcqdtsnkqtdvsd1fournine
bvcrcz5four4
4nineninecfhgtdphone9
zbkjgbshqqkrcb3qmtfmdrdcckcsxshjb2
1eightrblhbhljvkpshmrxc5
hjcrrdsvnbqktxrgmq9nqgcztbv
6lzsixl5one
twofivesevenfivesixonenine5seven
fourmldkgnzb8djlsdmjnzxbmmvpf59seven
8hnfkknnsrhm
three2krtqmmxqzs4jbrnrtrxzxsllblbkjmthcrlxxkdlh
mglfmvvnthreefour1
onehxz4fourhqcfvdlhg
zrzqdgs5jsttkrone
sevenrdmhnldsmdnineqfrgjhmhnnqkztxzm7
63seven
2seven3mrsltqb17
fdbtvthmmrb5gbxvcmtwosixt5five
eightlzglvxfone5five7dlqpmseven5
dmzdkbfive98onefivehhbljrnz
eight8ninefour
24nvmftwofive
seven3onefourrmgkxtcsfour
fgpxmqqsfdrk8eight8zhcrzvrzmdxbbfive
eightonetwo7ninesjsrlr
rrkrrtnkq941sixone
threeffspgv3eightfivesix5
lthnrlgfcnine2scdcvnineseven
sx86
cxklrckbz5lsqq28
5seven298
933five5cmddfj46
hrhhs76343
one3two4fourst4three
nine3three
dhtscvgm9foureight81vp
btpeightpzbtphdlcm8fiverknbrhthreelxndqcv
one96six45tm
fourninetkdrvnbznnine22
vxeightwothree5cd3jcnine
seven5one4one7ninefive3
nflkr2dlmtsrkrgkfvsixxvznjbvz3btxkhhqcc
eightrtz6jslqxsixoneeightnine
xmvxn5
tgnlrmjtkjdpbnpmsixbxfnl7sixone
htwonezcshpqgsix73qlgdqnkjskjthree
nrlkxq6fnfourseven
zmrlngjdhc41four4fourptrhddthreenhzv
n9twogdrzkcsbk8hph6
436sevens7cnkrrk
6qkdvkhtwo
mztkszm39
fourtwo4mqhjkkdzgffhqfktwonine
hbthree2hvpbznlgrxfgkthfour8
34prfzlx4three
29zzfdvghll9three6
two83
one982
36hhgdf7
seven6ninednnine9mbtzfm1
one38
seventhree5lsjxknqtdsbtxrkone
eightmfctkbc9jlxgdnchlq9one8nine
p371b
9ninejszqsnpkfbthree1h5xscpfzvl
three9ljd
fbbv9
five582
58dctdbhbninesixczhd
qp4
6pfqdeight
3onethreekqnnlt
m4fgbmdtwo3
twodkrmtqs4
9three6
six1798nineeightsqpvpsmcbmh
9qxxmrmbnine3fivefourfive3four
one7sevenone78ninetwozqps
973keight9seventwo
keightwothreethreeh6threeeightlnqdzhlt
five94
mqlltnfive8eighttwoqhztggvqqkcxgvgmch
2kpnsevenfive6
gtmszpsjmggr3
pm126one3
rvcqbtz9zjtndbxlrdcxzf3
mkninekhmtxzbjpd8threeeight7eight
5274xm636
bleightfive9vdddzjdntthreerxtvdslrvbcvf
9eight4sixdqzrltgpzlpxtcrzxbhmsmdtwothree
cpneightwofive3fourtwo
one61threejxbjvsltxzpntpv
19581
six2qllhlxhr1foursixz8
6278teight3three
8gstxqdngxzlxvnvphlsznr3kknftvzxcqqbrfteightthree
4jlzjvjfltwo7pv
7dvt
blhsm4xcrbrf68ninezvhhtqgphnzxlhl
9dvjvfourtcthree
onethreenfkgrvsevenkczctlgkt7
@@ -0,0 +1,4 @@
1abc2
pqr3stu8vwx
a1b2c3d4e5f
treb7uchet
@@ -0,0 +1,7 @@
two1nine
eightwothree
abcone2threexyz
xtwone3four
4nineeightseven2
zoneight234
7pqrstsixteen
+89
View File
@@ -0,0 +1,89 @@
pub fn part_1(input: &str) -> usize {
input
.lines()
.map(|line| {
let characters_digits = line
.chars()
.filter(|&character| character.is_ascii_digit())
.collect::<Vec<char>>();
let first_digit = characters_digits.first().unwrap_or(&'0').to_owned();
let last_digit = characters_digits.last().unwrap_or(&'0').to_owned();
let number = format!("{}{}", first_digit, last_digit);
let number: usize = number.parse().expect("Should parse as a `usize`.");
number
})
.sum()
}
pub fn part_2(input: &str) -> usize {
let numbers_spelled_out_with_letters = [
"one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
];
input
.lines()
.map(|line| {
let mut characters_digits: Vec<char> = vec![];
let mut temporary = String::from("");
for character in line.chars() {
temporary += &character.to_string();
let mut temporary_spelled_number_index = None;
for (index, spelled_number) in numbers_spelled_out_with_letters.iter().enumerate() {
if temporary.contains(spelled_number) {
temporary_spelled_number_index = Some(index);
break;
}
}
if let Some(temporary_spelled_number_index) = temporary_spelled_number_index {
let number = temporary_spelled_number_index + 1;
characters_digits.push(
number
.to_string()
.chars()
.next()
.expect("Number should be single-character digit."),
);
temporary = character.to_string();
}
if character.is_ascii_digit() {
characters_digits.push(character);
temporary = String::from("");
}
}
let first_digit = characters_digits.first().unwrap_or(&'0').to_owned();
let last_digit = characters_digits.last().unwrap_or(&'0').to_owned();
let number = format!("{}{}", first_digit, last_digit);
let number: usize = number.parse().expect("Should parse as a `usize`.");
number
})
.sum()
}
#[cfg(test)]
mod day_1_tests {
use super::*;
#[test]
fn test_part_1_example() {
assert_eq!(part_1(include_str!("../input_example_1.txt")), 142);
}
#[test]
fn test_part_2_example() {
assert_eq!(part_2(include_str!("../input_example_2.txt")), 281);
}
#[test]
fn test_part_1() {
assert_eq!(part_1(include_str!("../input.txt")), 55130);
}
#[test]
fn test_part_2() {
assert_eq!(part_2(include_str!("../input.txt")), 54985);
}
}
@@ -0,0 +1,8 @@
use puzzle_2023_day_1::{part_1, part_2};
fn main() {
let input = include_str!("../input.txt");
println!("- Day 1 of 2023: Trebuchet?! -");
println!("Answer Part 1: {}", part_1(input));
println!("Answer Part 2: {}", part_2(input));
}
+7
View File
@@ -0,0 +1,7 @@
[package]
name = "puzzle_2023_day_2"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
[dependencies]
+59
View File
@@ -0,0 +1,59 @@
# - Day 2 of 2023: Cube Conundrum -
Source: <https://adventofcode.com/2023/day/2>
## Instructions - Part 1
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:
```txt
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?**
## Instructions - Part 2
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:
```txt
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?**
+100
View File
@@ -0,0 +1,100 @@
Game 1: 5 red, 1 green, 2 blue; 2 green, 8 blue, 6 red; 8 red, 3 blue, 2 green; 6 red, 1 green, 19 blue; 1 red, 17 blue
Game 2: 4 red, 5 green, 2 blue; 7 red, 14 green, 3 blue; 2 green, 5 blue, 11 red; 10 blue, 3 green; 9 green, 6 blue, 13 red; 7 red, 5 green, 9 blue
Game 3: 9 green, 18 blue, 1 red; 6 red, 10 blue, 5 green; 4 blue, 4 red, 15 green
Game 4: 1 red, 13 green; 10 green, 2 red; 3 red, 4 green, 2 blue
Game 5: 4 red, 2 green, 1 blue; 4 red, 9 blue; 4 green, 1 red, 6 blue; 3 blue, 2 green, 6 red; 5 red, 4 green, 1 blue
Game 6: 6 red, 3 green, 6 blue; 3 green, 5 blue, 12 red; 3 green, 9 blue, 3 red; 13 red, 8 blue
Game 7: 3 blue, 1 red; 3 blue, 10 green; 4 green, 5 blue
Game 8: 11 green, 4 blue; 4 red, 4 blue, 11 green; 4 green, 3 blue; 1 blue, 6 red, 12 green
Game 9: 1 blue, 4 green, 1 red; 5 green, 3 blue; 9 green, 4 blue; 3 blue, 1 red, 10 green; 6 green, 2 blue
Game 10: 5 green, 6 red, 7 blue; 7 green, 5 blue, 5 red; 8 red, 6 blue, 8 green; 2 blue, 8 green, 6 red; 6 blue, 8 red, 4 green
Game 11: 1 blue, 10 red, 10 green; 11 green, 2 blue, 16 red; 4 blue, 7 red, 14 green
Game 12: 8 green, 9 red, 12 blue; 2 green, 4 blue, 7 red; 1 red, 9 blue, 7 green; 8 green, 2 red, 10 blue; 1 green, 5 red, 5 blue; 6 green, 5 red, 1 blue
Game 13: 3 green, 1 blue, 6 red; 1 green, 10 red; 1 blue, 15 red, 2 green
Game 14: 2 green, 6 blue; 1 green, 2 blue, 2 red; 5 blue, 1 green, 2 red; 4 green, 5 blue, 4 red; 4 red, 5 green, 4 blue; 1 red, 5 green, 6 blue
Game 15: 12 green, 7 blue; 19 green; 11 blue, 16 green, 1 red; 1 red, 2 green, 3 blue; 8 blue, 1 red, 19 green; 14 blue, 3 green, 1 red
Game 16: 2 green, 13 blue, 3 red; 5 red, 12 blue; 6 blue, 8 red; 4 red, 1 green, 4 blue; 1 green, 15 blue; 4 blue, 2 green, 1 red
Game 17: 11 blue, 7 green, 2 red; 12 red, 8 green, 8 blue; 2 red, 6 blue, 6 green
Game 18: 1 green, 2 blue; 2 green, 1 blue, 4 red; 3 green, 16 red; 2 red, 3 green
Game 19: 11 blue, 3 green, 3 red; 11 blue, 5 green; 3 green, 3 red, 8 blue
Game 20: 1 green, 6 blue; 4 blue, 6 green; 1 red, 10 green; 12 green; 5 blue, 1 red, 4 green; 1 green, 5 blue
Game 21: 7 green, 3 blue; 1 red, 5 blue, 6 green; 1 red, 11 green; 8 blue, 1 red, 10 green; 1 red, 5 blue, 3 green
Game 22: 3 red, 1 blue; 3 green, 1 red, 1 blue; 7 green, 2 blue
Game 23: 12 green, 1 red, 2 blue; 10 blue, 1 green, 1 red; 9 blue, 8 green
Game 24: 5 blue, 6 green, 6 red; 3 blue, 1 red; 8 blue, 2 green, 12 red; 1 green, 2 blue, 14 red; 2 blue, 5 green, 15 red
Game 25: 6 red, 13 green; 1 blue, 1 red, 3 green; 1 blue, 12 red, 10 green
Game 26: 16 red, 2 blue, 7 green; 1 blue, 7 green, 8 red; 1 blue, 3 red, 9 green
Game 27: 4 blue, 15 green; 6 green, 2 blue, 1 red; 9 blue, 10 green, 4 red; 3 red, 3 green, 6 blue; 11 blue, 7 red, 11 green; 6 red, 5 green, 13 blue
Game 28: 10 blue, 8 red, 10 green; 4 blue, 11 red, 6 green; 8 red, 9 green, 10 blue; 4 red, 9 green, 2 blue
Game 29: 4 red, 9 green, 7 blue; 10 blue, 6 green, 4 red; 1 green, 2 red, 10 blue; 3 green, 9 blue
Game 30: 6 blue, 9 green, 10 red; 6 blue, 4 red; 5 green, 2 blue; 5 green, 2 red, 2 blue; 6 blue, 8 green
Game 31: 7 blue; 2 green, 6 blue; 1 red, 9 blue, 5 green
Game 32: 8 blue, 2 red, 4 green; 6 red, 2 blue, 1 green; 14 blue, 8 green, 8 red
Game 33: 1 green, 1 red, 1 blue; 2 blue, 1 green, 12 red; 1 green, 1 red; 1 blue, 2 red, 1 green; 7 red, 2 green, 2 blue
Game 34: 3 blue; 2 blue; 10 red, 1 blue, 1 green; 5 red; 1 green, 1 red, 1 blue; 1 green, 2 red
Game 35: 10 green, 1 red, 16 blue; 4 red, 10 blue, 9 green; 1 green, 7 blue, 5 red
Game 36: 1 blue, 3 red, 16 green; 1 blue, 3 red, 1 green; 9 green, 3 red, 8 blue; 14 green, 6 blue, 3 red; 3 red, 12 green, 4 blue
Game 37: 11 red, 3 blue; 15 red, 8 blue, 6 green; 6 green, 19 red, 11 blue; 1 green, 4 blue, 14 red; 12 blue, 5 red, 8 green; 4 blue, 9 red
Game 38: 4 green, 10 blue, 3 red; 1 green, 1 red, 11 blue; 2 red, 12 blue
Game 39: 3 green, 1 red, 4 blue; 9 green, 1 red, 18 blue; 4 red, 4 green, 17 blue; 4 red, 10 blue, 14 green
Game 40: 5 red, 4 green, 8 blue; 1 green, 9 blue; 9 blue, 3 red, 6 green; 8 red, 9 blue, 9 green
Game 41: 1 blue, 9 red, 3 green; 9 red, 10 green, 15 blue; 13 red, 8 green, 8 blue; 19 red, 6 blue, 2 green; 7 green, 5 blue, 12 red
Game 42: 15 blue; 1 red, 1 green, 9 blue; 6 blue, 1 red; 1 green, 4 blue
Game 43: 1 green, 8 blue, 2 red; 1 red, 1 green, 6 blue; 7 blue; 7 blue, 3 red, 1 green; 2 red, 5 blue
Game 44: 7 green, 11 blue, 6 red; 9 green, 8 blue; 4 red, 15 green; 12 green, 14 blue, 8 red
Game 45: 4 red, 4 green; 14 green; 4 green, 2 blue; 1 blue, 12 red, 5 green; 3 red, 6 green; 11 red, 1 green
Game 46: 2 blue, 1 green, 1 red; 1 blue, 6 green, 1 red; 2 blue, 1 red, 1 green; 5 green
Game 47: 1 blue, 1 red; 14 red; 3 green, 2 blue, 17 red; 4 green
Game 48: 1 red, 11 green, 2 blue; 1 red, 11 green, 6 blue; 13 green, 1 blue, 3 red; 3 green, 4 red, 6 blue; 12 green, 5 blue, 1 red; 2 red, 4 green, 4 blue
Game 49: 5 blue, 3 green; 2 green, 8 blue; 5 blue; 4 green, 5 blue, 1 red; 4 green, 7 blue; 1 green, 3 blue
Game 50: 3 red, 5 green, 2 blue; 9 green, 7 red, 4 blue; 3 blue, 6 red, 13 green; 6 blue, 8 red, 9 green
Game 51: 2 green, 11 red, 7 blue; 5 blue, 13 red; 1 green, 2 blue, 3 red; 6 blue, 8 red; 11 red, 2 green, 4 blue
Game 52: 15 blue, 1 green, 4 red; 4 green, 10 blue, 2 red; 6 red, 18 blue, 1 green
Game 53: 2 red, 10 green, 6 blue; 4 green, 3 blue, 3 red; 17 blue, 19 green, 5 red; 6 blue, 6 green, 9 red; 5 blue, 17 green, 7 red
Game 54: 9 blue, 8 red, 6 green; 6 red, 8 green; 1 green, 6 blue, 1 red; 5 red, 4 green, 9 blue; 5 blue, 2 green, 5 red
Game 55: 8 blue, 8 red, 10 green; 3 red, 4 green, 9 blue; 4 red, 3 green, 7 blue
Game 56: 3 red, 6 green, 1 blue; 5 green, 1 blue, 1 red; 1 red, 2 green; 10 green
Game 57: 1 green, 4 blue, 12 red; 17 red, 7 blue, 10 green; 17 red, 5 blue, 3 green
Game 58: 1 red, 5 green, 14 blue; 5 green, 6 red, 7 blue; 4 blue, 8 green; 3 red, 9 green, 7 blue; 8 blue, 8 green, 6 red; 8 green, 7 blue, 5 red
Game 59: 3 green, 5 red; 2 red, 13 green, 1 blue; 19 green, 1 red, 1 blue; 19 green, 1 blue; 18 green, 1 blue, 5 red; 6 red, 9 green
Game 60: 5 red, 1 green, 6 blue; 8 red, 6 blue, 14 green; 8 green, 8 red, 3 blue; 2 blue, 5 green, 3 red; 4 blue, 1 red, 14 green
Game 61: 7 red, 4 blue, 2 green; 2 green, 8 red, 9 blue; 5 blue, 2 green, 8 red; 8 red, 1 green, 8 blue
Game 62: 6 red, 3 blue; 1 blue, 2 red, 2 green; 3 red, 1 blue
Game 63: 2 red, 1 blue, 2 green; 1 blue, 1 green; 2 green, 4 red; 3 green, 2 red; 2 green
Game 64: 5 green, 6 blue, 7 red; 2 red, 5 green, 8 blue; 7 green, 9 blue, 1 red; 4 green, 5 blue; 19 blue, 5 green, 13 red
Game 65: 3 red, 1 blue, 4 green; 5 green, 3 blue; 9 green, 1 red, 10 blue
Game 66: 6 red, 13 green, 2 blue; 2 blue, 5 red, 9 green; 18 red; 2 green, 1 blue, 1 red; 19 red, 10 green; 1 blue, 15 green, 13 red
Game 67: 8 blue, 3 red; 1 red, 12 green, 7 blue; 4 red, 6 blue, 5 green; 11 green, 10 blue, 7 red; 5 red, 9 green, 14 blue
Game 68: 1 red, 3 green; 10 blue, 1 red, 3 green; 1 green, 17 blue; 16 blue; 6 blue
Game 69: 11 green, 5 blue, 8 red; 2 red, 5 green, 1 blue; 10 green, 2 blue; 11 green, 7 red, 4 blue
Game 70: 2 green, 1 blue, 13 red; 16 green, 20 red, 4 blue; 10 red
Game 71: 10 blue, 6 green, 7 red; 5 red, 5 green, 2 blue; 7 green, 4 red, 5 blue; 1 red, 8 blue; 5 red, 1 blue, 8 green; 5 blue, 1 red, 5 green
Game 72: 2 red, 4 green; 2 green, 2 red, 1 blue; 3 blue, 3 green, 2 red; 2 green
Game 73: 5 red, 19 blue; 12 blue, 4 green, 16 red; 14 red, 11 blue, 1 green
Game 74: 2 red, 1 green, 9 blue; 5 blue, 1 green, 2 red; 2 green, 1 red, 13 blue; 2 green, 1 red, 3 blue
Game 75: 7 blue, 1 red, 18 green; 17 green, 8 red, 13 blue; 15 blue, 4 red
Game 76: 1 green, 12 red, 13 blue; 5 green, 11 blue, 12 red; 10 red, 1 green; 10 red, 2 blue; 5 red, 2 green; 2 green, 17 blue, 3 red
Game 77: 2 blue, 1 red, 1 green; 7 red; 7 red, 3 blue, 2 green; 10 green, 1 red; 3 red, 7 blue, 6 green
Game 78: 10 red, 2 blue, 2 green; 1 blue, 6 red, 4 green; 12 red, 8 green; 6 green, 8 red, 7 blue; 11 green, 5 blue, 6 red
Game 79: 7 green, 5 red; 6 blue, 2 green, 15 red; 9 blue, 2 red, 12 green; 1 blue, 4 red, 10 green; 4 blue, 12 green, 11 red; 5 green, 3 red, 5 blue
Game 80: 1 green, 13 blue, 2 red; 2 red, 1 green, 13 blue; 7 blue, 8 red
Game 81: 1 green, 2 red, 11 blue; 5 red, 3 blue; 1 green, 1 red; 14 red, 1 green
Game 82: 12 red, 3 blue, 8 green; 15 red, 9 blue, 8 green; 6 blue, 13 red, 8 green
Game 83: 4 blue, 6 green, 3 red; 7 red, 2 blue, 9 green; 6 green, 3 red
Game 84: 4 green; 3 red, 3 blue; 4 red, 1 blue, 2 green; 1 red, 5 green, 5 blue; 1 red, 5 blue, 3 green
Game 85: 3 red, 4 blue, 15 green; 9 green; 2 red, 4 blue, 6 green; 1 red, 4 green, 7 blue; 3 red, 10 green, 9 blue; 1 red, 13 green, 3 blue
Game 86: 8 red, 6 blue; 3 blue, 3 green, 15 red; 12 red, 6 green, 13 blue; 15 red, 6 green, 10 blue
Game 87: 4 red, 4 blue; 6 red, 2 blue; 5 blue, 3 green; 4 blue, 2 red
Game 88: 4 blue, 7 green; 2 blue, 7 green; 6 green, 4 blue; 1 red, 1 blue, 2 green; 11 green, 3 blue
Game 89: 1 blue, 12 green, 11 red; 3 red, 7 blue, 1 green; 7 green, 8 red; 6 blue, 2 green, 3 red; 7 red, 8 green; 11 blue, 5 red, 12 green
Game 90: 1 green, 12 red, 17 blue; 14 red, 17 blue, 9 green; 6 green, 9 red, 11 blue
Game 91: 3 green, 14 blue; 2 blue, 2 green, 6 red; 1 red, 11 blue, 1 green; 3 green, 4 red, 20 blue; 6 red, 2 green, 3 blue; 10 blue, 12 red
Game 92: 6 blue, 7 red; 2 blue, 4 red, 1 green; 4 red, 1 green, 3 blue; 2 red, 5 blue; 8 red, 6 blue; 1 green, 2 blue, 1 red
Game 93: 4 blue, 1 green, 4 red; 8 red, 4 green, 4 blue; 2 blue, 9 red; 1 blue, 4 red; 4 blue, 2 green, 11 red
Game 94: 5 blue, 1 green, 7 red; 1 green, 11 blue, 1 red; 1 green, 15 blue, 4 red
Game 95: 1 red, 3 blue; 1 red, 1 green, 8 blue; 3 red, 1 green, 3 blue; 3 red, 6 blue; 6 blue
Game 96: 4 green, 1 blue; 7 green, 3 red; 2 blue, 9 red, 16 green; 3 blue, 4 red, 11 green
Game 97: 6 green, 8 blue; 1 blue, 1 green; 3 green, 4 blue; 8 blue, 5 green, 2 red
Game 98: 18 blue, 6 green; 11 green, 3 blue, 7 red; 18 blue, 3 red, 7 green; 5 red, 5 green; 8 blue, 2 green, 11 red
Game 99: 3 red, 2 green, 3 blue; 1 red, 4 green, 1 blue; 2 green, 18 red; 15 red, 1 blue; 2 blue, 9 red, 2 green; 17 red, 3 blue, 4 green
Game 100: 9 blue, 8 red, 16 green; 3 red, 7 green, 8 blue; 1 green, 3 red, 12 blue; 3 green, 14 blue
@@ -0,0 +1,5 @@
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
+198
View File
@@ -0,0 +1,198 @@
use std::str::FromStr;
const NUMBER_OF_RED_CUBES_IN_THE_BAG: usize = 12;
const NUMBER_OF_GREEN_CUBES_IN_THE_BAG: usize = 13;
const NUMBER_OF_BLUE_CUBES_IN_THE_BAG: usize = 14;
#[derive(Debug, Default, PartialEq)]
pub struct NumberOfCubesOfEachColor {
pub red: usize,
pub green: usize,
pub blue: usize,
}
impl FromStr for NumberOfCubesOfEachColor {
type Err = &'static str;
/// Parses a string `string` to return a value of [`NumberOfCubesOfEachColor`]
///
/// If parsing succeeds, return the value inside [`Ok`], otherwise
/// when the string is ill-formatted return an error specific to the
/// inside [`Err`].
///
/// # Examples
///
/// ```
/// use std::str::FromStr;
/// use puzzle_2023_day_2::NumberOfCubesOfEachColor;
///
/// let string = "3 blue, 4 red";
/// let expected_result = NumberOfCubesOfEachColor {
/// red: 4,
/// green: 0,
/// blue: 3,
/// };
/// let actual_result = NumberOfCubesOfEachColor::from_str(string).unwrap();
///
/// assert_eq!(actual_result, expected_result);
/// ```
fn from_str(string: &str) -> Result<Self, Self::Err> {
let mut result = NumberOfCubesOfEachColor::default();
let subsets = string.split(", ");
for subset in subsets {
let mut subset_splitted = subset.split_ascii_whitespace();
let number: usize = subset_splitted.next().unwrap_or("0").parse().unwrap_or(0);
let color = subset_splitted.next();
if let Some(color) = color {
match color {
"red" => result.red = number,
"blue" => result.blue = number,
"green" => result.green = number,
_ => {}
}
}
}
Ok(result)
}
}
#[derive(Debug, Default, PartialEq)]
pub struct Game {
pub id: usize,
pub subsets_of_cubes: Vec<NumberOfCubesOfEachColor>,
}
impl FromStr for Game {
type Err = &'static str;
/// Parses a string `string` to return a value of [`Game`]
///
/// If parsing succeeds, return the value inside [`Ok`], otherwise
/// when the string is ill-formatted return an error specific to the
/// inside [`Err`].
///
/// # Examples
///
/// ```
/// use std::str::FromStr;
/// use puzzle_2023_day_2::{Game, NumberOfCubesOfEachColor};
///
/// let string = "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green";
/// let expected_result = Game {
/// id: 1,
/// subsets_of_cubes: vec![
/// NumberOfCubesOfEachColor {
/// red: 4,
/// green: 0,
/// blue: 3,
/// },
/// NumberOfCubesOfEachColor {
/// red: 1,
/// green: 2,
/// blue: 6,
/// },
/// NumberOfCubesOfEachColor {
/// red: 0,
/// green: 2,
/// blue: 0,
/// },
/// ],
/// };
/// let actual_result = Game::from_str(string).unwrap();
///
/// assert_eq!(actual_result, expected_result);
/// ```
fn from_str(string: &str) -> Result<Self, Self::Err> {
let mut result = Game::default();
let mut parts = string.split(": ");
result.id = parts
.next()
.unwrap_or("Game 1")
.strip_prefix("Game ")
.unwrap_or("1")
.parse()
.unwrap_or(1);
result.subsets_of_cubes = parts
.next()
.unwrap_or("0 red, 0 green, 0 blue")
.split("; ")
.map(|string| {
NumberOfCubesOfEachColor::from_str(string)
.unwrap_or(NumberOfCubesOfEachColor::default())
})
.collect::<Vec<NumberOfCubesOfEachColor>>();
Ok(result)
}
}
pub fn part_1(input: &str) -> usize {
input
.lines()
.map(|line| Game::from_str(line).unwrap_or_default())
.filter(|game| {
game.subsets_of_cubes
.iter()
.all(|number_of_cubes_of_each_color| {
number_of_cubes_of_each_color.red <= NUMBER_OF_RED_CUBES_IN_THE_BAG
&& number_of_cubes_of_each_color.blue <= NUMBER_OF_BLUE_CUBES_IN_THE_BAG
&& number_of_cubes_of_each_color.green <= NUMBER_OF_GREEN_CUBES_IN_THE_BAG
})
})
.map(|game| game.id)
.sum::<usize>()
}
pub fn part_2(input: &str) -> usize {
input
.lines()
.map(|line| {
let game = Game::from_str(line).unwrap_or_default();
let mut maximum_number_of_cubes_of_each_color = NumberOfCubesOfEachColor {
red: 1,
green: 1,
blue: 1,
};
for number_of_cubes_of_each_color in game.subsets_of_cubes {
if number_of_cubes_of_each_color.red > maximum_number_of_cubes_of_each_color.red {
maximum_number_of_cubes_of_each_color.red = number_of_cubes_of_each_color.red;
}
if number_of_cubes_of_each_color.green > maximum_number_of_cubes_of_each_color.green
{
maximum_number_of_cubes_of_each_color.green =
number_of_cubes_of_each_color.green;
}
if number_of_cubes_of_each_color.blue > maximum_number_of_cubes_of_each_color.blue {
maximum_number_of_cubes_of_each_color.blue = number_of_cubes_of_each_color.blue;
}
}
maximum_number_of_cubes_of_each_color.red
* maximum_number_of_cubes_of_each_color.green
* maximum_number_of_cubes_of_each_color.blue
})
.sum::<usize>()
}
#[cfg(test)]
mod puzzle_2023_day_2_tests {
use super::*;
#[test]
fn test_part_1_example() {
assert_eq!(part_1(include_str!("../input_example_1.txt")), 8);
}
#[test]
fn test_part_2_example() {
assert_eq!(part_2(include_str!("../input_example_1.txt")), 2286);
}
#[test]
fn test_part_1() {
assert_eq!(part_1(include_str!("../input.txt")), 2617);
}
#[test]
fn test_part_2() {
assert_eq!(part_2(include_str!("../input.txt")), 59795);
}
}
@@ -0,0 +1,8 @@
use puzzle_2023_day_2::{part_1, part_2};
fn main() {
let input = include_str!("../input.txt");
println!("- Day 2 of 2023: Cube Conundrum -");
println!("Answer Part 1: {}", part_1(input));
println!("Answer Part 2: {}", part_2(input));
}
+7
View File
@@ -0,0 +1,7 @@
[package]
name = "puzzle_2023_day_3"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
[dependencies]
+67
View File
@@ -0,0 +1,67 @@
# - Day 3 of 2023: Gear Ratios -
Source: <https://adventofcode.com/2023/day/3>
## Instructions - Part 1
You and the Elf eventually reach a [gondola lift](https://en.wikipedia.org/wiki/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:
```txt
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?**
## Instructions - Part 2
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:
```txt
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?**
+140
View File
@@ -0,0 +1,140 @@
...........................775.651...............887....79...946...921...493.....942..942.....151....155....................................
......240...................*.....-......................$..*...................*.......%.....+....................956.549.*290.......834...
.485...+............437......906......%..608.805.725..72.....242....745..61......440................................*..*.........515...*....
..........917.......&....146........790.....*......*....*..........*.....*...............207*......................796..116......../...924..
722...323.-................./...410.............72..748.442............384.708...............849..%............................470..........
.....*..........................*.....271..691....-...............4*...........388.................448......&........*....848&......751.....
....370..$....639.748.......*...467....*.....*........921*909.....................*...32.....................165..452.30....................
........984....*.....*...782........711.....50.172...............61&..........415.803.*.........524.......................203.......106*643.
...............57..433.........390....................&../.............*122...........674.........*.........................................
379..................../.........*........908..477...305.876..*..............297.415*......+.......94........../.....@378.......226..56*....
...*..-......82.......167...936.17..958...=....*...............196......+......*.......-...380.992.............989.........29......*....301.
..124..317.....*....................*..........839.......................191.882......231.........+......976.................+......469.....
............643................*........778............541........655..............*............*........./............*.................515
.....&............498#...&....726.774..............111....*378..................723.221.......473............752....523.638.......789...*...
.....353................518..........-.........../....*...............*88.........................*..@280..=..-....................-..297...
...........279...........................*816.....286.975.&319.....614......694.......799.......503.......861...569.............+...........
..474........*.228..............308......................................................*............207........................838..408...
...........226./....*................82.........................268/......814.........640.............../..489........719..=..........*.....
....83............88.544....250.......=...87..............199.........115*....................................*...377.@.....643........658..
........-...651.............*................&..............................*379.....411...686.397............202.*....../........217.......
.....781.......*897......630................330.....117.961..........61..543.....#...*.....*.......323.............996.603.......*..........
.......................................................*........473....*.....739.184.511..........+......43.833.................953...@.....
....110......@471...........*464....@.347......779................/.....205.*.......................681.....@.........................694...
.........................203......158.-....310./...449...726*982.............437.....+....259...................185......940*702............
.....465....*.......747....................*..........*...............................238..&......./..963...755....*........................
.....*....687..104..%.........645........959..497..732........988........733.....12...........417.176....$..........176.323....657..........
...566........*...........938*......418......*............925....*28..............-.156........*................................*..#........
.............933.......................*....988........../............................*........813.................868*674...375...839......
.....................804.......464..452...................................47......324.789..........692*288..................................
...959...........792....*10.....=......................*455.77...827.99....*.........................................166.......8...586......
.....*...607......*..............................12.764......*.......*..905....590.236...#.677...823......972..204............*......*......
..661....*........776....938..901.............@.*.........$...216...995...........*....382..*....#....546*.....#...........564........707...
......755................*.......*698......315..291.......964................-.......=.....865........................521........150........
........................323............./............973.........*35..........318.....204...........546..+667....214%..*..............973...
........143......&725...........619....149..............*235..650.........604..........................*..............195..............*....
................................*.................................926...................@240......+...433..302..672.........977....149..335.
.......880.......&...............301.512.$.....876......331.897...#..............#...............464......+...........938.........*.........
......@....942...603....&....879..........117..........*.....*.............562..905....377*862..............*56.........%........352..*165..
.726......*..........239....*.....915..............@...661...905..............*...................466....223.................730............
....*......97..839.......308.........*....115....512..........................497.392.....563........=...............448...........462*884..
....122.........*...471*...........52...&..=...................=..................@.........*...............................531.............
.........*..522...&.....274...........116......*572...........907..........................161..670@..@....................=........57*.....
.........28.*.....606.......................925...............................908...86...............78..............712.....813*......16...
....549.....512....................................825.....797.......224..660*........@.425*656.........=536..256.......*........599........
...*.............963..................842..704.............+....425..*..............................102.......$....565.179..774/........576.
...................*..........................*..............=...*....922........50...262....%............603......*........................
.......636.......349...&...224...$............899.........983..319.............#........&...663....*575..%.......95.....383*................
......=...............928........218................84.............964.........953..+...........212.........................857.............
............................179.......68......................&....*.................787.............92&.72....455..969...........846..40...
.993=..../..........110.407*...........%.............164..#....306.215...................552..............*....=...#.....69.602...#...*.....
......322..........#...........561..............968..*....913............%..........@586...=.330...........166.............*........863.....
............810...........157.*....557.....30.*.....774...................968.601*...........*....491..........557.....83*..................
.......*368.*.......842...*...435.-...........65.-................................680.....913....#.......793....*.........87.262....34.-....
....896......875.....*...........................581.957..758............$................................@..981..............#......*.844..
..................957...150.......503................@....*......89....59......261..........653....................................372......
...731...-129..+........*........-......................718.713....*.......197..*......30......+...476............872.......................
....*...........671....917.......................800.&......=....197..763....*...96......#.........*......%......*..........739......290....
.....234..............................814*251....../.755.............../...375.....................309.914..816...877..=.......$......$.....
.........543.378.....74.%608.25...755..........237..............834..................431..................../..........585..................
....408...&...*..............*................*.............214*.....................*.........89.475*.......................@..939..824....
...*..........526..........713..&.....132...899..108.75..#..................521....428....97../.......603.....248.........878...&...*.......
....383...............873......1....................*....850....862....%......#.=................533.........*.......................863....
.............852.........*................578%....................*..492.........905.145.927........*........437.107.....@....29............
......604.......#./531.179..&........56.........921..233.......943......................*..........174...........*.......271.*...32.........
........*..619.............588......*............*...*..............918*837.....120.128......508...........536...............558...*638.....
523....794...-....................451..544....648..365.778.....@.............@.....*............$..%414...*............453#.................
..................&......124*...........*...............*...259........696...424...........*...............322..534................*519.....
........201*.30...474........567.526..363............%.963......287+......*.........939.964.....994.............*.....-........287.......657
........................709*......=.........854...527................50..591...859....%..........*....196.......188..395..157...*...........
.281*....878................354.......*221...*............308....309...*.........$..@...72#......577.........................*...734.....481
.....9....*.............658........235......767..12..548...=...#.......585..830....609........................603.130.....884...........*...
........324........@...*........................*....*........628.............................................*...$...........=......658....
..................139.206....$.....768*........986....311..........967...15...174....100-.....7$..............962....=.........561..........
......521.....154.............318......622...................-.............%...@.................856.......60.........24..481.......520.772.
.825..#.......*.............................180.............228.11.....173.......128......428.........405.+...68...........=..882......*....
....*.......657...........27....798*460...................@............-..............31.*.....840...........*................@.............
.965...931............974...*...........................798.................455*.........856......*...809...97..934.740$..570...............
........*..511.$427....../..652..-297............296........$........552..........884..................*........%........*........128.......
..........-..........207............................=....641.........+..........-..*....43..........329................990...........*......
.10...................=..11....&............................./.143........875..732....&.......&............................349.....265...858
...*......222....495%...*...618..322.......%.........116...833....*........*.........776....288....760.........-............-...............
....291......*..........453.........*...811...398..............515........365..445....................*.....961.........433......743...$....
.............33..................543.........@..........................=...../.....793*...........266..............668...........#.....804.
................701....................17*.................449*741.....961......814..........................*245......*...809*.............
.......206......*....668..728$............529..........*93........................-...833.713..............69.......292........157...224*...
..........*585...969............810..522............866..............254.....570........*....*.....588..................+113.......-.....752
................................/......../......257.............119...-..844...*..979..442....169.....=.259......+.............752..401.....
...726...967........&.234.................326.....*....590*636...*............130.../.........................933.....652*439...*...........
.....*......*12..332...-...........500#..........944..............747.......$.....................203....513.......................%864.....
....389.&....................*...............938.......893....970.........864........538.755&.258..*........#...............717.96......+...
.65.....180...&.............864.....169.........*................*...390............*.........*....904.........................*...354...478
....620......472.726.931...............*.......150../.......@....960....................*928.812...........................428......*.......
...*................*.................463..........323.....478..........964..........175.........324%........=827......66.......193..303....
313.......................@...705.214.....174&........................-.....271........................818...............*.........+........
........171+..830...328..158...*..%..................17....721.....568......../...........949.............*.............608.....90......570.
....327..........*....*.......44......................*..................193-.......67.................970......966.503................#....
669*..........386..306....+............105............443...........................*........490..130...........*....$..........$62.........
......454...............&..954...38....*..........229....................643......388.671....@.......*...8......506....66*148.........$.....
......*................259.........*.................*756.......596.........*........................638..+....................%....854.....
...700......895..............................757................*.........847..............630*612..................854..606....38..........
...............*.....93.....573......274........*...952..336...................562..................+...637............*.*..................
945........../.814..=..........*....*...........38..=............-....&........*..................118......*.........745..855.........367...
......676..688..................604..153...............671......513...690....891.%.....101.728..........767......28...................../...
.........=.......700..222.443............114.....................................458...../....#...................*.........=...............
...........660.%...&.....*.....98.232.......*............308.......650..267/..........$............................417.....806.....502......
.......276*....500............@.............63.......621*.....520...-........913.....225.........620.597...709*632.............663*.........
...................232...149............65.......................&........................228.....%.....-................467............800.
..........118........+....*....@.........-.458...737.....-247.........425................/..................574......424*.........421..*....
......158.-....*........564.599......128......*...#..........................419.............764*156.............................*......996.
............577.563.....................*...777.......................508..............*827............................*465.....306.........
.........................*..............848......996*......688....154...*.......%...780......51...410......357.148..856.....................
...648.............835.713....*...609.......................&........*..885....494..........*..........661....*.............................
...-.....477./693..*........938.....*./...........642..149......465.502......$............=.523.........#.......892................=824.....
....................296...........44...707..........+.....*...................462......476........@...............*..........388............
.....58...321..............127................................446...............................965....446........114.........*.............
.........*........951...3....*.................623.263.............=.-....122..........................=....519*...........692.......%313...
........943.......*......$....990.......795..../......*..135.....815.483....*..937*.............................634..............771........
............460....757.....@......511/..*............564..-..............340.......109.206.......%785..148...21....................*....&...
.47.........&...............102........265......555..................182......12*.........................*...%.................788..200....
.../............=..................#82..........$.......207.............*863.....751.........251.....641.702.......141..640.................
..........23..902.......174...............*.............=.....314...........................*..........*.....*667...........*...............
.........*...............*.......*766..842.35.......243..........*......@..................57..435....501.285.............964.....*.........
..165...100.@512.........292.......................%......79..@...726....341.511*.............*...................573..........602.74.......
...*..................................596#...&...............769........................314.397..&31................%..855..................
...6.....673....................898..........836.......827.......+.....-..............................133*766..........*..............290...
..........*.........799........*.........629.......634........%.188.103.......594......464.799*295.............895...930.........-....$.....
.....908..504.......*......603..800..936...*......*.........768..........973...*.......*...............904*16.*................358..........
.....@............825..%......&.........*...963.294.74...........%........*....102...967...-343.................#..................94.698...
.810...................968..............429...........*....950..313..482..397...................33.........@..297..198...114.......*...*....
.....-............................554..................................-.......245.$...............991..282.........-...*....161..894..78...
..705.....177.....*..872@.285........*.../813.........235....729..........*287..*...472.788.645........................144..................
.............*..984.......*........722............496*..........*990....79......715........*............456...................812..470......
............518......@.....950.........712..............981...........................238....579.533........373.466...615/......$.....*907..
..716..907.......761..471..............*......../...........823..+............978*......=.....*.....#......&....*...........................
....*...............*........990.331...46....871...........*.....447.723...@...............594...............801......................#757..
...312...*.........211..........*.................90.860...970.........*...375...........*.....-....*779.........&..........................
.......692..............602.............................*.............595.............841...166..327......-444....154.......................
..............$....316..=.............+978.843........42....135/.+332.........454.........................................707.../......295..
.........$....743..../.......-................+........................*990..................343......#.....*...............*....684........
......651.....................644....................887.812........187.................783........749...928.291...........131...........293
@@ -0,0 +1,10 @@
467..114..
...*......
..35..633.
......#...
617*......
.....+.58.
..592.....
......755.
...$.*....
.664.598..
+226
View File
@@ -0,0 +1,226 @@
use std::collections::HashMap;
#[derive(Debug, PartialEq, Default, Clone, Copy)]
pub struct GearPosition {
pub index_line: usize,
pub index_character: usize,
}
#[derive(Debug, PartialEq, Default, Clone, Copy)]
pub struct NumberPosition {
pub index_start: usize,
pub index_end: usize,
pub value: usize,
pub gear_position: GearPosition,
}
pub fn get_numbers_positions_from_line(line: &str) -> Vec<NumberPosition> {
let mut result = vec![];
let mut number_string = String::from("");
let mut index_start = 0;
let mut index_end = 0;
for (index_character, character) in line.chars().enumerate() {
if character.is_ascii_digit() {
if number_string.is_empty() {
index_start = index_character;
}
index_end = index_character;
number_string += &character.to_string();
} else if !number_string.is_empty() {
let value: usize = number_string.parse().expect("Should parse as a `usize`");
result.push(NumberPosition {
index_start,
index_end,
value,
gear_position: GearPosition::default(),
});
number_string = String::from("");
index_start = 0;
index_end = 0;
}
}
if !number_string.is_empty() {
let value: usize = number_string.parse().expect("Should parse as a `usize`");
result.push(NumberPosition {
index_start,
index_end,
value,
gear_position: GearPosition::default(),
});
}
result
}
pub fn is_symbol(character: char) -> bool {
!character.is_ascii_digit() && character != '.'
}
pub fn is_gear_symbol(character: char) -> bool {
character == '*'
}
pub fn part_1(input: &str) -> usize {
let lines = input.lines().collect::<Vec<&str>>();
lines
.iter()
.enumerate()
.map(|(index_line, &line)| {
get_numbers_positions_from_line(line)
.iter()
.filter(|&number_position| {
let index_start = number_position.index_start.saturating_sub(1);
let index_end = if number_position.index_end + 1 >= line.len() {
line.len().saturating_sub(1)
} else {
number_position.index_end + 1
};
let has_symbol_on_the_left =
line.chars().nth(index_start).is_some_and(is_symbol);
let has_symbol_on_the_right =
line.chars().nth(index_end).is_some_and(is_symbol);
let has_symbol_on_the_top = lines
.get(index_line.saturating_sub(1))
.is_some_and(|&line| {
line.get(index_start..=index_end)
.is_some_and(|value| value.chars().any(is_symbol))
});
let has_symbol_on_the_bottom = lines.get(index_line + 1).is_some_and(|&line| {
line.get(index_start..=index_end)
.is_some_and(|value| value.chars().any(is_symbol))
});
has_symbol_on_the_left
|| has_symbol_on_the_right
|| has_symbol_on_the_top
|| has_symbol_on_the_bottom
})
.map(|number_position| number_position.value)
.sum::<usize>()
})
.sum()
}
pub fn part_2(input: &str) -> usize {
let lines = input.lines().collect::<Vec<&str>>();
let mut number_positions = vec![];
lines.iter().enumerate().for_each(|(index_line, &line)| {
get_numbers_positions_from_line(line)
.iter()
.for_each(|&number_position| {
let index_start = number_position.index_start.saturating_sub(1);
let index_end = if number_position.index_end + 1 >= line.len() {
line.len().saturating_sub(1)
} else {
number_position.index_end + 1
};
let has_symbol_on_the_left =
line.chars().nth(index_start).is_some_and(is_gear_symbol);
if has_symbol_on_the_left {
let mut number_position = number_position.to_owned();
number_position.gear_position.index_line = index_line;
number_position.gear_position.index_character = index_start;
number_positions.push(number_position);
}
let has_symbol_on_the_right =
line.chars().nth(index_end).is_some_and(is_gear_symbol);
if has_symbol_on_the_right {
let mut number_position = number_position.to_owned();
number_position.gear_position.index_line = index_line;
number_position.gear_position.index_character = index_end;
number_positions.push(number_position);
}
let index_character_top =
lines.get(index_line.saturating_sub(1)).and_then(|&line| {
line.get(index_start..=index_end)
.and_then(|value| value.chars().position(is_gear_symbol))
});
if let Some(index_character_top) = index_character_top {
let mut number_position = number_position.to_owned();
number_position.gear_position.index_line = index_line.saturating_sub(1);
number_position.gear_position.index_character =
index_character_top + index_start;
number_positions.push(number_position);
}
let index_character_bottom = lines.get(index_line + 1).and_then(|&line| {
line.get(index_start..=index_end)
.and_then(|value| value.chars().position(is_gear_symbol))
});
if let Some(index_character_bottom) = index_character_bottom {
let mut number_position = number_position.to_owned();
number_position.gear_position.index_line = index_line + 1;
number_position.gear_position.index_character =
index_character_bottom + index_start;
number_positions.push(number_position);
}
});
});
// Key: "index_line-index_character"
// Value: usize
let mut gear_positions: HashMap<String, Vec<usize>> = HashMap::new();
number_positions.iter().for_each(|&number_position| {
let key = format!(
"{}-{}",
number_position.gear_position.index_line, number_position.gear_position.index_character,
);
match gear_positions.get_mut(&key) {
Some(gear_positions) => {
gear_positions.push(number_position.value);
}
None => {
gear_positions.insert(key, vec![number_position.value]);
}
}
});
let mut result = 0;
for (_, value) in gear_positions.iter() {
if value.len() != 2 {
continue;
}
let first_number = value.first();
let second_number = value.last();
if let (Some(first_number), Some(second_number)) = (first_number, second_number) {
result += first_number * second_number;
}
}
result
}
#[cfg(test)]
mod puzzle_2023_day_3_tests {
use super::*;
#[test]
fn test_part_1_example() {
assert_eq!(part_1(include_str!("../input_example_1.txt")), 4361);
}
#[test]
fn test_part_2_example() {
assert_eq!(part_2(include_str!("../input_example_1.txt")), 467835);
}
#[test]
fn test_part_1() {
assert_eq!(part_1(include_str!("../input.txt")), 553079);
}
#[test]
fn test_part_2() {
assert_eq!(part_2(include_str!("../input.txt")), 84363105);
}
}
@@ -0,0 +1,8 @@
use puzzle_2023_day_3::{part_1, part_2};
fn main() {
let input = include_str!("../input.txt");
println!("- Day 3 of 2023: Gear Ratios -");
println!("Answer Part 1: {}", part_1(input));
println!("Answer Part 2: {}", part_2(input));
}
+7
View File
@@ -0,0 +1,7 @@
[package]
name = "puzzle_2023_day_4"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
[dependencies]
+75
View File
@@ -0,0 +1,75 @@
# - Day 4 of 2023: Scratchcards -
Source: <https://adventofcode.com/2023/day/4>
## Instructions - Part 1
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](https://en.wikipedia.org/wiki/Scratchcard) 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:
```txt
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?**
## Instructions - Part 2
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:
```txt
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**?
+208
View File
@@ -0,0 +1,208 @@
Card 1: 57 76 72 11 8 28 15 38 54 46 | 77 87 71 98 40 7 84 43 61 64 5 50 19 83 79 99 36 47 4 95 30 44 37 55 26
Card 2: 44 69 14 83 54 48 21 6 20 26 | 80 26 86 3 9 4 62 34 15 87 60 88 90 29 65 46 92 73 24 12 40 10 99 37 74
Card 3: 15 60 63 84 20 93 36 39 17 19 | 68 80 17 91 20 84 69 72 15 39 5 61 74 99 60 85 19 45 24 79 53 36 7 63 93
Card 4: 22 74 83 58 88 46 7 52 84 5 | 75 20 95 8 37 56 31 42 73 43 40 48 4 28 99 45 90 63 81 93 68 50 46 30 7
Card 5: 4 97 41 50 32 26 68 84 5 11 | 91 70 87 4 88 13 48 51 32 34 38 82 86 11 1 50 40 43 28 5 61 89 84 41 37
Card 6: 79 97 39 26 57 69 38 87 60 44 | 22 92 80 38 27 66 54 2 9 62 3 4 71 99 24 97 14 7 93 28 53 50 77 68 73
Card 7: 73 91 51 23 90 67 19 81 50 12 | 4 76 97 64 19 85 31 3 74 12 23 60 20 68 52 39 43 65 37 63 40 59 99 80 6
Card 8: 23 64 38 82 68 79 49 56 5 76 | 68 25 64 30 40 52 16 53 95 96 85 9 4 7 26 80 62 67 73 35 32 44 90 69 93
Card 9: 75 87 69 31 8 11 89 49 95 24 | 35 26 68 69 42 66 37 77 25 45 75 72 38 50 27 24 32 46 11 10 14 95 62 7 86
Card 10: 37 25 47 36 57 81 44 6 79 98 | 67 34 86 70 39 97 80 69 27 17 7 50 99 84 45 32 49 53 15 95 19 18 47 37 41
Card 11: 87 98 16 76 21 53 8 42 40 75 | 21 7 89 85 65 30 32 19 68 22 64 82 48 62 39 46 4 57 77 18 55 24 34 29 67
Card 12: 60 11 44 35 9 56 93 91 15 32 | 31 45 37 63 26 12 15 14 48 92 81 1 97 65 29 95 57 77 99 93 27 25 58 66 61
Card 13: 25 75 5 60 47 83 8 37 2 43 | 52 30 68 13 1 92 89 63 78 57 87 75 28 82 59 46 33 3 65 41 47 69 21 2 96
Card 14: 64 44 89 88 1 38 20 99 9 81 | 71 68 91 21 92 75 49 22 27 12 9 26 57 13 66 45 40 37 16 4 44 90 98 85 61
Card 15: 16 56 91 62 12 83 25 3 70 61 | 81 55 73 96 13 7 67 99 88 90 87 48 83 35 19 97 9 31 20 49 38 44 41 45 5
Card 16: 78 68 81 18 76 41 88 45 24 87 | 59 84 67 36 33 57 42 32 11 74 65 31 54 46 72 39 98 40 16 49 79 19 3 44 22
Card 17: 84 11 48 66 54 86 28 4 45 23 | 4 54 42 62 81 8 92 45 47 66 84 48 18 72 28 86 23 34 3 24 73 82 96 11 59
Card 18: 46 40 41 22 75 92 68 10 52 3 | 84 73 9 22 7 19 3 65 32 6 99 77 97 63 62 59 57 17 8 68 91 28 39 4 41
Card 19: 19 57 22 85 75 69 50 62 65 61 | 35 24 50 47 74 97 61 27 66 57 77 75 22 30 70 41 62 69 85 58 81 65 19 91 63
Card 20: 18 13 96 41 20 44 62 97 57 52 | 18 59 96 40 23 58 20 57 41 97 44 62 75 54 85 78 94 52 64 34 37 45 84 13 53
Card 21: 34 3 13 85 81 19 37 97 29 91 | 9 97 52 3 35 48 24 34 17 50 21 71 57 36 94 82 19 4 14 83 98 37 80 91 59
Card 22: 18 14 95 74 23 71 31 83 51 57 | 94 14 63 18 16 73 57 31 5 23 51 69 85 45 70 35 74 49 79 27 40 95 83 13 71
Card 23: 54 12 52 31 58 93 9 45 27 64 | 48 54 93 12 44 64 56 83 35 94 33 4 58 89 8 45 27 1 86 90 52 31 19 57 9
Card 24: 56 75 17 67 59 37 76 94 25 36 | 24 14 56 53 82 35 92 96 17 34 25 1 16 86 41 95 64 45 38 63 31 18 80 33 66
Card 25: 32 22 47 24 80 92 96 67 5 26 | 22 81 87 47 26 96 92 60 57 64 66 16 5 83 67 49 32 39 71 80 40 63 99 75 53
Card 26: 62 36 66 9 3 71 75 67 29 61 | 9 31 66 82 29 41 67 71 38 36 28 76 14 75 69 61 99 57 62 88 70 95 63 10 59
Card 27: 46 38 59 90 1 65 16 80 76 34 | 70 15 49 31 27 71 54 46 76 1 8 77 93 2 90 39 14 67 62 16 78 56 68 9 58
Card 28: 47 85 54 21 37 14 44 73 12 51 | 78 70 14 77 98 88 25 49 9 79 58 23 52 2 43 17 12 84 59 51 56 89 47 48 6
Card 29: 74 37 60 11 56 21 87 44 33 46 | 80 61 34 54 9 3 45 7 55 13 98 84 10 19 14 8 90 81 50 69 31 12 38 29 78
Card 30: 29 20 44 62 79 34 52 15 49 48 | 17 84 34 1 33 9 23 55 94 10 95 69 42 79 78 44 51 82 20 25 81 29 15 13 32
Card 31: 88 41 38 98 34 40 92 36 25 50 | 33 54 18 53 46 69 8 22 25 36 51 34 42 92 85 45 40 60 84 27 97 39 10 70 41
Card 32: 5 28 85 29 95 37 60 34 24 16 | 74 8 48 73 34 65 66 56 64 85 78 17 39 67 92 30 75 22 95 12 29 24 6 2 51
Card 33: 71 31 99 53 62 80 65 32 13 23 | 87 20 55 24 42 19 67 77 37 89 32 83 44 9 60 46 47 36 49 35 92 10 82 2 81
Card 34: 78 61 12 81 96 82 7 30 80 32 | 62 8 56 89 11 12 39 31 17 18 79 51 30 92 48 5 45 78 41 44 77 98 71 67 73
Card 35: 59 35 63 76 51 8 53 70 24 97 | 20 36 31 17 77 26 34 15 41 39 61 24 35 46 80 74 2 71 5 91 16 11 55 87 4
Card 36: 46 51 79 66 57 52 21 11 75 33 | 88 64 74 99 22 39 42 11 14 65 1 56 86 8 26 16 72 13 55 20 60 40 19 85 58
Card 37: 83 88 1 19 95 30 38 43 14 51 | 98 20 22 55 13 58 93 21 68 11 76 70 71 35 44 90 52 53 75 17 96 27 49 31 26
Card 38: 87 49 43 19 16 34 88 66 67 9 | 70 46 63 58 7 53 96 1 59 35 91 85 18 21 93 68 90 73 11 92 60 61 98 38 15
Card 39: 24 68 25 61 54 63 30 37 21 73 | 50 84 48 10 81 5 62 28 92 66 96 6 20 83 78 88 31 89 12 71 60 8 34 70 90
Card 40: 18 72 44 15 3 19 69 63 73 57 | 14 3 52 76 71 12 50 13 86 21 55 31 27 29 43 47 90 75 9 97 6 32 96 37 18
Card 41: 81 66 49 20 86 80 4 55 93 44 | 87 81 7 47 25 85 80 51 76 27 78 10 16 50 33 66 13 64 35 18 44 63 29 92 48
Card 42: 27 21 14 28 69 89 94 9 19 46 | 92 13 27 99 96 19 43 54 4 14 45 16 44 83 24 61 2 28 5 90 49 51 63 64 73
Card 43: 34 49 58 85 23 88 84 78 89 55 | 72 45 73 23 75 52 84 78 46 55 58 71 98 5 56 91 49 39 88 70 42 59 89 85 34
Card 44: 18 69 46 58 73 59 56 23 12 40 | 71 23 87 93 21 84 10 79 47 92 91 13 52 1 32 78 59 95 72 55 97 56 43 61 75
Card 45: 33 47 58 69 57 1 82 6 61 48 | 48 97 4 1 67 66 82 12 6 29 21 96 90 33 57 28 47 69 74 27 2 32 58 61 9
Card 46: 42 54 98 50 36 86 27 66 29 60 | 32 23 40 62 38 91 43 98 29 85 18 30 66 28 81 35 68 61 11 27 50 22 41 46 42
Card 47: 1 31 87 71 53 17 5 93 84 56 | 48 26 14 47 34 44 18 93 17 88 61 8 95 74 53 50 56 80 62 84 99 49 87 52 1
Card 48: 40 75 79 29 64 57 33 49 95 68 | 7 39 63 79 89 10 23 40 22 86 92 13 57 29 9 19 90 87 58 12 77 16 75 4 91
Card 49: 4 45 87 47 71 35 9 2 81 77 | 93 33 49 75 11 34 62 39 83 40 55 17 84 43 80 60 46 7 18 56 48 66 95 57 74
Card 50: 88 42 2 30 24 89 15 93 16 45 | 93 45 72 68 30 28 17 82 64 91 29 98 14 24 88 70 55 48 58 10 42 83 66 2 77
Card 51: 91 96 87 48 6 73 95 55 71 89 | 94 49 84 33 82 9 21 32 25 46 65 15 86 83 66 11 37 1 14 61 92 36 35 45 27
Card 52: 48 3 94 56 41 13 34 8 96 25 | 40 88 46 14 68 25 75 66 87 55 64 78 92 43 19 97 53 90 83 59 69 31 84 95 13
Card 53: 13 45 61 92 91 32 49 58 43 36 | 44 70 55 28 2 6 35 79 24 54 82 95 52 73 75 84 34 57 21 23 33 22 80 88 1
Card 54: 61 52 20 8 73 54 83 60 29 6 | 74 40 27 46 81 75 3 42 47 69 22 59 58 49 90 63 57 50 79 70 82 5 53 91 39
Card 55: 41 51 64 55 57 44 26 70 62 34 | 24 82 49 39 56 84 31 27 86 77 22 6 73 72 99 47 60 18 53 68 42 19 66 9 50
Card 56: 30 89 82 17 72 46 98 5 54 58 | 4 86 18 15 84 41 16 63 44 91 12 31 66 96 94 87 49 59 67 64 80 33 5 11 40
Card 57: 39 80 17 47 15 96 69 50 46 24 | 5 83 16 52 57 27 98 43 78 1 66 90 19 6 58 3 49 94 85 62 44 54 75 14 9
Card 58: 42 77 37 13 74 40 31 92 36 46 | 16 74 80 59 51 31 95 85 40 93 23 15 32 18 46 97 36 13 79 10 37 99 77 25 92
Card 59: 39 1 78 7 57 46 91 26 12 94 | 46 13 26 83 21 1 67 78 50 94 8 12 39 61 86 91 35 29 32 72 30 97 57 16 7
Card 60: 62 32 18 51 40 96 93 36 80 84 | 42 93 65 8 2 52 84 70 11 1 92 21 80 99 18 14 17 47 56 90 49 67 19 48 97
Card 61: 6 83 74 89 44 73 39 42 47 88 | 72 74 42 21 88 77 18 6 83 85 49 73 5 39 78 44 64 10 47 14 89 53 98 13 92
Card 62: 91 86 35 23 30 28 77 88 56 41 | 54 26 90 20 96 78 14 5 47 98 31 55 74 83 33 15 67 92 19 40 73 72 52 81 94
Card 63: 87 91 78 92 33 71 80 47 13 65 | 32 33 56 55 2 4 61 71 91 97 93 78 83 74 3 13 47 70 54 80 65 60 49 26 96
Card 64: 70 61 63 52 32 35 85 46 54 4 | 42 54 32 84 56 46 29 61 63 78 4 36 80 86 26 17 3 87 48 21 85 52 35 70 22
Card 65: 83 95 45 97 49 67 13 92 1 90 | 68 75 20 96 6 33 73 1 50 14 17 66 34 78 54 84 92 9 64 61 85 88 72 42 12
Card 66: 1 7 99 75 17 21 48 70 30 13 | 70 80 45 89 75 7 21 99 20 54 42 46 67 85 61 17 1 16 30 92 77 48 13 68 90
Card 67: 69 55 20 91 47 31 33 75 56 39 | 69 31 62 20 58 1 93 48 35 55 47 13 56 60 50 75 25 37 91 81 10 39 32 33 54
Card 68: 14 97 54 28 73 64 81 32 47 17 | 86 48 88 25 47 65 22 81 28 95 41 14 27 26 46 64 79 61 45 96 32 9 21 54 53
Card 69: 6 21 89 82 75 48 46 56 68 47 | 48 32 74 30 13 56 93 90 68 33 41 58 21 47 8 17 65 6 89 97 75 82 46 26 59
Card 70: 35 48 78 92 64 30 88 77 76 10 | 76 33 48 67 78 64 24 69 36 14 77 85 30 73 53 91 3 35 96 88 43 84 10 95 92
Card 71: 59 78 57 66 15 18 41 83 70 35 | 7 62 19 30 48 97 89 71 40 27 11 63 60 47 23 86 10 84 4 75 80 69 61 67 25
Card 72: 80 82 46 70 10 14 55 49 62 9 | 31 76 62 17 8 49 19 50 85 72 77 75 42 48 33 60 54 45 12 91 20 92 15 3 25
Card 73: 38 83 96 47 42 99 13 82 36 85 | 74 86 59 16 49 45 81 61 44 39 3 91 9 26 35 25 55 21 19 41 90 70 10 29 4
Card 74: 92 36 96 65 24 6 98 13 33 86 | 17 83 30 5 46 51 54 81 44 99 33 56 45 14 57 34 8 16 77 48 40 94 82 73 75
Card 75: 14 21 57 66 33 8 90 7 4 28 | 91 61 3 84 89 45 60 56 51 10 58 20 96 78 73 93 97 44 19 15 12 90 35 87 42
Card 76: 37 91 60 44 43 3 40 33 95 51 | 24 39 81 1 46 83 97 88 87 6 67 40 22 96 93 2 71 33 29 15 41 16 89 21 68
Card 77: 91 84 43 9 87 96 37 64 41 31 | 35 13 30 43 78 32 23 85 84 19 88 68 10 63 27 77 61 50 41 94 54 12 97 86 33
Card 78: 9 78 53 16 80 56 91 3 62 70 | 85 64 21 88 51 16 15 4 69 30 13 1 70 17 52 23 90 5 24 50 19 81 41 67 12
Card 79: 59 28 42 51 66 58 63 9 24 47 | 69 95 26 36 14 62 13 20 35 25 34 74 40 41 9 39 45 77 5 10 55 96 22 81 49
Card 80: 72 83 73 23 85 2 53 22 3 43 | 14 50 67 63 19 76 39 60 31 33 62 92 29 12 49 75 69 78 44 8 96 95 34 65 20
Card 81: 2 46 29 50 65 57 55 83 74 12 | 4 70 97 54 68 99 81 5 84 10 73 61 88 66 27 8 56 33 79 47 85 49 17 16 34
Card 82: 37 30 10 3 8 34 44 24 57 13 | 42 17 25 65 48 71 4 64 51 83 75 27 72 96 45 18 11 15 70 53 91 14 12 87 59
Card 83: 82 81 15 4 54 96 74 72 37 70 | 37 78 72 25 4 66 81 97 6 83 43 96 61 44 15 71 40 54 27 70 82 98 74 93 7
Card 84: 97 52 96 23 80 53 57 83 16 62 | 5 31 89 91 84 33 52 83 76 23 64 67 10 97 29 63 96 58 74 53 62 57 80 81 92
Card 85: 53 33 76 24 81 68 51 47 40 89 | 70 38 51 50 85 57 89 40 30 61 1 24 54 75 32 33 96 19 14 53 76 20 7 99 47
Card 86: 19 96 52 18 15 53 82 16 86 13 | 69 27 32 85 87 30 33 83 11 47 3 21 68 70 42 61 46 2 64 65 44 1 97 48 74
Card 87: 18 40 55 62 39 95 60 11 76 46 | 82 81 22 46 92 80 62 91 12 40 76 60 69 78 17 18 11 93 56 39 37 88 3 64 95
Card 88: 72 65 91 61 57 4 49 24 45 31 | 28 49 91 31 19 59 65 36 34 87 72 24 60 89 17 12 57 30 75 32 63 8 21 4 25
Card 89: 18 24 64 43 33 56 6 67 8 16 | 40 21 27 52 3 23 65 89 16 7 96 31 48 73 33 37 18 99 12 50 74 26 71 84 8
Card 90: 75 3 92 35 12 26 49 59 60 55 | 65 58 39 73 3 56 11 44 4 47 68 24 86 10 61 6 72 13 82 42 29 93 97 77 8
Card 91: 78 40 49 75 60 15 59 7 31 93 | 71 9 48 10 69 29 65 40 21 57 68 87 12 35 81 70 30 94 36 97 51 43 8 82 5
Card 92: 3 53 23 43 15 4 98 11 67 29 | 35 3 93 87 83 60 5 92 1 90 67 23 78 98 20 37 81 71 31 82 95 47 53 75 21
Card 93: 20 61 6 36 52 77 59 16 18 81 | 66 29 4 87 61 92 78 30 68 69 67 57 88 83 71 54 24 21 13 56 84 35 60 86 53
Card 94: 25 52 87 17 94 41 23 30 72 53 | 93 62 38 77 31 24 21 36 75 64 45 83 56 39 90 29 55 43 71 54 42 98 76 74 28
Card 95: 84 66 91 8 26 82 85 96 31 36 | 93 51 40 98 69 74 53 67 86 23 77 41 62 89 64 34 5 26 50 73 42 43 13 19 91
Card 96: 7 6 90 39 14 73 66 81 33 67 | 63 26 1 58 29 10 3 13 94 9 85 68 69 19 53 96 90 36 49 99 31 74 54 45 77
Card 97: 66 64 77 7 88 18 40 24 10 63 | 28 22 62 41 30 21 19 12 50 43 46 42 56 6 60 36 95 82 97 2 73 55 38 53 8
Card 98: 48 10 16 15 93 40 37 72 57 88 | 10 59 38 19 97 23 51 40 35 31 56 54 21 27 28 81 15 67 12 57 37 65 9 22 74
Card 99: 45 57 7 23 86 82 15 14 75 35 | 55 19 84 37 82 39 15 77 42 52 44 18 75 45 7 69 67 23 86 6 89 14 43 57 35
Card 100: 68 85 29 69 17 44 19 56 92 8 | 8 4 20 98 36 39 78 79 72 81 51 22 13 47 2 77 30 28 64 41 89 57 50 34 16
Card 101: 6 91 90 43 85 1 19 2 28 9 | 63 25 2 9 83 85 87 43 91 6 62 64 74 28 19 82 92 29 36 1 71 90 60 99 84
Card 102: 20 72 12 52 58 28 30 76 42 55 | 30 47 59 29 20 93 90 33 76 58 78 28 52 83 48 72 54 42 67 17 55 12 36 2 37
Card 103: 58 18 40 8 73 69 22 74 26 63 | 61 40 63 41 82 87 22 8 34 6 73 95 69 44 45 85 62 74 27 28 26 4 96 58 15
Card 104: 42 71 57 39 22 79 43 80 90 37 | 43 37 76 94 40 67 4 55 74 21 7 42 3 39 28 12 80 57 32 61 95 58 64 90 13
Card 105: 60 9 50 14 56 11 54 33 77 84 | 77 81 17 99 11 84 70 60 5 43 83 19 80 13 54 33 50 30 87 31 9 4 37 56 14
Card 106: 79 87 86 96 1 8 63 43 39 91 | 6 2 75 63 67 38 11 96 90 91 87 97 86 9 21 77 43 36 79 8 40 85 39 1 13
Card 107: 97 83 21 39 74 64 79 70 77 14 | 85 32 55 18 24 14 79 57 51 12 4 21 23 70 26 83 39 66 63 1 64 73 30 8 77
Card 108: 18 41 11 62 88 38 73 4 47 36 | 82 53 41 92 65 15 42 47 85 96 26 43 58 62 11 3 54 55 89 63 30 17 20 93 2
Card 109: 28 34 55 39 22 99 98 89 86 54 | 58 76 46 70 91 43 2 79 16 25 89 42 78 52 12 56 44 69 80 85 84 99 62 19 15
Card 110: 32 38 50 41 8 97 84 60 92 40 | 43 7 51 76 69 38 92 34 41 71 8 49 95 79 32 45 42 58 60 40 4 3 98 31 20
Card 111: 61 7 67 98 74 21 79 4 85 68 | 90 80 4 8 46 55 40 28 30 38 64 86 73 51 42 66 69 15 29 6 52 78 82 49 41
Card 112: 13 92 98 37 72 52 1 30 42 36 | 17 65 49 6 5 33 40 10 57 72 12 53 7 15 44 18 90 46 81 99 26 16 23 52 66
Card 113: 39 30 46 62 55 42 32 77 9 37 | 37 21 50 40 63 97 28 11 51 26 75 86 80 32 16 69 77 60 6 99 9 72 22 55 79
Card 114: 54 6 72 17 56 76 23 78 7 38 | 15 76 40 56 8 50 51 97 94 64 13 3 69 24 54 66 14 25 82 1 71 41 47 74 92
Card 115: 50 66 30 89 46 20 35 59 22 88 | 96 72 32 97 61 64 25 70 4 11 88 34 46 6 10 73 71 79 45 33 66 50 24 13 42
Card 116: 83 33 99 22 90 32 11 28 47 85 | 80 58 57 7 15 1 23 59 86 54 67 36 83 38 34 18 37 35 19 90 45 24 46 4 84
Card 117: 95 23 58 8 76 82 60 1 15 80 | 75 77 10 85 36 52 91 54 44 96 97 89 25 67 16 31 99 51 68 83 55 29 3 20 33
Card 118: 53 7 99 97 39 37 80 52 18 77 | 76 78 83 34 75 69 39 14 27 44 89 56 23 30 43 48 57 61 29 82 87 93 67 62 12
Card 119: 19 22 6 97 71 68 59 95 67 75 | 91 40 20 74 87 46 4 85 63 64 50 88 14 1 54 39 3 62 58 10 28 55 27 86 60
Card 120: 37 76 87 74 15 84 14 11 99 60 | 24 15 92 60 25 3 86 1 33 5 62 65 79 6 91 45 11 14 10 2 43 4 68 85 54
Card 121: 74 43 96 14 67 85 19 51 80 95 | 27 53 14 15 72 99 85 30 33 20 13 58 12 25 36 18 45 67 34 79 32 76 96 95 55
Card 122: 93 51 95 32 2 18 40 72 31 45 | 8 98 70 17 62 22 63 72 69 73 3 26 42 25 1 41 28 13 77 92 32 60 56 2 65
Card 123: 9 82 93 20 35 69 87 40 30 67 | 87 10 67 63 76 23 45 35 54 5 75 79 66 40 1 89 71 20 77 43 90 65 9 82 37
Card 124: 93 48 59 54 75 8 83 35 4 64 | 71 59 41 35 4 65 49 5 98 91 54 45 76 64 93 75 8 83 48 87 94 32 16 89 82
Card 125: 24 14 40 22 2 57 67 35 36 98 | 36 82 19 88 23 55 15 97 78 35 94 24 67 52 14 30 40 56 38 57 2 31 22 98 71
Card 126: 22 7 97 12 95 66 69 51 59 88 | 94 88 59 58 70 64 95 29 7 93 68 21 16 19 36 39 41 66 10 76 78 82 63 34 56
Card 127: 46 9 32 85 22 20 14 68 98 61 | 69 25 4 70 64 57 14 89 41 98 22 53 27 77 20 56 84 42 85 40 90 6 61 71 60
Card 128: 53 84 81 45 23 13 93 34 42 80 | 80 74 39 50 75 49 7 61 43 5 1 51 36 54 57 97 26 32 82 98 68 45 93 37 86
Card 129: 40 29 85 88 86 7 49 67 91 92 | 86 38 79 31 57 34 78 17 52 53 22 36 62 75 21 70 88 7 3 49 28 6 85 14 4
Card 130: 63 20 36 62 43 98 99 12 46 57 | 14 32 99 22 17 70 5 91 57 95 49 15 28 46 84 89 78 79 43 98 45 50 88 16 23
Card 131: 7 16 87 36 73 82 11 40 14 69 | 25 31 82 24 50 38 2 28 4 23 72 6 51 79 86 46 55 97 42 90 84 1 39 32 27
Card 132: 67 56 15 63 40 9 59 23 94 27 | 26 65 80 40 46 23 37 78 27 12 34 98 41 59 94 16 50 79 90 15 4 7 6 62 17
Card 133: 18 91 27 52 4 34 12 32 65 41 | 45 55 7 3 84 79 54 91 75 80 17 49 42 9 18 48 59 6 8 22 94 10 93 53 57
Card 134: 78 75 48 26 14 8 91 41 34 68 | 18 29 57 5 17 22 56 97 74 34 13 50 40 33 62 20 10 71 58 1 21 88 87 8 25
Card 135: 5 97 16 92 74 51 61 65 3 14 | 15 50 86 24 99 90 59 32 45 81 97 75 6 25 29 80 9 89 46 70 40 57 42 63 60
Card 136: 81 35 23 70 51 14 31 50 67 7 | 32 28 40 58 4 99 18 95 11 90 86 13 84 74 61 5 44 47 24 38 21 1 77 48 78
Card 137: 74 99 57 81 5 1 90 9 69 30 | 88 23 97 7 25 68 78 91 53 15 55 81 92 90 12 18 50 71 61 75 8 76 36 19 34
Card 138: 37 2 84 13 78 51 29 15 42 71 | 49 30 16 88 79 67 76 75 38 80 91 6 28 83 14 26 1 19 40 18 32 98 74 17 44
Card 139: 49 75 16 61 39 4 51 55 17 97 | 11 45 56 47 81 78 67 21 57 42 84 58 8 13 10 91 7 19 46 14 90 87 26 1 18
Card 140: 39 19 41 45 17 30 29 66 61 25 | 61 53 29 41 37 30 95 93 45 17 8 21 66 10 14 78 65 18 39 5 52 91 19 25 4
Card 141: 7 66 29 40 9 14 34 64 4 31 | 98 63 65 6 92 56 81 67 48 88 49 18 38 61 13 95 28 85 20 17 21 30 58 52 89
Card 142: 32 88 54 27 21 86 49 87 44 45 | 15 44 67 75 87 79 21 10 34 70 54 49 88 3 28 32 65 27 43 98 53 64 45 86 9
Card 143: 14 7 67 53 37 73 45 18 62 34 | 87 68 3 22 40 86 26 85 70 4 61 78 1 29 48 12 37 10 77 54 99 36 94 79 15
Card 144: 92 35 52 27 19 16 58 4 22 85 | 47 37 30 51 96 28 58 81 85 9 19 10 46 22 27 7 35 52 16 60 4 92 53 13 84
Card 145: 71 32 62 83 43 20 97 57 78 24 | 88 34 23 25 67 52 11 9 49 80 70 29 43 2 44 45 62 56 33 3 20 98 28 77 79
Card 146: 99 11 17 93 16 77 1 46 55 68 | 25 17 77 99 35 53 3 84 98 2 21 74 27 58 16 20 33 22 39 28 69 9 92 46 52
Card 147: 56 26 30 23 66 94 82 47 14 49 | 68 41 6 13 99 7 71 67 35 93 57 84 44 40 70 89 42 63 74 22 20 55 33 91 64
Card 148: 21 6 43 36 7 44 61 23 93 57 | 53 20 51 59 74 77 16 92 47 25 62 58 18 85 3 63 46 81 99 5 79 70 69 75 34
Card 149: 31 36 91 20 17 50 1 18 64 52 | 66 90 80 33 26 24 30 58 45 77 25 29 44 48 6 35 96 13 78 65 68 98 93 89 94
Card 150: 81 91 37 66 12 33 59 97 38 32 | 61 38 91 95 75 85 48 44 37 47 84 66 35 62 79 94 25 22 97 17 10 31 96 5 78
Card 151: 32 35 11 75 63 61 42 62 10 56 | 4 44 53 12 50 76 51 5 82 25 30 8 89 41 34 98 54 96 37 74 35 16 31 57 65
Card 152: 96 60 29 43 99 19 80 8 5 2 | 87 52 19 11 99 35 20 60 55 80 24 21 8 61 38 78 42 28 95 6 64 65 49 59 26
Card 153: 53 30 75 13 87 77 56 89 63 6 | 7 54 93 80 47 4 72 9 69 44 97 96 23 24 94 67 55 8 33 30 37 6 14 5 3
Card 154: 10 65 46 58 13 25 69 52 19 3 | 47 41 9 3 40 79 89 21 33 73 14 7 74 65 31 62 24 69 60 87 12 16 53 80 82
Card 155: 24 51 35 95 93 73 36 65 27 20 | 14 83 97 94 29 39 19 38 33 32 44 92 60 25 76 64 49 71 65 34 91 31 53 74 23
Card 156: 52 31 50 54 82 42 23 9 39 3 | 29 64 88 70 48 74 12 90 75 57 23 25 58 68 36 33 73 5 84 28 47 92 50 41 21
Card 157: 66 20 50 96 6 84 54 67 59 81 | 77 60 38 65 37 44 15 73 23 83 18 71 89 53 90 36 40 32 2 39 78 63 8 51 19
Card 158: 38 46 85 81 87 86 98 90 37 34 | 41 71 35 26 12 19 51 93 39 20 76 24 7 80 50 56 49 2 57 84 68 92 54 1 75
Card 159: 61 36 84 47 4 22 49 17 31 75 | 77 83 49 55 84 80 18 44 31 47 22 67 4 68 69 35 75 5 59 13 61 39 36 54 17
Card 160: 90 70 62 65 87 95 15 77 76 35 | 70 94 97 10 90 80 35 27 84 87 42 62 54 26 95 57 82 63 1 18 92 25 49 64 21
Card 161: 44 6 28 50 79 16 15 83 45 53 | 79 72 12 45 50 35 67 6 89 28 15 61 16 7 46 36 44 55 27 92 1 59 83 53 94
Card 162: 29 51 46 64 4 75 37 78 81 71 | 83 71 37 39 74 66 32 1 51 93 43 46 20 3 15 50 81 64 75 73 78 29 33 4 22
Card 163: 1 52 37 97 88 47 94 10 98 5 | 85 31 33 46 15 1 16 61 98 59 64 94 83 68 35 11 44 80 38 36 84 72 86 40 29
Card 164: 60 40 94 62 18 71 92 25 21 64 | 64 18 58 76 38 55 40 45 71 92 73 75 25 62 12 94 68 79 23 91 21 60 72 39 7
Card 165: 63 88 91 22 85 18 39 55 33 84 | 95 88 37 5 39 46 33 61 32 45 74 20 27 35 76 85 84 18 54 86 91 75 22 55 63
Card 166: 72 11 31 50 53 82 41 74 62 87 | 42 34 50 11 96 3 77 7 37 22 44 38 62 1 87 68 12 54 74 53 47 82 69 89 85
Card 167: 79 26 70 95 25 16 18 37 75 61 | 39 11 68 61 44 53 42 94 37 45 75 78 62 18 95 26 79 92 38 13 16 64 21 91 57
Card 168: 94 86 69 88 31 15 62 44 19 14 | 3 24 29 8 44 61 89 7 75 15 91 36 45 70 66 4 35 6 71 22 25 39 55 33 18
Card 169: 86 68 72 15 42 99 9 35 2 74 | 42 84 59 86 6 15 53 89 85 79 20 68 62 61 10 2 9 51 99 54 33 35 13 48 93
Card 170: 83 6 15 80 93 63 79 50 69 5 | 15 25 6 93 69 50 83 68 16 40 66 58 63 79 52 7 80 34 61 95 5 33 78 91 32
Card 171: 33 85 4 12 72 62 49 67 17 53 | 4 17 53 72 47 6 49 56 82 48 12 26 30 85 61 15 36 70 64 25 2 33 67 46 62
Card 172: 98 63 26 82 12 61 56 95 27 99 | 76 30 14 95 26 97 71 19 57 67 73 48 63 54 82 18 98 27 61 5 12 44 1 56 74
Card 173: 7 32 34 4 22 79 27 10 78 65 | 3 81 65 36 91 62 94 54 41 32 12 28 39 34 18 61 78 79 80 66 9 63 43 72 97
Card 174: 14 78 60 32 26 31 15 80 11 72 | 1 31 33 35 73 83 97 36 21 3 26 9 91 23 51 84 82 70 22 20 34 90 98 87 69
Card 175: 73 14 7 11 20 64 30 90 62 23 | 60 53 15 73 63 19 71 92 48 89 80 44 78 79 2 76 45 64 42 35 81 27 10 21 26
Card 176: 32 30 39 10 1 3 67 66 94 62 | 86 95 56 54 58 35 90 19 74 43 5 48 17 2 46 65 97 71 36 31 69 8 47 94 42
Card 177: 24 90 40 47 51 75 63 29 57 10 | 49 68 61 43 30 26 84 59 99 75 44 41 17 24 12 38 90 37 36 35 91 9 89 46 8
Card 178: 73 74 31 76 10 21 70 3 30 41 | 39 14 30 70 79 75 97 44 87 20 92 12 86 56 18 46 8 90 23 98 2 59 28 53 3
Card 179: 78 44 89 84 50 97 55 90 77 99 | 79 1 88 65 2 50 72 68 7 15 85 41 64 93 37 16 53 44 42 48 89 97 59 60 8
Card 180: 55 98 13 45 33 91 88 4 49 37 | 18 44 64 83 56 79 81 26 78 54 72 75 11 70 66 57 73 61 62 34 19 95 93 94 76
Card 181: 94 47 65 55 8 45 1 67 71 25 | 99 34 43 64 36 50 6 51 27 59 37 40 3 98 72 78 38 74 82 46 85 90 48 32 84
Card 182: 78 75 63 31 30 70 84 50 28 19 | 61 18 58 87 77 48 71 50 91 92 60 86 73 94 85 57 97 15 1 25 74 67 11 68 47
Card 183: 94 27 68 41 8 72 48 85 97 49 | 81 35 90 69 76 18 53 1 59 25 88 31 4 93 84 32 9 55 66 50 22 62 43 60 17
Card 184: 40 31 56 54 59 98 93 81 24 44 | 62 42 93 56 99 10 81 59 37 6 41 66 44 72 31 30 20 54 51 24 27 83 40 73 98
Card 185: 38 73 79 48 3 46 99 93 50 24 | 65 34 40 2 20 92 10 32 67 57 22 47 96 11 7 31 87 6 28 95 77 25 58 29 27
Card 186: 47 65 99 98 90 68 13 49 51 10 | 90 82 27 68 84 83 57 50 18 5 49 65 85 10 46 13 21 81 73 51 71 47 98 88 99
Card 187: 25 56 18 15 59 47 20 86 50 83 | 25 57 83 36 56 87 50 34 9 70 4 64 77 45 92 13 20 47 48 15 97 18 86 28 59
Card 188: 99 16 44 2 85 17 71 45 49 11 | 94 13 45 36 77 89 26 6 39 27 84 1 80 21 73 41 33 90 46 72 65 96 34 71 83
Card 189: 34 24 76 68 47 19 85 15 50 46 | 43 67 4 44 14 34 19 61 47 68 50 46 99 94 16 76 15 28 36 27 52 85 88 24 89
Card 190: 56 20 43 86 2 88 87 30 14 4 | 43 14 19 92 3 23 87 74 50 97 2 88 18 80 20 86 36 41 95 27 57 98 49 30 26
Card 191: 47 2 18 84 91 66 24 6 42 56 | 12 93 7 50 42 45 2 91 66 4 32 47 19 56 49 18 15 24 44 84 97 6 16 31 25
Card 192: 42 88 68 56 93 48 9 52 20 70 | 30 93 42 4 68 70 36 56 9 15 88 98 64 67 33 91 20 61 50 27 13 94 52 48 85
Card 193: 46 57 19 40 9 7 47 33 86 11 | 65 54 38 43 82 55 79 51 77 73 74 97 75 96 6 47 62 88 92 18 84 48 41 29 52
Card 194: 58 23 35 79 82 72 44 93 12 43 | 43 60 2 24 77 48 61 25 44 75 35 12 93 51 36 72 6 31 29 50 37 80 19 14 87
Card 195: 15 77 78 50 36 83 68 52 86 26 | 16 72 67 88 14 81 34 24 71 32 91 77 90 1 98 95 7 28 49 84 86 20 44 73 56
Card 196: 25 3 32 15 1 56 27 51 82 81 | 87 79 15 11 98 54 56 88 18 92 69 25 66 27 60 58 44 1 51 3 32 81 12 72 41
Card 197: 3 99 81 8 93 28 76 7 27 48 | 78 98 85 5 93 77 72 62 69 82 50 9 35 74 18 10 33 67 90 31 79 84 58 29 17
Card 198: 26 81 19 24 59 82 8 95 86 17 | 13 22 10 96 19 20 88 3 90 78 24 9 50 34 6 94 7 60 44 76 31 81 26 33 43
Card 199: 77 91 58 16 47 94 23 30 88 5 | 38 66 12 25 95 67 72 89 36 45 63 15 54 98 74 57 32 39 59 28 7 62 82 13 26
Card 200: 82 47 52 12 83 4 26 93 33 9 | 31 30 91 2 6 27 28 1 81 8 75 92 56 57 41 24 72 85 53 74 59 11 66 32 54
Card 201: 4 13 26 57 84 17 63 10 98 56 | 72 85 68 47 44 60 54 34 38 16 8 11 23 84 32 18 69 13 26 35 9 73 43 15 89
Card 202: 11 9 1 42 71 78 97 89 8 10 | 33 17 81 48 60 96 69 37 12 46 73 4 76 54 86 91 28 5 51 98 99 84 13 85 32
Card 203: 37 80 7 87 79 60 6 49 16 12 | 23 34 15 46 38 20 27 45 33 97 37 14 68 83 49 79 43 70 57 60 11 63 24 35 73
Card 204: 84 24 48 76 7 18 77 37 69 5 | 88 39 92 94 34 37 11 40 85 35 2 81 73 58 42 66 83 9 56 12 14 51 62 20 7
Card 205: 5 84 4 6 95 77 59 67 74 35 | 58 47 29 34 79 86 35 89 71 96 27 64 90 48 37 78 1 39 46 21 98 91 43 8 56
Card 206: 56 21 34 13 1 17 99 11 76 60 | 36 24 83 31 50 19 82 32 61 9 98 71 79 39 97 37 29 13 27 10 52 22 41 40 59
Card 207: 62 7 22 90 51 96 12 13 36 52 | 48 37 70 24 73 51 83 3 5 77 29 87 23 18 26 76 19 97 20 86 84 14 63 33 21
Card 208: 40 42 5 91 29 59 70 49 23 94 | 82 81 30 61 64 65 19 9 67 75 92 16 26 52 73 43 55 35 17 93 39 90 74 53 51
@@ -0,0 +1,6 @@
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
+173
View File
@@ -0,0 +1,173 @@
use std::cmp;
use std::str::FromStr;
#[derive(Debug, Default, PartialEq, Clone)]
pub struct CardNumbers {
pub numbers: Vec<u32>,
}
impl FromStr for CardNumbers {
type Err = &'static str;
/// Parses a string `string` to return a value of [`CardNumbers`]
///
/// If parsing succeeds, return the value inside [`Ok`], otherwise
/// when the string is ill-formatted return an error specific to the
/// inside [`Err`].
///
/// # Examples
///
/// ```
/// use std::str::FromStr;
/// use puzzle_2023_day_4::CardNumbers;
///
/// let string = "83 86 6 31 17 9 48 53";
/// let expected_result = CardNumbers {
/// numbers: vec![83, 86, 6, 31, 17, 9, 48, 53],
/// };
/// let actual_result = CardNumbers::from_str(string).unwrap();
///
/// assert_eq!(actual_result, expected_result);
/// ```
fn from_str(string: &str) -> Result<Self, Self::Err> {
let result = CardNumbers {
numbers: string
.split_whitespace()
.map(|string| string.trim())
.filter(|&string| !string.is_empty())
.map(|string| string.parse::<u32>().unwrap_or_default())
.collect(),
};
Ok(result)
}
}
#[derive(Debug, Default, PartialEq, Clone)]
pub struct Card {
pub id: usize,
pub winning_numbers_count: usize,
}
impl FromStr for Card {
type Err = &'static str;
/// Parses a string `string` to return a value of [`Card`]
///
/// If parsing succeeds, return the value inside [`Ok`], otherwise
/// when the string is ill-formatted return an error specific to the
/// inside [`Err`].
///
/// # Examples
///
/// ```
/// use std::str::FromStr;
/// use puzzle_2023_day_4::{Card, CardNumbers};
///
/// let string = "Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53";
/// let expected_result = Card {
/// id: 1,
/// winning_numbers_count: 4,
/// };
/// let actual_result = Card::from_str(string).unwrap();
///
/// assert_eq!(actual_result, expected_result);
/// ```
fn from_str(string: &str) -> Result<Self, Self::Err> {
let mut result = Card::default();
let mut parts = string.split(": ");
result.id = parts
.next()
.unwrap_or("Card 1")
.strip_prefix("Card ")
.unwrap_or("1")
.trim()
.parse()
.unwrap_or(1);
let mut numbers_parts = parts.next().unwrap_or("").split(" | ");
let winning_numbers =
CardNumbers::from_str(numbers_parts.next().unwrap_or("")).unwrap_or_default();
let owned_numbers =
CardNumbers::from_str(numbers_parts.next().unwrap_or("")).unwrap_or_default();
result.winning_numbers_count = owned_numbers
.numbers
.iter()
.filter(|&owned_number| winning_numbers.numbers.contains(owned_number))
.count();
Ok(result)
}
}
pub fn part_1(input: &str) -> usize {
input
.lines()
.map(|line| Card::from_str(line).unwrap_or_default())
.map(|card| {
let winning_numbers_count = card.winning_numbers_count as u32;
let base: usize = 2;
if winning_numbers_count > 0 {
base.pow(winning_numbers_count.saturating_sub(1))
} else {
0
}
})
.sum::<usize>()
}
pub fn part_2(input: &str) -> usize {
let cards = input
.lines()
.map(|line| Card::from_str(line).unwrap_or_default())
.collect::<Vec<Card>>();
let mut cards_identifiers = cards.iter().map(|card| card.id).collect::<Vec<usize>>();
let mut index_card = 0;
loop {
if index_card >= cards_identifiers.len() {
break;
}
if let Some(card) = cards.get(cards_identifiers.get(index_card).unwrap_or(&0) - 1) {
let card_position_index = card.id - 1;
let maximum_index = cmp::min(
card_position_index + card.winning_numbers_count,
cards.len() - 1,
);
for index in card_position_index + 1..=maximum_index {
cards_identifiers.push(index + 1);
}
}
index_card += 1;
}
cards_identifiers.len()
}
#[cfg(test)]
mod puzzle_2023_day_4_tests {
use super::*;
#[test]
fn test_part_1_example() {
assert_eq!(part_1(include_str!("../input_example_1.txt")), 13);
}
#[test]
fn test_part_2_example() {
assert_eq!(part_2(include_str!("../input_example_1.txt")), 30);
}
#[test]
fn test_part_1() {
assert_eq!(part_1(include_str!("../input.txt")), 24160);
}
#[test]
fn test_part_2() {
assert_eq!(part_2(include_str!("../input.txt")), 5659035);
}
}
@@ -0,0 +1,8 @@
use puzzle_2023_day_4::{part_1, part_2};
fn main() {
let input = include_str!("../input.txt");
println!("- Day 4 of 2023: Scratchcards -");
println!("Answer Part 1: {}", part_1(input));
println!("Answer Part 2: {}", part_2(input));
}
+9
View File
@@ -0,0 +1,9 @@
[package]
name = "puzzle_2023_day_5"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
[dependencies]
rayon = { workspace = true }
indicatif = { workspace = true }
+128
View File
@@ -0,0 +1,128 @@
# - Day 5 of 2023: If You Give A Seed A Fertilizer -
Source: <https://adventofcode.com/2023/day/5>
## Instructions - Part 1
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](https://en.wikipedia.org/wiki/Sand_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](https://en.wikipedia.org/wiki/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:
```txt
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:
```txt
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:
```txt
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 number `81`.
- Seed number `14` corresponds to soil number `14`.
- Seed number `55` corresponds to soil number `57`.
- Seed number `13` corresponds to soil number `13`.
The gardener and his team want to get started as soon as possible, so they'd like to know the closest location that needs a seed. Using these maps, find **the lowest location number that corresponds to any of the initial seeds**. To do this, you'll need to convert each seed number through other categories until you can find its corresponding **location number**. In this example, the corresponding types are:
- Seed `79`, soil `81`, fertilizer `81`, water `81`, light `74`, temperature `78`, humidity `78`, **location `82`**.
- Seed `14`, soil `14`, fertilizer `53`, water `49`, light `42`, temperature `42`, humidity `43`, **location `43`**.
- Seed `55`, soil `57`, fertilizer `57`, water `53`, light `46`, temperature `82`, humidity `82`, **location `86`**.
- Seed `13`, soil `13`, fertilizer `52`, water `41`, light `34`, temperature `34`, humidity `35`, **location `35`**.
So, the lowest location number in this example is **`35`**.
**What is the lowest location number that corresponds to any of the initial seed numbers?**
## Instructions - Part 2
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:
```txt
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?**
+221
View File
@@ -0,0 +1,221 @@
seeds: 2019933646 2719986 2982244904 337763798 445440 255553492 1676917594 196488200 3863266382 36104375 1385433279 178385087 2169075746 171590090 572674563 5944769 835041333 194256900 664827176 42427020
seed-to-soil map:
3566547172 3725495029 569472267
2346761246 1249510998 267846697
1812605508 937956667 271194541
1421378697 1209151208 40359790
2083800049 2788751092 262961197
2938601691 473979048 463977619
473979048 1517357695 947399649
4136019439 3566547172 158947857
1461738487 3051712289 350867021
2614607943 2464757344 323993748
soil-to-fertilizer map:
3107230831 2583931429 576709409
970181981 608291332 1441137369
743954495 3859046283 158951815
3683940240 3227916509 91282070
608291332 2448268266 135663163
3775222310 2049428701 398839565
2411319350 3319198579 539847704
2951167054 4017998098 156063777
902906310 3160640838 67275671
fertilizer-to-water map:
1257642402 395703749 69589612
1800674 2215701547 90550534
2757853693 358464863 37238886
3285451399 181079109 43937782
2346544130 3513448371 192150886
3866348216 4231433060 63534236
1327232014 1560332334 90281838
2538695016 616206288 114467702
255018176 225016891 46372244
1171065990 3705599257 27021880
1070753744 730673990 442780
221369008 3479799203 33649168
2987721226 271389135 80072982
1198087870 732917444 24556356
199036270 2306252081 22332738
0 731116770 1800674
3929882452 3989920675 212758268
631506549 757473800 322942578
301390420 0 157952443
2795092579 157952443 1997721
1222644226 2619085211 34998176
954449127 499901671 116304617
1429766246 159950164 21128945
2205492221 2074649638 141051909
2749302577 3732621137 8551116
459342863 1219863414 57737723
3329389181 3741172253 59047790
2797090300 2328584819 190630926
3278448653 351462117 7002746
126959518 1277601137 72076752
92351208 465293361 34608310
4142640720 3866348216 123572459
2143980560 1080416378 43307177
1450895191 2672287871 693085369
517080586 3365373240 114425963
3388436971 1662866566 411783072
2187287737 2654083387 18204484
1417513852 1650614172 12252394
3067794208 1349677889 210654445
4266213179 4202678943 28754117
2653162718 1123723555 96139859
1071196524 2519215745 99869466
water-to-light map:
512627839 90187036 1196629
3379634653 2059506154 33434334
3286651054 4276482087 18485209
4233695090 28914830 61272206
3413068987 3322576776 23288997
3736304424 3345865773 43267308
1246285471 2994853001 251748584
3779571732 1946298040 113208114
390808412 3287769466 34807310
1881283842 2879009693 106527924
3964031050 2506138169 12994476
3436357984 793897944 162691614
2255160753 2092940488 151061610
853985057 3506201042 119010035
301385394 1856875022 89423018
972995092 658665705 34308693
4159948022 1315925500 65322692
640912738 250463411 213072319
1761800914 91383665 102591221
450345319 3246601585 5793995
3186220306 4173678310 91115364
28914830 3633635453 176360375
456139314 193974886 56488525
2523290324 3809995828 187303152
2406222363 3389133081 117067961
205275205 2782899504 96110189
2135785589 1100569535 119375164
1121466033 533846267 124819438
1007303785 2244002098 114162248
3599049598 3997298980 137254826
4077949072 463535730 70310537
4225270714 3625211077 8424376
1498034055 2519132645 263766859
2710593476 1381248192 475626830
3977025526 692974398 100923546
4148259609 4264793674 11688413
1987811766 2358164346 147973823
3892779846 1244674296 71251204
3340510149 4134553806 39124504
1864392135 956589558 16891707
425615722 1219944699 24729597
513824468 973481265 127088270
3277335670 2985537617 9315384
3305136263 3252395580 35373886
light-to-temperature map:
1094191559 698410082 28110394
383870732 1189042355 107231661
3711052230 2164474756 34756304
745558539 170241759 7170863
491102393 503970250 194439832
4034618875 3142749029 146609939
3781998432 1718948669 129329785
2440091414 3071819711 70929318
1301358031 55123603 115118156
0 2789116652 87933685
770729148 177412622 48955790
3772681560 3886204605 9316872
752729402 37123857 17999746
3745808534 2137385460 7147939
2028807236 3677936618 208267987
2237075223 3289358968 92979022
88764920 1960439220 176946240
3568470355 2258695303 142581875
3276170082 1848278454 112160766
2637902204 1129503077 39814191
3000547589 892603630 188042422
2511020732 226368412 126881472
1122301953 1296274016 52818372
1440958847 1353023078 243104929
2963423732 0 37123857
3388330848 2199231060 48304954
1175120325 377732544 126237706
819684938 1349092388 3930690
3752956473 1169317268 19725087
3911328217 2144533399 19941357
1416476187 353249884 24482660
2677716395 3895521477 285707337
265711160 2413138935 118159572
685542225 1080646052 48857025
3556608598 2401277178 11861757
734399250 2247536014 11159289
87933685 3677105383 831235
3188590011 1596128007 87580071
836373414 2531298507 257818145
3471876393 2877050337 84732205
1684063776 726520476 166083154
823615628 3560998296 12757786
3436635802 1683708078 35240591
3931269574 3573756082 103349301
1850146930 3382337990 178660306
2330054245 2961782542 110037169
temperature-to-humidity map:
1773059646 4122818507 172148789
2417158855 2859734866 110076859
977168274 1576624124 28149321
4275291678 3797606290 19675618
1141296808 749646180 267286171
3592756112 2969811725 273274339
0 19621130 7167651
2059084943 2697725300 48133058
2107218001 3920609496 145140777
1453481278 1152911564 151292167
1408582979 1465584228 44898299
7167651 0 19621130
2907567891 1829621431 240604380
2252358778 3652347291 145258999
1005317595 1016932351 135979213
1945208435 2745858358 113876508
2397617777 4065750273 16506015
3251499859 1776094709 53526722
2867005672 4082256288 40562219
26788781 1304203731 161380497
3305026581 2409995769 287729531
3866030451 3243086064 409261227
2414123792 1773059646 3035063
911026677 1510482527 66141597
3148172271 3817281908 103327588
2527235714 2070225811 339769958
188169278 26788781 722857399
humidity-to-location map:
3907319746 3137303541 31421983
3085093695 1018495475 286155292
2898003508 2491485887 87665522
2546787368 2901838353 7997221
3835317650 2829836257 72002096
2554784589 3509894030 133012322
3487595595 3719561871 104747874
3714670750 2667334372 120646900
975094571 2909835574 227467967
2985669030 3864000834 99424665
3672962118 2449777255 41708632
3631107133 2787981272 41854985
3938741729 3963425499 15057061
3447904506 3824309745 39691089
1824175159 1304650767 641793976
242892183 0 6504921
3371248987 3642906352 76655519
1698833898 2258930589 81940357
0 6504921 242892183
2465969135 3978482560 80818233
3592343469 4256203632 38763664
3953798790 3168725524 341168506
2775979874 4134179998 122023634
1780774255 975094571 43400904
1311468847 1946444743 312485846
2687796911 2579151409 88182963
1202562538 2340870946 108906309
1623954693 4059300793 74879205
@@ -0,0 +1,33 @@
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
+276
View File
@@ -0,0 +1,276 @@
use indicatif::ParallelProgressIterator;
use rayon::prelude::*;
use std::ops::Range;
use std::str::FromStr;
#[derive(Debug, Default, PartialEq, Clone)]
pub struct RangeConverter {
pub source_range: Range<usize>,
pub destination_range: Range<usize>,
}
impl FromStr for RangeConverter {
type Err = &'static str;
/// Parses a string `string` to return a value of [`RangeConverter`]
///
/// If parsing succeeds, return the value inside [`Ok`], otherwise
/// when the string is ill-formatted return an error specific to the
/// inside [`Err`].
///
/// # Examples
///
/// ```
/// use std::str::FromStr;
/// use puzzle_2023_day_5::RangeConverter;
///
/// let string = "50 98 2 ";
/// let expected_result = RangeConverter {
/// source_range: 98..100,
/// destination_range: 50..52,
/// };
/// let actual_result = RangeConverter::from_str(string).unwrap();
///
/// assert_eq!(actual_result, expected_result);
/// ```
fn from_str(string: &str) -> Result<Self, Self::Err> {
let numbers = string
.trim()
.split_ascii_whitespace()
.map(|string| {
let result: usize = string.trim().parse().unwrap_or_default();
result
})
.collect::<Vec<usize>>();
let destination_range_start = *numbers.first().unwrap_or(&0);
let source_range_start = *numbers.get(1).unwrap_or(&0);
let range_length = *numbers.get(2).unwrap_or(&0);
let result = RangeConverter {
source_range: source_range_start..(source_range_start + range_length),
destination_range: destination_range_start..(destination_range_start + range_length),
};
Ok(result)
}
}
#[derive(Debug, Default, PartialEq, Clone)]
pub struct CategoryConverter {
pub name: String,
pub ranges_converters: Vec<RangeConverter>,
}
impl FromStr for CategoryConverter {
type Err = &'static str;
/// Parses a string `string` to return a value of [`CategoryConverter`]
///
/// If parsing succeeds, return the value inside [`Ok`], otherwise
/// when the string is ill-formatted return an error specific to the
/// inside [`Err`].
///
/// # Examples
///
/// ```
/// use std::str::FromStr;
/// use puzzle_2023_day_5::{CategoryConverter, RangeConverter};
///
/// let string = "
/// seed-to-soil map:
/// 50 98 2
/// 52 50 48
/// ";
/// let expected_result = CategoryConverter {
/// name: String::from("seed-to-soil map:"),
/// ranges_converters: vec![
/// RangeConverter {
/// source_range: 98..100,
/// destination_range: 50..52,
/// },
/// RangeConverter {
/// source_range: 50..98,
/// destination_range: 52..100,
/// },
/// ],
/// };
/// let actual_result = CategoryConverter::from_str(string).unwrap();
///
/// assert_eq!(actual_result, expected_result);
/// ```
fn from_str(string: &str) -> Result<Self, Self::Err> {
let mut lines = string.trim().lines();
let name = lines.next().unwrap_or_default();
let mut ranges_converters = vec![];
for line in lines {
ranges_converters.push(RangeConverter::from_str(line).unwrap_or_default());
}
let result = CategoryConverter {
name: String::from(name),
ranges_converters,
};
Ok(result)
}
}
impl CategoryConverter {
pub fn convert(&self, number: usize) -> usize {
self.ranges_converters
.iter()
.find_map(|range_converter| {
if range_converter.source_range.contains(&number) {
Some(
range_converter.destination_range.start
+ (number - range_converter.source_range.start),
)
} else {
None
}
})
.unwrap_or(number)
}
}
#[derive(Debug, Default, PartialEq, Clone)]
pub struct Almanac {
pub seeds: Vec<usize>,
pub categories_converters: Vec<CategoryConverter>,
}
impl FromStr for Almanac {
type Err = &'static str;
/// Parses a string `string` to return a value of [`Almanac`]
///
/// If parsing succeeds, return the value inside [`Ok`], otherwise
/// when the string is ill-formatted return an error specific to the
/// inside [`Err`].
///
/// # Examples
///
/// ```
/// use std::str::FromStr;
/// use puzzle_2023_day_5::{Almanac, CategoryConverter, RangeConverter};
///
/// let string = "
/// seeds: 79 14 55 13
///
/// seed-to-soil map:
/// 50 98 2
/// 52 50 48
/// ";
/// let expected_result = Almanac {
/// seeds: vec![79, 14, 55, 13],
/// categories_converters: vec![CategoryConverter {
/// name: String::from("seed-to-soil map:"),
/// ranges_converters: vec![
/// RangeConverter {
/// source_range: 98..100,
/// destination_range: 50..52,
/// },
/// RangeConverter {
/// source_range: 50..98,
/// destination_range: 52..100,
/// },
/// ],
/// }],
/// };
/// let actual_result = Almanac::from_str(string).unwrap();
///
/// assert_eq!(actual_result, expected_result);
/// ```
fn from_str(string: &str) -> Result<Self, Self::Err> {
let mut categories = string.trim().split("\n\n");
let seeds = categories
.next()
.unwrap_or_default()
.strip_prefix("seeds: ")
.unwrap_or_default()
.split_ascii_whitespace()
.map(|string| {
let result: usize = string.trim().parse().unwrap_or_default();
result
})
.collect::<Vec<usize>>();
let categories_converters = categories
.map(|category_string| CategoryConverter::from_str(category_string).unwrap_or_default())
.collect::<Vec<CategoryConverter>>();
let result = Almanac {
seeds,
categories_converters,
};
Ok(result)
}
}
impl Almanac {
pub fn minimum_location(&self) -> usize {
self.seeds
.par_iter()
.map(|&seed| {
self.categories_converters
.iter()
.fold(seed, |accumulator, category_converter| {
category_converter.convert(accumulator)
})
})
.progress()
.min()
.unwrap_or_default()
}
pub fn set_seeds_as_range_pairs(&mut self) {
self.seeds = self
.seeds
.par_chunks(2)
.progress()
.flat_map(|chunk| {
if let [range_start, range_length] = chunk {
let start = *range_start;
let length = *range_length;
let range = start..(start + length);
range.into_iter()
} else {
let empty_range = 0..0;
empty_range.into_iter()
}
})
.collect();
}
}
pub fn part_1(input: &str) -> usize {
let almanac = Almanac::from_str(input).unwrap_or_default();
almanac.minimum_location()
}
pub fn part_2(input: &str) -> usize {
let mut almanac = Almanac::from_str(input).unwrap_or_default();
almanac.set_seeds_as_range_pairs();
almanac.minimum_location()
}
#[cfg(test)]
mod puzzle_2023_day_5_tests {
use super::*;
#[test]
fn test_part_1_example() {
assert_eq!(part_1(include_str!("../input_example_1.txt")), 35);
}
#[test]
fn test_part_2_example() {
assert_eq!(part_2(include_str!("../input_example_1.txt")), 46);
}
#[test]
fn test_part_1() {
assert_eq!(part_1(include_str!("../input.txt")), 313045984);
}
#[test]
#[ignore]
/// Ignored because it is a expensive/slow test to run.
fn test_part_2() {
assert_eq!(part_2(include_str!("../input.txt")), 20283860);
}
}
@@ -0,0 +1,8 @@
use puzzle_2023_day_5::{part_1, part_2};
fn main() {
let input = include_str!("../input.txt");
println!("- Day 5 of 2023: If You Give A Seed A Fertilizer -");
println!("Answer Part 1: {}", part_1(input));
println!("Answer Part 2: {}", part_2(input));
}
+8
View File
@@ -0,0 +1,8 @@
[package]
name = "puzzle_2023_day_6"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
[dependencies]
rayon = { workspace = true }
+73
View File
@@ -0,0 +1,73 @@
# - Day 6 àf 2023: Wait For It -
Source: <https://adventofcode.com/2023/day/6>
## Instructions - Part 1
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:
```txt
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 traveled **`0` millimeters** by the end of the race.
- Hold the button for **`1` millisecond** at the start of the race. Then, the boat will travel at a speed of 1 millimeter per millisecond for 6 milliseconds, reaching a total distance traveled of **`6` millimeters**.
- Hold the button for **`2` milliseconds**, giving the boat a speed of 2 millimeters per millisecond. It will then get 5 milliseconds to move, reaching a total distance of **`10` millimeters**.
- Hold the button for **`3` milliseconds**. After its remaining 4 milliseconds of travel time, the boat will have gone **`12` millimeters**.
- Hold the button for **`4` milliseconds**. After its remaining 3 milliseconds of travel time, the boat will have gone **`12` millimeters**.
- Hold the button for **`5` milliseconds**, causing the boat to travel a total of **`10` millimeters**.
- Hold the button for **`6` milliseconds**, causing the boat to travel a total of **`6` millimeters**.
- Hold the button for **`7` milliseconds**. That's the entire duration of the race. You never let go of the button. The boat can't move until you let go of the button. Please make sure you let go of the button so the boat gets to move. **`0` millimeters**.
Since the current record for this race is `9` millimeters, there are actually **`4`** different ways you could win: you could hold the button for `2`, `3`, `4`, or `5` milliseconds at the start of the race.
In the second race, you could hold the button for at least `4` milliseconds and at most `11` milliseconds and beat the record, a total of **`8`** different ways to win.
In the third race, you could hold the button for at least `11` milliseconds and no more than `19` milliseconds and still beat the record, a total of **`9`** ways you could win.
To see how much margin of error you have, determine the **number of ways you can beat the record** in each race; in this example, if you multiply these values together, you get **`288`** (`4` \* `8` \* `9`).
Determine the number of ways you could beat the record in each race. **What do you get if you multiply these numbers together?**
## Instructions - Part 2
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](https://en.wikipedia.org/wiki/Kerning). There's really **only one race** - ignore the spaces between the numbers on each line.
So, the example from before:
```txt
Time: 7 15 30
Distance: 9 40 200
```
...now instead means this:
```txt
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?**
+2
View File
@@ -0,0 +1,2 @@
Time: 38 94 79 70
Distance: 241 1549 1074 1091
@@ -0,0 +1,2 @@
Time: 7 15 30
Distance: 9 40 200
+114
View File
@@ -0,0 +1,114 @@
use rayon::prelude::*;
#[derive(Debug, Default, PartialEq, Clone)]
pub struct Race {
pub maximum_time_in_milliseconds: usize,
pub best_distance_in_millimeters_recorded: usize,
}
impl Race {
pub fn get_all_winning_strategies(&self) -> Vec<RaceStrategy> {
(1..self.maximum_time_in_milliseconds)
.into_par_iter()
.map(|time_in_milliseconds_holding_button| RaceStrategy {
time_in_milliseconds_holding_button,
maximum_time_in_milliseconds: self.maximum_time_in_milliseconds,
})
.filter(|race_strategy| {
let distance_in_millimeters_travelled =
race_strategy.calculate_distance_in_millimeters_travelled();
distance_in_millimeters_travelled > self.best_distance_in_millimeters_recorded
})
.collect::<Vec<RaceStrategy>>()
}
}
#[derive(Debug, Default, PartialEq, Clone)]
pub struct RaceStrategy {
pub time_in_milliseconds_holding_button: usize,
pub maximum_time_in_milliseconds: usize,
}
impl RaceStrategy {
pub fn calculate_distance_in_millimeters_travelled(&self) -> usize {
(self.maximum_time_in_milliseconds - self.time_in_milliseconds_holding_button)
* self.time_in_milliseconds_holding_button
}
}
pub fn part_1(input: &str) -> usize {
fn get_numbers_from_line(line: &str) -> Vec<usize> {
line.split(':')
.last()
.unwrap_or_default()
.split_ascii_whitespace()
.map(|value| value.trim())
.filter(|value| !value.is_empty())
.map(|value| {
let result: usize = value.parse().unwrap_or_default();
result
})
.collect::<Vec<usize>>()
}
let mut lines = input.trim().lines();
let maximum_times = get_numbers_from_line(lines.next().unwrap_or_default());
let best_distances = get_numbers_from_line(lines.next().unwrap_or_default());
maximum_times
.iter()
.zip(best_distances.iter())
.map(
|(&maximum_time_in_milliseconds, &best_distance_recorded_in_millimeters)| Race {
maximum_time_in_milliseconds,
best_distance_in_millimeters_recorded: best_distance_recorded_in_millimeters,
},
)
.map(|race| race.get_all_winning_strategies().len())
.product()
}
pub fn part_2(input: &str) -> usize {
fn get_number_from_line(line: &str) -> usize {
line.split(':')
.last()
.unwrap_or_default()
.replace(' ', "")
.trim()
.parse()
.unwrap_or_default()
}
let mut lines = input.trim().lines();
let race = Race {
maximum_time_in_milliseconds: get_number_from_line(lines.next().unwrap_or_default()),
best_distance_in_millimeters_recorded: get_number_from_line(
lines.next().unwrap_or_default(),
),
};
race.get_all_winning_strategies().len()
}
#[cfg(test)]
mod puzzle_2023_day_6_tests {
use super::*;
#[test]
fn test_part_1_example() {
assert_eq!(part_1(include_str!("../input_example_1.txt")), 288);
}
#[test]
fn test_part_2_example() {
assert_eq!(part_2(include_str!("../input_example_1.txt")), 71503);
}
#[test]
fn test_part_1() {
assert_eq!(part_1(include_str!("../input.txt")), 1083852);
}
#[test]
fn test_part_2() {
assert_eq!(part_2(include_str!("../input.txt")), 23501589);
}
}
@@ -0,0 +1,8 @@
use puzzle_2023_day_6::{part_1, part_2};
fn main() {
let input = include_str!("../input.txt");
println!("- Day 6 of 2023: Wait For It -");
println!("Answer Part 1: {}", part_1(input));
println!("Answer Part 2: {}", part_2(input));
}
+8
View File
@@ -0,0 +1,8 @@
[package]
name = "puzzle_2023_day_7"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
[dependencies]
array-init = { workspace = true }
+87
View File
@@ -0,0 +1,87 @@
# - Day 7 of 2023: Camel Cards -
Source: <https://adventofcode.com/2023/day/7>
## Instructions - Part 1
Your all-expenses-paid trip turns out to be a one-way, five-minute ride in an [airship](https://en.wikipedia.org/wiki/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](https://en.wikipedia.org/wiki/Dromedary).
"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](https://en.wikipedia.org/wiki/List_of_poker_hands) 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:
```txt
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` and `KTJJT` are both **two pair**. Their first cards both have the same label, but the second card of `KK677` is stronger (`K` vs `T`), so `KTJJT` gets rank **`2`** and `KK677` gets rank **`3`**.
- `T55J5` and `QQQJA` are both **three of a kind**. `QQQJA` has a stronger first card, so it gets rank **`5`** and `T55J5` gets rank **`4`**.
Now, you can determine the total winnings of this set of hands by adding up the result of multiplying each hand's bid with its rank (`765` \* 1 + `220` \* 2 + `28` \* 3 + `684` \* 4 + `483` \* 5). So the **total winnings** in this example are **`6440`**.
Find the rank of every hand in your set. **What are the total winnings?**
## Instructions - Part 2
To make things a little more interesting, the Elf introduces one additional rule. Now, `J` cards are [jokers](<https://en.wikipedia.org/wiki/Joker_(playing_card)>) - 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`.
`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`.
Now, the above example goes very differently:
```txt
32T3K 765
T55J5 684
KK677 28
KTJJT 220
QQQJA 483
```
- `2T3K` is still the only **one pair**; it doesn't contain any jokers, so its strength doesn't increase.
- `KK677` is now the only **two pair**, making it the second-weakest hand.
- `T55J5`, `KTJJT`, and `QQQJA` are now all **four of a kind**! `T55J5` gets rank 3, `QQQJA` gets rank 4, and `KTJJT` gets rank 5.
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?**
+1000
View File
@@ -0,0 +1,1000 @@
88788 501
99929 849
J8787 166
878T7 667
2J957 35
AQAA2 997
T6QQ5 151
84TJ9 142
AT938 566
A4AK7 297
3J383 85
T66TT 408
49J94 377
4AA4A 50
AA2K6 678
77758 586
A6J27 681
88TTT 554
JKQ26 346
8793J 304
8A53A 691
J6792 412
47QT6 21
65JQ5 633
Q2K5T 623
53353 985
AA792 205
52552 311
K6KKK 545
Q74Q4 756
KKK65 632
K6TTT 159
QTTQT 570
T6974 416
KA396 772
22A22 833
73629 293
3K33J 884
767Q6 334
A88J8 613
28789 560
6JT83 247
72629 659
A7J2K 456
K4879 197
QK76J 720
TJ923 747
J6664 706
4QTQQ 649
9K476 815
J7A77 505
8KK87 893
Q6576 718
6T6T2 529
Q39A9 426
J55A2 208
75444 96
8J6KJ 787
J244K 775
467J5 646
6KJ37 53
Q27T3 515
3QAJK 936
AA99A 195
45664 328
68456 376
56J34 557
9T22Q 628
679KK 844
78Q2J 824
3Q449 877
8TT82 565
4J596 255
AQ853 981
445KK 79
3KT85 589
6Q2A7 993
AJA44 179
TJ925 17
626JT 309
89273 471
J99A3 495
7Q945 805
T5JK4 193
TJ4J6 752
T63JQ 898
827KA 414
T686K 427
55QT3 891
K48AA 630
2T777 146
TKTTK 133
T68T8 229
55255 955
3642A 669
AJJQT 921
98AA9 647
Q32Q2 1000
44T4T 851
8J448 145
3333Q 935
25225 338
K484K 33
Q88T2 530
8QA9Q 281
22864 384
4Q5QT 757
7T3QT 863
3TA87 769
88686 612
TK2KK 880
TTT82 415
77Q77 232
JQ3T5 653
858Q4 749
J9K54 896
7JAT4 928
22452 176
3J725 522
694K6 721
8Q88Q 521
TATAA 181
6J8TQ 693
J54A8 122
73J85 13
9984T 90
444J4 173
99T97 907
35333 134
2A3Q5 852
KK77K 806
JJ895 937
37839 161
596TK 797
77T77 244
44774 452
7K557 28
33JTT 171
45JT2 878
9AKK2 268
9675K 483
77TJ7 274
55Q55 964
Q6666 390
9AT7T 931
KT829 716
AJ477 624
3JQ33 661
667Q6 464
47J44 6
J4A95 486
T9QK3 525
7A76A 767
749Q9 109
77QJA 742
K534A 779
Q88T8 451
T3A9K 808
A7AA6 513
6JAT7 150
6K88Q 314
444JT 829
5QJJ5 618
6TT66 534
6656A 57
65646 446
Q666Q 40
KQ2A2 140
A777A 675
TT777 830
T2T5T 831
9A799 116
AJJKA 130
53626 201
J44J4 126
J58QT 778
2K22K 580
K5KKJ 803
K6384 717
484Q7 604
Q9QTQ 186
8KJ69 916
323A4 726
77K7K 248
Q4987 335
4J87T 302
J7557 599
KKK4J 294
A59KJ 729
JQQ65 228
TT5QT 113
J799Q 49
28833 454
45J4A 502
3TTT3 924
75557 700
6565A 398
2J442 307
2J2J2 654
3AQAA 282
5Q282 178
822J2 811
4T9T9 453
377Q7 357
5TJ4Q 719
7K4KA 894
6T5TT 922
7QJ6Q 114
TQ38K 885
83A33 322
Q7J72 999
8A8AA 503
328KJ 342
9K3A4 587
834A8 249
QQK5Q 231
29929 391
8QJAQ 860
92QK6 705
Q88Q9 367
22422 284
KK96K 762
T47QQ 643
9K622 217
4KJ6Q 976
49494 547
T333T 405
57675 528
9A88T 845
A4T85 303
66677 239
763Q7 639
KKKJ7 601
5K5KK 206
66222 257
TAKTK 504
36636 24
89998 655
KJKJ5 713
QT2QQ 804
T6666 419
Q3KJT 564
K3K38 542
2K2A2 288
4A584 437
JJ4J7 932
7395J 792
J89T5 343
K89K6 711
96696 685
T9455 362
25257 238
6Q9J6 992
QA239 765
63736 477
83467 933
562A8 994
42284 187
J9333 491
K442K 3
KJ6Q5 78
Q277K 220
55528 20
8J888 318
4Q34Q 807
58J3J 18
686A6 332
5JJ25 365
47QA4 251
64J4K 433
KA5QK 900
9QQT9 36
77577 861
KJ6A2 301
J5AA5 286
K9T6Q 172
33737 540
95955 732
22233 665
2Q435 500
7A757 354
QJ375 743
64TKK 345
7J486 295
5Q5QQ 682
K5655 163
J56J5 112
229J7 709
69436 22
38839 460
T66J6 194
Q2999 211
6J474 15
33444 511
35A54 189
72TT6 773
7A7JK 984
2635T 230
TQ855 129
6K633 489
7K458 862
299J2 783
22322 316
996T2 326
5TK7J 188
KTTTT 11
488J8 174
68475 904
9KK99 399
4447T 431
T9AAA 541
4A977 131
59359 66
59QQ9 463
5T293 493
32323 736
J553Q 440
A2555 266
4AAAA 68
A3AKA 780
3444T 37
TQ77T 744
6J655 687
99AQ2 551
TKATA 679
8K4J6 879
3K8KJ 333
3Q3AJ 226
T67KQ 535
K236J 866
63336 934
648A5 484
4TT4T 911
98K56 117
349QT 696
985T4 867
9T339 402
88A8A 938
3J3J3 38
26752 177
JA668 29
KKAA7 263
AJAJ3 674
7A87T 141
K3J3A 558
3888J 199
6242K 989
3JAQQ 946
AA7KJ 43
JT623 550
QJQ4Q 372
99JJJ 386
83383 712
5K7J6 942
6Q639 168
JJ8JJ 961
5294A 776
66766 638
3T9JT 104
A7T8J 213
Q74J7 175
5296K 250
25888 204
A5AJQ 598
TJKK6 396
TTJTA 753
74QK4 766
8QTAJ 16
A2632 225
22825 823
J5286 606
999T9 533
22252 572
2Q222 98
55J55 684
K38K2 959
JAA4Q 908
49J54 55
7K37Q 315
39354 421
8Q76Q 730
666JQ 864
77TTK 583
Q9T87 846
44494 92
JJK24 909
AAAAK 422
25Q7Q 947
Q4658 82
K2Q8T 886
7T979 47
K365Q 657
4T822 945
57KK5 650
69555 441
J8J8T 960
KAKKK 103
9T5JA 479
88KK6 361
47569 209
39Q58 69
33399 271
9A6TK 673
28AAA 45
64449 967
T4J6Q 492
6222A 727
TAA72 265
KK667 457
9Q9Q6 432
K6K3K 300
5QTQQ 404
TJ44J 781
8595A 234
K2539 498
KK77J 207
A42Q9 602
23333 543
9J299 758
29222 821
KKTAJ 136
59555 856
5Q98Q 523
65558 872
464K6 798
7773K 519
AJAJA 380
77977 591
57443 125
AAJAA 450
5AA6A 881
69679 458
6JQ3K 139
Q3J3Q 636
AQ556 221
A6J3K 741
TT7T6 56
3QQQA 972
27399 754
54Q5Q 592
Q2975 920
93898 770
86828 27
TTT9T 809
6QA73 344
A8J74 546
J8J88 374
24T42 183
387Q6 14
98A99 418
AA3AA 245
44KKK 240
8658K 317
28228 555
2AAAA 381
8A2T3 331
75Q82 899
387KK 737
K444K 839
K9999 424
KK9AK 948
QQAQA 512
475KK 820
72277 430
JT7T3 466
Q555Q 853
5555K 562
QQ58J 537
J3762 536
85283 196
9T44T 651
6KTAJ 785
24J29 666
36653 962
KQAKA 596
KTK5A 597
Q999T 842
82828 629
AT7AT 848
73TT8 215
A4Q4Q 791
T8326 8
5QQQ7 977
TKKKT 680
A92A9 277
6689J 539
2J222 963
566Q8 802
Q9QQQ 387
2322A 403
66366 147
JJJJJ 951
278T9 496
6949T 465
3K5K8 692
TK3K2 608
AA9AA 918
653JK 703
4K5JA 475
63863 72
5593J 388
55474 476
99T9T 923
5A95J 825
T5K28 723
KKJJK 869
57865 160
JKKTT 272
AAAAT 631
TTJ4J 905
93369 214
8J777 944
96267 236
56Q9T 164
7QQ42 819
67K4T 434
AAA8A 93
JAJKQ 310
97J77 859
K7K9J 462
88JJA 283
74A44 25
KKAJK 548
3TT5Q 593
27762 914
TT3TT 369
6388Q 656
3T48T 156
AJQJ5 507
65K2Q 855
A4652 663
65A72 957
J66J6 998
44434 100
99777 449
3J2Q2 567
66QQ8 889
A999J 363
AAJJ2 364
7789A 350
73737 980
QQQT8 411
T224K 227
K3289 155
AJA77 971
88548 305
55554 76
38386 97
999A9 200
KJK55 7
J77J7 237
777JK 259
577T2 777
99969 407
9898J 761
225K9 722
9TT39 995
7TJ5A 745
45477 865
TTAJ4 838
TT22J 149
4J222 939
A8A98 84
8Q333 327
A3Q3A 897
29K68 575
5K558 621
58778 152
2923Q 107
4K6KJ 735
T9J99 115
33T3Q 524
8KKKT 91
33T35 397
QQKQT 298
48J36 795
7J777 51
J585A 264
45545 81
T88JT 634
43364 584
77A77 616
AJ4Q8 54
3A362 389
73732 755
68666 447
2Q6Q6 568
34K33 409
T5K34 60
TJ9T6 635
4QQ44 913
K3JK3 253
66A2A 686
KTK33 423
6AAAA 950
7554J 470
4444T 763
22772 702
24229 121
8J86K 683
KK7A5 474
6T632 987
2J2K2 368
AAJ54 611
QAT87 697
J9QQ8 740
92QQ2 688
6TKA8 184
QQQQA 202
A5JJ3 890
3T445 590
93995 348
6QQJ3 873
T4TJ4 841
2T2TT 269
K8J7T 223
89999 958
Q77J6 379
TT2TT 2
6JQ29 280
8TQT8 615
6TTTT 978
T6A66 517
77884 439
33633 494
T99T5 153
7T54J 953
33739 65
4K544 556
9Q9J9 751
8QQ79 637
2QQ69 786
TKJ2K 930
56545 41
5A8A4 676
66566 868
69996 915
JJQQQ 9
J27KJ 499
22424 26
64QQ4 323
988A8 123
7K447 410
T8K8T 620
7KAJK 573
88855 531
75743 943
KT7KK 578
J3A56 708
3224A 158
J73J2 290
79955 858
58JK5 640
A4AJJ 340
33J44 648
95785 527
3K548 965
K47J4 552
9QQJQ 275
J85Q7 75
64466 461
478KQ 132
88989 828
T2T22 710
38A22 442
8QJJ8 704
K4KKK 325
29942 875
3AK56 210
388K6 31
82233 182
A9ATT 968
AJK46 906
699T9 218
33338 353
55J33 664
8J868 901
44249 927
KTT7J 800
8TA2Q 137
88928 313
AA5A9 472
5AAAA 406
23JJQ 627
79JA2 585
Q6J99 919
3J444 952
3KKKK 19
7QQTK 812
8QJ83 48
2252Q 892
65556 480
3336A 731
976JK 672
QAAAQ 561
J69J9 510
K7777 355
Q8888 58
Q8QJ8 887
88848 843
KKJ35 903
92988 986
33344 62
55JK3 241
K37Q5 847
TAA7K 428
A33AA 349
2K222 222
9AK56 563
QT382 644
KK2T2 488
AA552 715
96A37 262
3J376 949
JTJJT 594
KKQJK 448
999JJ 71
8556A 74
Q4JJQ 292
55JK6 366
444Q4 724
7QK58 940
K2J8T 559
9T96T 312
Q679A 73
33A37 870
93TJA 734
44489 191
9TA9A 478
66K5K 836
A8J8A 119
322K2 59
777TA 111
A7778 609
AJK96 83
TTJ5T 827
3QQQ3 514
32242 595
T5JT5 652
544J5 996
884QK 467
7737J 12
Q5TA9 538
8J5J8 401
68KQ9 569
9QKJK 1
AAAJ8 801
3333J 888
7Q979 373
77277 252
AKKQQ 394
QTJ47 695
JJJT7 793
A27A5 358
99939 148
8T7J8 738
Q9924 438
73763 607
KJT44 127
8T288 975
64K4K 279
6A6JA 925
56555 110
77427 671
9956J 941
7757J 359
J3337 80
44256 642
JJ555 871
55859 784
896TK 324
66K66 336
2Q2QQ 750
93833 87
5JA3K 689
TQKQ3 395
K8334 308
22A42 983
533JA 974
9J7T7 455
8888T 840
TAT95 370
22T22 509
TKQJ7 581
48448 641
J3993 102
TQ8A5 270
2KT39 291
TQTTT 445
J2A5T 89
2KQ98 170
A5AA5 520
QJT8T 571
J7AAA 733
227A2 61
T555T 973
TT63A 436
48JA6 420
788K9 690
2A2K4 260
3TJTT 759
74K87 506
45Q22 400
228J8 771
AJJ2T 52
9274T 610
T4TQT 956
JTT66 790
4344K 508
8878A 243
55666 788
5A2Q5 768
77T78 296
KJK59 360
TTTJT 954
952J9 603
J6666 487
JTJ29 32
9A278 516
933AA 874
57357 835
334AJ 287
J4KK4 276
J2226 698
49999 382
Q6QQ2 549
6A4J3 670
8QJA2 826
999K7 138
K7Q87 242
22226 413
7K9K8 285
A85AA 299
2JJK2 385
Q3TTQ 5
377QT 902
82223 63
QQ7Q6 64
9J7JQ 469
7A7TT 970
45JJ2 162
82J4T 383
9AA99 748
53K53 794
K2KKK 982
646J3 330
26J27 216
87A26 605
343J5 966
QQ4QQ 622
9JTQ9 912
A3A38 337
T2538 34
52553 224
66622 444
5T5TT 701
8JJKJ 895
A333A 101
KK5QQ 694
J9999 979
KTKT7 668
QQ622 725
55Q7K 77
79TK8 392
JJ98A 352
2A332 883
33T39 834
94J73 212
Q22QJ 267
53A9A 67
69666 169
KAJAT 95
QQ84Q 728
63723 774
Q3A8K 375
3J36Q 625
85J88 714
5T9J3 124
2KK2K 614
Q5JKJ 988
68926 203
TQ799 822
46TT4 44
97997 482
2A282 106
6TQ88 459
33999 707
7Q264 574
AAAA7 739
86888 154
A752J 10
2T727 760
5T54T 662
2QQQQ 626
6797J 143
6K56T 105
679Q8 88
8AK25 579
K6AJK 645
8J83J 746
A7AA2 854
9J2TQ 319
A8J84 577
87787 799
867AJ 837
QQJQQ 796
QQTQQ 576
225T5 588
5QQ77 677
K7KKK 969
T7TTT 832
A4AA6 192
KQ987 190
ATTAT 425
6J9A4 378
99Q2J 128
95549 917
KKQKK 180
6A5Q7 254
8378J 991
64444 553
JTTJT 789
J75K5 810
QQK28 258
4K3J6 518
2TTT7 135
K3339 532
27222 94
29A29 857
49882 351
63J33 198
5T5J7 910
7443K 185
4K44J 393
K6626 417
28888 347
T47KT 882
22562 273
K8627 118
Q92KK 926
J2644 600
AA6T7 86
2QQ22 929
447J7 246
J8A25 167
2A898 468
46K55 660
JTTT9 23
QQQ7Q 219
7Q7JQ 42
77A37 108
33244 850
Q8529 46
82A5Q 443
76877 278
A7J3T 320
QKT4K 782
57AJA 99
8Q3J3 39
KA4QQ 582
KKKJK 481
66864 876
KK3K3 816
Q8853 813
223T6 544
KAKTK 261
99Q9A 764
Q7425 235
A86K5 321
J483K 435
KK8KK 339
A52TQ 30
TAA37 473
K4AAK 658
KK48A 429
64484 497
3K3TA 289
8898J 144
JAJAJ 356
K8286 329
82KQ6 818
55T55 814
7KA9Q 619
727A7 817
893J3 485
452J5 371
K6969 256
5J528 490
77498 990
6J86K 699
J9373 526
KQQKK 157
77AA2 120
J488Q 165
63885 4
T94K3 233
AA4JA 306
7QQ9J 617
88KKK 70
485QT 341
@@ -0,0 +1,5 @@
32T3K 765
T55J5 684
KK677 28
KTJJT 220
QQQJA 483
+282
View File
@@ -0,0 +1,282 @@
use core::str::FromStr;
use std::{cmp::Ordering, collections::HashMap};
#[derive(Debug, Default, PartialEq, Eq, Clone)]
pub struct Card {
pub label: char,
}
impl Card {
const LABELS: [char; 13] = [
'A', 'K', 'Q', 'J', 'T', '9', '8', '7', '6', '5', '4', '3', '2',
];
pub fn strength(&self) -> usize {
Card::LABELS.len()
- Card::LABELS
.iter()
.position(|&current| current == self.label)
.unwrap_or_default()
}
}
impl Ord for Card {
fn cmp(&self, other: &Self) -> Ordering {
self.strength().cmp(&other.strength())
}
}
impl PartialOrd for Card {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl From<char> for Card {
fn from(label: char) -> Self {
Card { label }
}
}
#[derive(Debug, Default, PartialEq, Eq, Copy, Clone)]
pub enum CardsHandType {
#[default]
HighCard = 1,
OnePair = 2,
TwoPair = 3,
ThreeOfAKind = 4,
FullHouse = 5,
FourOfAKind = 6,
FiveOfAKind = 7,
}
impl CardsHandType {
pub const fn strength(&self) -> usize {
*self as usize
}
}
impl Ord for CardsHandType {
fn cmp(&self, other: &Self) -> Ordering {
self.strength().cmp(&other.strength())
}
}
impl PartialOrd for CardsHandType {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
#[derive(Debug, Default, PartialEq, Eq, Clone)]
pub struct CardsHand {
pub cards: [Card; 5],
pub bid: usize,
}
impl CardsHand {
pub fn hand_type(&self) -> CardsHandType {
let mut label_counts: HashMap<char, usize> = HashMap::new();
for card in &self.cards {
if let Some(label_count) = label_counts.get_mut(&card.label) {
*label_count += 1;
} else {
label_counts.insert(card.label, 1);
}
}
let keys = label_counts.keys();
if keys.len() == 1 {
return CardsHandType::FiveOfAKind;
}
if keys.len() == 2 && label_counts.iter().any(|(_, &value)| value == 4) {
return CardsHandType::FourOfAKind;
}
if keys.len() == 2 && label_counts.iter().any(|(_, &value)| value == 3) {
return CardsHandType::FullHouse;
}
if keys.len() == 3 && label_counts.iter().any(|(_, &value)| value == 3) {
return CardsHandType::ThreeOfAKind;
}
if keys.len() == 3 && label_counts.iter().any(|(_, &value)| value == 2) {
return CardsHandType::TwoPair;
}
if keys.len() == 5 {
return CardsHandType::HighCard;
}
CardsHandType::OnePair
}
}
impl Ord for CardsHand {
fn cmp(&self, other: &Self) -> Ordering {
if self.hand_type() != other.hand_type() {
return self
.hand_type()
.strength()
.cmp(&other.hand_type().strength());
}
for (self_card, other_card) in self.cards.iter().zip(other.cards.iter()) {
if self_card != other_card {
return self_card.cmp(other_card);
}
}
Ordering::Equal
}
}
impl PartialOrd for CardsHand {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl FromStr for CardsHand {
type Err = &'static str;
/// Parses a string `string` to return a value of [`CardsHand`]
///
/// If parsing succeeds, return the value inside [`Ok`], otherwise
/// when the string is ill-formatted return an error specific to the
/// inside [`Err`].
///
/// # Examples
///
/// ```
/// use std::str::FromStr;
/// use puzzle_2023_day_7::{Card, CardsHand, CardsHandType};
///
/// let string = "32T3K 765";
/// let expected_result = CardsHand {
/// cards: [Card { label: '3' }, Card { label: '2' }, Card { label: 'T' }, Card { label: '3' }, Card { label: 'K' } ],
/// bid: 765,
/// };
///
/// let actual_result = CardsHand::from_str(string).unwrap();
/// let actual_hand_type = actual_result.hand_type();
/// assert_eq!(actual_result, expected_result);
/// ```
fn from_str(string: &str) -> Result<Self, Self::Err> {
let mut input = string.split_ascii_whitespace();
let result = CardsHand {
cards: array_init::from_iter(input.next().unwrap_or_default().chars().map(Card::from))
.unwrap_or_default(),
bid: input
.next()
.unwrap_or_default()
.trim()
.parse()
.unwrap_or_default(),
};
Ok(result)
}
}
#[derive(Debug, Default, PartialEq, Eq, Clone)]
pub struct CamelCards {
cards_hands: Vec<CardsHand>,
}
impl FromStr for CamelCards {
type Err = &'static str;
fn from_str(string: &str) -> Result<Self, Self::Err> {
Ok(CamelCards {
cards_hands: string
.trim()
.lines()
.map(|line| CardsHand::from_str(line.trim()).unwrap_or_default())
.collect::<Vec<CardsHand>>(),
})
}
}
pub fn part_1(input: &str) -> usize {
let mut camel_cards = CamelCards::from_str(input).unwrap_or_default();
camel_cards.cards_hands.sort();
camel_cards
.cards_hands
.iter()
.enumerate()
.map(|(index, card_hand)| {
let rank = index + 1;
card_hand.bid * rank
})
.sum()
}
#[cfg(test)]
mod puzzle_2023_day_7_tests {
use super::*;
#[test]
fn test_part_1_example() {
assert_eq!(part_1(include_str!("../input_example_1.txt")), 6440);
}
#[test]
fn test_part_1() {
assert_eq!(part_1(include_str!("../input.txt")), 250370104);
}
mod hand_types {
use std::str::FromStr;
use crate::{CardsHand, CardsHandType};
#[test]
fn test_five_of_a_kind() {
let cards_hand = CardsHand::from_str("AAAAA").unwrap();
let expected = CardsHandType::FiveOfAKind;
let actual = cards_hand.hand_type();
assert_eq!(actual, expected);
}
#[test]
fn test_four_of_a_kind() {
let cards_hand = CardsHand::from_str("AA8AA").unwrap();
let expected = CardsHandType::FourOfAKind;
let actual = cards_hand.hand_type();
assert_eq!(actual, expected);
}
#[test]
fn test_full_house() {
let cards_hand = CardsHand::from_str("23332").unwrap();
let expected = CardsHandType::FullHouse;
let actual = cards_hand.hand_type();
assert_eq!(actual, expected);
}
#[test]
fn test_three_of_a_kind() {
let cards_hand = CardsHand::from_str("TTT98").unwrap();
let expected = CardsHandType::ThreeOfAKind;
let actual = cards_hand.hand_type();
assert_eq!(actual, expected);
}
#[test]
fn test_two_pair() {
let cards_hand = CardsHand::from_str("23432").unwrap();
let expected = CardsHandType::TwoPair;
let actual = cards_hand.hand_type();
assert_eq!(actual, expected);
}
#[test]
fn test_one_pair() {
let cards_hand = CardsHand::from_str("A23A4").unwrap();
let expected = CardsHandType::OnePair;
let actual = cards_hand.hand_type();
assert_eq!(actual, expected);
}
#[test]
fn test_high_card() {
let cards_hand = CardsHand::from_str("23456").unwrap();
let expected = CardsHandType::HighCard;
let actual = cards_hand.hand_type();
assert_eq!(actual, expected);
}
}
}
@@ -0,0 +1,8 @@
use puzzle_2023_day_7::part_1;
fn main() {
let input = include_str!("../input.txt");
println!("- Day 7 of 2023: Camel Cards -");
println!("Answer Part 1: {}", part_1(input));
// println!("Answer Part 2: {}", part_2(input));
}
+5
View File
@@ -0,0 +1,5 @@
[package]
name = "puzzle_2023_day_8"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
+78
View File
@@ -0,0 +1,78 @@
# - Day 8 of 2023: Haunted Wasteland -
Source: <https://adventofcode.com/2023/day/8>
## Instructions - Part 1
You're still riding a camel across Desert Island when you spot a sandstorm quickly approaching. When you turn to warn the Elf, she disappears before your eyes! To be fair, she had just finished warning you about **ghosts** a few minutes ago.
One of the camel's pouches is labeled "maps" - sure enough, it's full of documents (your puzzle input) about how to navigate the desert. At least, you're pretty sure that's what they are; one of the documents contains a list of left/right instructions, and the rest of the documents seem to describe some kind of **network** of labeled nodes.
It seems like you're meant to use the **left/right** instructions **to navigate the network**. Perhaps if you have the camel follow the same instructions, you can escape the haunted wasteland!
After examining the maps for a bit, two nodes stick out: `AAA` and `ZZZ`. You feel like `AAA` is where you are now, and you have to follow the left/right instructions until you reach `ZZZ`.
This format defines each node of the network individually. For example:
```txt
RL
AAA = (BBB, CCC)
BBB = (DDD, EEE)
CCC = (ZZZ, GGG)
DDD = (DDD, DDD)
EEE = (EEE, EEE)
GGG = (GGG, GGG)
ZZZ = (ZZZ, ZZZ)
```
Starting with `AAA`, you need to **look up the next element** based on the next left/right instruction in your input. In this example, start with `AAA` and go **right** (`R`) by choosing the right element of `AAA`, **`CCC`**. Then, `L` means to choose the **left** element of `CCC`, **`ZZZ`**. By following the left/right instructions, you reach `ZZZ` in **`2`** steps.
Of course, you might not find `ZZZ` right away. If you run out of left/right instructions, repeat the whole sequence of instructions as necessary: `RL` really means `RLRLRLRLRLRLRLRL...` and so on. For example, here is a situation that takes **`6`** steps to reach `ZZZ`:
```txt
LLR
AAA = (BBB, BBB)
BBB = (AAA, ZZZ)
ZZZ = (ZZZ, ZZZ)
```
Starting at `AAA`, follow the left/right instructions. **How many steps are required to reach `ZZZ`?**
## Instructions - Part 2
The sandstorm is upon you and you aren't any closer to escaping the wasteland. You had the camel follow the instructions, but you've barely left your starting position. It's going to take **significantly more steps** to escape!
What if the map isn't for people - what if the map is for **ghosts**? Are ghosts even bound by the laws of spacetime? Only one way to find out.
After examining the maps a bit longer, your attention is drawn to a curious fact: the number of nodes with names ending in `A` is equal to the number ending in `Z`! If you were a ghost, you'd probably just **start at every node that ends with `A`** and follow all of the paths at the same time until they all simultaneously end up at nodes that end with `Z`.
For example:
```txt
LR
11A = (11B, XXX)
11B = (XXX, 11Z)
11Z = (11B, XXX)
22A = (22B, XXX)
22B = (22C, 22C)
22C = (22Z, 22Z)
22Z = (22B, 22B)
XXX = (XXX, XXX)
```
Here, there are two starting nodes, `11A` and `22A` (because they both end with `A`). As you follow each left/right instruction, use that instruction to **simultaneously** navigate away from both nodes you're currently on. Repeat this process until **all** of the nodes you're currently on end with `Z`. (If only some of the nodes you're on end with `Z`, they act like any other node and you continue as normal.) In this example, you would proceed as follows:
- Step 0: You are at `11A` and `22A`.
- Step 1: You choose all of the **left** paths, leading you to `11B` and `22B`.
- Step 2: You choose all of the **right** paths, leading you to **`11Z`** and `22C`.
- Step 3: You choose all of the **left** paths, leading you to `11B` and **`22Z`**.
- Step 4: You choose all of the **right** paths, leading you to **`11Z`** and `22B`.
- Step 5: You choose all of the **left** paths, leading you to `11B` and `22C`.
- Step 6: You choose all of the **right** paths, leading you to **`11Z`** and **`22Z`**.
So, in this example, you end up entirely on nodes that end in `Z` after **`6`** steps.
Simultaneously start on every node that ends with `A`. **How many steps does it take before you're only on nodes that end with `Z`?**
+732
View File
@@ -0,0 +1,732 @@
LLLLLLLRRRLRRRLRLRLRLRRLLRRRLRLLRRRLLRRLRRLRRLRLRRLRLRRRLRRLRLRRRLRRLRRLRLRRLLRLLRLRRRLRRLRLLLLRRLLLLRLRLRLRRRLRLRLLLRLRRRLRRRLRRRLRLRRLRRRLRLLLRLLRRLRRRLRRLRRLRRLRLRRRLRLRLRLLRRRLRRRLRRLRRRLLLRRLRRLRRRLRLRRRLRRRLRLRRLRRRLRLRRLRLRRLRRRLRLRRLRLLRRRLLRLRRLRRRLLLRLRRLRRRR
DGK = (KVQ, XHR)
KTC = (TVB, MTH)
CGR = (VVK, BKP)
LCG = (FQC, KHX)
PSZ = (FSF, QSM)
FBJ = (FHP, SPX)
KJD = (NRQ, VDH)
NCM = (JPJ, KNG)
TXH = (HNK, VHQ)
NND = (TRC, DFM)
JQN = (CNX, XLD)
RHB = (CDG, GBT)
JBN = (PXV, GVN)
DFC = (JRN, TXH)
TXG = (CHT, VBL)
XXQ = (JDC, JGV)
SVF = (FVD, LHQ)
FVK = (LCG, RNB)
XKT = (MPF, XJJ)
MHB = (JSJ, VQM)
FVC = (HXF, VVN)
JJR = (VNS, SLM)
RMT = (GDS, XHP)
CHT = (PXS, VLF)
SFJ = (XGC, LPM)
BJL = (XDN, VXN)
PQK = (NHS, DVB)
PDB = (JPQ, TVJ)
RGL = (DNN, NCN)
KRN = (SBL, PHL)
MTF = (PJL, KQR)
BTL = (CCF, LDP)
NLV = (CPM, HVL)
GCQ = (QMF, JVH)
KVH = (VKD, PQG)
RLB = (GSS, JVP)
QRB = (TNL, DKN)
JFV = (RDR, NSB)
BFC = (LGH, XLX)
HGQ = (SLM, VNS)
FQC = (VFQ, BXC)
DDS = (XHR, KVQ)
VQV = (SFT, BFQ)
XFD = (HVV, FLH)
TVP = (XQF, KSS)
GBH = (NPX, LDB)
KHL = (MGS, MMD)
NPX = (BJL, SFF)
VMG = (DHX, GVC)
RTJ = (XRF, BPK)
TLM = (NCG, QBB)
LXS = (TVB, MTH)
XNM = (QFL, KQK)
KQR = (QRD, JBN)
JQD = (DNN, NCN)
QCF = (MXL, MXL)
QMH = (NKG, SDJ)
NKK = (MCB, RLB)
MPJ = (BTL, JTF)
TLS = (VPJ, LMD)
XJB = (LML, TKZ)
HGF = (HBF, QHB)
KNJ = (QKM, XLR)
XCF = (QCJ, HTN)
HFS = (NKC, JFV)
QLS = (QBB, NCG)
QFL = (NXQ, QBN)
MTH = (FLN, LQR)
VND = (KMM, MQH)
NQQ = (VVH, NDL)
BTV = (QSM, FSF)
SLT = (NRQ, VDH)
NKG = (TBV, XCV)
SLM = (LBN, HPK)
CMQ = (KKS, VBH)
JTF = (LDP, CCF)
VFC = (GKH, KPS)
KCC = (JVM, MTF)
KFP = (MVX, NMX)
NQF = (QSK, KCC)
GGC = (VBV, TJR)
QQS = (NKK, NQC)
LXK = (FXC, QBC)
DVQ = (TFF, LKB)
PBL = (BGQ, FHQ)
KHV = (BVJ, XSD)
LDB = (SFF, BJL)
RJG = (LJB, CJM)
RCX = (QTB, PPL)
FLH = (HSX, KVX)
XTV = (HST, VCC)
GDC = (CMH, NCT)
RDP = (FKR, GHJ)
NXM = (PVV, KRX)
SCQ = (MFN, GRB)
MRT = (XGT, VLK)
DHJ = (XHP, GDS)
XFL = (TJK, QMH)
XQF = (CCQ, RPH)
CLV = (CKD, CCD)
CMT = (NCD, XDM)
NCT = (SXG, CLF)
JSS = (GMJ, LJC)
TLQ = (CRC, DXQ)
DMJ = (HHB, DRV)
JBH = (FVC, HDX)
QXK = (QSB, JBH)
DQN = (QMD, GDN)
SDH = (PRH, BCX)
QSB = (HDX, FVC)
MTP = (VVG, SPN)
CTM = (MFG, GGJ)
HND = (MNV, TXG)
MJS = (DMJ, QQG)
JNL = (LKB, TFF)
QLL = (FKM, HNH)
PNM = (PQR, NRL)
VSF = (LPM, XGC)
QBC = (QQS, MVF)
BFM = (FBP, BQJ)
KNG = (RTJ, CXN)
VFQ = (HFS, LBS)
LKB = (QVB, TXF)
KQD = (CDJ, CDJ)
ZZZ = (DHJ, RMT)
XKX = (HVP, NJF)
GSL = (QMS, DHM)
PNT = (CDJ, GJZ)
KBN = (CMQ, JBG)
DNX = (SFM, GFJ)
NMX = (XRR, LKL)
VPJ = (PSK, GQL)
XQD = (QCF, QCF)
HRM = (RHB, XXJ)
LCL = (MRT, FMB)
DRG = (RNB, LCG)
BKP = (QLL, MMQ)
FSF = (SLR, XGV)
KHX = (BXC, VFQ)
SXG = (NHL, KGK)
MJD = (TDH, RFP)
NRL = (CSG, MPT)
FBP = (QGC, GXH)
HDT = (LHQ, FVD)
BMP = (RMG, JXM)
NCN = (SLT, KJD)
NXQ = (JPP, QQL)
NGV = (HNJ, VVQ)
NPN = (MXL, NJK)
FVD = (XBQ, NKF)
GQM = (QCG, GGC)
QBP = (XML, HND)
VQT = (BTL, JTF)
HKP = (CMH, NCT)
JHP = (NDL, VVH)
FRL = (SHD, FNH)
FLN = (NVL, HGF)
MXH = (QSD, KKR)
BGL = (XCX, RFC)
RSQ = (MKH, TLS)
VML = (RJM, CXK)
XHP = (MJS, DNP)
GRV = (XRN, TVQ)
GKH = (BCF, VSD)
SPH = (MVX, NMX)
TLD = (LFR, GFQ)
LML = (QKS, NND)
PKT = (VXC, CMF)
LLQ = (THT, GRV)
CKD = (SPB, QDV)
KRM = (JQV, JNG)
RNS = (HJJ, MLV)
FKR = (FKK, BHN)
XNH = (SCQ, KLF)
GDN = (LBL, FHT)
CRB = (NHQ, QRB)
JKQ = (DPT, KBN)
NJF = (RJG, NGF)
NRT = (NSK, CSL)
LJR = (VTT, HCQ)
HLK = (DFC, DPV)
PQR = (MPT, CSG)
DNF = (NJF, HVP)
MPV = (HJD, XSF)
TBV = (XTJ, SVH)
LKX = (XFJ, HBM)
KTP = (CGR, RVR)
HVL = (BJH, QXK)
GJD = (XJJ, MPF)
HLC = (VVQ, HNJ)
JTX = (NCD, XDM)
CSG = (MFF, RKT)
PCH = (PGJ, GQM)
SFF = (VXN, XDN)
TCF = (KNG, JPJ)
LDP = (XFD, SBS)
XCR = (GJD, XKT)
QBM = (GFB, LRH)
CLP = (RJM, CXK)
MTT = (HST, VCC)
TQL = (BPM, GGT)
LFR = (HNF, RDP)
JHN = (CMT, JTX)
XCX = (CHG, CHG)
XGT = (HLK, QJF)
TQS = (TKL, MNF)
KFL = (HGQ, JJR)
LHQ = (XBQ, NKF)
CCQ = (DBP, HHC)
TKL = (VDN, PBP)
LBX = (BXM, SDH)
XLX = (NGJ, LHJ)
GVN = (BPG, TNK)
CCX = (HCQ, VTT)
KQK = (QBN, NXQ)
NQC = (MCB, RLB)
MPF = (DFT, SBG)
BNH = (MLV, HJJ)
CJM = (LBH, TNM)
CND = (VKB, PGQ)
HXM = (GMJ, LJC)
TKZ = (NND, QKS)
RKT = (LNQ, KFL)
GXH = (RQP, LBX)
TFF = (QVB, TXF)
LNK = (FDC, MXH)
KPK = (BNH, RNS)
QQG = (HHB, DRV)
MFP = (PQK, NBF)
VVK = (QLL, MMQ)
GFB = (RHN, LCN)
PPD = (QCJ, HTN)
FXV = (BPM, GGT)
KSS = (CCQ, RPH)
KCM = (LTB, PCH)
RHN = (FXV, TQL)
LFV = (DDJ, NQF)
JKG = (BGQ, FHQ)
MBS = (RQJ, LDQ)
HHC = (NGV, HLC)
CCD = (QDV, SPB)
RFM = (FTB, HSB)
QCG = (VBV, TJR)
GRH = (LXK, LGQ)
CDJ = (QQJ, BFC)
THT = (TVQ, XRN)
QRD = (PXV, GVN)
VHQ = (SXV, GJL)
MLV = (VRM, MCP)
XRR = (CLV, PBJ)
NMS = (DGK, DDS)
JPS = (JKT, KHL)
DJJ = (QMS, DHM)
MFG = (TLQ, VQD)
GPQ = (SHL, BNR)
QVB = (GDC, HKP)
LNN = (CMF, VXC)
VBQ = (LNN, PKT)
MMS = (SVV, HRM)
BGJ = (HXM, JSS)
QCK = (JSJ, VQM)
PKB = (XNH, JQH)
BCF = (TQR, TLL)
JRN = (VHQ, HNK)
SHL = (DMK, JBX)
LRG = (NSK, CSL)
NJV = (FJH, TXC)
GHQ = (FSB, HFX)
LHN = (TLS, MKH)
HBF = (BMP, GLM)
DTP = (DVQ, JNL)
FXR = (FTB, HSB)
PDS = (XLD, CNX)
SXV = (CPC, JNF)
QMF = (GGF, JDP)
JVP = (GPC, DNX)
RMG = (HRF, PKB)
LRH = (LCN, RHN)
HVP = (RJG, NGF)
TRC = (VKX, RQL)
PJL = (QRD, JBN)
HNK = (GJL, SXV)
CHM = (NBF, PQK)
PGH = (KMM, MQH)
SDN = (MFP, CHM)
DMK = (VRP, NNX)
MRR = (NGK, SMQ)
QDV = (NDM, JPT)
PGJ = (QCG, GGC)
BVJ = (NLV, HBR)
PGQ = (BGK, GBH)
LKL = (CLV, PBJ)
FDC = (KKR, QSD)
JDP = (PDB, PTX)
NJJ = (HSJ, GRH)
TVJ = (HDT, SVF)
NJK = (RBV, ZZZ)
HHN = (DPP, TLD)
QMS = (BLS, TQS)
QVR = (CVB, BNJ)
FFQ = (RMJ, HGZ)
LGQ = (QBC, FXC)
JPP = (RSG, KTG)
DPV = (TXH, JRN)
HBR = (CPM, HVL)
NSK = (JQN, PDS)
SBS = (HVV, FLH)
BFQ = (VBQ, JPB)
LBN = (LXJ, CCR)
RBD = (KRM, PNX)
NQX = (LML, LML)
XSA = (QKS, NND)
NDB = (HFX, FSB)
QMD = (LBL, FHT)
XTJ = (JDT, JDT)
GLH = (SHL, BNR)
FXC = (MVF, QQS)
HSX = (NFN, LVG)
JNF = (JJH, FNR)
CXK = (SPC, TVP)
GGF = (PDB, PTX)
XBQ = (QNX, JCQ)
LJC = (SFJ, VSF)
MMD = (XLK, CND)
HFG = (JKT, KHL)
NHQ = (TNL, DKN)
JVM = (KQR, PJL)
CGH = (RTC, VFC)
HNF = (GHJ, FKR)
TMF = (NMS, GJH)
NGJ = (NXM, BDB)
MRM = (JKQ, MPS)
QTC = (JSS, HXM)
TNM = (JFF, QXR)
DHK = (LJR, CCX)
XSB = (MRR, CXC)
XRN = (XDP, QBP)
XCV = (XTJ, SVH)
VVA = (QSM, FSF)
NKC = (RDR, NSB)
MXL = (RBV, RBV)
PTX = (TVJ, JPQ)
VRL = (NQX, XJB)
RQK = (MPS, JKQ)
PBJ = (CKD, CCD)
VRP = (DQN, QLC)
KLF = (MFN, GRB)
XXJ = (GBT, CDG)
HST = (QHV, MMS)
SFT = (JPB, VBQ)
NRR = (LCL, MQR)
CSL = (JQN, PDS)
LHJ = (BDB, NXM)
TXK = (DHK, KLC)
CDK = (XCX, XCX)
FHT = (NGQ, JHN)
QQJ = (LGH, XLX)
BQJ = (GXH, QGC)
TTA = (QKM, XLR)
TVB = (FLN, LQR)
PPL = (FRL, NCX)
SPS = (XFJ, HBM)
SVH = (JDT, VRL)
QBB = (PXG, MTP)
JSJ = (VVB, NRR)
KKS = (RGL, JQD)
JDT = (NQX, NQX)
GKQ = (LLT, JRH)
VVH = (BPT, KRN)
JCQ = (CRB, PBS)
QXR = (BTV, PSZ)
VQR = (RCX, KKP)
QSM = (SLR, XGV)
JKD = (JDC, JGV)
XLD = (LFS, QVR)
TJK = (NKG, SDJ)
PVV = (HDK, VQV)
BDB = (PVV, KRX)
MPS = (KBN, DPT)
FHP = (PPD, XCF)
HTN = (KCM, PXC)
GHJ = (BHN, FKK)
JCC = (LQM, KVH)
LQR = (HGF, NVL)
LGM = (DDJ, NQF)
NJN = (QCF, NPN)
PRH = (DFF, DFF)
XDM = (FBJ, PJM)
HFN = (KRS, XSB)
GLM = (JXM, RMG)
RQP = (BXM, SDH)
BPG = (QJT, KTP)
JPB = (LNN, PKT)
DKN = (CJD, BGR)
CDG = (GSL, DJJ)
XDN = (CGM, VMG)
NQP = (SKT, JCC)
DNP = (QQG, DMJ)
NNX = (DQN, QLC)
FTB = (JFL, VJJ)
FHQ = (SMJ, XFK)
GGT = (KPK, LNT)
NGF = (LJB, CJM)
QFX = (KCN, TMF)
NKF = (JCQ, QNX)
DBP = (NGV, HLC)
RBV = (RMT, DHJ)
NML = (MBV, VCG)
KXJ = (MXH, FDC)
GFQ = (RDP, HNF)
SHD = (CMG, CTM)
GTX = (LNK, KXJ)
HXF = (KTC, LXS)
CMM = (NQP, SBR)
SDJ = (TBV, XCV)
CHG = (RMJ, RMJ)
DPT = (CMQ, JBG)
BGR = (RLM, NML)
THM = (XQD, NJN)
HJJ = (MCP, VRM)
NRQ = (JHR, GCQ)
KKR = (HSN, NJJ)
KVX = (LVG, NFN)
LTT = (TLD, DPP)
NVL = (QHB, HBF)
CXN = (XRF, BPK)
KLC = (CCX, LJR)
JDC = (DNF, XKX)
MGS = (XLK, CND)
RLM = (VCG, MBV)
VDN = (NMQ, TPR)
HSB = (JFL, VJJ)
HDS = (KLC, DHK)
XSD = (NLV, HBR)
HJD = (NJQ, PBQ)
CGM = (DHX, GVC)
LDQ = (PBL, JKG)
RDR = (XHQ, MGQ)
GPC = (GFJ, SFM)
NQT = (KRS, XSB)
TDH = (RBD, XLP)
QJF = (DFC, DPV)
VNS = (HPK, LBN)
QSD = (NJJ, HSN)
JHR = (QMF, JVH)
SMQ = (FXR, RFM)
CMG = (MFG, GGJ)
NKQ = (VFC, RTC)
VXC = (LHN, RSQ)
DHX = (LCT, XNM)
TCX = (NQT, HFN)
DRV = (TFN, QBM)
JPT = (GQX, XCR)
HRF = (JQH, XNH)
MCS = (BGJ, QTC)
PQG = (NCM, TCF)
XHR = (PJK, VPN)
MLX = (PGH, VND)
MKH = (VPJ, LMD)
TJR = (VQT, MPJ)
VLF = (GLG, QFX)
JNG = (KLR, MPV)
HDK = (BFQ, SFT)
HFX = (MLX, SPL)
BXC = (HFS, LBS)
CCT = (GTX, HPT)
VLK = (HLK, QJF)
NCD = (PJM, FBJ)
VGT = (JNL, DVQ)
LMD = (PSK, GQL)
KRX = (HDK, VQV)
QNX = (CRB, PBS)
NJQ = (GHQ, NDB)
TNV = (FBP, BQJ)
GNR = (XQD, NJN)
KKP = (QTB, PPL)
DBX = (KCQ, CPS)
VRM = (TLM, QLS)
LVG = (BRP, NJV)
NHL = (SPS, LKX)
MNV = (VBL, CHT)
PJK = (HHN, LTT)
VBH = (JQD, RGL)
GRB = (NKQ, CGH)
SKT = (KVH, LQM)
TPR = (RXR, KHV)
VVB = (LCL, MQR)
VKX = (MRM, RQK)
LTB = (PGJ, GQM)
QCJ = (KCM, PXC)
BGQ = (SMJ, SMJ)
RCV = (NQQ, JHP)
DHM = (TQS, BLS)
KRS = (CXC, MRR)
JFL = (BLT, PNM)
TXC = (NRT, LRG)
MVX = (LKL, XRR)
QSK = (JVM, MTF)
BGK = (LDB, NPX)
GJZ = (BFC, QQJ)
PXC = (LTB, PCH)
HMQ = (BGJ, QTC)
RXR = (BVJ, XSD)
BXM = (PRH, BCX)
FJH = (LRG, NRT)
GJH = (DGK, DDS)
BPT = (SBL, PHL)
RQL = (RQK, MRM)
SJB = (RQJ, LDQ)
NFN = (NJV, BRP)
MND = (NQQ, JHP)
NMQ = (KHV, RXR)
XGV = (TXK, HDS)
SPC = (KSS, XQF)
RMJ = (SMR, QRS)
CNX = (LFS, QVR)
KLR = (HJD, XSF)
XLP = (KRM, PNX)
LPM = (CMM, PHF)
FNR = (CCT, VTP)
NGQ = (CMT, JTX)
CCR = (BFM, TNV)
LCN = (FXV, TQL)
HVV = (HSX, KVX)
FSB = (MLX, SPL)
GGJ = (TLQ, VQD)
NHS = (DRG, FVK)
RQJ = (PBL, JKG)
VCC = (MMS, QHV)
HDX = (VVN, HXF)
VQM = (NRR, VVB)
TFN = (GFB, LRH)
QRS = (VQR, MDS)
HBM = (VTQ, SDN)
CCF = (SBS, XFD)
VCG = (HMQ, MCS)
NBF = (DVB, NHS)
DVB = (FVK, DRG)
PGB = (TDH, RFP)
XRF = (KFP, SPH)
KMM = (PDJ, GQN)
KTG = (GGQ, HNR)
BJH = (JBH, QSB)
JJH = (CCT, VTP)
LBH = (JFF, JFF)
GLG = (TMF, KCN)
TQR = (THM, GNR)
MQH = (GQN, PDJ)
MQR = (FMB, MRT)
FNH = (CTM, CMG)
SMR = (VQR, MDS)
GDS = (DNP, MJS)
LCT = (KQK, QFL)
VKB = (GBH, BGK)
VTQ = (CHM, MFP)
TNK = (QJT, KTP)
HNJ = (VVS, GCX)
JKT = (MMD, MGS)
PBP = (TPR, NMQ)
CPS = (KNJ, RFZ)
RNB = (KHX, FQC)
CMF = (LHN, RSQ)
HPK = (CCR, LXJ)
MFN = (NKQ, CGH)
HHB = (QBM, TFN)
DDJ = (QSK, KCC)
DFM = (RQL, VKX)
FKM = (GKQ, VJG)
HSJ = (LGQ, LXK)
HPT = (KXJ, LNK)
BNR = (JBX, DMK)
GJL = (CPC, JNF)
DFF = (KCQ, KCQ)
MCB = (GSS, JVP)
CPC = (JJH, FNR)
XLR = (MJK, DSM)
SBG = (JDG, XFL)
XSF = (NJQ, PBQ)
NGK = (RFM, FXR)
HSN = (GRH, HSJ)
LQM = (PQG, VKD)
VXN = (VMG, CGM)
PSK = (VGT, DTP)
JQH = (KLF, SCQ)
RJM = (SPC, TVP)
VSD = (TLL, TQR)
KCN = (GJH, NMS)
QHB = (GLM, BMP)
FMB = (VLK, XGT)
GBT = (DJJ, GSL)
LGH = (NGJ, LHJ)
SLR = (HDS, TXK)
VVQ = (GCX, VVS)
MDS = (RCX, KKP)
KVQ = (VPN, PJK)
CLF = (NHL, KGK)
XFK = (KQD, PNT)
CJD = (NML, RLM)
MCP = (TLM, QLS)
SPL = (PGH, VND)
GSS = (GPC, DNX)
RPH = (DBP, HHC)
HNR = (XXQ, JKD)
VBV = (VQT, MPJ)
PHF = (NQP, SBR)
BRP = (FJH, TXC)
AAA = (RMT, DHJ)
PBQ = (GHQ, NDB)
PXG = (VVG, SPN)
PNX = (JQV, JNG)
XHQ = (SJB, MBS)
VBL = (VLF, PXS)
VVG = (MTT, XTV)
PXS = (GLG, QFX)
MMQ = (FKM, HNH)
PHG = (HFN, NQT)
MFF = (KFL, LNQ)
PJM = (FHP, SPX)
SMJ = (KQD, KQD)
XGC = (CMM, PHF)
PDJ = (QCK, MHB)
SPN = (MTT, XTV)
BPK = (KFP, SPH)
MVF = (NQC, NKK)
LJB = (LBH, LBH)
GQN = (QCK, MHB)
NCG = (MTP, PXG)
GQL = (VGT, DTP)
NCX = (FNH, SHD)
HGZ = (QRS, SMR)
GMJ = (VSF, SFJ)
RFP = (XLP, RBD)
TXF = (GDC, HKP)
NBA = (SMR, QRS)
QTB = (FRL, NCX)
QLC = (GDN, QMD)
QHV = (SVV, HRM)
XTM = (GRV, THT)
VPN = (HHN, LTT)
RFZ = (XLR, QKM)
CMH = (SXG, CLF)
GFJ = (TCX, PHG)
VTT = (LGM, LFV)
RTC = (GKH, KPS)
XFJ = (VTQ, SDN)
GCX = (PGB, MJD)
MJK = (CLP, VML)
QQL = (RSG, KTG)
NSB = (XHQ, MGQ)
HCQ = (LGM, LFV)
GQX = (GJD, XKT)
RVR = (VVK, BKP)
JBG = (KKS, VBH)
JFF = (BTV, BTV)
BPM = (LNT, KPK)
LNQ = (JJR, HGQ)
FKK = (GLH, GPQ)
SBL = (CDK, BGL)
LNT = (BNH, RNS)
JRH = (JPS, HFG)
VVS = (MJD, PGB)
DPP = (LFR, GFQ)
MNF = (PBP, VDN)
QKM = (DSM, MJK)
JPJ = (CXN, RTJ)
QGC = (RQP, LBX)
CVB = (MND, RCV)
RFC = (CHG, FFQ)
KPS = (BCF, VSD)
XML = (MNV, TXG)
JVH = (JDP, GGF)
CRC = (XTM, LLQ)
VJG = (JRH, LLT)
SPB = (JPT, NDM)
JGV = (XKX, DNF)
GGQ = (XXQ, JKD)
XLK = (PGQ, VKB)
JBX = (NNX, VRP)
RSG = (HNR, GGQ)
GVC = (LCT, XNM)
XDP = (XML, HND)
CXC = (SMQ, NGK)
PXV = (TNK, BPG)
NDM = (XCR, GQX)
CPM = (BJH, QXK)
KGK = (LKX, SPS)
BLT = (NRL, PQR)
BHN = (GLH, GPQ)
BLS = (TKL, MNF)
PHL = (CDK, BGL)
BCX = (DFF, DBX)
HNH = (GKQ, VJG)
VKD = (NCM, TCF)
DSM = (VML, CLP)
DNN = (SLT, KJD)
SBR = (SKT, JCC)
TNL = (BGR, CJD)
DFT = (XFL, JDG)
MPT = (RKT, MFF)
TVQ = (XDP, QBP)
LLT = (JPS, HFG)
DXQ = (XTM, LLQ)
SFM = (PHG, TCX)
BNJ = (MND, RCV)
PBS = (NHQ, QRB)
JXM = (HRF, PKB)
VTP = (HPT, GTX)
SVV = (XXJ, RHB)
MHA = (QQJ, BFC)
MBV = (HMQ, MCS)
VJJ = (BLT, PNM)
QJT = (RVR, CGR)
VVN = (LXS, KTC)
QKS = (TRC, DFM)
MGQ = (MBS, SJB)
NDL = (BPT, KRN)
JPQ = (SVF, HDT)
VDH = (JHR, GCQ)
KCQ = (KNJ, KNJ)
XJJ = (DFT, SBG)
JQV = (MPV, KLR)
VQD = (DXQ, CRC)
JDG = (TJK, QMH)
SPX = (XCF, PPD)
LXJ = (TNV, BFM)
LBL = (NGQ, JHN)
QBN = (QQL, JPP)
LFS = (CVB, BNJ)
LBS = (JFV, NKC)
TLL = (THM, GNR)
@@ -0,0 +1,9 @@
RL
AAA = (BBB, CCC)
BBB = (DDD, EEE)
CCC = (ZZZ, GGG)
DDD = (DDD, DDD)
EEE = (EEE, EEE)
GGG = (GGG, GGG)
ZZZ = (ZZZ, ZZZ)
@@ -0,0 +1,5 @@
LLR
AAA = (BBB, BBB)
BBB = (AAA, ZZZ)
ZZZ = (ZZZ, ZZZ)
@@ -0,0 +1,10 @@
LR
11A = (11B, XXX)
11B = (XXX, 11Z)
11Z = (11B, XXX)
22A = (22B, XXX)
22B = (22C, 22C)
22C = (22Z, 22Z)
22Z = (22B, 22B)
XXX = (XXX, XXX)
+168
View File
@@ -0,0 +1,168 @@
use core::str::FromStr;
use std::collections::HashMap;
#[derive(Debug, Default, PartialEq, Eq, Clone)]
pub struct DesertMap {
pub directions: Vec<HorizontalDirection>,
pub nodes: HashMap<String, [String; 2]>,
}
impl FromStr for DesertMap {
type Err = &'static str;
/// Parses a string `string` to return a value of [`DesertMap`]
///
/// If parsing succeeds, return the value inside [`Ok`], otherwise
/// when the string is ill-formatted return an error specific to the
/// inside [`Err`].
///
/// # Examples
///
/// ```
/// use std::str::FromStr;
/// use std::collections::HashMap;
/// use puzzle_2023_day_8::{DesertMap, HorizontalDirection};
///
/// let string = "
/// RL
///
/// AAA = (BBB, CCC)
/// BBB = (DDD, EEE)
/// CCC = (ZZZ, GGG)
/// ";
/// let expected_result = DesertMap {
/// directions: vec![HorizontalDirection::Right, HorizontalDirection::Left],
/// nodes: HashMap::from([
/// (String::from("AAA"), [String::from("BBB"), String::from("CCC")]),
/// (String::from("BBB"), [String::from("DDD"), String::from("EEE")]),
/// (String::from("CCC"), [String::from("ZZZ"), String::from("GGG")]),
/// ])
/// };
///
/// let actual_result = DesertMap::from_str(string).unwrap();
/// assert_eq!(actual_result, expected_result);
/// ```
fn from_str(string: &str) -> Result<Self, Self::Err> {
let mut result = DesertMap::default();
let mut lines = string.trim().lines();
let first_line = lines.next().unwrap_or_default();
for character in first_line.chars() {
result.directions.push(HorizontalDirection::from(character));
}
lines.next();
for line in lines {
let mut line_splitted = line.split(" = ");
let key = line_splitted.next().unwrap_or_default();
let values_line = line_splitted
.next()
.unwrap_or_default()
.replace(['(', ')'], "");
let mut values_line = values_line.split(", ");
let value = [
values_line.next().unwrap_or_default().to_string(),
values_line.next().unwrap_or_default().to_string(),
];
result.nodes.insert(key.to_string(), value);
}
Ok(result)
}
}
#[derive(Debug, Default, PartialEq, Eq, Copy, Clone)]
pub enum HorizontalDirection {
#[default]
Left = 0,
Right = 1,
}
impl HorizontalDirection {
pub const fn index(&self) -> usize {
*self as usize
}
}
impl From<char> for HorizontalDirection {
fn from(direction: char) -> Self {
if direction == 'R' {
return HorizontalDirection::Right;
}
HorizontalDirection::Left
}
}
const KEY_START: &str = "AAA";
const KEY_END: &str = "ZZZ";
pub fn part_1(input: &str) -> usize {
let mut desert_map = DesertMap::from_str(input).unwrap_or_default();
let mut steps = 0;
let mut current_step_key = KEY_START.to_string();
while current_step_key != KEY_END {
let direction_index = steps % desert_map.directions.len();
let current_direction = &desert_map.directions[direction_index];
let current_step_value =
if let Some(step_value) = desert_map.nodes.get_mut(&current_step_key) {
step_value
} else {
break;
};
current_step_key = current_step_value[current_direction.index()].to_string();
steps += 1;
}
steps
}
pub fn part_2(input: &str) -> usize {
let desert_map = DesertMap::from_str(input).unwrap_or_default();
let mut current_step_keys: Vec<String> = desert_map
.nodes
.keys()
.filter(|key| key.ends_with('A'))
.map(|key| key.to_string())
.collect();
let mut steps = 0;
while !current_step_keys
.iter()
.all(|step_key| step_key.ends_with('Z'))
{
let direction_index = steps % desert_map.directions.len();
let current_direction = &desert_map.directions[direction_index];
for current_step_key in current_step_keys.iter_mut() {
let current_step_value =
if let Some(step_value) = desert_map.nodes.get(current_step_key) {
step_value
} else {
break;
};
*current_step_key = current_step_value[current_direction.index()].to_string();
}
steps += 1;
}
steps
}
#[cfg(test)]
mod puzzle_2023_day_8_tests {
use super::*;
#[test]
fn test_part_1_example_1() {
assert_eq!(part_1(include_str!("../input_example_1.txt")), 2);
}
#[test]
fn test_part_1_example_2() {
assert_eq!(part_1(include_str!("../input_example_2.txt")), 6);
}
#[test]
fn test_part_1() {
assert_eq!(part_1(include_str!("../input.txt")), 15871);
}
#[test]
fn test_part_2_example_3() {
assert_eq!(part_2(include_str!("../input_example_3.txt")), 6);
}
}
@@ -0,0 +1,8 @@
use puzzle_2023_day_8::{part_1, part_2};
fn main() {
let input = include_str!("../input.txt");
println!("- Day 8 of 2023: Haunted Wasteland -");
println!("Answer Part 1: {}", part_1(input));
println!("Answer Part 2: {}", part_2(input));
}