diff --git a/problems/data/day3.txt b/problems/data/day3.txt new file mode 100644 index 0000000..adf173d --- /dev/null +++ b/problems/data/day3.txt @@ -0,0 +1,300 @@ +RCMRQjLLWGTjnlnZwwnZJRZH +qnvfhpSbvSppNddNdSqbbmmdPrwttJVrVPDVrJtHtwPZhrPJ +BFpFzSSqSFFSvQsnWgCMjTLzng +DbWVcVRRdlLffvtqjTWNgQ +mJJMpsmrMrJSHJpsHrFHvBvgHvqfNvzffgTvfj +mMhPjmjmFPJhMSGGcDRlwRdcLGPc +qFcbmWFJqqWpRJcQWpqsQQQwSPCPrHRHCPdNZtSrSHwrNZ +jGMjGLhhhgTvghgtGVjnNCrPVwZSZffSNSwHZZdH +DvzDlvvhnjlMlglglGGhDLpqqcJWWtsmszpWbBBBmQmb +SPLPHQbJSbPsvTLmfDvVDctvWhcDlD +jdRRzzGgJqwrpMRMgdjlcVcWqfWWlfDlmmlWhB +rwgRGdpGprNNLQLsbZJPsn +GZhTVLztHrSzrRBz +MJWjMvsfSCLSnrJn +MjglcgWMdccvZGFtTDchLLLh +rgDHBgBjRgRTgwzwthBnQwmBtB +MsMpSfMsTGTFFLdFFFMFsnNmthNnzhthtwmWnznz +pZMpJdvJMGRHVJJTVHjb +TQVqZVBcBBdBfbpN +zvzrtCshrntCHslPMMMFpZHbNSpb +hLWhGLttsvLvrrWvhzVmQgwJZTRcggTjGcgT +SqRGLHtSbtNTbhjFTjDDpF +WwgJgmdmMdwPDVQQBBhSBFwV +JMPlmlSldWZmRqtLsRGRtvls +mZvmvPNmlNJPJzzmgNvNgdqqdBSpfHBqSsHqHfwpsffq +nhDQDrwLrVVnqfGnsBGBGGsH +VjCDMhbDjLjtFhtLhLhQjNZcZPwWWcczmvglgJJN +wwqnwZGGZqqMpMprpZqwGlLDtNDffdBdNVBmNGBN +TSTchTFbRLfLmVhNDm +SCLRvJQvRFTSRjqMqPZrZnrzZzjp +cJfqGjgGJcsgsPnghgBm +FHHbQQHLWLbPQThqQQRnZs +lLLMSCvrlFMwlSlFcNwqDVVpJcfjzVDf +cRdRDhsDFzPztwJdGP +CVqpCqCgSNfCSQBpjtBwtlBBHLlmGjGG +qfQfCVQfgQnVNpQCMqfcrFrwWDhrDnsvcRDsbc +nFWWzqWZQSqnJzNJzslJVsdV +vBBvsLvbBmBmRlGTNJJvRRTD +tBbpmmPwCmHpMHHMrPCCcSnZSgcFcZgWFscSfgth +LLssTJrqrpvrvvpJvdjggMlgzVgVggPlFPqz +HwZwCZfHNtbMzjgVnFPC +RSttfRwZDtBcZwQMQdrQsdTBQQmW +lJnNhMJqljlNhSrdWlGGGQHwwH +vbTpbCsTFCTmbSmcRfVCfRpwcPdwWQQrdwHwBHrPdwrLLB +sVTmDfmCTVmJjgSzzntDtt +DQtMjZHZHvMbwwTSpqLtpJ +FzVFlsNdVczWPzWcslVfSLqLsqJpSwwsJswLrf +dNFFWcmzWFGLWcdcFgvZvvRHQvjMHDMBGD +MVPTmPvbMgrTmmmmMRMvPvBwFGhhDCdFFwLCLdJhDGFRhG +fqqWfpZWzWsDwhwdhwqGLD +ZWSSftStnnplcQLSbVMBvTbrMlbrBvvl +FSsHDmtFLbbFbLGg +vrvzTzWzzzvppzSzTMnfTggjVgbgjbLjgPPnbGbVGL +pdMwrBpfwfSMTTWdMTpBDCBtmsmltslcBDCshDHs +RgbmfGtmRVgLLSVSnSrWWSHhnh +ccTvlvNppsFnbFnhnWnPHJ +pqNjDBjNNjvpZfmtjbCLbCmb +qsSVpSVfWqgNrVtWptpmSfqbPQljbHPHlDnljRSlwSnwQn +dcGBrMFMdLTGGdlwDwMRHwwMbjHP +CFBvhFhTLFCGvFchChBdBTJtsNpWqfVgtszprmVWNqNgvV +sjsTgNSNqSjgMmVPmmmrpH +RftCcWddRCZfPtCfcQZdcZDcrBllBFpVHprHWlHHpHJJmlFp +thPZRtLcDRdDCTTsqbnwjhvNjq +TQPtgfgdPcdSQhjwHhHBLS +RrqCqVVbJmVRJmsrzmJpWljlSHLSBwSSRWllWv +CVrDNbHrJHVMCbrDJsdFdFcPFZngMfFdTPfP +NNlZgndqmGVGGVZNWQmWmbhbbhpbbhtCbhtgCpCtMF +THfLPTzwJTJrvHRwwsbFbhfbMCpphVtBbB +RjrvzHLzPDvLzPHrTJVrwPndZQNlDZGndZWDdNNcmlQq +tjDsjDGtTjVVbQVCggvrbg +qrWWRBllRFrdlSMCdbSJCP +cZcncRnhphpZWRNtrmsrGpHffmwH +qpRjdcqTcMbbMRTwtnplnwnhPzhBhw +FSFLvNrsPNrsGSLsrFSGfnwBQwZnZwhQQLwwQhnn +sWNVmVmCFNWGsCrrjRTmMjRjPRqgJqJg +sVCnzVpmFpVSnNFCmnmzwRFDWDdMllDccMdwDMjWjWlWjg +BJbPJGGGHPZqZQbpMlWWMWlBljjjgDjh +tGQPpZtfTPpqrHsVLSzmRNLtSFsN +WCDlBWWlvMFWlQWpmSZdZnNmGfJZFZ +LqjTjgtjPcHTTJgLThztcLTLnHnmdSpZdpdffnmZSppfGpSn +PtzqzjtqJgggzhqqccqhrQMsMvMwrCwMlBvMwvvsvs +NMsJfsHTMVbjnLnVsC +htWllhmZcWDWBwhZPcmpVRjnVMRLCCjLFpCwRb +PmZMrBtcPmZWhzDWBtMmJQdddHfQGNSqHqQGGTgr +NmfnnsPlHnGqnlsNNmRPltRLvrhvrSGJSJjvFFFSSFJLhb +PzQZccVPVwgPjrJSJjhFFpQr +TdwBgdTVwzdwzlmNfRqPmqqTql +BVLLBPmPmWBlMlLJnJlBlFQVgdRDdRZRZHpZjQzdRdZQdzQZ +trGTsfbTTgHZptzSZW +fsfTNcCqqNhhVhVFVhVBWLLB +LJwgJNfbCvwCJCwBCCNhhHmGHWWSMWmWmbMmTmmGdS +lzRnnltsstZzzRTfHtHWHGWftfHW +ZFFzVFqzqlFcZscZpRZsNphjhjvjfgJhQgQvwvhC +HHzcFNcHFjhjZjlrghLL +pMZJptpZWCmpttRMCWnnDnBGGDLhlLQrhl +MJsMCTZTTpTJRmMCJzfNsNcfNHqzvvfcww +ZDtllsDlVsrQBqQqRfWl +wvJgpPhhscgvpJFNrRjRrWRjqrRjdjRv +zpsNzCsNCJCCPPHSLzznMnDSLGLM +rfrJjFWrwjpnJjjjfrjJJnFVTgTggRWRRRPPLQgCgQcPPT +sSNbSvqmsSZDZZBtNTTPGgMLMRVcgPCMRb +zZDZzNNSmrfpjFCjzj +dbbNJPBbbrFqNqttqrGbqDcmDQRmFmwcwSnQSDcpwS +ZMMTsHjzLlLcnSVwpRRQ +hZTWjWvTZzTTWhszfwbJhrgJqtBbJGdqNPqt +rrqgHrgtcHJRRjWZlRvnnWBn +QbhVmdFppwbdjnMvlnBwMWZP +TpFDdVTFTDfhHfJcSJSzGZGf +sqNTNZHsHjjFBBwJMMNMcCJD +WGLQPjfWfQWPWmtLSRRRLwBJDbtCCJJCbbwCMBbMBc +RnPdLQfPLRdndGGRvfjlgdrTTgTsrgTrZFzF +BfHbjVVqSBFfMSlCLCDrGSQssvlr +tTpnnzpcPnwzhcnJTDtTPRprGlRGGGCWlQsWvrlvrQGQrC +DPwhghDTpPVHqqdgZbZq +ZzPqfGPtRtqfqPbqfGgGZbrhMjmjBCpHpHNCmHtHjmBHnj +QJwllvFWwDvnwCBBzjwwpC +ccJLVQzWFJvVJlVbgrZZLZLRRPSgdr +rBGbLbnTfnZrQbTnHldqsMmHsqlsWfMd +JcJjCCPzPtjCNHdlGGMlll +jjgpRRvcGbwpThVppT +ttDfjtqfjtpTWWwfTbtlWccNGRSZNGPGhZGhGhcwRh +LbCrHdvzLSSHmSRNmc +JCsBvrvBLzFQbbvlVVnpQpDtWlDqfq +vvdvJBfvdTvRBflBJPNmmffmgPCMwDgsss +rFjqLnMcnqrrtMLtjNgCPCsNzzgsPCGFNs +VqLqnLVZqjMZqWnrVtWlZJJSvHvBdRSvBdRvvJ +zZBDzgQQZLlcglzjrCrCMFjGZbMsHm +PnnJVRfttTtwVnnVFGHVsjCFCjrsMM +wPRpRpRnNTpPNlBdQQDdgDNMhN +bNQpFpnwgtDHpbnhWtffmfmhvhhfsZ +LcdLdwCLPPSVSqqwZGhWdJhGJZhlGlsm +TBwSLPSPVRSVqSVqVrcnpMDDngMgnQpbRQFDNH +vPSvBJZSSdJgpJJZBDGDGrdqGdllGrGDrh +HMtsltFlRVVFtlscRjjMcsWwWChWmrnwDWGwChmjGCWq +MQHNlTVHNVHpbbpbTvvBvf +VsbPMwhbWhzdpzNNggnBcTBWNngQ +RmtZZFZqSjqVHmGQNcBHNLGLGHQH +JjRClqCjZlDZmqSqljFZZqRCvsvPfshhMdwsDwbVwzMzhffb +bfGtRgfDtVmsMzTbmz +LjGZwQLLdjFdHLNMhmzBzMNHNmzN +wjQLCFvnnQGdZLGWSjdqWDfPlrRpqRDDRqrpPr +pqnBZqjCNCqQqmllpHGMGdTfML +PsFgrRvSPsWTwWWQwGHLHW +SrvgsFbrrPJJFsrFPtFSCChBDQjqCqtNhDqhCqNC +RJZRWZWMWZPZffRCPWMdRdfQQQjJzHQsssjrSQFVschVHr +NgpnDgvGTNTVFHFFjVFF +jntvgljpGvlnbLtLbBvnLRPlCCwwCfRqMCCqqqddqw +PFBMVDSVPHMTThtMtSBMMVNbQprHbNRgNRRgLnvpnjnN +scGcrcwlswdGlcqvbQgnnpQnqLjnpp +ffwswWzcmlcWWsmcZhrDFrZMFZBMFzhM +LMdZGqdRSSZmCZMRfQjnggvlvggRcznz +tjjFhBrtpthpslcvvlcQzFnFvQ +jrhbjtpJtbZqCLdWLq +HBGBfBttZzbGbljPdpFddFqRmqRzRN +JDWghDDSDqmmDDpc +CLvgMvChCvLphCTSShhMhQsBbfTfsGsrBfjfrljrZZff +RgHgDqDzqQqgcdHqcZGTNlGffGBDGZBTGZ +LFLPWsmvrbwhwwswrTlTTCBNGFfGlNJZNS +vhrLnvhNmWvMsrvwqMdRcptQtztcjptz +sLMLsThhjgqLlsnsLgTLtMFcRbcPcJSwJbbSbtSWScSt +fvrjjDjvNprdPwwJCCSrWPFP +vfZdGzVzfvGGVGpBjnnMglTsgZlqsMlM +TCVMfCfBnHHfLLPFWb +GgQlGJzNzbzHcHHLlcPLHL +tQbNQGgRZZCVtVMZ +QFFMzwjwngsvsBjGGJWbBbBWbB +QdmVDmVDWRPWVPVV +QHtHSdDpLQCCSHrtqrdrttDfLgvnFvFghNszzwgngFwsNF +RzzTNpSRBzSBVpSRlHNSHBSSGPcLNGtjhPPcbcGhPPhcrnct +CCmmCwwdfFJqDmdwsddhsmvdcMbLfcftttbPnjMPbcjPMPbP +mdZQmvssFdqsFZvsZQmvDvmWzgQBWTRzTzHlppWRglHBQh +VWmnfQWzWWnHWMfmmMVNMfWjtBtBNSNSrlStlpjJBBlgBS +cZZvbwsZsbbZvvscCRdFTTTQrBStdBJgSdhjgBjBjJjpJJ +wCFTCbZbFwwCTvFTwsPGccMzMDWVWfzLGmqHnnDHGLQL +sNQQHbbhdlpdrQllqpsqSpGjZDZGgDnVcnjjnnDZ +WWRLGFvJBJPvzzWjnTncDVZTTPgDff +FLRLGRFRJLBWJmJzMRLCvldrMrbbltdhQQlNqtMbsb +HZllwlZSlSZwhvmQjcZhTqcT +sPzzdgpszpzsBdvvMccvcqPThjhM +JDdsDspLzsdzBgVdBGBzCLlwbbwWSnlnnWffHwJcNlHw +nzCTCnpqJqfCnvvjZjWjPcZrmcmZfW +GNdwgVjwRdRglMrPWLPWZWcNWW +dVblgtRwQgSGVBldbQBbBRJnQJTsJHTqnzzJFpjvHnnn +dqpQQrdqQpLfqcGSdggQdgRMmwHBMMBVNRNDFFBDBgNt +vTzsnZCnlCnshbPlvZJbBzVmmVRDNwtHFBwMDVBR +lJCshjTJbVqfVdjjjG +WlLCJlHLcZcJWcWZJnLHnPqlFtSthTnFNThVtNhVhvNVzVtF +QfbgRsspfDRsgfjqqRRpDbSNSTFzBbTbhttVBhVNBzzT +fwgfRdpdfQDqgPHHZJZCcdGddH +sbrbmVmfddzJntZZtwtMMf +PvhwPRlvvWhFvSRhpFMMJGMFppnBTBGJ +RPlCCLDPDClwHbrdzsdNLzgs +HZgqtgbqRZvzwzCh +BFqmGfrNLQfhzJWBhRJwJR +LFqFQjrcrcqFNMmMdHggntDPMnsDbn +NmWmPblGnnTTNlFGPmNWfwdchdlHdBdwcfCfZppZ +rzqzRjgVrJrzzcFdqdCBFBhZhH +VDRsRMjRJJrQsJPTGFNvsbnsnLGm +nrbrBLTffjNRzGQSJHJQGT +tcZqMcppCmHRQPGGCG +pMDcZhpgcpFDfrwNDDrLVjGj +LWlmlmWqvrBMWWBlmjLThBrfPJZfZZCwPCJJwPCTcggCsd +pSbRHbzpHDVFRQRfPdfnZswgcJcppp +SzRNGbzSWNPLWqLv +vqslblpspsvqBFSqcrrZZDdTfFPHccrf +GWRhWmjwhRcQdCDrPjDP +mcWLVnnWJgGRzVSsVSpSSptNpMvb +wHTPfdTvHlPHGpdvvTddGfcJLLWWwWWcCWrqrVMWCVLL +zhsSNZhnshNSnvZmvsCWWSLrVMcrSCLWJcrq +snDnshmNsjnTdHPfDGvdDT +CfrnFFMnnsRNrNCwFCrdssgqgqvVZvZqlTWBNWZqlJBW +htDhDLhwPWWBqTghgB +DPLPzHDtSPStjLGLtzSMwbdMdnCHrRdCFsmfnR +nBNWCvJmVPNnCPNDJWbtmSwqTttcQsSqtqTjQQ +pMflzLlffRRMRdFlflpLddGdsTjwHqzcvwTqtsStQQjtwwsQ +ZhGlphlpvvLLfFGvMLhfrfWNJNNPVPbnPhnDgDbDDNbJ +ZCpCmVlZvlpBBwvvMCrJhrfhMfjjWMSG +qhstFzFFqzHGzNfSMJSGzM +QnHRPRgRQPtPhtnDsqsbDQPBlTcpBwmVmTvbwdwBTVZVpl +PHmqHdddqBWMmTvMvTGMBWPdwhssnnHlhgsNwhwNHQzwrswh +cSbVcDLtbfLSFzhlhJswgtrsww +bSLlFLFFLDZVLpZVjFLdPMdBBqGGPmmqWGdGjM +FQCnQwFRbnrSfgQgwFRCnswmPLpMppPdMMllpLMptMLldPSZ +cJhhJcJVBJjhfHDvJqThvVDcpdGGqdZGdlltpqWdMqpdGWtG +HhzTjJBzJTvNJHvzvvNBzBFnFCNCbCwrbnRbgRwfwQsg +jRzDgbDDQDgVqqDGsjttNdwqNJZNwNdTWrpB +MHvvvlSHFllMhhMrpWBJtlWdpJrTwZ +mFcFFHmCmtcvfvFFHHLDGnRVzjDgnmgmnzGgGg +JJhDpDdmsJJdgmhrpPjGjFLPPSNpjL +WbznbRGnPfrfRSrN +WqGnnVGVMGHtWTCgJvZHggBggZCg +wlrPQtZQvwrzlvNfZLMZBjbbqjqLbSBjTg +PGJDVdsdhsPVPjbTcLcGLgjqbM +VPDRHWRdsRQvpfmmlw +pvTZTSpTZvGGphNvvbDpdrMqrjlWdPqqjWdldNrd +gmmJmsQfJgcRQJQJJncVQjMWllSnqljqBlPPjPHHHH +QVJQRVcwmJcchwpSZLwGbSZZ +zjrDMWcjDzQjDlWrnqqRBRNhBJRBhBJqnf +TTGPPdgGLwdHGwGPTgLbbvhHtRRNRRSfchqRvSqHRJ +TZTccPpdZwPQjllsspjVzD +jHLHhHFRjhcblDRRWbWTdtppLTntTnMmGLMvTp +BBQBgBBCrrgqJqTtMZMpngdtpvpG +QJJJQrsVsQQfQVPCNqsNSjHdhhdRHDNHFHFclh +RbCLnvdtnLRLRbmLPpHdQCvmNJpJSZSJlgDzglGlzcclcDGD +qBBwMjfsFMjsMbfWbwjlzDZlcWclJczgNDGNDl +wqjhrwwhhCvbQPrRnC +vpWDDDWZQQNGllwHlwWVGj +LCPdqdcdtsvdsCtsddvmVrVjjrBwHlmswmBnmw +fLfvSgvMfdCPqzZNThfNNpTJJQ +CVVVLbNVmGNQbGbGHHbHbvdwgQlwJDTFgJQdDZDJFD +ssWBsBWrjSzWrPtBjnSCTwvFZlDjwZDdgwTDwggv +nntPBqBrPsBfnCRCBWzCVcGVHMLNcbHLNmHqGphp +sbbwwzdsbqQQbQnnNbPNGbznHHRdLTggMVHFVvRZTRVRHMZF +mWffDWfflBpfmcWjWrrJVvgRLlMZVVhMFFTlHhMM +rJJCctmjcfvzsqsqbtbqPP +HGWjHWzVctQVcJVtjvRsvLTddqDDDsjRLg +bbMnlNChZQLZhdDs +SMMMMMMNmMllSlrmCczGcVzBcGWFBQGcrt +VwQlqcLfdLGqdqDjjgZrjZBdttjd +zSPPPJzJGjJjZrCBDt +WMTMsTWsccsvGGwH +hZvbQrjTTZjZcjWNrjnQrcTRpGMqcRfRRGzHfHfpfRMqRz +mDJlFmwCVVwbCVbPBRLMMLpRLwRLHqpR +gsCmgJsPDCtCVlvbhgQjhgQbnQbd +fSgbhhGPGJGhRDmlhhHcHDBH +LsMwQWFswsQMsQMvjslcBcDldBTWfDcHRRdl +ZpVFwLQwVLQvCVsMjrJbbCNPbzSJtPbPPf +VDzWMCpfCcCRDzqDzqNnvLZnfntHQnPPLQlt +sJmdbTBdmmGhFhhbJNNQlJnQlQLHPZNn +sdwmwsdrmMRpDRMLcw +JpWmSWpCnCbJBZHZVldbdfZf +rgdrgNdrjgNPrMjwTssrPdfDZqsVfQHDFlQDDHQVsZfB +TRPdNNLgjNwrRTrJpppzCmzmCLSnvS +QbtQJHQmbmfmBRvbQRzBvldqcFljsGcFdGdvsqqGls +ChCPWhDhWZWJVnZpCNChhVDcMcDdcdgGscjgFjGFlsjjGq +WZNTWNhNZfJJbTJTmR +CHGCHFcZvCrchrZrhsVtsBQjMstfZMMBgg +NNqwDLmDjJgQBmVQ +wdWLLTgWRTWcCcbrHCHhGW +bTZZvNjNjLgTCHcWhccfhWJdhvnc +mnFFmPGSwRPShzVPPWPdhhzr +FRtBFGBMFQFttRwtZgTjCTnQNbNLjTCH +bJSqrSpDJbSNbFjSFCfPWGcwGWPrcTCfwr +tRtLhDsvhQZlHRhRtQQnCnCcdwCPwTwdGcGP +HsHvsmBZvmvsmBhHvLssVqDSNgFMDzgbbDVJzbpMVq +nSSDHRRRQRBCLCQC +qGmfPzGmGlrrrpfrqlzrJtLvBlhQbSCvbtCtlFhLFC +zzpmqqJJVVfJfPfMpfdHNndsNwDSMSDDNcsc +CscQsVMhCsMsMHhhVthtwmgZNRqzWLBRLRLmBWmZWBND +JQJdddrjrLqBgDBq +QbFlTffpMbMnsPCh +gDdbVbVDddDfVfWQfBRLQZsZLRQQ +FCCTrGCMStwGHTtTWLQhLZrlRssRhRhp +FSHqtFTmFwmCsSwGTHtMTSdjjcdnVddgzmbVmjmndbbD +JtBBMcLWLdfFLhMttcWWhfWLrTRGFsbwTmRGwmwbbCTGGsbD +PzQpSQQQvzVvpzHqjvNvQSvGRmmTDVRDmsGsRGsrcDcDGC +cQPHSPvPvZHqcZjzpZjnZNtWlLdtldJWfnfhlJJtLdMg +nPPssTBnMJPdtHPVHtRhpv +bSSgGFWDgWwDFFlmWlcShqdpRqpVcHvvnqpvpRHd +bGFnGljgSsjBCTBszz diff --git a/problems/src/day3.rs b/problems/src/day3.rs new file mode 100644 index 0000000..c568730 --- /dev/null +++ b/problems/src/day3.rs @@ -0,0 +1,189 @@ +use std::collections::HashSet; + +const INPUT: &str = include_str!("../data/day3.txt"); + +pub fn part1() -> String { + let rucksacks = input(INPUT); + format!("{}", item_sums(&rucksacks)) +} + +pub fn part2() -> String { + let rucksacks = input(INPUT); + format!("{}", badge_sums(&rucksacks)) +} + +#[derive(Clone)] +struct Rucksack { + pocket1: HashSet, + pocket2: HashSet, +} + +impl Rucksack { + fn duplicate_item(&self) -> char { + self.pocket1 + .intersection(&self.pocket2) + .next() + .unwrap() + .clone() + } + + fn joint(&self) -> HashSet { + self.pocket1.union(&self.pocket2).cloned().collect() + } +} + +fn intersect_rucksacks(rucksacks: Vec) -> HashSet { + let sack = rucksacks[0].clone(); + rucksacks + .into_iter() + .skip(1) + .fold(sack.joint(), |cur, sack| { + cur.intersection(&sack.joint()) + .cloned() + .collect::>() + }) +} + +fn input(text: &str) -> Vec { + text.lines() + .map(|line| { + let compartment_size = line.len() / 2; + let pocket1 = line + .chars() + .take(compartment_size) + .collect::>(); + let pocket2 = line + .chars() + .skip(compartment_size) + .take(compartment_size) + .collect::>(); + Rucksack { pocket1, pocket2 } + }) + .collect::>() +} + +fn item_priority(item: char) -> u32 { + if item.is_ascii_lowercase() { + return (item as u32) - 96; + } + if item.is_ascii_uppercase() { + return (item as u32) - 38; + } + panic!("not an ascii letter"); +} + +fn item_sums(rucksacks: &Vec) -> u32 { + rucksacks + .iter() + .map(|rucksack| item_priority(rucksack.duplicate_item())) + .fold(0, |cur, i| cur + i) +} + +fn badge_sums(rucksacks: &Vec) -> u32 { + let mut i = rucksacks.into_iter(); + let mut sum = 0; + loop { + let sack1 = i.next().cloned(); + match sack1 { + None => return sum, + Some(sack1) => { + let sack2 = i.next().unwrap().clone(); + let sack3 = i.next().unwrap().clone(); + sum = sum + + item_priority( + intersect_rucksacks(vec![sack1, sack2, sack3]) + .into_iter() + .next() + .unwrap(), + ); + } + } + } +} + +#[cfg(test)] +mod test { + use super::*; + use std::collections::HashSet; + + const TEST_DATA: &str = "vJrwpWtwJgWrhcsFMMfFFhFp +jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL +PmmdzqPrVvPwwTWBwg +wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn +ttgJtRGJQctTZtZT +CrZsJsPPZsGzwwsLwLmpwMDw"; + + #[test] + fn it_splits_rucksack() { + let rucksacks = input(TEST_DATA); + assert_eq!(rucksacks.len(), 6); + assert_eq!( + rucksacks[0].pocket1, + "vJrwpWtwJgWr".chars().collect::>() + ); + assert_eq!( + rucksacks[0].pocket2, + "hcsFMMfFFhFp".chars().collect::>() + ); + } + + #[test] + fn it_finds_duplicates() { + let rucksacks = input(TEST_DATA); + assert_eq!(rucksacks[0].duplicate_item(), 'p'); + assert_eq!(rucksacks[1].duplicate_item(), 'L'); + assert_eq!(rucksacks[2].duplicate_item(), 'P'); + assert_eq!(rucksacks[3].duplicate_item(), 'v'); + assert_eq!(rucksacks[4].duplicate_item(), 't'); + assert_eq!(rucksacks[5].duplicate_item(), 's'); + } + + #[test] + fn casts_characters_to_numbers() { + assert_eq!('a' as u32, 97); + assert_eq!('A' as u32, 65); + } + + #[test] + fn item_priorities() { + assert_eq!(item_priority('a'), 1); + assert_eq!(item_priority('z'), 26); + assert_eq!(item_priority('A'), 27); + assert_eq!(item_priority('Z'), 52); + + let rucksacks = input(TEST_DATA); + assert_eq!(item_priority(rucksacks[0].duplicate_item()), 16); + assert_eq!(item_priority(rucksacks[1].duplicate_item()), 38); + assert_eq!(item_priority(rucksacks[2].duplicate_item()), 42); + assert_eq!(item_priority(rucksacks[3].duplicate_item()), 22); + assert_eq!(item_priority(rucksacks[4].duplicate_item()), 20); + assert_eq!(item_priority(rucksacks[5].duplicate_item()), 19); + + assert_eq!(157, item_sums(&rucksacks)); + } + + #[test] + fn it_gives_joint_hashsets() { + let rucksacks = input(TEST_DATA); + assert_eq!( + rucksacks[0].joint(), + ("vJrwpWtwJgWrhcsFMMfFFhFp" + .chars() + .collect::>()) + ); + } + + #[test] + fn it_finds_badge_item() { + let rucksacks = input(TEST_DATA); + let result = intersect_rucksacks(rucksacks.into_iter().take(3).collect::>()); + + assert_eq!(vec!['r'].into_iter().collect::>(), result); + } + + #[test] + fn it_finds_badge_sums() { + let rucksacks = input(TEST_DATA); + assert_eq!(70, badge_sums(&rucksacks)); + } +} diff --git a/problems/src/main.rs b/problems/src/main.rs index 289ae6c..b2586bf 100644 --- a/problems/src/main.rs +++ b/problems/src/main.rs @@ -1,5 +1,6 @@ mod day1; mod day2; +mod day3; fn main() { let day = std::env::args().skip(1).next(); @@ -9,6 +10,8 @@ fn main() { Some("1b") => day1::part2(), Some("2a") => day2::part1(), Some("2b") => day2::part2(), + Some("3a") => day3::part1(), + Some("3b") => day3::part2(), _ => panic!("unrecognized day"), };