day03 finished

This commit is contained in:
Ruediger Ludwig 2023-01-28 06:00:12 +01:00
parent eb1ce68486
commit d7c85a75f6
8 changed files with 534 additions and 37 deletions

6
data/day03/example01.txt Normal file
View file

@ -0,0 +1,6 @@
vJrwpWtwJgWrhcsFMMfFFhFp
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
PmmdzqPrVvPwwTWBwg
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
ttgJtRGJQctTZtZT
CrZsJsPPZsGzwwsLwLmpwMDw

300
data/day03/input.txt Normal file
View file

@ -0,0 +1,300 @@
fBDGBcBrGDvjPtPtPV
QhzJLlLJZgLZzNTgZClQHvRvHFvrjrvnNjHnFjPF
ChldsCZhsQzsCGrrSfMfGpfrdM
MJbgcgJlvMSbfjMSbllmCrntwmFrrFwgtCtFFG
vPhddVZZhmnmdnHmHn
vNBZppZQhjSzfScjDN
jwhqbZRvbzvbqqpqzqHHCCCzsLmmQVtmJVJtLWLPrVLLVrmp
dGMfMGMdBBMSTfdMGTNlcZGGPSmQJVVWsJQPLmPLVPtmWPLW
llMBBcfBnBcZMGgqvCDbjbwgCHjvzH
RSDprRrwgVVRwrGqrJsNFJslgglmmNszzN
LLnWjcHWnCTmpClhHp
MpfMZWjtLMjpjtBPnLPndMBGRqwbwBwvrGwGrGVbVvwD
PQNGshQWtwWNcjssJHHJdlBLBlLrRDFFCrdwSlLB
mbzqZqsgMzfnbmbfgpZvZBLrLlSCrprDlLCrdFBlDL
MfvZzqMmsVnVzzTTbMzfvnctjhcHPQJJjNTGWjQJJHWP
MdLWQdMZrPQWsPdMQPLSqGpHGbGqpqqqVzpm
BhgFhVgnlgBNFtNwzpbTGbTTHpwwbF
tCfvvCfgvBjnfflftCvjWZVddMQZsMMsRdMZMP
lTLdHVlqmqWdvjvJttvFlJtC
ngbMTgGhQpgrGtvCzcCJccCrcj
npgwnDpSDbgbbnGGDQnMDSMgZZWVqNTNPRRdwLLNLqmPZTLP
RRSFZvRdrdbSvSVLRZrSGZZrHcHPfPPwJJVJmPHmJfHVThPm
WnLjBQBCQWqCQwpPmHTcfQpm
gBDttlnqLqlvzzlGRRlr
wGpdGdddMPDWgFJGBzmMlntTbZMtZbnT
qNSqQrrqSjQVrsvTtzNnnZTnfNztZw
rcVrjjsswVvRRHsFJLCDCpCddGCCcG
jLMhCPWLCSWSrRLPWmPPLSCLtcTvHHDhZcfHHltlfZtlfgfH
rBBNrbVdtZlvVcZc
FppGdpFsnsqGJnsFzGdJszbdwSLRSRPrSRjqrMqCwQMWQqRS
jTjZwnpjMDfZnmZfsRhGGztqCzwsdGws
JHrWcNrNNrJHLHlzsCtzGRRRHv
rNLrVBJFLmfCnbTpVQ
LGWJvDFssFmMBhThMvnB
CprbCNZpwfpwfrbZJMQMTQcVVgBZcVQBZc
ptNwfwzHzqzlttbrlpCCqzwtFLGSWFsPDLWFHSDjJWSDLFDs
MZJjSsCsMsZSSdZJhdjZtCbPHljqlLPlPRRDLqHHqLbB
mmwmVpGrnngmggGwnccPbDBPLLLllLBcFRFb
GQzVTQTTVzVrQrmvpTnmrQmMvZRhZZCZSZfCsfttSJddNC
gHZZQRdVgRQWWRPHWPnttDTmqQqDQnStzNqD
bscfjslJJspBLsslNStSmTmLmmDTzNnS
JJCrbbhBsplrrChpBbfjlpbbFWWVggPPhZVRRFPdVMddPnMg
FtLfHNhFJCClJlst
jnDQqnDSDSRqwBwnjdFlZbsrTZdsJsGCbw
zDFSmjSDVqnRMHmphPhfWPgW
rSpRtSPWpStVqrwSSdrrhZvnBBnDBvsqjlBqvvnnzl
LFNLLFfFFhMFbcbmbHbHgTNcvZvBZMsvBnJBzsZvjJvZlvnZ
gmFLhTTbFmmQrrSWWpwWVtwQ
DzmDJGSccGJPcdcJPJqwplhjBHmHVwwtBthV
grMMvRsNRnWCFrgZRrZFhpVVlHVnhpVjVtljhhhf
FFZFZTsvCMSQTdGcTHzT
TLsGTnZncjVmVLgm
DvRwMcHMvMbwBVlCBlzlMjCC
FdRtRHDwQvPnTfPqcFPP
rZNdpBSldLLCJZbbCT
WQcQwqsmQmmqJgTRLRCqLq
znQcwsmPcmnCzQmfGGnzHSDFlNptNthPSdllhFPplS
vWCWvVhhjPNjNNvWVNbnbHnrbGrmlPqnqqbw
JdZSLMgsdgQMcQssQnnDqmDqlDqnDlwrHc
tdgQSSdpQtSMSNWpWRfRCwjpjV
qhdJFpChSJhDFDrqbpJbddSHPPRnGGBfBrHfZRnjRnlBZH
zsMVzmwmtLMtmQTzvwlRcZnZZljvvfGcBjcZ
ttQzMtVgMWVMQsmtJgqJgCJbqhgbBSBN
BWvdCmZBrNRrGSSfTzQJJRTz
gMblllMgLVswbgwMsLjgLLnlVtfHfttSQttTJTSQGfGPTPTB
LMgnMgscgqbFBqvBNFBmNm
VlcczDZjjVbznwLnwpTH
NfJPJNfJdJMSHSHnjBRSnbbL
NddqPttjsdZDqhcqlFcD
NVrNBBFFFrvJJrVTFTNvWBCbCCgWGqDqhqghCLqbqtCC
mfZVPZPcqtLbcqgc
fwZlwzfRfQQPMZBBwwBjFSjTVrBT
GWWNMfWWwGWMtjJnVnJzlzVsvLnsVn
ZpRqHTBddsvtPLqVPP
bpSDgStgTbdFTpDdRmfwfmfGFcMQGWMcjQ
gCgGBgfCbRLbBLGnGBBfRGwprctZFMvtFtvSNNTZZtMvLc
DhJhDzzQlDdshVJlDdhqzqzQZFpppFMNtMZMtFFVvtpSMpFV
qQdsDHWWslnNgHmBbHBf
MRvnJFZVnvzJrWWSqMSPTSNqNj
GlcbDpCHCCczdsDppcccBGccqjwTTwQPPSjNjWSWSwwsPsws
GbdlBbgdVtngtzVg
GqTSRpgJgDNSNJqJlSTJlJCBmmcnjCjLFcMFmnGsmBsM
HPhfPrWdfrQPPPhQWHbLFFWFCmFjMBFFsLBFwj
fdzVbvfshrbzvfbfdVPvQtqqJgqgDpNTgqZZtglZtZDD
wsPhrDMfrwdvHdTFrrtH
lnQbNBbqVBqHGJSddvTlJJJJ
cjnHznzbQmgzqQjBWwZwRjDRfWWhWsWD
SsScnttbbSzRRMMMLpsBLP
dDJGgjGJVMSBBBMj
JGDNCfgfSChDJrgqdgqJqGbNbbcbNtzWFctbzzlWtFFn
dtsBsCMtwSVBlLZZZnMgcMZZ
brppQHGznLZgJzJJ
fprvRpNHpNnvbGDBCBPwBWFWBFBvtB
qjgjSgHNlSGHnjfSVDvDPRDDtcdDcGtD
FMTnnLQZtRZDbcZv
zhBLzrCwnCsTCMCQTFLwwCzpHgNlNmHqhlqSpWllmlllhh
bJqqFdfbGdfPNsJsdSRCFLRHLDDBHDnShL
lQWlWQpwQjlpwrjrwTSCTLMCCNTHRDDDDRRB
wtWgQmQQWtwWwrljNPfGPzJmbbfzmzZf
MjppbDGmNNblCpzsNZzhNPgHtzzs
qvdrqrQVVWLfqWfRRPRwZPPwggpf
cqdcdpqSrrSvrvWvvvrSbcGTTTbGlFFCCcnnGbTb
HLNfNGttHVFBHWSr
RZCLsbCbLbLhwzDgbZCbRZhhnpSnnWpWplFFnDnqlBFVpSVB
MzbhhzwcLGGfGMvMTv
PdBlpdVJlmftGbTzwbtRTGGL
NQNMgWNNQNScDhsSHSWhsNgbRCLwGnnwqLwLHbbCGGTjTR
MvhRMMRvQshgSNDWFrfBfJFZrFPJJJPBBp
qdtnQqWtnjfGGzsnGQmWWfqQNbRTgggRFNbCFNSSFlSJsrTr
PZBBbPMvVcMpSRSlSCpCSgCT
MvHZhwMVLDHDcZMvLQfwGWqwWjqjGbmnQq
NFPmjNhGthGNpddddFpzBbqPczSqPDzzDgbgLZ
VJWvwQrlLHWrvlQZDgZSSDSDBqbb
WfHwMWfvRvMWrWJsrfMRWGFmGGLttMNpjCpTdmFFht
DppfNpLwhTBRDbblgWNgCdgCvs
nLcLqFJrHJmLcFmqMFCdzdHdsgvdzvbvWPWs
nVFqrrQcSVmFjrmJnrFrSjTtRGRLBwfRTfZwhBQhRGGw
sHrZdHGpHhsrLpsssGLzhrdtWdJTMWJvffVdmnbfJVnW
cggRDCCjlPQCgDRnfbTtfMJfWVTm
cCDwQNlwQPjgCFDljwpSLFzGFzZhzsstSpGz
dGTGpGdPZZCpnnLRpgzgzn
lflshFjFcrNdBjMjMnmL
hDfrldDfbVPbQCtHHZ
cSRZmtFZScfjZtLbmCNMqhMVQCjwqqCwVB
pddczHpHHzgWdGdsvPrPzcvrJMNwJCQwJhNwBhCJBVMpCVJB
cgrWcHdnPHHznlmftmtLnRDD
PZFMMVJVZmVJVHMNJNVfNdNNSnSWsSRhgRRQnWSsRnSWmszc
llljlTwlprClTbTpwLlgQqhcnwnczhcgSqsQRR
TpCtGtrTBDZVZHNQZQdB
SggjglBBlzbDgdpFJddZpF
CCNLsfNfrcMLsTLPfPmndmTwmZtZJZJdJplp
sfWCqcvMrlMfMLsLNfhVGvjjjSzSzVQhQvVH
NTBhNhfBvfflsbSmcl
nrMZRnHHwBMZRsSsgSsGrbmdms
nPPFVwVWJqJBVJLT
vvWqWJWJvzfFZZJvWQzqZvdPPHjSfHjssHsbsfbjSHRR
DCwtDVjMCrltCnCrDCDmbTssPHLTLldssdSldSRp
nMcGtDmBmMGrGvvvvFhjFZgWcN
tGWWWfWpMDjMZbTbnqTC
JFscJzFPDJDJZnrJ
sBFPcBsSPBvmSPwFzSSQfpwWfDpgNNfWtfgpftfg
BvTsJJzQJLMlbhmbFlNmTl
PjGnpdpGcgDmhvnvmvlbmq
dRtDGGgcDtjRcwdgQLVLRMJsszJVLRQv
FGbPPfFSchBGSvGGWsjSTLVQLLVTsQlj
dDzPnCrRCrrWHHTTHsdVjs
wrwCgzMrNprCwRJJwnnbFmmpGZtcvcbFfPFmFG
fbrJjmmmZgmZLJZsBBWlCBGnCWdnfF
RVMDDNDHPNvvRvDtHMcctMqFslqWPnClddlClFlnBqCG
MDDvHzHVQMMDtTHJLrnggSZLTJZgTL
dgBBCBBdvbmrRczFMHMSrqjjSPzn
tZTwQlLVwnQLQQFJVPzjDSSzJFPD
fhWhQpTTZQlWfQWpWQWQLhBgchhRCsdbvNnbgRsmRR
LttflLnGrnMsmmHgWTbdMW
vBSWzZRDccWBFBmJsmPJmgbsgB
FppcFWRNRZLLppGrGrqr
JJClRmLlFGvMTlFLLfPFQQcDpQcjFcjqBc
zgHSZhggggtwSZhrDgsZgbjVQcVcjPNqcpQQqBjNQzNp
hZnsShSWGDMMMRnv
RbDbslClhsfNCbsMjbNrjNMfpTTTTJSzHTpLVzLLVWVzJz
ggFGgmqFZBnnSzTWPpHBLzdT
vmWZWGwcZZqthjDrbclNCjlD
dCHwnVBBCBnVHddqnQRdbbbrgTsfWwjcWlsfwDDg
hhlFpMtGJlZmDjfWfscjWDGD
hFNFvZmppmSlNJMmNFztmzFhdVPPHQQqqHPvLBQnBQQPQPnC
WfzsplQpvQgfwzlbllPGtPJTTwtGGZBTTGJB
VrmMjmFDjNjjDFBhHTcZtBRRGcGV
mqrFmmLrjmjZnmqLrmQsfvbsfsSSlpWqgglp
lsQVfDpfflpGGmQRRgdQbdfbWdqnjnHnqZHJTqqrWjqqcWnZ
PPFhFFtwzqjHgjWTWF
SwMwMhNMlMsgfQfl
cSttSDQQCgVvQQSvsstthQcslLLgLgLnpglffjfFlLFblnlH
rTTwTbdBpTHJfZZJ
BddPBzwMBzqRqddRGbVShvVhVQvQscvGtV
sSpsHqHMspqMqWsspwsSWsbBPvjrFbddrGTvZLFjdZTZGLLG
NccDncRVNDVJLvLPPJTJGvJL
mRCDNNhgDnghNRQNggNRcNlMtpMPMMtHtShlSSMtlhHW
QrjSFQWzDdCHtpFlbBbVns
PhJwNLfNqgfdLlZHpZJJpptBBb
qmwhfhhfMNWSmSdQCddv
VfRMdbshRmJBqbmDBH
CWwWCWTCrzFpzWwCWFzgppqHDtZBfqDmQtBftBDFqBtq
WlzrWWGWPrpGCGdfSsRGVnGVdNnR
lhLTfppGRhhbZntsbTqMbq
jrHWBHrMgjHPWMgWBJWBWjstPvwFFbbbvtvFqbPtvqws
rBJJJVWjBjLphcMhSVRV
fjrBPBjWVPWPrwtjPpRQZZVdZQddFdHFTZdT
GqlllsGLgMCqGqgTFbmHdTmRzgTm
qHchGscqGClHGhNwhjJJNWpwPB
JzrrJZqLFrnMzVjNNnNnNDwdGHGlHlHbpTZDlmpTHb
gQfQcRWPWgQSStCtfcsPsPmhsGdDhdGDHTwHpDlHwhTG
fvWQgCtfWgtttcPQcPBtjVdBMJMLJBFJMJVzNrJr
cMzNjGGNQFVzNNQVjNdqRLbFDqRpgLRDpDHD
TwtwWJJBJSvmJCWSvTTmTbBpfpRZSfDqqSqDgHLgqdDDqD
vtvmPrtWQMrbhMrG
NqCPqJNJQQQQGCtGPmMTrTpHlNdmpTrwdN
bzhZRDbnZHrmmcwRfM
vWhsnVWWswhSFvDSDsnhbDsLPqqPFjQjgFgtjqqCLJPgQQ
nqpfqfcnclcNcjjQ
BLQJQmLPPvdtTFNjlFNwPs
DgDgLLCQBBmpVSMrgfqnpp
njCnCwwcVCBWjrrhWrHdzJqmhl
QNGptTTQGLTdhqmdJBHT
GtLvDDvLMvppGGVZMssfCBMfcfMf
npPQGpDnsbJhvldphHFfpl
mgqZcqzczzzcqmRzrbrzBvfBLvlhhftFWlhlFtLBvv
cgjmTgbbMgmzqRRwGDDVQVGVSPwTJV
VhPNvgVhbjPsNvsChTZlHtlwZccZMhwlcm
fpznDWDzDfRqffpnrmcRmwlTMZrHTBHB
fWdQLFSnDzpndqzzqgsVvPsJLMsPCgvjPP
RFRDQVvqVMZGBVzqgqPNJNmNhqqPjnPS
rcLLCWrtwlWrWlTbTtlLWrWtjPPgdwgjmNmShpJnjSpSjgSg
LbLTnbbTHsWlfbtZRZGQHHZZDQMVFz
dwcLLSLVdwLdvdfZNJgQZWfffVJQ
CTMlCRCCCTCtBmCFMQJNNNbNfWvQjvZggT
mRnnnpFlvhnlMmBmFMCMCcdHrwzqszprdcwzLDwrSz
JSHLHRMlzJHcGMpwCffZctZmgfqqZm
vnTWvQrnrQjNnBWvnvDnVgqtVWwVgfFmqWfqZFWZ
rdQDBdBrQQhmBNjDTmrTnzPzPPLHSSHzHHRHRLdGLl
GvMRRwGwRFmZRnmbMhZMGcpgZBpdgBJcTsjsBstdds
SNlPzzlPDDQSDDDqfllqDLBpTgWBgWdTpcWjJQsWjjTp
rScrCqPCSLDNrqlFmRVRRrbhmRmFRw
dbtgMNlNSMQPSLNdvVQgSfcHHfJfHJtfmmHTqZffJH
wssswnzwChsrGCCwGCjzCsHFHbzZffbFBcffbHHTBJTZ
rsDRGDwjhWbrbRhGCGLdLNlNQVVDPSlMVMvv
BgPccPPRlZZmTMTZzZTC
jjNjntVtQnWHrJjFPnnqDqJTJTzqJmDDCqChzS
FnQHQjHVNnWVvQpgLPGRdcLpbfLLBl
JLMhFJfHHLJChRvfjLJJnFRpPrpPSrNnrTrTTPntTptrpw
QgcBCqcGBBGzGrNQNSwSrPPTsr
zzWdmzcWcdHCJCRRCF
GSRcjdjGcBnFWbnVLFQR
pCNqTqhDsMsMmNtNCZmMMtdCbVFzbFwnFFnWWFnzVLTQWQLF
qNJpMdCsDNsNNvGPlSPPJjfBBB
lsHjgmFsnFTwHgSPDRSrDqnqrrnr
NmZWcZmzNMZWJbbWvJMJJMzBBBrRrdRfDfppBNqSrrrPBP
JZQZzQtWJhmltVwVCjwGjs
DslBHDpdDlslgffFWnGqHfzH
JNMMCCCCSMvzzGfMzP
hNtCJTwRwZQbwrplpDjlpz
vwvJwLBzwhhwvzwrgwshLwVWWgFfmlSFVRDfWFSVFVfF
mNqbdPnNdpdjnMqSFFMDfSFVMDFRSV
ddpTPTqmbNjjNqndZzvLzJZzHCrrCCzsJH
SLjjlGMVpLpNSTDspsrHpFFwRrZgRfwpfgFZ
nQtWPzbPNQtbdzPtbBCQJNPcwFvZJZFFJrwRwrHcfcfrgF
NQCnqPBWddbPnbCdWdWQnmdVhsMMDsslmSSmMLlVTTDVMm
FZmcqBChfFmfsDjjnNMNjSDgNs
RZwzdvdZRvTRRlvWSgDjStnpntDwNMtD
vHTGRvvvZHlQPRQTbPTVfLJPqcLJBhfmFVJPCF
dStFcccjFjqGFrFHmSHFBjBvzhpprWZpppbppDvzhsvDhT
VMVLNfCCCRTTDtDDDTRz
QLJwMMLnLNVLdtGGgmdScBnB
nTCWnTnrllglrNgNTZFgSZbddHtdHLLwtMLQtfbM
BJGqppPCJVmqqhBJCdwwpLSLHddfHSLHtw
qmzBhczVGsqVBqnFcCjRWNrNlrgD
phrHLNtnMpslNFfwVGwFZSBfFTTz
cmJJDmmbCnCCfBSJGVBwfBfz
DdqdDbcqCPcCQRWmQPqNHhnRMntNNMNhlsLsML
gHHWJWMWsHWgWSnPwVnVNGGDbnwwTl
QjThjhFqqhmQTCVPfDVqPbDVVl
mpFLLrZjjBcmLFmmFtLBJMddMgSdHTscvcJzRHRs
gRdwcCddwghzddzzzsGfZsGnqlqVVhjGDj
DMBNpMDHrNrNLFMmpQJHZGnPjFPFlZjlfGVljGVf
SpbQNmHMzgcRwSSD
drqcMpNbpFpmjzfz
HLGZGsnGLwllzHGGgGnGsBFfmJtmtjfJDSBSJJJB
ZZwQwHTgZnwLGTTnQTHVlgbWCQNhzNcMqbrzcNNQdNcr
TDScznfzNlpbbrtsvjdcbh
BBHqFGWGFmVWqVBBWMtvCLvsLdvrvjLjdLbsvm
tPZHGFJPJqVwMWHJVRRSZNfQnzfpnTpNfl
FWNZgWCngsNwJwlQlrRTRhSjSS
GGLcVVcVmppMmpTjTRHlbRbSrVBh
rvmdzPcdzmzMrCNNPJFntFsCtD
MtfLBzSLmMtfBMQzMmzmSlfdTDvGCZGCndZnZgWDwGCZ
HhqrrpppcqhdbjPvbgGvTCnWDbTWZT
cNjsdqPqchJBlmzlVQLtBJ
DwwVFZlDBsZFDvLPdpjLjSVHjpLc
nMnztWhhfPSffcddGpgp
tQnrQzhzNtzbNrBwPJwTslTvNFFP
LWMvHJJrJwtzvgwMwVdGfcpNfdDVDWfdBB
jZPFmjnbmhPfTVfVHdhTTV
qqQCmCmbqCQqjQsQvrQSHSJrzz
wNzmDRwmgcGphZcPvLLZHjjFLF
JlbsClVVqDqFZjJD
WSlnCbttftsCsWftbCCrTffbpdzMwgMgSpRmdwdRzggmDGGg
gCCRBClgfCgFFTltTGgBqTsQhzLzQQNPnvrNzHrrfPzHLr
DMjqWSVwDwDwZDHZNvLQnrnrPrNv
bcmWJqdVcbtgBglbGTCl
SFDcrFHtlqhqqLdzTTwdJLPNDL
vBWsWvsmgvvvdPwNnn
smfRbpsWMBmsmMsBBBNbtSFttjCHSScbhHtHhHjb
SQpgGgMNvggQGMvQcgnHWmldnHWTWndnSHHF
DwbDPzthtttljTzTFBlmzl
DstCswftDbZbCChPPRrfwsfPQlLccJQLvVGNGNVpMNvZcvgG
HdqfjjLfHqFSHddVWNBjsWhWRRJtBNBs
gPMQHpmrcmnbRQNRRJsWttWW
pmbcZwbrPPrnTPMFFdDwqHwvHDvzDq
FFsVtFGVGvWVhlfVhzlsFvHbPwPmwHLTSbLjcLtbSbLm
rZrpJwCqnnJHmqcbcTLTbS
RCZZQMQpzvRhswVg

