summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--input/day_3.txt300
-rw-r--r--src/day_3.rs123
-rw-r--r--src/lib.rs4
-rw-r--r--src/main.rs3
4 files changed, 428 insertions, 2 deletions
diff --git a/input/day_3.txt b/input/day_3.txt
new file mode 100644
index 0000000..5533a94
--- /dev/null
+++ b/input/day_3.txt
@@ -0,0 +1,300 @@
+zBBtHnnHtwwHplmlRlzPLCpp
+vvhJccJFGFcNsdNNJbhJsJQplQMRLQMlfdfTPCLfQQCT
+GPhjcjhZDjWtnSVH
+BNhHVhrGNVTbDHdDJdJRPJdSQQSJwPjR
+lvtsfbsqzwSnJcvjSm
+MftttFLftZMLgtgMbltMqZzbDNrTpVGhNWrDTrpTGNpZGZhD
+VSSHcTgTtTdtllZlzmmbljTn
+RqMqsFfQLLFLQFMMfRLPZLvPpCfWrbpmCbjCnfjlWmnrmmnm
+hqRDqPDRsqNHwtHSNBZtJd
+tNFDpDFrtdjfmjjjFmFFdScpZhZScTJgpHccHhMJgS
+lLzSlSCQqbsVhBghggBZgCcJ
+zRLVVLQnvQqVVzRldfWrwffjjdwSdfjv
+bpWqqqWvHBpwGBCCRl
+hJdjdJFQqdBBDMMC
+tFFzJZFtJSqtZJQsWLbNSTnffHfvTH
+lFhRZhFjPlqMlJqZJlJcRLwrLrwStRwtsVVtVSrgRV
+WcpDvDfBmpDHzWBDbpbmWmNVSSTzLTtrVswgttVVzwwr
+pbWfmGBpHfDmWnvvGbmWnjjMqPJMlMFPdGcjqPqPhP
+NjFNRlpVLFCSSlbBWWfw
+pssPZQQsMnzmtnQPttzDBbBJBcrrJWbrZSBJSbfC
+QTHPHspMNGHdhvRR
+QfPdSJfFJmthSthtwbsNLbPLlLTLpbvP
+nHnMBnZqqgBMnWrZMqnZVcbCqRwNsvblRwppbllTsRNp
+nZHBHznMnWgcrnVBtjFdfmzQNtNddjNF
+hFhfPghppPhpRNhzsjsvHVzjpsGnWz
+tTjlCCwMqtdMjMctGJWHwWnVwWnwvWGs
+rZdrjBBtqdCtlcdgFZQLfhRLFSgRNP
+RDHSWrJWffJFlJCgCMCDjCvzjPMP
+QtGTndBwBtNzBVjBCMgB
+LdwwMpTdwsRHsqSHqHJl
+RfsfzvLLFvFzCSvSbDsTpTGMPMZPPTMt
+jqWBjwBBNwWqwPGZbTwVwVtD
+BnhgglhhNNngqjBjHNWrZLlFLSCJSFFCCQzQvQFCFF
+HLvLDQbvnDQDvbHTLhntSnGBSlfGldddcmfMMf
+NgFjZjrZZJrlfJfSVcBJGc
+scWCNFZpsjzrDLwLhbQzhQwD
+SlqJlThDPqpwSTwhcbDdbWDbZGcZNcDb
+MsnWWjHjvLvfscjjgdzNdbgbcc
+vQQvWVQFLLHfHVBWfsfmFFpJRhhSplqlRJqpBwlqTCPC
+DZbDzzZDjQbPGZFFSSgSlFCzTgzm
+qLnvwvhddrqMrwrCTLLFJjmtSlFlSH
+VdhvsWqdVWvvRhsvqbpbPcZfPpjZGBQNRj
+mJNtNFmzDZtzdzrLtwwRqJSchgfGcRfwRB
+pWpjQjCTQnHMWCCpjQpHvTqcwTwScfRcBcSGBRThwS
+MQHjvjVCCqsvljWnVQzLtNPZzmzLVNLddtPN
+QVRPRVDgsRjLssnL
+TTGDJDJfbfLHSnsMWWbs
+qGqqTFFDqgQgQQQq
+nlMnRRjbMjCdJVQJCZ
+nGqfLwfNLFNLnPPGFVVCdVGZJtCtCCVzJz
+LHHfPNHnPqqLwqPqDPWfNFvMglbhhbMgmclgcllDmgmrcl
+cLLWWSThtdLpRcddcgPRZFDMCVPPMCCPCPCZ
+NfGbGNzrBNffGNJjbPPZsZmZZPmDHpMH
+zlJBfzlQzNjNjfJcpwSdvWhcvLwQWt
+cVVQfVCJVrVcTJnfNvlDFmDrmlvrFWlL
+snZHpMhZtMbtPNvzHWWvNFNvNW
+gppnbbbRgMnZbswRqRwbqTcCCSTCJJdGjgfVGTdcCG
+jplgNdrHrrNZgdHmlHNJHddlDSPPSTlzTSlTSDSzCQLfzf
+vscvWWWvGWGGscbFMpRWFwQTPzfLQwQwPfLbzSzzDL
+GvGBWpqcMVRNNZHgdHdtBJ
+LchbZhjjZFjwSmPRqRffqbdtggdR
+vWHMWlHJdGqtRqHV
+MvzCJlnMnlTNnNNLLdhjjCdjjhDjjL
+FNCllHFvCGvwQcPQJfgfmwgh
+zjtRpbDLjtsrzbLLQmfBTgTBQQfhbfQB
+WLgqRzqsrWvFGFZFZC
+qjLlNcLjcNWpQLlQMmvmhCvCgsMZZghj
+tGSDJtRGJzHMMGDVZCfvmfhzmZZgZsmv
+BSSRDRHBGHtSSSbGJSwHbNcLQddqMNlrqcMQMldBWc
+JSfctrtctDpszHvzVQHr
+glCWjhWmFjlmlhmdWPhVVznvcHjszbvvpHvznv
+FgBmFhCBCGFqglgmhCFmSTSRLJLLZfSRJcDSGMtM
+vZGlFFtLMLdShSSShRVtVf
+rQNvmznWPNCPNsrCsbWbsPCvjShhhfHBBHJjSJRhjSRnHhSj
+mCNsQCmqszNcQzrzrrzWvGgGMgpdFpMLlFZGwcLDdg
+QJRJQDlcqLlWbNGL
+HCnwwsCrnstLWqtWNgZNgg
+rsnTrTCHTnnVwnsVPqqDQcRjcczMPvPRzM
+qCzjqnzVdzrdhnhddDbDBMPttcGBDBDPnc
+sZgRQWHgWHHLsgsRRZsJbpJlDcDGNcTDFtGNFFcJNFPBPBTc
+WggbRQSRRgRSsWWmbHqvVffVwhzvCdmfhmdV
+lhqWcNpQGcNmmHmNPWCsQzQsgrQrBMCMbMVM
+wDLFFDJvSFFZRDZSzCrzTzsRgVWbCrMW
+dFwDtZfdjFZWFFfmHGPnPPmqfmPNcN
+lcMRNJRGGLJnNVFbVrwrwZrD
+tjCzQjQhQwgWFShVFS
+ffHQsQssQTzBsPnLpMPRwsJP
+MQSMSBSRFMQLJChLChjTBh
+WmVlPrwnpwDlflNpDrNnDlDwThJCCdLJhhdhCfJTccGjvscd
+gnDVnNnwgglwDwptSZFzgQHqbjZgZZ
+nwBcFgwTDcNrpZMD
+WQWCLZmvhMRvNjsNSD
+CGGWmZGHHhtVzHbTqgTdbgzz
+RmcTCwvssRbsThTcVRJJfSPqfJwJFqfjfMFq
+zQNZDWtQlDZGBQPfFQqjJLjL
+rrglggZGWnrnrrHlDhsbsPTVCsCVsTRpHv
+wFGfzSvCPGttSzqwmtqmvvPRDDRCWgWWDTBTMcBcBWbCRM
+hVJJHQHnpWnDTNnnDb
+LJsVVdhQqvmdbbSf
+srlJztzsVVsSsVtRlNllTWzzmqGhqWLPCDCgmChPLDdqCmCP
+bZQMZpbvMBMgmDGmZLSPZd
+MpScMSMpvfjMBcBcfMfSBnzlTjssNszrNrtlTVzlzFVN
+rCtgrgClprGGClnJCZmwtMjZRjbjjcjZQv
+PWVfBHWPdbNfbbRmRj
+sPsVqFPsHWLhBVVqHFqPVddWSDLJgpTCnnrRRLGpJSSTRrgT
+zjqpGjrQjGqSHCVvCrRZDN
+cTdshMhdmcMNmddRHBhvCCBCCvHZDC
+JTmTmJnLTdwzNQpPWJWgpP
+BmpZmrzZnznHbpprSbQSQbqdSVqbPQcV
+fRGTGJZRTTDwJTJRGDfgJgNFlSSFcldfdccFVlPlFFQPSQ
+GvTTTZZLmsntzmCL
+VhMcrmbhvzMSnhvftbRbllLtglBBtf
+HqqqJqDqPjJPNjjDVFDZCdqBtRtGBGlGRfQQgttQfHlTQl
+pCZJPqqZpmhvhpVh
+dWLBJHJhGJGMBJRcDLDSQsSQpvcR
+ZlnnPqglblfRRpSvSsnz
+sPTgZVjjmwVTljrwTTlbwVGdJhBNNdFdMGNHHJMjBNFN
+FhFrfbfgbLRdfqfrmvDgLdjrcQtSNStHHHQlSjJJPllt
+CnspzZWTpCnMVzzZZGZRCzttHNjNlQlSNtNlNjVcjlQS
+GCZsZBRwnvwfbqwFwb
+bZnJFJgLFRnqQZqJQJFQGpCLNcGlLllClNtccjGc
+rVfvwPDhPHGtlcbClr
+mBhshsfMvBvqsQJdTbgnqQ
+jgWHqMSWMGqWjWjqbWGJQDfVqLfrfDfJhVLfTr
+pPplwsRZPFZFtLhfwgfwrhJL
+zlRsdgFcRgmjdBCMHdjHWB
+qJSGJSPQWzcprtQZtt
+mBMVfsNBnZzcNtcc
+LMLBsmMlvBgFsghVVvfgLBvbJJSqgGHqPGPtCWwbJHqCPG
+ZvZLcdMGVMlHDvDpvqhH
+NNSrQNbJbrTnnWZDDZqqhqpW
+wbgNJrsrCwwJQZbsrJBFzjCCdzGdjcGzMdzj
+JbVmdVLJJJdQMnzmmMgHjPqqjNgvqwngHNNP
+ZfffDZZsRpcpRDcCRrlpplcWSSgwgSwjvvsjPSwhNSWggh
+cCtfppZrpjtMMmdQQTLz
+TtbnmbdmTmgTlPNhqvqj
+wrwrLsVZRsJJJsfHjvPPWfhjHqRN
+sDZwDvsCCQLJZQJQsMCMzZBtSMpndcSFnnSBFtSBmdBc
+mWFTZdmQdZFrFQbCRsrspjSjnvCLRS
+GwlDqcNHDzwGfHSRqCgJsSpnvpSL
+NGlcNwHLLGfDDHDhDwDcwVczbPddZtMFWttWWtdPPdQdhPWd
+mnfcZgcdZqnqdfFqPmHfhqsbgVMCJNMtvCJtMvtblTJtvb
+rRLDDjPSjjPDGBQSBNbtLVtbMNNJlTMtbl
+SzjDDzRRpGQDDDPHzdsmnnhsqcqdFq
+ZDGNRDGjSdwnnmnsVNsHJJ
+tMBWWrddLPLhvWTTPLccvmmbVpgsJHmccppJ
+ClPrtBWWrhrFLBPlCRzjzGqdRzjRdRGZjF
+csTRNQNJcNBDLfhfMf
+qGmWpGHqrqPLChPRhVFPDD
+tgHrtnrrJnZRTZcv
+FLqrfmLDrqCmqjTqcbGqRTGVvb
+FMtWMSWzzFStJzPzhWzhQvTvHVjjTjHTTHvbHc
+PgtWWstWtSpZWPzWwnrBsdBDdFLfllLlfC
+mThbMDMQDCDbwLqWpqPpdhwR
+zgrcffgHNZltZSgHLsRsLLWRWgLqppsW
+SVlSrfSHlSSVlrJfVctlNDMCmMFbnbRDbDBFJFbBRM
+PrBrWqtRPdBLLrBwqpswgpwhgpnZhhzsgw
+FTFRSVJQVJflFfQQgggGMZngGQZszZ
+TbmfFJFSDFblSTDSFFbmVSDrPLLWtcmBqqRmBtmcLtcrjP
+DjPsMwDjLVVTsvNNRTNTRT
+ztdQQHqHlFNtfRNNNMgg
+FzhMhHQlDcCrhCCc
+zSHGzzmHgnnMDLTNTG
+lPVBtvhQjpNSMWTLBD
+VCftbjvbVCfPbZwsJsrSgSSZwC
+CbwgmvMnmnCwMmwRQqJBGBgHZHpJHdtdZpJt
+zVSlNSDlrzNhqlNTScDzVWfBBZZZZGBstGsdsWFpdHdJsW
+NDlLzhrVcqRPCMRwLLLw
+TjTHHLwnLjVlTwLjgVfvsFvDsdWfvDvFMd
+qbRRRpmpcmDcczppztSqSvWFssFGfWdMvfQWdfsG
+RZpqDBmtrzhzphjTgjHlnwjgJhgJ
+dLmMgdgzwDLzDWFhBWvzFzzBZJ
+tTVcppbSTfstTMMHfTbhBchhJFCWcjWBZhjGGB
+SSSSNbsNRpRRsRrfVHfRpNtlPgQDLPdMmlDLlrPnqPdPLl
+qqbTCSqdqqFZdRLZhwhZ
+HWWlHtlrBfGtVssnsLnHfJVPPMMFzhPRwMPwFhzPZzPMGM
+nfmtsrlsnrfVnHJrVBWlsVfgbbNTNSvmvvpcTjLjLbqvvS
+GGhFvGPFcThqffPdnfNLqZZCSwtQSwZpwQQBsL
+RglMRrJJgHBCBZSQQpdr
+WmbRHHbzDgJMDzRDMdWmWHzHNFFvvGGhnvVvvfcvnFfcbvnT
+QsfQmsLfZZZcshnJ
+dSgdWgSVVFvzSpqFdqTgWRHbJNcbZNCTJCNNZRRCCh
+FcpVjgDvVVFdVWFvzjwwQtBMLtBBGDwftPrB
+rqsRrHsvsPqswNcJcNJrnnBrNn
+bFjgGFdbVRNNnpRQpV
+GSthhggGDSvMRqtHvMfM
+ZwVPgMsgVsGzVsRZpgpzzgpFMrNbbLFrDLFFrrSDLfrNBN
+qvnjBhQhntbfDLrF
+CJlHHcHcTWqvpBdsWRpdPdgs
+BjmTDjJBCBWrgQRPFlWWlW
+dHphshtdtVHVhpJqspdvRrqFPgrLPPFPrrRPvQ
+sdMsMtStVszpwMzHjJGjCcZjmScNfCDf
+DmGdDffgDSDDdJstqdJldlRt
+MhnvMCZCbbZHMvsCHtrcVrPjJcRqVtlt
+LsQbsFZvZhQzZwhQWTNgBWpNwSGpTmfS
+RRJQnCzbZZLTZJCBtWvFtsfqBqtfWb
+prjlChGNldGNdlSVMhWfqWtfsvwvqsFtdtsq
+GGjNDNhpMGMGVhrnZZTzcTHCCJcDHc
+RmbMmjgpPjMBsBMfchhVsc
+HwFWFTztSrtFpcQvBsSqVscBBC
+zWwnJFHtWWHDgbGgdpGpnl
+mnbWbRRLRFnmmWcCDTBVwCDBlwNW
+ggJPtpdHGfdZtMHgtZgVPPBCVsPNBcsBTTDDCC
+hpvJJTpGhdhtJdMHqvmmnLvSbmnFnRFm
+WWtrWrNgVbRjMrQCNzqJFwQJFNTJ
+LdHPhcdchQQssLzJrz
+pBccnHpnrrcGHnnSlWjnRMSlbt
+NMMfNFnZgMVThhTMcgTDJDJjsVvvJJqJmHsqHG
+LQpwwprCQzBNBdGjGjHswswdvm
+CBCzzCrbWbSlNQnTRgPPfFRWnfgc
+RFwHVQRwFgTQSFVhdsdHsBdDBnnqnq
+LGftLtPGGMzlNrhlPqPsrJ
+fvGpWpMtccpTwwpRRQhh
+TTJCGdTGtZRQQCnzcnCv
+FWWHPSFNFbDbDDqSWnVmLRRjRRQLhcmLjS
+qPwPWwFppbwggGZGfdJZgdnGdd
+zSTWzrzWTLWpCtCGpqqGgplc
+nZWwsJVZZBnJHJCclHllgtChgCgc
+DFnVBJsFssVVFBFnBdfvjDSmTMWzrmMfRmTv
+MJmgMssrsggqqMVstbwTcTbPbTTwThmw
+NRBBGRjHVRRcRbCp
+QnSfzLWzNHzNVQQVjrglJMsMFvgJdFWrgZ
+ggLLGnhgnPvJHZnN
+VBtmVSldbSBVlcNPHvjmNcwNZZ
+tdWqSVSSBztVWGrThLhfrfvG
+TDqrjdSwLqDppdTCdzPBFmmjQmhHFPFQhPFR
+zlGbMcVcVtsPHFRhWRRsPF
+btgvlVVcDZZZqgrz
+DgwlgbbFDDjjPTHDrmddPhPV
+WqtMBBtQsttMNWQBqsbJpGGzdPdTHLVmTzJhmTPhHHPTmH
+qQsqGZNQtZGMNsNtZpFnjnCRbZffwwSRljFf
+gMdFLCdnMZCTFFCqnTgWLCHfSgPgPHStcQQmfSBBSfHg
+vrwwrwzbGjjswjvhGGsjPQmqRmHPbBtcBQtqfmcH
+qzJllVsGVGljjsrzwDzhwzDGTddNLFnZWNdpCVWTNTZTLZCF
+LtwMhDtctwbwwppdWBJQJBWPvPfDfqvG
+FTzrNrgSRFrgzFRHNVFQJvlqHjBvQWlQWqPBfq
+sFgNzmVmNzgTvVTMwhMhstMwZtsbsc
+MrBDQVzzlrvhQzQrDMVQrzrzgRJnRRwwRbwSwwVRRNSgwwwJ
+qFTPTvfTHcqqncpcwR
+LmtdGGPmTPGCTLHLWsZMhvZMMMzrzzdlMQ
+ZVNpjfpZNpfNgNjzNVfWtnbbWmBHtsZWBSZBGS
+MrDrQvvDrPLDMvFvdmBGGsBBCtsHrnrGCm
+ltRMwLLDDRlvQwvlQcwhqfcJNpgzjJpjhJ
+sRRRlRbcFbBBdnFBwCGppNvGrTCDDGVNlr
+PPSLQzHjzZZPLZPjgTNTgpCbVJvGrNCTGr
+ZLHHPQjhQmWWSRRnssdtbnmfwF
+GRwrMrHJGwJPGWsgfqQgsc
+VbTvLQCZLSWWsgWf
+TVDvVCvppvTDmzZVTbZpTzBBNQQQJlJBBJBNNJmRBwRH
+shJRWJsjZGNjSTrjFS
+dMLCddggldQzMCCVgzVVLmLvTwNFFSqpNSqSbFGSqTTpMTFN
+VGQvVglCLcVzgdddCDVvlsPZRRBDJPHZWZZnBsWJRR
+CrwlwhRCMrswnsHBFccHHWFc
+QJTmtfQgLtzQfLQfdPcWSFHHDDSpcFpFBg
+jTQTqbfQfmLbLQJbJrRCWjljZGjNrZlZlC
+JmthDmLShtJmHphphJQCwjdjdFDzFgzFdgdNlC
+sbMTVBrWMbNvVMnsWMnVzjsjwCfjFgfZzfdgdzlj
+NvqbbBcMMPPSqLSpGGthmp
+RfGWFHlPFFNWGFZRZBjvwCvzBwhhrvvjzmrr
+sLJSLMSTSJTbStJtMSqSqbpMrvmrzWdvhmjDCzzwrrpjdDDv
+SbQqsqsWcZPcQGFG
+BjqbMqMVBsfqGqFqGLmF
+ZZQbQPddPcwbPnRQltdtQZdnmFNrvfhGrhrWWFNWWtmNFNNW
+dJJQccnRPpcbQcMHsSgSMsDMTJSg
+WWGBBvPflnWbBWhvhbPvNfnnVCFZmVRVZmVGMVwRLCCCGwVC
+gjszgTMrgzgqCRRdmJRjJLVw
+grzQHzqczMSzqSHcgQsqPvPlbNblpPhhPPbHvnhp
+sJDDNWdnRLTTvqwSFPCmLCCrCq
+thzplgfjglflFcbMclpppMfcwPqCZQCmqCwrzCqmQmHSqPqq
+MhcpFBMBlhjbBTdnNJWvNvsvBd
+czwwghnWWfcfgwfWthfrvVvrjdrdvDDVrbzrLF
+RHPPMRpQPRMPPJRjJQsZsrrvvJBDDVDVdFqrBrFdBv
+smjMsGZHRsHSmRQNGHPpSTwwttCflwngnChcCtWW
+bprrrwrtLDtrWwrQjRDQDbPPVHVmmmmHNWlPlVNPZZlv
+hqqhfnBCTfnnhzJwzsqzfPZZMCCVZVHHFvZMFvZmlC
+TzhhdJTqJzcBdJJnzjtQrLdjwgLtpbgrLQ
+qzQvzzgWSCqtqqGpddGc
+jLrZNZhZrNRLHNffhrjNjNdtdZtGcPFwFwpbGwbVpdwC
+nHnhrLNCCMHmhHBMhrzvgJvsWSWMWzzWzSlv
+RzcbzdRFzbbzbzbFdZFTHMZPhVhVQMLrlrQPhLZlMM
+BNGfBvsNttVmMhlMLm
+BwGjpllswfjwpcFDWcWcbpdb
+SjzpswrLSDjVSpwlmZJBTBdNJLvBNvHQZT
+rCcCtbqgCfthggtbGGMqqghqZQvvQTBNJQHQZQTcZTJFZFFd
+CggGMtqMfWbbGghPhhbCMtmsSppSspjpmWzjVSWlVrrm
+PmWTPThTQWnLWQFl
+VNcSVfMbtsddBQNnNpdl
+sSjctwjVSzzccjgnTnDTHRDhqjRR
+WfMWfCNCjWWHNTccMjRjfRcMbqSwfVwqwsfGGbssrJSrswVw
+llLFQLlvlPFnhQBPBZQBqvBwzSzGGhShJVwShmsJbbmzSG
+lnPqvQZBFFBnnpgplFvtvHDjTdcTjTMMjCRNCMWgRC
+rprFNFFNjNLmMdgcqL
+BvzCQQbBQgffsDbvVHMdbcVqmLVqlmqq
+JvJCzBDJwnsRnQDszCBnnnQBrjZPjFpgZFTFZRpTrpZFGFtT
+wBHQQZHVCcpwDgdZdMsZjvMZFn
+GPSzlNlJLfzzzvsWdWLMmFWLMM
+NfqGSfrTNzRTqJfRbptQHFQFrwrFHBHw
+sNjVMVNVMzPzQgghcMsNzJtjSJtTFDTJtJnnDLjDnL
+CHwrdCpvCrwrWdpZqcpFttJSFJTLLHLJfbnbfD
+qrlZCwlqZrqqpWdlRqCRqdqcVNsVMzQzmNgNPBsRhVQVVzMs
diff --git a/src/day_3.rs b/src/day_3.rs
new file mode 100644
index 0000000..5335624
--- /dev/null
+++ b/src/day_3.rs
@@ -0,0 +1,123 @@
+use std::{ops::Deref, str::FromStr};
+
+use anyhow::{anyhow, Context, Result};
+
+pub fn day_3() -> Result<()> {
+ let input = include_str!("../input/day_3.txt");
+
+ println!("day 3");
+ println!("part 1: {}", part_1(input)?);
+ println!("part 2: {}", part_2(input)?);
+
+ Ok(())
+}
+
+trait Priority {
+ fn priority(self) -> Result<u8>;
+}
+
+impl Priority for char {
+ fn priority(self) -> Result<u8> {
+ match self as u8 {
+ c @ 65..=90 => Ok(c - 65 + 27),
+ c @ 97..=122 => Ok(c - 97 + 1),
+ c => Err(anyhow!("failed to get priority of {}", c as char)),
+ }
+ }
+}
+
+#[derive(Debug, Clone)]
+struct Backpack(Vec<char>);
+
+impl Backpack {
+ fn get_local_union(self) -> Result<char> {
+ let (left, right) = self.split_at(self.len() / 2);
+ left.iter()
+ .cloned()
+ .find(|&item| right.contains(&item))
+ .context(format!("Failed to find union in {:?}", &self))
+ }
+
+ fn get_group_union(group: &mut Vec<Backpack>) -> Result<char> {
+ group
+ .split_first_mut()
+ .and_then(|(first, others)| {
+ first
+ .iter()
+ .cloned()
+ .find(|item| others.iter_mut().all(|b| b.contains(item)))
+ })
+ .context(format!("Failed to find union in {:?}", group))
+ }
+}
+impl Deref for Backpack {
+ type Target = Vec<char>;
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
+impl std::str::FromStr for Backpack {
+ type Err = anyhow::Error;
+
+ fn from_str(s: &str) -> Result<Self> {
+ Ok(Backpack(s.as_bytes().iter().map(|c| *c as char).collect()))
+ }
+}
+
+pub fn part_1(input: &str) -> Result<usize> {
+ input
+ .lines()
+ .map(Backpack::from_str)
+ .try_collect::<Vec<_>>()?
+ .into_iter()
+ .map(|b| b.get_local_union())
+ .try_collect::<Vec<_>>()?
+ .into_iter()
+ .try_fold(0, |sum, c| c.priority().map(|p| sum + p as usize))
+}
+
+pub fn part_2(input: &str) -> Result<usize> {
+ let lines: Vec<&str> = input.lines().collect();
+ lines.as_slice().chunks(3).try_fold(0, |acc, g| {
+ let mut group = g
+ .iter()
+ .cloned()
+ .map(Backpack::from_str)
+ .try_collect::<Vec<_>>()?;
+
+ Ok(Backpack::get_group_union(&mut group)?.priority()? as usize + acc)
+ })
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_part_1_example() -> Result<()> {
+ let test_input = r#"vJrwpWtwJgWrhcsFMMfFFhFp
+jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
+PmmdzqPrVvPwwTWBwg
+wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
+ttgJtRGJQctTZtZT
+CrZsJsPPZsGzwwsLwLmpwMDw"#;
+
+ assert_eq!(157, part_1(test_input)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_part_2_example() -> Result<()> {
+ let test_input = r#"vJrwpWtwJgWrhcsFMMfFFhFp
+jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
+PmmdzqPrVvPwwTWBwg
+wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
+ttgJtRGJQctTZtZT
+CrZsJsPPZsGzwwsLwLmpwMDw"#;
+
+ assert_eq!(70, part_2(test_input)?);
+ Ok(())
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 1d417d7..e0ca15f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,4 +1,6 @@
+#![feature(iterator_try_collect)]
+
pub mod day_1;
pub mod day_2;
-pub mod day_3 {}
+pub mod day_3;
pub mod day_4;
diff --git a/src/main.rs b/src/main.rs
index fc0ca4b..b06c9d1 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,9 +1,10 @@
-use advent_of_code_2022::{day_1, day_2, day_4};
+use advent_of_code_2022::{day_1, day_2, day_4, day_3};
use anyhow::Result;
fn main() -> Result<()> {
day_1::day_1()?;
day_2::day_2()?;
+ day_3::day_3()?;
day_4::day_4()?;
Ok(())