From 64a9220b62976636f012e4b1e2e6ac8cbde9827e Mon Sep 17 00:00:00 2001 From: Tom van der Lee Date: Sat, 3 Dec 2022 18:03:54 +0100 Subject: Day 3 --- day3/__init__.py | 60 +++++++++++ day3/example.txt | 6 ++ day3/input.txt | 300 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 366 insertions(+) create mode 100644 day3/__init__.py create mode 100644 day3/example.txt create mode 100644 day3/input.txt (limited to 'day3') diff --git a/day3/__init__.py b/day3/__init__.py new file mode 100644 index 0000000..a9e1506 --- /dev/null +++ b/day3/__init__.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +from abc import ABC +from typing import Iterator, Any, List, Tuple + +from aoc import BaseAssignment + + +class Assignment(BaseAssignment, ABC): + def calculate_priority(self, item: str) -> int: + ascii_nr = ord(item) + + if ascii_nr >= 97: + return ascii_nr - 96 + + return ascii_nr - 38 + + +class AssignmentOne(Assignment): + example_result = 157 + + def split_rucksack(self, rucksack: str) -> Tuple[str, str]: + half = len(rucksack) // 2 + return rucksack[:half], rucksack[half:] + + def find_common(self, rucksack: str) -> str: + compartment_one, compartment_two = self.split_rucksack(rucksack) + overlapping = set(compartment_one).intersection(compartment_two) + + return overlapping.pop() + + def run(self, input: Iterator) -> Any: + return sum( + [ + self.calculate_priority(self.find_common(rucksack=rucksack)) + for rucksack in input + ] + ) + + +class AssignmentTwo(Assignment): + example_result = 70 + + def run(self, input: Iterator) -> Any: + prioritisation = [] + + while True: + try: + rucksack_1 = set(next(input)) + rucksack_2 = set(next(input)) + rucksack_3 = set(next(input)) + + prioritisation.append( + self.calculate_priority( + rucksack_1.intersection(rucksack_2, rucksack_3).pop() + ) + ) + except StopIteration: + break + + return sum(prioritisation) diff --git a/day3/example.txt b/day3/example.txt new file mode 100644 index 0000000..f17e726 --- /dev/null +++ b/day3/example.txt @@ -0,0 +1,6 @@ +vJrwpWtwJgWrhcsFMMfFFhFp +jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL +PmmdzqPrVvPwwTWBwg +wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn +ttgJtRGJQctTZtZT +CrZsJsPPZsGzwwsLwLmpwMDw diff --git a/day3/input.txt b/day3/input.txt new file mode 100644 index 0000000..712656e --- /dev/null +++ b/day3/input.txt @@ -0,0 +1,300 @@ +fzmmmfwDWFzlQQqjCQjDGnqq +tJHJvLJVVttNsvTtTvgHHSVwCsQRQQZCZZMqQMQBnqBMQs +LgThNJhNSgTJVgvgtghPhbpfWzfbwfPmpprb +lDLnSnLZRjmWrlhrFF +PffQJNqJbPZbpmjrrCVNFmCh +qzbcbqfMfZMTfQTqqzzTPPLMHgBBBtHRStvgHRDBnSRL +WPZfJlZZCMwwZPWCwWzVHQhsshVSsfNQHdvQNN +FLGDGGnGdVjQQQDQ +ccFFbggLnRcLFRtFBmnJzdZZzZBMpwJlZMppMp +RZsnCZssCnDccJCnfcQfHTdzMzhdLdMTqdRqpRLwqq +tNrGNrrvGhTThQqw +rrFStPgrFWWgvmPgQjtmNtmJcfJcsJsZblDZfbfHDFHnfl +RdTfgbbPbJWDDqRvsDsmVG +NSQZLQZHpFGLqnLszrJm +ZMSNMHhNZMMSQwhQJWPBJCbhbcgtgfcJ +qZfqPvLnnZGpGpCJlvsMsMlHJJHB +mTWFFFTTtVSJMzzjWgSH +RbVdtdFtcrmbRQDDVHDQTbDNwLPLfnqZnhZhQnNwfNqnnn +nhHfSGHGThhZjnhrrSnsSczdzlfzzdQQVzRNFNcFdl +JJvCDvmCbtvpvbMmDvLbCJpmqdVVVcMcNGzRcNFcRRzRclQd +vwDCwtLmwLBDJmCHHjHHWGZHBnsnnj +QWTMqZhThbTbLwtGBrQfQQNr +jdzSSccVPPcgcLrDBtDVwCfNNC +vcBgcmssccplTnnTqsMhWW +FlcwZhBhGZhFJnGtZZFwlGsWRLHdWqMzPjWRLTLJHHjdWq +vfmrmbpfpMfzjHjfdM +VCSmVpmrNDMZhSMcsFnh +nHqQVtVZGGwwwnSF +fMBBBWCsCfMMbWfbsGmGzFjQGQFCPhFQhF +fbcsWpJRsWlcNVLtqtLLQcZQ +rgNJdfNJpgpJVMMVfmfVJgCtCTqqqzwTqrBsTswcCCss +lFLHGWLvHQFhnQFhbFnbHWWPBtwqzBPTcsPTswZCPBGCTC +QQtbRtLhtjgdfMRMDV +jTRhJpGhQPfPLsDhWh +wVVMbqbHwVwwMplHWfsfNmWcSLqcLmSs +lVCZlHnwHdRpRGvZTBGJ +csppppDDbGLbSqndFHHNdHsH +lVTlgWgjzCzfgvfggZWWlnHPPBHrSCqBmrSBrHHBnF +QFgvFfjTvZjzlvVTWljvTtMbLcccbRRMbwLMMLQLbw +tjhLjLJzpJpwjsqqfQqNrNfRnsRR +WvwGBPwWZZrnbBNrNnnC +PDvGVTgvTMGvZTGTPvWDZVJjljtLzhtmLlJjwJVJLm +WbzpSNswNWszwSLgSNMcrrBfPJJcfsHMrvMv +CFllhlGFDVFRCmhQDlDTBBcvgBCTcHPHrfrHTJ +qGRgVFhDDZmDnDqhgQFGqzwtzSjddwZbzwpLNzjpdS +FlpZrQSJJmQpSpqlQgbbRZCgGCZdDdbNdd +WswHfjfnhWPFDsFRDcbBbR +WjHvjjWTfTvHFjzvPnPtttVTTJVLtJSpmtlltp +tnjrnnnnhNlPBtbbcWpZScpjbZSz +wmsFqfqqqGHTLbzpLLbgzMcH +FGJqsmQGRVFwwQJschPdhPrBndBhtPhrQQ +dRdJRfTnCRNlJjPBDmBJsbBDzm +wSFWSgGVSLwpFhpLhQjzgPzbtDPDbPBsztrP +WMGvVMLLBCclNHHRlM +gfSffQBDBtZvwwpWDHcbwb +JnCmmJCRmztsVPJRFjFchcGGWFWcGcHFvGLvHF +VCPzJnsPVCjtPjdMsMdmVmMBfgTZBTMfSfZSSlfNNgSSfg +lwHJSVZHWWVwJQwbbVVtwWVVdpdPfRfgDLPZLTZLDLgRDTZL +hhBrBqRcnhsFFfddmdmmCmmppn +MNNBBRRshNHbtVMzQJMM +NBsSNtLNTtNsvlTBBRLgFSCbFmbHFCFhgcghSm +WJWWDdVzDZJjDJQcCDHmmhCnmHmHFm +zQVdQZQwqVQHjqzWWWdHpzMwGMBlGLLtTvRvRNsMwwNN +ZCztttSjGSqRZgRPDNQQNr +hLvmHshLmLcFwwhhwLqMVRRRJQQVNnRJMVRDNNRr +HFhTpFqqLcssmqmFftblBSjCjStjbGWBfj +crffjHDfrQfnfpLPgbgP +TmFvFCmFTFFCtNsmMsRvlRTpPbLGMnGSngPppShGpbdgGJ +vmslmwTNmtstzFsCvRFrHBrDZzcQnWqcDDHqQB +LQLPVLGdGrRPRhHgwMhllhhs +ZbSZTNqSZfNqNCtSSmTttbpSWMlzWlslpWHsWgJWhwJzBMlz +bqjqqFFjHqTTTZTmSNbfmdrFQnDdcvVDGQDvvVnQnr +mQdcdsSThlccSWhMgDnQnFtjQPtnjPNvtR +zzsGwzrrHGBfZJGrJpDtNHFjvNvDvVRvNRtV +wZBCGrbrszTbThcTcLcb +gJDDDDcPQgQfNFPhhZGDDcZZSLVtlCqzsMlzqpszlsVtFSql +bBrdwHTrHWTrTtzLlSMCCCprCq +dnBwRvmnbmBvTpbnbWbTjZPQJhhchmJcmcQPfmGNcJ +sjMGBLWGZjsLjJTBCCbvNrBCHC +mpcRfDSSdqDdlRqdwRvFrHFbrHJFJVvDVrTb +qvlgqwpcSQSfLjjhzgnMzsnP +VgmLHHNRNVLNhsNgRHLltjjbCWnCWZbldntW +GGMFPJqPwJGTvvCCdqdqlqCj +rGwGrMQzJQBjJwTVHgDQDHcsfhVhVg +pblwGBlFlWwwlgCSFwbLvQZFvzvZhzvmQTLLzJ +HfqccHzVDNqLmmPmPPQZ +MNtrVdDjHtrzGBdbGWCblw +NNhnnLdnnfhdhVjvThvqVvCj +tHtHBzBGWHBWGtPBSvvpGZVbSsTFjSqqVbscgjCjqqSC +HBtzJHzzpDZpzMWpGPtWHvZwQmNLlmQnmNdfMmNRmwmlwd +QzGqGwmbfTdPBgRRcgmMPC +NtNZhljrNjrSrtltWlCJCJJfcVVRcJcRgPjf +NlWSZZWsHhWWlprSSvZWHrWfQLLQbLGfQpQzzTFQbwzQdd +gcwcSnccnwLRRSzcBQRvZZdvtNtvRbQJQv +CqrCrrPsVstvbfDfbb +TPlPVhWFFMGMnMjbcT +gjjHGvcHgsgbSRQbRFWbjC +ttnBTNSSfwBLzplWPPdlLlMPlMCQ +TBZpDtmnnZNvhJDHggqqgS +zfqzzGwMbllcJFqm +NpHgpRZrRpSrSZLghlTjchNlNbhFmchb +RHLWHgLBggZpHpgHRZrLgZLQCMzCfDWGMCzMQQGvPmvvfC +bBWWlFFBBFdVMLfvsfjrtBvTrr +qZsgNZzcwfjZrfPf +gcnNNcDncsDGzggDnNRJnzHhmlMVSSbhVVVmMbbhVmMlGl +dNNRQszqRhPNfddWltvDltMMNlnncv +ZjZbpgpSpjpJgpCCpbFlTnSDTlzclDnMvnnMlT +GCJpjbgzJCpwZwrHZrgHsRBwBVRRsqdqPhLBQqsP +mnnVCcwGwnsVJntmfnBtBhTDzpzzpDWbDbsLLzpWDz +FcHQdZSRHbhZZWWhrW +dNljMlPPHdMPvRlHMRdjRRNBnwJfCVqwqqffCfCwtcBV +ZGtGzBBGjvdZvLWLcrPVcZcsNVNmVpcH +MnlgngCJMgJbhfDbCDPrHHVcNNrVpbVpVmmcVq +lSPhlClftSSBvdGS +jFhGqVCcPMMdGFqczBltzrtglrsrjBgB +wWgwvfDZvnpmnHwHTfNpDbtRWbzltRlSrRlbBSbbzt +fHJvJvvTwwJPhCccgQCM +BrrrBVgNppDVBbTgDvqWdWZqWqwNmNNHvH +sHsHnHlcJjFwMMFFvGdPvv +HllCQCJQJsnjgtVTbBgpQrSr +JgLPLwbhBrCbLBCJPFFlPFZRTNTZFRqlRq +pmffSWvDcfSfGmvsNHZsTRsWllssbT +vDddMmScdStfzGcpzzwhJwJwnCbLwwLLCwht +sWSSvmsZsdZPWdLPRRsmSrrnlnvJjfnggfrgtfjnjr +VWWWBhhHBBHtljMMfJHrrt +WWqpWVqQqLNGRNZP +QHjjGVBQpffpjqppQsSsQHWJcVVgJFWcFTWgNLggFPNc +bzzmbzzZnZztFTNJWRqmqcgJ +zDZlqMtbwhCBBfppvHDGvf +BNTdfWJmzHNHHzzTdLCfCfCswQjRjljVsh +FbGnrFnrPGSSvGPFZFFPGClLQpjQRwLjLplQhRlsrQ +GbnvvgvPFwbwcnZMMGSFvFHdNHmTBNJNmmmDTJDBmWcT +rBhRPrjJrRtTHtWHWcjc +SDdGqmhdFSqblLGlHHfHWl +DSSmFqhsFqFdzqFgwsVnvBQPPQPQVrnRsJMR +NZcgQdmSwZgdPFPVNFPqqVVF +hlhhjMhGjLhLDGDhCBJDCrRFRrqqpLPfpfPRVPprPm +MlhjlMDDJTCmZddQQSTcTT +zRddrwzwNhrzrtCLtLfsLrqflC +MbSDZvVwGZpJwvHvBVfsqtjqlsPPfsqsfclb +vJpvJvZTVgTdTgwdTn +SZMsTTScDMqwtDDJ +VWrbzFvnrvFQQtnhzdPFmfwGfqmGPfDwmfPJ +rrLbrnVrLvVQpLHSHjsTBBjZBt +bSrpbWpPpfzPRWrWvhJgddrcccgFnFss +ljGNTCtMNLGQjNMjQMGtZJDDggcldcFcvhdFddnhhF +vNCmQMjmvGzpRPPzzmfw +BrbdcqcdSZRLQltNDqFpCpHH +jnTzWsWjWjwTQnzMvFlCzNDhNhDCFGpHpH +wmmvjVQMvwmsQMMwnsTPgVfgJcLcgfSbbBdBbJSdbSBS +bJFbMdcmgFSFgmggJFcGwjRdzPWZWGDDGGRwGD +hrttffCVVCTVlrttQwzRzwWTqRGDGwjTvG +rfLChHhlpHrfHlnWlpWCpQVcMSmMmSJMmggbmMSMLFNSSs +JRMBJfMJQJTcNNdD +LHsLmspghmmpdwwwcwRCpPTT +ttLLlRSlqjrMqFtZ +VjtHVHtvVqttCdnGpHtplcshglNgprrlMhrcNghw +WTWRvRWFZQLWDvDWzwscNfcflcshlshFlw +WQmBQWPTVGnJPnvn +cpRwjcQwVfQzQPQl +BZgGDBZBsgWBDDJzlhfhJVmzVfmThm +FqWDDGrGDFNqFrDZFnplNHnSwtnSRwRplN +VMLVRhRLRfhfgGdfVdZWRdTHNqHCDTrSJNBBBgJNQgND +swlcpsFPcPwzpSlTTDrNrQPQqQBBrH +zsppFscsscmbzsFsbsZbMfRZdVdVMbVSWhLG +NjcjHFjrHHFpjGtVtGWVZW +fwPlsJqdndPnwJfQdfllwNtWGdtWMMbtbmbGWbMWGN +CPlwnCwnwqClTJThTDzzFcHNSShrRh +llqlsNsPNTpDNTDNNf +cnvcWFjSrMSFnvWHTzTggHCcllzLpg +wjJSSrFrrMMJGrFFFGjGvJnFswsRwRdmBdZbbqqsPtQqPZls +jlclpqjcRqpjzjnVPgTmBmjCrC +vGvsFNGGMZNvdGshQNJvJgbVMrnbrHVBgBTTbBBPBT +SvJNGhvvvFdfQvFshSpqPqLzRRPctRcLWwlf +LWSSqLVBbNqqLrWHLSHzWbbqQfFgZtmtJCQZzgtCFCQCCnJQ +PlldGDGdjGsMPhssjPmQZFJQQZQghChZQJgv +jwMcMpsPRRdsRjPwNpTWBLSBqVqTNJWT +hWnMWgTffWFbMLfHnFMNfHgjtBSNRzjBBSzSBBcStdzBtz +VGrVCGcVJswvPqJQjtQppBzpSwdjpt +ZqqsCrmmsfmWcHhngg +vnNnssMcZnlnlMFMsnFcZMGqJCbLbNLNqgLbgLNTCpLgwC +hmjzBzHmRSfBfmqgQwpQQJbQJmwT +WVVtthRtRdsdqtddZd +LhZBLfZpmcsFpFzm +vTRRwTRRPnCTwlFgmsczzLmgLvFs +HVVVNCPPHTTtClRVNSnwLTHSQHBMMHrHWBhrQbJhWMMbZbJZ +WPTnnDPjvPlChhJPcgCC +DRQdBqsDQHQLHsBSmVLBcbwgCClbgCGlJghgmhgw +dHMHQDVVRBsMWTNfWfzWzf +PlgFPFFJGgJhhMGZwGbpBtQjjjStBttptlSb +TTcDzmHvdvnDDzdTVnTDmSspWspQLpWmSsmqppsWtb +CHVdcHvdbrwJCMPRGJwP +BtBfcPfBhBGDhwHMlCmrNSCM +dQdzLFTQnRnQVvgLnNlrCCpFrJCNrHJrwm +zRVLZQRRvQGbwtWfbGZb +PPcWcwMmCwwgnphCCLpjHp +TtZsJTzzJSSSZJsdJtTrpblhRlHHHMngpLnnjHps +ZDrvdFZtJqtStrZfMcGDVwfwffmWmP +wCwSzzsHChhMVMhCPsSVLFWcdcWGPccRdjFdJjDR +wBTTlBfgTlfpQQltmfgGGctRdGJJJFDJDDWdDt +TppwnmlnQQqnlpqlmmwqlpphHqrVrZZSzshzShqzsrZVqs +CCqCTgmdMCCCMMsWgqqnTCmJDGJcGGJfrGNGrSrrQpwFFSwG +vZbDZvhDbzHzwNzwNGFNpNGc +ZjBRVHPRtRLjLMWsCDlmgMdBmW +MMsstRChwbChqRBqDrJNpNDsHdlNlJdr +vLmPLfGGGGcTmFfTSgvPCvpZQlHHZpdrFJplQdZHQdHH +GgPLmvGVSPfmfcfgBtjwCRwwjBbtVWbh +LPPgFPccLPRswfsHfJgDsH +bpbpTnCCrnmCtjBnTfDshHDwQVTwsDhQ +BbrjnjnWCbBWZbPWzLDzDWdNlMWS +pnncvLbcppBHgBRpddGd +MtJfjVMtMmFJDjWSjVWzGdGgNQRBzBGNBMCGNB +ZdDdsJFdDmtJmLTbwcvcbcnwZv +FGsfFdNdhfbDdbhbLMhbNNTPJVCCZTLJnCRVJLPCRTVR +qHjsczptHpmgHZBBVVTrrPzrBP +lmpSlcglQtqWtcWjpQQfWsGDMhGFwdbGGNWhDv +hNNNjMFMwthjFfvZBjFFvNSdnzSGGdGmHzHgGWSfHWSR +ppJpcCVslpQJpJJDWHCHmRHHWWGSDn +QbsrJQTQJVJNMNnZTZNZvZ +NmRNLtGNmfcRrtDtrJCnWHJD +blSzzSBssgfslWCCCJWFWHrsZF +zTzbPBhMlTVSzMlMldlgMvvvvMLGcQRmqLLfvRwQ +nnZsfsPLLfZfHLWdsZWZHdmcSpTcGmNScJTRGsTJmNcF +gqVqDMgBlDbwwCqVbQFpTNFcTRSJNSrqqTSm +jlMVMjljQBjMwhLfWWzhhfhZtmLH +bfHwMvzwFBNpRjfZ +nddcVJpGVpGqPVBBFBmhBhmsNRJs +DWcPgPcPgnqCPlWWVWGMwbzwvQSSLbvgLpHHMz +NMVqtdPVHgVlrfVrpnjCwNjjpCpNNpCb +zhSvfWWzRfRLfvSpQjwbmmmvQvwwCD +LBRRTRcLJSgqqMJlVVft +GpgNzzSMGpGTrgzgMzJTrPgzjRwBdBlBbLRBjdBwVbLRVbSR +sQWCfQcflhtQQcWCmsmlsbLnRdwqqBmmbBVbLVLwnB +fCtQWFWDZFCQhCctFDsftNpzPPzZJpgJJNTgNlPZgH +DqLtMSDLLttjdDSRdjZtdpdqVWFslFWrqWPqhwhfFwwCFw +CvTbNvvTJNGHnVJwPfwFFFwsrh +cQBzGBHnTQGgcNtdMMBpDBtCdtLL +QsNDfdDNQsSTtrQZQtJJZC +lLvRWMVMLzWbRjvVgVVGvmTtCrZBrTFFbmJCmsBCrr +lljvlgpMGgRpsjsRlGGsMdqDdpDqNqfhqqSdncpqdP +sVSJVmmtmsCCwschrbNMbcBs +ZgLLfqvzzqgfdqHQLnTLfQQFhFMrhbNGBwgGbMlNcFclwN +LTzqZrHHQvjLHnHdQTdTQvZQJjCpCJDPmCRRtCpStRRmVtmm +ccQVcVHwnnDqNqSWNnVvqwcgJblgRslgmdGlssmGbQdddb +rpFtPrzrMFZvZTLPpglhdssFshssJhsggG +pTtLtBMjZLfHvNWqcBHf +PZnSjnnsVfjfLLff +crvccpglrtHfNbzbHLzmGN +lptTLFFpdgvttFWltTclplDvhJMSMPhJPhChShPBZBMJhPMT +mPSPdnhznPdhSmPGchJdFDtBhghgFgWpFBQhTBMg +rHNNvbqHHHwZwMGMWtgtQMZQFQ +wRqqRffvvNHwrHqrNqLvCrqvmPnzdsGJsSsSdSsLPVVPnjsn +CzlngWpClJlzRJpDnpmzCndrhBcrhwcsBcLsNcsmLdQQ +qqSjqFGTFbPFSPTVjcBcBsDdQrwBVLrNcc +PtDDtZTvGDvFCMzZlRJCfWfJ +vtQDpvpvVvvcSFrrljZZsVjFrV +RqcTTRddRrlsjZrwrT +zmbdRdMmMgbPDcGhGmnDpcQn +gZqJRZRZdltFVGZQDZwV +MCMSRHCMRHBBVtVCGwDCFGtD +jcHsTMBNSSrBMjmMrcTMpRqpJggllnprqzRPzdlP +mWSWHdmHWZWjBnGs +TvchwtTfcTvhzwVGNtdrbjnnBnsnNr +JTdwghvMzwfdcMVJqPmQFRPpCDJRJFFC +DsHDCrszvvhHsshvsrrsgwdPpdLFgWLpbRpWFfMjWjWF +BVJPJmPmGZVnfbVfMWpdLMWb +cNGtnttqmJHNvNzDPPHN +gpjmMQMrfmMntCSCNmSNCm +vDRqphDhzHSdtqdCNH +LFLLcbJRJLppFQlpMFfF +SnSdvchzZZczndNvwcwnQrGfqrTTfhhTDgRGGLQQ +lVWHWMmWmttsFBMLLqLTRRRqqDBGTf +bsFPbFFssmFjWRmjVFjHbczvpZCwvwZccndpvzpzCP +jzngbHrlHQllcbcTCtHGWtftGCHqWC +JJgmsJRwFqChLGtqGs +SmJmSmDdSPRwSMppJdPPwVvvzNQvjrNMNjMZZrQgZNgQ +PvPlPcZPZFllzNzCDdhhdHjrpHNjHBHB +VmgWtJWrqbQmqGDBdGQjjhBGdG +tmbgggbgnMWnStttgnfnTzrCfPvFnccnPclT +RQQbdSRdpprQSNVqqqfrffjvnjnJnhnVvHhBhVjJtjJz +WGgGgLmLgGZMPDBhDJDHjMBFnD +WPPwPGwlLgZwmWlslCLRNbrsTrfRrNNQqsspBT +dNNpHpchLppdccTNtZZTRRPSSnwPPSbSnhhrhnSJ +qfqsFsqffgQMznJrPznbMrrB +vglfqQCgDgFjglCDCjLZpTHNPHttdcZVVN +FWtDHDStZwrFCDwrgWPFDsWQJZzlMdpZzlNpNjdjjQzNzj +BqnVGVcbTmGfHLGVzvpQpvJvQlflMdJp +ThRRchnHqLTGbFCCCrrSSFhFCs +wJrwdZPnJwqPbJPCnjFZdvHtMvsLsTsDtHsHDDqvpH +RWzNRWjRfgjNMMLvcMcLNt +WGGRQzzRmRmVQSgwrwJjjCbJhnbShJ +cjngcvcwbMwWnbMWjbgvnsjPftsqfthqsBtsJJJJBt +HrGFmDDzpmLTHpDsPfsBNBPfzZNPqN +DDVmDplDrpGSVSTTHGlpLnPwCRnWcvWCdPbbMvcVdW +BVRlBfPBffWswVWQsfwBNNPMFMmmGFZGnWZGtztrzMZMnz +HqSJchHTHbTgHhGhvmRzFmnFtzRF +RJqHTpgDLJDSqLJJPNVjsfPwBVsVLlfN +NDrBlSmrFBlbbJllmtHHwhNNhZztqHVRzQ +CMTCGLcvvtfCdCcCvCnMTMcTzjHwVZVRLjRRjQjRHRwzwjVH +dfGdgGMGPggnvfvgbtDtlSJPDSFJPslJ -- cgit v1.2.3