View file

@ -1,7 +1,6 @@
use itertools::Itertools; use itertools::Itertools;
use std::num::ParseIntError; use std::num::ParseIntError;
use anyhow::Result;
use thiserror::Error; use thiserror::Error;
use super::template::{DayTrait, ResultType}; use super::template::{DayTrait, ResultType};
@ -14,13 +13,13 @@ impl DayTrait for Day {
DAY_NUMBER DAY_NUMBER
} }
fn part1(&self, lines: &str) -> Result<ResultType> { fn part1(&self, lines: &str) -> anyhow::Result<ResultType> {
let vector = Day::parse(lines)?; let vector = Day::parse(lines)?;
let max = vector.iter().max().ok_or(CalorieError::Empty)?; let max = vector.iter().max().ok_or(CalorieError::Empty)?;
Ok(ResultType::IntResult(*max)) Ok(ResultType::IntResult(*max))
} }
fn part2(&self, lines: &str) -> Result<ResultType> { fn part2(&self, lines: &str) -> anyhow::Result<ResultType> {
let vector = Day::parse(lines)?; let vector = Day::parse(lines)?;
let sum = vector.iter().sorted_by(|a, b| Ord::cmp(b, a)).take(3).sum(); let sum = vector.iter().sorted_by(|a, b| Ord::cmp(b, a)).take(3).sum();
Ok(ResultType::IntResult(sum)) Ok(ResultType::IntResult(sum))

View file

@ -1,7 +1,6 @@
use std::cmp::Ordering; use std::cmp::Ordering;
use super::template::{DayTrait, ResultType}; use super::template::{DayTrait, ResultType};
use anyhow::Result;
use thiserror::Error; use thiserror::Error;
const DAY_NUMBER: usize = 2; const DAY_NUMBER: usize = 2;
@ -13,11 +12,11 @@ impl DayTrait for Day {
DAY_NUMBER DAY_NUMBER
} }
fn part1(&self, lines: &str) -> Result<ResultType> { fn part1(&self, lines: &str) -> anyhow::Result<ResultType> {
let sum = lines let sum = lines
.split("\n") .split("\n")
.map(RPS::parse_line) .map(RPS::parse_line)
.collect::<Result<Vec<_>>>()? .collect::<Result<Vec<_>, _>>()?
.into_iter() .into_iter()
.map(|(first, second)| second.asses_pair(&first)) .map(|(first, second)| second.asses_pair(&first))
.sum(); .sum();
@ -25,11 +24,11 @@ impl DayTrait for Day {
Ok(ResultType::IntResult(sum)) Ok(ResultType::IntResult(sum))
} }
fn part2(&self, lines: &str) -> Result<ResultType> { fn part2(&self, lines: &str) -> anyhow::Result<ResultType> {
let sum = lines let sum = lines
.split("\n") .split("\n")
.map(Strategy::parse_line) .map(Strategy::parse_line)
.collect::<Result<Vec<_>>>()? .collect::<Result<Vec<_>, _>>()?
.into_iter() .into_iter()
.map(|(first, second)| second.fullfill(&first).asses_pair(&first)) .map(|(first, second)| second.fullfill(&first).asses_pair(&first))
.sum(); .sum();
@ -55,7 +54,7 @@ enum RPS {
} }
impl RPS { impl RPS {
pub fn parse_line(line: &str) -> Result<(Self, Self)> { pub fn parse_line(line: &str) -> Result<(Self, Self), RPSError> {
let mut parts = line.split(" "); let mut parts = line.split(" ");
let (Some(first), Some(second)) = (parts.next(), parts.next()) else { let (Some(first), Some(second)) = (parts.next(), parts.next()) else {
Err(RPSError::IllegalLine(line.to_owned()))? Err(RPSError::IllegalLine(line.to_owned()))?
@ -119,7 +118,7 @@ enum Strategy {
} }
impl Strategy { impl Strategy {
pub fn parse_line(line: &str) -> Result<(RPS, Self)> { pub fn parse_line(line: &str) -> Result<(RPS, Self), RPSError> {
let mut parts = line.split(" "); let mut parts = line.split(" ");
let (Some(first), Some(second)) = (parts.next(), parts.next()) else { let (Some(first), Some(second)) = (parts.next(), parts.next()) else {
Err(RPSError::IllegalLine(line.to_owned()))? Err(RPSError::IllegalLine(line.to_owned()))?

144
src/days/day03/mod.rs Normal file
View file

@ -0,0 +1,144 @@
use itertools::Itertools;
use thiserror::Error;
use super::template::{DayTrait, ResultType};
const DAY_NUMBER: usize = 3;
pub struct Day;
impl DayTrait for Day {
fn get_day_number(&self) -> usize {
DAY_NUMBER
}
fn part1(&self, lines: &str) -> anyhow::Result<ResultType> {
let sum = lines
.split('\n')
.map(|rucksack| find_double(rucksack).and_then(priority))
.collect::<Result<Vec<_>, _>>()?
.iter()
.sum();
Ok(ResultType::IntResult(sum))
}
fn part2(&self, lines: &str) -> anyhow::Result<ResultType> {
let sum = lines
.split('\n')
.chunks(3)
.into_iter()
.map(|chunk| find_badge(&chunk.collect::<Vec<_>>()).and_then(priority))
.collect::<Result<Vec<_>, _>>()?
.iter()
.sum();
Ok(ResultType::IntResult(sum))
}
}
#[derive(Debug, Error)]
enum RucksackError {
#[error("No double item found")]
NoDoubleFound,
#[error("Not a valid char: {0}")]
InvalidChar(char),
#[error("Need at least two elves for common item")]
NeedAtLeastTwo,
#[error("No common badge was found")]
NoBadgeFound,
}
fn priority(c: char) -> Result<i64, RucksackError> {
match c {
'a'..='z' => Ok(c as i64 - 'a' as i64 + 1),
'A'..='Z' => Ok(c as i64 - 'A' as i64 + 27),
_ => Err(RucksackError::InvalidChar(c)),
}
}
fn find_double(content: &str) -> Result<char, RucksackError> {
let length = content.len() / 2;
let part1 = &content[..length];
let part2 = &content[length..];
for c in part1.chars() {
if part2.contains(c) {
return Ok(c);
}
}
Err(RucksackError::NoDoubleFound)?
}
fn find_badge<'a>(elves: &[&str]) -> Result<char, RucksackError> {
if elves.len() < 2 {
return Err(RucksackError::NeedAtLeastTwo);
};
for c in elves[0].chars() {
let mut found = true;
for other in &elves[1..] {
if !other.contains(c) {
found = false;
}
}
if found {
return Ok(c);
}
}
Err(RucksackError::NoBadgeFound)
}
#[cfg(test)]
mod test {
use super::*;
use crate::common::file::read_data;
use anyhow::Result;
#[test]
fn test_rucksack() -> Result<(), RucksackError> {
let input = "vJrwpWtwJgWrhcsFMMfFFhFp";
let expected = 16;
let result = find_double(input).and_then(priority)?;
assert_eq!(result, expected);
Ok(())
}
#[test]
fn test_part1() -> Result<()> {
let day = Day {};
let lines = read_data(day.get_day_number(), "example01.txt")?;
let expected = ResultType::IntResult(157);
let result = day.part1(&lines)?;
assert_eq!(result, expected);
Ok(())
}
#[test]
fn test_find_badge() -> Result<(), RucksackError> {
let input = vec![
"vJrwpWtwJgWrhcsFMMfFFhFp",
"jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL",
"PmmdzqPrVvPwwTWBwg",
];
let expected = 18;
let result = find_badge(&input).and_then(priority)?;
assert_eq!(result, expected);
Ok(())
}
#[test]
fn test_part2() -> Result<()> {
let day = Day {};
let lines = read_data(day.get_day_number(), "example01.txt")?;
let expected = ResultType::IntResult(70);
let result = day.part2(&lines)?;
assert_eq!(result, expected);
Ok(())
}
}

View file

@ -1,5 +1,3 @@
use anyhow::Result;
use super::template::{DayTrait, ResultType}; use super::template::{DayTrait, ResultType};
const DAY_NUMBER: usize = 0; const DAY_NUMBER: usize = 0;
@ -11,11 +9,11 @@ impl DayTrait for Day {
DAY_NUMBER DAY_NUMBER
} }
fn part1(&self, _lines: &str) -> Result<ResultType> { fn part1(&self, _lines: &str) -> anyhow::Result<ResultType> {
Ok(ResultType::NoResult) Ok(ResultType::NoResult)
} }
fn part2(&self, _lines: &str) -> Result<ResultType> { fn part2(&self, _lines: &str) -> anyhow::Result<ResultType> {
Ok(ResultType::NoResult) Ok(ResultType::NoResult)
} }
} }

View file

@ -1,5 +1,6 @@
mod day01; mod day01;
mod day02; mod day02;
mod day03;
mod template; mod template;
pub use template::DayTrait; pub use template::DayTrait;
@ -9,12 +10,13 @@ pub mod day_provider {
use super::*; use super::*;
use thiserror::Error; use thiserror::Error;
const MAX_DAY: usize = 2; const MAX_DAY: usize = 3;
pub fn get_day(day_num: usize) -> Result<Box<dyn DayTrait>, ProviderError> { pub fn get_day(day_num: usize) -> Result<Box<dyn DayTrait>, ProviderError> {
match day_num { match day_num {
1 => Ok(Box::new(day01::Day)), 1 => Ok(Box::new(day01::Day)),
2 => Ok(Box::new(day02::Day)), 2 => Ok(Box::new(day02::Day)),
3 => Ok(Box::new(day03::Day)),
_ => Err(ProviderError::InvalidNumber(day_num)), _ => Err(ProviderError::InvalidNumber(day_num)),
} }
} }

View file

@ -5,39 +5,84 @@ mod macros;
use anyhow::Result; use anyhow::Result;
use common::file::read_data; use common::file::read_data;
use days::{day_provider, DayTrait, ResultType}; use days::{day_provider, DayTrait, ResultType};
use std::env; use std::{
env,
time::{Duration, Instant},
};
use thiserror::Error; use thiserror::Error;
fn output(day: usize, part: usize, result: ResultType) -> () { fn output(day: usize, part: usize, result: ResultType, time: Duration) -> () {
match result { match result {
ResultType::IntResult(value) => { ResultType::IntResult(value) => {
println!("Day {:02} part {}: {}", day, part, value); println!(
"Day {:02} part {}: {} ({})",
day,
part,
value,
time.as_secs_f64()
);
} }
ResultType::StringResult(value) => { ResultType::StringResult(value) => {
println!("Day {:02} part {}: {}", day, part, value); println!(
"Day {:02} part {}: {} ({})",
day,
part,
value,
time.as_secs_f32()
);
} }
ResultType::LinesResult(value) => { ResultType::LinesResult(value) => {
println!("Day {:02} part {}: {}", day, part, value[0]); println!(
"Day {:02} part {}: {} ({})",
day,
part,
value[0],
time.as_secs_f32()
);
for line in &value[1..] { for line in &value[1..] {
println!(" part : {}", line); println!(" part : {}", line);
} }
} }
ResultType::NoResult => { ResultType::NoResult => {}
println!("Day {:02} part {}: (None)", day, part);
}
} }
} }
fn run(day: Box<dyn DayTrait>, part1: bool, part2: bool) -> Result<()> { fn run_part(day: &Box<dyn DayTrait>, is_part1: bool, lines: &str) -> Result<Duration> {
let lines = read_data(day.get_day_number(), "input.txt")?; let now = Instant::now();
if part1 { let result = if is_part1 {
output(day.get_day_number(), 1, day.part1(&lines)?); day.part1(lines)?
} } else {
if part2 { day.part2(lines)?
output(day.get_day_number(), 2, day.part2(&lines)?); };
}
Ok(()) if matches!(result, ResultType::NoResult) {
Ok(Duration::ZERO)
} else {
let elapsed = now.elapsed();
output(
day.get_day_number(),
if is_part1 { 1 } else { 2 },
result,
elapsed,
);
Ok(elapsed)
}
}
fn run(day: &Box<dyn DayTrait>, part1: bool, part2: bool) -> Result<Duration> {
let lines = read_data(day.get_day_number(), "input.txt")?;
let elapsed1 = if part1 {
run_part(day, true, &lines)?
} else {
Duration::ZERO
};
let elapsed2 = if part2 {
run_part(day, false, &lines)?
} else {
Duration::ZERO
};
Ok(elapsed1 + elapsed2)
} }
#[derive(Debug, Error)] #[derive(Debug, Error)]
@ -52,9 +97,12 @@ enum ParamError {
fn run_on_parameters(params: &[String]) -> Result<()> { fn run_on_parameters(params: &[String]) -> Result<()> {
match params.len() { match params.len() {
0 => { 0 => {
let mut runtime = Duration::ZERO;
for day in day_provider::get_all_days() { for day in day_provider::get_all_days() {
run(day, true, true)?; runtime += run(&day, true, true)?;
} }
println!();
println!("Runtime: {}", runtime.as_secs_f32());
} }
1 => { 1 => {
let mut parts = params[0].split("/"); let mut parts = params[0].split("/");
@ -64,12 +112,13 @@ fn run_on_parameters(params: &[String]) -> Result<()> {
if let Some(part_str) = parts.next() { if let Some(part_str) = parts.next() {
match part_str.parse::<usize>()? { match part_str.parse::<usize>()? {
1 => run(day, true, false)?, 1 => run(&day, true, false)?,
2 => run(day, false, true)?, 2 => run(&day, false, true)?,
p => Err(ParamError::UnknownPart(p))?, p => Err(ParamError::UnknownPart(p))?,
} };
} else { } else {
run(day, true, true)?; let runtime = run(&day, true, true)?;
println!("Runtime: {}", runtime.as_secs_f32());
} }
} }
} }