summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorToby Vincent <tobyv@tobyvin.dev>2023-12-08 13:06:29 -0600
committerToby Vincent <tobyv@tobyvin.dev>2023-12-08 14:37:45 -0600
commit6d31120a46210275970200b96b25499bd37530c9 (patch)
tree0fd43397940f4225c8fd3b0f559651da879d6d82
parent5258a4300378d239bdd12358b593e53f908dfc76 (diff)
feat: impl day 8
-rw-r--r--input/day_08.txt716
-rw-r--r--src/day_08.rs160
-rw-r--r--src/lib.rs1
-rw-r--r--src/main.rs3
4 files changed, 879 insertions, 1 deletions
diff --git a/input/day_08.txt b/input/day_08.txt
new file mode 100644
index 0000000..c4c3165
--- /dev/null
+++ b/input/day_08.txt
@@ -0,0 +1,716 @@
+LRLRLRRLRRLRLRRRLRRLRLRRLLLRRRLRRRLLRRLRRRLRRRLRRLRRLRRRLRRLRLRLRRRLRRLRRLLRRRLLRLRRRLRRRLRRLRRRLRRLLRLLRRRLRRLRLRRRLRLRLRRRLLRLRRLLRRRLRRRLRLRRLLRRLRLRRLRRRLRLLRRRLRRRLLRLLRLLRRRLRLRLRLRLRRLRRLRLRRRLLLRLLRRRLRRLLRLRLRRRLLRLRRRLLRRLRRLRLRLRLRRLRRLRRRLRRRLRRLRRLRRRLRLRRRLRLRRRR
+
+FTD = (QRN, JJC)
+LMR = (KND, NTK)
+XMV = (RGS, CGP)
+KSC = (TGM, CPQ)
+MTP = (BBX, TVN)
+MSR = (GGL, GGL)
+LGX = (DTT, PKP)
+NLV = (DDK, MCH)
+KSF = (DQS, CTM)
+BFB = (JQD, CMG)
+TGH = (FVM, TNT)
+SJG = (XVB, LKD)
+XTK = (XHD, JTP)
+XVK = (RBH, JGS)
+RFS = (FPG, LTD)
+QTQ = (QMH, QDB)
+LHS = (CRH, RRQ)
+RJP = (HSR, TBP)
+CKS = (XCC, XCC)
+HGP = (VKR, GSB)
+GNM = (GSM, KJL)
+JRN = (MGQ, VLL)
+BBG = (QPL, KKN)
+RNV = (DTC, RCP)
+PJJ = (CDX, THL)
+KNF = (GXG, DCN)
+XNL = (QKC, FBF)
+QJS = (SSK, GNR)
+TNH = (HDQ, KVK)
+CXT = (SVL, DQN)
+NKV = (RPS, KPG)
+NPQ = (TTT, TRL)
+TVX = (HQV, MXC)
+PCB = (PRX, KCT)
+JND = (KKS, DNF)
+MKB = (TQC, HCQ)
+JXH = (XLF, TVX)
+KPG = (CCC, HHJ)
+PRN = (RVT, CSS)
+TLQ = (KNF, JHM)
+SJV = (SGS, TBH)
+DLM = (JQH, DKV)
+JHS = (JKJ, SVT)
+XLG = (HVD, JND)
+CPV = (DDS, RGG)
+TTP = (PSS, MDJ)
+LPC = (QSP, SDT)
+BPJ = (GGK, NSN)
+FPL = (KKL, LPS)
+TNC = (XXB, GQP)
+PRQ = (SVN, HDB)
+KKN = (LCV, MGD)
+QNM = (RLJ, NHT)
+GMB = (CHK, VLS)
+KFG = (RKJ, DMR)
+FML = (HCJ, BDS)
+DRJ = (BSF, BDF)
+FBB = (DLR, FQN)
+VFQ = (THC, MHG)
+PFF = (TNT, FVM)
+LVV = (VLG, DHP)
+CCC = (MSL, KJP)
+HMS = (FMQ, KBV)
+FND = (TNH, CCL)
+GHK = (JFS, TQP)
+TRJ = (SSN, KSC)
+XKR = (BMX, DLS)
+TKQ = (DSB, LFF)
+HBX = (HQD, XJF)
+RCF = (MVK, BPC)
+MFR = (NDL, XBG)
+FDF = (HFR, JSB)
+DBH = (XLQ, DRJ)
+BCP = (XGX, GMR)
+CNX = (BFB, XBS)
+PTQ = (XNN, BMK)
+HJS = (CCL, TNH)
+NQH = (HPR, DTN)
+RTL = (FVG, SHS)
+CDV = (XHD, JTP)
+XNN = (KFG, NFQ)
+RPS = (CCC, HHJ)
+TVN = (SXH, HMK)
+CBN = (PKP, DTT)
+DCN = (RCF, BQC)
+SBD = (XMV, SSF)
+THV = (DLC, RHV)
+SXG = (LMJ, SBD)
+JVK = (VKS, BHS)
+XTV = (PSC, HXN)
+BJN = (LSJ, NSX)
+HQV = (FSR, RNV)
+SSK = (JNG, BBG)
+FRJ = (CNX, CTF)
+VNH = (HJS, FND)
+QGT = (VKS, BHS)
+VRH = (HJS, FND)
+PBD = (PRN, HLR)
+DNJ = (SXG, QCF)
+PRX = (JBS, JSH)
+GCV = (BVC, TXS)
+GQP = (DMX, CDS)
+MHG = (DNR, BVH)
+BSN = (BDS, HCJ)
+BKQ = (RQB, RQB)
+LRT = (DPT, KSF)
+VTL = (XRF, VCB)
+DQN = (CSP, XBF)
+LXN = (CNC, MDL)
+XVQ = (NLJ, SBJ)
+VBQ = (MDM, BTC)
+HTB = (KGJ, KQK)
+NKJ = (LTM, MNJ)
+CBT = (KSC, SSN)
+HKL = (JBC, NQN)
+TGN = (VXR, JQG)
+MDJ = (GTC, NJF)
+CGP = (QRH, SJB)
+LLV = (RBH, JGS)
+DPT = (DQS, CTM)
+NNJ = (TVX, XLF)
+XHD = (XNL, VGB)
+NVF = (TKL, HXJ)
+SGS = (SNP, CKJ)
+RCP = (GGF, NCK)
+VXR = (XJV, VXX)
+VRQ = (QKH, DHT)
+KKS = (PTH, LXJ)
+KJT = (TNC, HVV)
+LMP = (VLG, VLG)
+TKL = (KMV, XPB)
+CVC = (VVD, PRQ)
+SKB = (RTL, DRK)
+GSM = (XKK, JPX)
+LKD = (NDB, XQN)
+HRQ = (PRQ, VVD)
+LKH = (THL, CDX)
+PXL = (TLV, FRX)
+HXJ = (XPB, KMV)
+DTC = (GGF, NCK)
+DNK = (FBS, FRP)
+BSB = (HML, BGT)
+VHM = (CRH, RRQ)
+VCR = (FML, BSN)
+LQB = (GGN, GSS)
+SJL = (QSP, SDT)
+HBN = (QRJ, LXR)
+BTD = (CSX, FRQ)
+QPP = (KNP, VRQ)
+LDD = (BVC, TXS)
+KDV = (VRG, TDF)
+MSM = (NVJ, SJG)
+KGX = (BBV, SPB)
+HDP = (HKC, RFB)
+CNR = (DTF, CBL)
+DDK = (NBR, SRM)
+XBF = (DGL, FSC)
+HDB = (FKJ, BPD)
+FVM = (XDM, QMF)
+SCX = (KKL, LPS)
+XHR = (FML, BSN)
+VTB = (GPN, HDP)
+DJC = (FJP, TQJ)
+PTH = (KXV, KJK)
+DPG = (SNG, BPJ)
+KLT = (PBD, LSG)
+BDN = (FBR, HBN)
+DPF = (BNM, JVM)
+JHM = (DCN, GXG)
+TBP = (PLR, DXS)
+RGS = (QRH, SJB)
+RMA = (HDD, CMP)
+MQZ = (JQM, VVG)
+XGX = (QTQ, LLX)
+KJX = (JND, HVD)
+RXM = (SKB, HSG)
+LCG = (VGL, LDT)
+VDK = (JKH, FTD)
+HRB = (GPN, HDP)
+ZZZ = (LTD, FPG)
+VGG = (CML, JQS)
+FRX = (FSP, VBQ)
+JTP = (VGB, XNL)
+DHT = (KJT, PLS)
+CCL = (KVK, HDQ)
+BBC = (DLS, BMX)
+CTJ = (KCQ, LNP)
+PHJ = (DQP, TLQ)
+SVL = (XBF, CSP)
+NXA = (RVD, QNM)
+NSQ = (PDC, DKQ)
+SVK = (MVS, HTG)
+BVH = (NQH, VHL)
+DLX = (KBR, VPV)
+SCD = (RHV, DLC)
+DRK = (FVG, SHS)
+BDS = (MCL, FLR)
+PNX = (SPB, BBV)
+QMC = (TLP, GJX)
+XKB = (BPM, SQD)
+PSS = (GTC, NJF)
+VXK = (GCG, DRD)
+MFC = (PFF, TGH)
+RMB = (NDK, PMJ)
+RGG = (CGV, XVQ)
+JNC = (BHK, BFQ)
+BCB = (VLL, MGQ)
+BCR = (HTB, TLT)
+RHG = (MKB, XTQ)
+XXR = (GMB, QRX)
+XJF = (JNC, QBK)
+PLR = (TTG, TTG)
+RDQ = (QLV, LKR)
+QQK = (LQB, JDB)
+VCB = (NVF, GLR)
+RPP = (JGM, PSX)
+KBV = (BTB, VHG)
+QPM = (RNB, GBC)
+CSS = (QLH, BTR)
+GBC = (VKX, NSQ)
+JJJ = (SHQ, PMS)
+CDJ = (HQK, BKR)
+THL = (HDM, RHG)
+FGK = (QPM, JSC)
+HDQ = (CBT, TRJ)
+TLP = (STK, NPL)
+GKV = (VKR, GSB)
+CNC = (BSB, TNB)
+QSP = (NGF, HXM)
+PRV = (HDD, CMP)
+SQD = (BJN, MDQ)
+DKQ = (PBX, XTV)
+MXK = (JFS, TQP)
+TGM = (NPQ, PHS)
+HBD = (LTM, MNJ)
+BSF = (NCQ, KLT)
+GXG = (BQC, RCF)
+HKV = (JGM, JGM)
+QHK = (FPL, SCX)
+SXH = (SVS, MSM)
+PLS = (HVV, TNC)
+XJV = (VTB, HRB)
+HQK = (VNH, VRH)
+GGL = (RPG, RPG)
+RQB = (CKS, CKS)
+NCQ = (LSG, PBD)
+VPQ = (FRJ, BNT)
+RVD = (RLJ, NHT)
+HTG = (DGF, GCQ)
+KMX = (LCH, SCG)
+RMD = (JVK, QGT)
+FKR = (RXM, MTN)
+VNB = (KBR, VPV)
+LSG = (PRN, HLR)
+CTM = (BKQ, RJG)
+TNB = (HML, BGT)
+SRM = (HKV, RPP)
+MSL = (XHR, VCR)
+SQX = (SGL, NQV)
+MGQ = (LPC, SJL)
+GCG = (NJX, KSR)
+HTX = (HBN, FBR)
+NJX = (RGL, PND)
+SGZ = (PNX, KGX)
+XLF = (HQV, MXC)
+HQG = (CKV, HKL)
+BBV = (NXM, HMS)
+QRJ = (GPS, LKK)
+CKF = (XCC, SGZ)
+HKC = (NNJ, JXH)
+SHM = (NKV, TCS)
+SVS = (NVJ, SJG)
+SSR = (GGL, HVG)
+NVJ = (XVB, LKD)
+QGP = (QHK, FJH)
+FRQ = (FBP, TKQ)
+KMV = (CPV, SMX)
+LSJ = (LCP, SRJ)
+CSM = (HKN, DJC)
+JRK = (BKR, HQK)
+RNB = (VKX, NSQ)
+FSR = (RCP, DTC)
+DKN = (FNQ, TCT)
+MVK = (XKR, BBC)
+NDG = (DKN, NFN)
+MVS = (DGF, GCQ)
+GDA = (KGX, PNX)
+DQP = (KNF, JHM)
+XPB = (SMX, CPV)
+VXX = (HRB, VTB)
+JSC = (GBC, RNB)
+VLS = (NDC, RTM)
+JFS = (PVF, KJJ)
+DBK = (LFN, CFJ)
+MTN = (SKB, HSG)
+SDK = (QQK, NSR)
+GMR = (LLX, QTQ)
+VBH = (FRJ, BNT)
+GPN = (HKC, RFB)
+FSC = (KDK, FDF)
+TKM = (CXB, MTP)
+VLG = (RFS, RFS)
+RFB = (NNJ, JXH)
+QHD = (QRX, GMB)
+GSS = (VMV, DFT)
+MCF = (QJS, TDX)
+DTF = (VQR, LFP)
+XHM = (CTG, TND)
+JQH = (BCP, KSH)
+SBM = (MTN, RXM)
+KGJ = (SVK, SCT)
+TDP = (MCD, CQG)
+BNM = (RQS, JJJ)
+LTD = (HBX, THT)
+TQJ = (SJV, MXJ)
+BPM = (BJN, MDQ)
+THT = (XJF, HQD)
+QMF = (XKB, GST)
+HQD = (QBK, JNC)
+NHS = (VXR, JQG)
+THX = (TKM, TKM)
+GST = (SQD, BPM)
+QJD = (CKV, HKL)
+VLL = (LPC, SJL)
+KXD = (TND, CTG)
+FBS = (KDV, NVM)
+KVK = (TRJ, CBT)
+QMH = (RMV, TTP)
+RVJ = (KXQ, MCF)
+HXN = (BMM, TGX)
+LFF = (DPF, CBF)
+KJL = (XKK, JPX)
+QQM = (VHM, LHS)
+LQQ = (LFV, GNM)
+THC = (BVH, DNR)
+QRX = (VLS, CHK)
+NDK = (FKR, SBM)
+FKJ = (LRT, PDN)
+SJM = (XNN, BMK)
+DRD = (KSR, NJX)
+JBC = (XTK, CDV)
+JPX = (NHH, PHJ)
+SNG = (GGK, NSN)
+RBN = (NFN, DKN)
+MSH = (JQH, DKV)
+RTM = (VGJ, SKL)
+KNP = (QKH, DHT)
+TDX = (GNR, SSK)
+SCC = (LFV, GNM)
+GKL = (GDM, KKR)
+BPD = (LRT, PDN)
+JFJ = (TGP, NLR)
+VMV = (XPQ, TDP)
+RBH = (QQM, HRD)
+BNT = (CTF, CNX)
+JSP = (NDK, PMJ)
+FNV = (FTD, JKH)
+HKN = (TQJ, FJP)
+SGL = (DBH, XHC)
+VVG = (MDT, PCB)
+FVG = (PGF, LPD)
+RMV = (MDJ, PSS)
+TQP = (PVF, KJJ)
+SKL = (VFX, CGD)
+HDD = (TLG, QGP)
+SBK = (NSR, QQK)
+GJX = (NPL, STK)
+PBX = (HXN, PSC)
+KCJ = (CNR, NQM)
+FJP = (MXJ, SJV)
+NCR = (DNJ, BSR)
+NFQ = (RKJ, DMR)
+KSR = (PND, RGL)
+LCH = (THX, THX)
+DQX = (LHH, BHD)
+NHT = (JRN, BCB)
+SDT = (HXM, NGF)
+CHK = (RTM, NDC)
+LTM = (VSD, PXL)
+KCT = (JBS, JSH)
+CBF = (JVM, BNM)
+GPS = (NCR, MHD)
+VHZ = (MTP, CXB)
+BBF = (NQM, CNR)
+HMK = (MSM, SVS)
+PHS = (TRL, TTT)
+SNP = (FTN, KRS)
+BHK = (NDG, RBN)
+KJP = (VCR, XHR)
+NLR = (DLM, MSH)
+SXX = (GKT, KNX)
+FLR = (GXF, XLR)
+HCQ = (JJG, MSF)
+JGM = (QDQ, QDQ)
+TDF = (QHD, XXR)
+BSR = (QCF, SXG)
+HLR = (CSS, RVT)
+XDM = (GST, XKB)
+HHJ = (KJP, MSL)
+NSN = (SBK, SDK)
+RPG = (RVD, QNM)
+JQS = (CNJ, QKP)
+CNJ = (NMT, DNK)
+VSD = (TLV, FRX)
+XLR = (CRF, PTX)
+HSG = (DRK, RTL)
+FBR = (QRJ, LXR)
+KXV = (JSP, RMB)
+GVJ = (XRF, VCB)
+VLB = (CNC, MDL)
+DNR = (VHL, NQH)
+TTT = (XVK, LLV)
+LLX = (QMH, QDB)
+RLJ = (JRN, BCB)
+XBG = (PRV, FQZ)
+NQN = (XTK, CDV)
+LXJ = (KJK, KXV)
+MQN = (BDN, HTX)
+MBL = (GKT, KNX)
+QRN = (VNB, DLX)
+PFG = (VMR, QPP)
+CDS = (MSR, SSR)
+GKT = (MQN, LQF)
+BBX = (HMK, SXH)
+BMK = (KFG, NFQ)
+HRD = (VHM, LHS)
+VQR = (RMM, DBK)
+JJC = (DLX, VNB)
+HPR = (LJM, FGK)
+PLM = (LCB, JFJ)
+VHG = (CXT, FGG)
+CQG = (MKM, MDV)
+HDM = (MKB, XTQ)
+CRF = (CVC, HRQ)
+LFV = (GSM, KJL)
+SCT = (MVS, HTG)
+PSC = (TGX, BMM)
+KRS = (LMP, LVV)
+GNR = (JNG, BBG)
+NCP = (JQS, CML)
+KCQ = (FCS, RLD)
+VGB = (QKC, FBF)
+TND = (VCX, RDQ)
+QKC = (LKH, PJJ)
+QKP = (DNK, NMT)
+NFN = (FNQ, TCT)
+VPV = (DXG, KMX)
+SHQ = (XKX, GKL)
+RQS = (PMS, SHQ)
+JBS = (SXX, MBL)
+JJG = (QMC, VSV)
+JQD = (VLC, PFG)
+TCT = (JMX, VFQ)
+VSV = (GJX, TLP)
+MXC = (FSR, RNV)
+JSS = (KFB, SHM)
+DHP = (RFS, ZZZ)
+CRH = (XPC, NLV)
+SVN = (BPD, FKJ)
+LKR = (FSX, BTD)
+JNG = (KKN, QPL)
+NGF = (XHM, KXD)
+CPQ = (NPQ, PHS)
+NVM = (TDF, VRG)
+BMX = (CDJ, JRK)
+TBH = (SNP, CKJ)
+CMP = (TLG, QGP)
+PMS = (GKL, XKX)
+JGS = (HRD, QQM)
+LCV = (GKV, HGP)
+MHD = (DNJ, BSR)
+DGF = (KCJ, BBF)
+BQC = (MVK, BPC)
+VGL = (VXK, BXP)
+DLS = (JRK, CDJ)
+FGG = (SVL, DQN)
+NHH = (TLQ, DQP)
+DSB = (DPF, CBF)
+MSF = (VSV, QMC)
+SSN = (CPQ, TGM)
+PLA = (VVG, JQM)
+RVT = (QLH, BTR)
+PSX = (QDQ, MQZ)
+SRJ = (FBB, RMK)
+LQF = (BDN, HTX)
+XPC = (DDK, MCH)
+MCD = (MKM, MDV)
+DBT = (VGL, LDT)
+HFR = (QFT, VPJ)
+CFJ = (SKH, LMR)
+BGT = (PCH, DPG)
+QLA = (CXB, MTP)
+FSP = (MDM, BTC)
+JJF = (MCF, KXQ)
+NSR = (LQB, JDB)
+KND = (VDK, FNV)
+CKJ = (FTN, KRS)
+QLH = (LGT, QPK)
+TGP = (DLM, MSH)
+HVG = (RPG, BBZ)
+SKH = (NTK, KND)
+DLC = (PLM, VNF)
+HVD = (KKS, DNF)
+FQN = (DXK, CSM)
+DMR = (JSS, LGG)
+LNP = (FCS, RLD)
+QPL = (LCV, MGD)
+RGL = (TMK, SQX)
+RLD = (VTL, GVJ)
+NCK = (RJP, MGN)
+CDX = (RHG, HDM)
+CTF = (BFB, XBS)
+VKX = (DKQ, PDC)
+FSX = (FRQ, CSX)
+BTR = (QPK, LGT)
+MGD = (HGP, GKV)
+FNQ = (VFQ, JMX)
+CGV = (NLJ, SBJ)
+JVM = (JJJ, RQS)
+QDB = (RMV, TTP)
+GGN = (DFT, VMV)
+QFT = (THV, SCD)
+LFP = (DBK, RMM)
+RHV = (PLM, VNF)
+GGK = (SDK, SBK)
+QRH = (JJF, RVJ)
+TQC = (MSF, JJG)
+KDK = (JSB, HFR)
+VKS = (DQX, XHK)
+FJH = (FPL, SCX)
+RMK = (FQN, DLR)
+STK = (VBH, VPQ)
+TNT = (XDM, QMF)
+SCG = (THX, RTK)
+LGG = (SHM, KFB)
+GGF = (MGN, RJP)
+DDS = (CGV, XVQ)
+DMX = (MSR, MSR)
+DTN = (LJM, FGK)
+FGL = (JHS, PGS)
+CSX = (FBP, TKQ)
+NDB = (FGL, MTF)
+LKK = (NCR, MHD)
+MDQ = (LSJ, NSX)
+DLR = (CSM, DXK)
+JPQ = (PFF, TGH)
+NBR = (HKV, HKV)
+PTX = (HRQ, CVC)
+PGS = (JKJ, SVT)
+XLQ = (BDF, BSF)
+GLR = (HXJ, TKL)
+NQM = (DTF, CBL)
+SVT = (TBX, CTJ)
+LGT = (HBD, NKJ)
+TLT = (KQK, KGJ)
+PMJ = (FKR, SBM)
+SMX = (RGG, DDS)
+NJF = (PTQ, SJM)
+QCF = (LMJ, SBD)
+DKV = (KSH, BCP)
+RRQ = (XPC, NLV)
+BTB = (FGG, CXT)
+DTT = (VRX, BCR)
+LPD = (QJD, HQG)
+LMJ = (SSF, XMV)
+BKR = (VRH, VNH)
+XCC = (KGX, PNX)
+FQZ = (CMP, HDD)
+MCH = (NBR, SRM)
+NPL = (VBH, VPQ)
+LHH = (NCP, VGG)
+TBX = (LNP, KCQ)
+HXM = (XHM, KXD)
+KQK = (SVK, SCT)
+BHD = (NCP, VGG)
+GCQ = (BBF, KCJ)
+JMX = (THC, MHG)
+SJJ = (MFC, JPQ)
+JKH = (JJC, QRN)
+PVF = (GCV, LDD)
+MNJ = (VSD, PXL)
+XVB = (XQN, NDB)
+KKL = (DBT, LCG)
+MDT = (PRX, KCT)
+TTG = (NDL, NDL)
+XRF = (GLR, NVF)
+VCX = (QLV, LKR)
+MDV = (RMD, JRT)
+JSH = (SXX, MBL)
+CGD = (TGN, NHS)
+FRP = (NVM, KDV)
+RTK = (TKM, VHZ)
+QLV = (FSX, BTD)
+TRL = (XVK, LLV)
+BFQ = (RBN, NDG)
+MDM = (VLB, LXN)
+HCJ = (FLR, MCL)
+BVC = (XLG, KJX)
+TCS = (RPS, KPG)
+PKP = (BCR, VRX)
+DGL = (KDK, FDF)
+VNF = (LCB, JFJ)
+TGX = (SJJ, MHR)
+MDL = (TNB, BSB)
+RJG = (RQB, LQG)
+LCP = (RMK, FBB)
+QDQ = (VVG, JQM)
+TMK = (SGL, NQV)
+BHS = (XHK, DQX)
+CMG = (VLC, PFG)
+SJB = (JJF, RVJ)
+VPJ = (THV, SCD)
+RKJ = (LGG, JSS)
+BDF = (KLT, NCQ)
+PCH = (SNG, BPJ)
+CML = (QKP, CNJ)
+PND = (TMK, SQX)
+GTC = (PTQ, SJM)
+BMM = (SJJ, MHR)
+CTG = (VCX, RDQ)
+QKH = (KJT, PLS)
+BBZ = (QNM, RVD)
+MXJ = (SGS, TBH)
+HML = (DPG, PCH)
+KFB = (NKV, TCS)
+BPC = (BBC, XKR)
+JQG = (VXX, XJV)
+VKR = (LQQ, SCC)
+VVD = (SVN, HDB)
+MGN = (HSR, TBP)
+NMT = (FRP, FBS)
+LCB = (NLR, TGP)
+JQM = (PCB, MDT)
+VGJ = (VFX, CGD)
+GXF = (CRF, PTX)
+LQG = (CKS, CKF)
+NXM = (FMQ, KBV)
+LDT = (BXP, VXK)
+TLV = (FSP, VBQ)
+CKV = (NQN, JBC)
+NQV = (DBH, XHC)
+FBF = (LKH, PJJ)
+HSR = (PLR, DXS)
+XPQ = (MCD, CQG)
+VRX = (TLT, HTB)
+CSP = (FSC, DGL)
+KBR = (DXG, KMX)
+XBS = (CMG, JQD)
+KNX = (LQF, MQN)
+CXB = (BBX, TVN)
+FCS = (VTL, GVJ)
+XHC = (XLQ, DRJ)
+GDM = (GHK, MXK)
+VFX = (TGN, NHS)
+LXR = (LKK, GPS)
+XKK = (PHJ, NHH)
+LFN = (LMR, SKH)
+DFT = (TDP, XPQ)
+NSX = (LCP, SRJ)
+NDL = (PRV, PRV)
+MTF = (PGS, JHS)
+XTQ = (HCQ, TQC)
+SPB = (HMS, NXM)
+JKJ = (CTJ, TBX)
+MCL = (GXF, XLR)
+NTK = (FNV, VDK)
+VRG = (QHD, XXR)
+KJK = (JSP, RMB)
+QPK = (HBD, NKJ)
+DNF = (PTH, LXJ)
+LPS = (LCG, DBT)
+GSB = (SCC, LQQ)
+KJJ = (LDD, GCV)
+FPG = (THT, HBX)
+FTN = (LMP, LMP)
+SBJ = (LGX, CBN)
+AAA = (FPG, LTD)
+NDC = (VGJ, SKL)
+VLC = (QPP, VMR)
+SHS = (LPD, PGF)
+JSB = (VPJ, QFT)
+LJM = (JSC, QPM)
+NLJ = (CBN, LGX)
+JDB = (GSS, GGN)
+BXP = (GCG, DRD)
+PDC = (XTV, PBX)
+XQN = (MTF, FGL)
+MHR = (MFC, JPQ)
+DXS = (TTG, MFR)
+DQS = (BKQ, RJG)
+TXS = (XLG, KJX)
+PDN = (KSF, DPT)
+VMR = (VRQ, KNP)
+HVV = (XXB, GQP)
+VHL = (HPR, DTN)
+QBK = (BFQ, BHK)
+XXB = (DMX, CDS)
+XHK = (BHD, LHH)
+KSH = (GMR, XGX)
+DXK = (HKN, DJC)
+KXQ = (TDX, QJS)
+DXG = (LCH, LCH)
+BTC = (LXN, VLB)
+TLG = (QHK, FJH)
+JRT = (JVK, QGT)
+RMM = (CFJ, LFN)
+MKM = (JRT, RMD)
+SSF = (RGS, CGP)
+PGF = (QJD, HQG)
+KKR = (MXK, GHK)
+FBP = (DSB, LFF)
+XKX = (KKR, GDM)
+FMQ = (VHG, BTB)
+CBL = (LFP, VQR)
diff --git a/src/day_08.rs b/src/day_08.rs
new file mode 100644
index 0000000..167d951
--- /dev/null
+++ b/src/day_08.rs
@@ -0,0 +1,160 @@
+use std::collections::HashMap;
+
+use anyhow::Context;
+
+use crate::{Problem, Solution};
+
+pub struct Day08;
+
+impl Problem for Day08 {
+ const DAY: u8 = 8;
+
+ const INPUT: &'static str = include_str!("../input/day_08.txt");
+}
+
+impl Solution for Day08 {
+ type Answer1 = usize;
+
+ type Answer2 = usize;
+
+ fn part_1(input: &str) -> anyhow::Result<Self::Answer1> {
+ let (mut instructions, nodes) = parse_input(input)?;
+ let mut step = 0;
+ let mut node = "AAA";
+ while node != "ZZZ" {
+ step += 1;
+ let (left, right) = nodes
+ .get(node)
+ .with_context(|| format!("No node found: {node}"))?;
+ node = match instructions.next() {
+ Some('L') => left,
+ Some('R') => right,
+ Some(c) => anyhow::bail!("Invalid instruction found: {c}"),
+ None => anyhow::bail!("Failed to get next instruction (this should not happen)"),
+ }
+ }
+
+ Ok(step)
+ }
+
+ /// Calculate the least common multiple of each ghost's step count
+ fn part_2(input: &str) -> anyhow::Result<Self::Answer2> {
+ let (mut instructions, nodes) = parse_input(input)?;
+
+ nodes
+ .keys()
+ .filter(|s| s.ends_with('A'))
+ .map(|mut node| {
+ let mut step = 0;
+ while !node.ends_with('Z') {
+ step += 1;
+ let (left, right) = nodes.get(node).expect("Invalid node");
+ node = match instructions.next() {
+ Some('L') => left,
+ Some('R') => right,
+ Some(c) => panic!("Invalid instruction found: {c}"),
+ None => {
+ panic!("Failed to get next instruction (this should not happen)")
+ }
+ }
+ }
+ step
+ })
+ .reduce(lcd)
+ .ok_or_else(|| anyhow::anyhow!("Failed to find any ghosts"))
+ }
+}
+
+fn parse_input(
+ input: &str,
+) -> anyhow::Result<(impl Iterator<Item = char> + '_, HashMap<&str, (&str, &str)>)> {
+ let (instructions, rest) = input
+ .trim()
+ .split_once("\n\n")
+ .context("Invalid input format")?;
+
+ let nodes = rest
+ .trim()
+ .lines()
+ .map(|l| {
+ let (name, paths) = l
+ .split_once(" = ")
+ .with_context(|| format!("Invalid node format: {l}"))?;
+
+ let paths = paths
+ .trim_matches(['(', ')'].as_slice())
+ .split_once(", ")
+ .with_context(|| format!("Invalid node format: {l}"))?;
+
+ anyhow::Ok((name, paths))
+ })
+ .try_collect::<HashMap<_, _>>()?;
+
+ Ok((instructions.trim().chars().cycle(), nodes))
+}
+
+fn lcd(n: usize, m: usize) -> usize {
+ n * (m / gcd(n, m))
+}
+
+/// Greatest common divisor using [Stein's algorithm]
+///
+/// [Stein's algorithm]: https://en.wikipedia.org/wiki/Binary_GCD_algorithm
+fn gcd(mut n: usize, mut m: usize) -> usize {
+ if m == 0 || n == 0 {
+ return m | n;
+ }
+
+ // get common factor of 2
+ let shift = (m | n).trailing_zeros();
+
+ // shift n and m until odd
+ m >>= m.trailing_zeros();
+ n >>= n.trailing_zeros();
+
+ // reduce greater value until equal
+ while m != n {
+ if n < m {
+ core::mem::swap(&mut n, &mut m);
+ }
+ n -= m;
+ n >>= n.trailing_zeros();
+ }
+ m << shift
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_part_1() -> anyhow::Result<()> {
+ const INPUT: &str = indoc::indoc! {"
+ LLR
+
+ AAA = (BBB, BBB)
+ BBB = (AAA, ZZZ)
+ ZZZ = (ZZZ, ZZZ)
+ "};
+
+ Ok(assert_eq!(6, Day08::part_1(INPUT)?))
+ }
+
+ #[test]
+ fn test_part_2() -> anyhow::Result<()> {
+ const INPUT: &str = indoc::indoc! {"
+ 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)
+ "};
+
+ Ok(assert_eq!(6, Day08::part_2(INPUT)?))
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 6564671..7004331 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -7,6 +7,7 @@ pub mod day_04;
pub mod day_05;
pub mod day_06;
pub mod day_07;
+pub mod day_08;
pub trait Problem {
const DAY: u8;
diff --git a/src/main.rs b/src/main.rs
index e113a75..52da9eb 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,6 +1,6 @@
use aoc_2023::{
day_01::Day01, day_02::Day02, day_03::Day03, day_04::Day04, day_05::Day05, day_06::Day06,
- day_07::Day07, Solution,
+ day_07::Day07, day_08::Day08, Solution,
};
fn main() -> anyhow::Result<()> {
@@ -11,6 +11,7 @@ fn main() -> anyhow::Result<()> {
Day05::solve()?;
Day06::solve()?;
Day07::solve()?;
+ Day08::solve()?;
Ok(())
}