diff --git a/Cargo.lock b/Cargo.lock index 7e8746c..35720b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -189,6 +189,14 @@ dependencies = [ "indoc", ] +[[package]] +name = "day-19" +version = "0.0.0" +dependencies = [ + "indoc", + "nom", +] + [[package]] name = "deprecate-until" version = "0.1.1" diff --git a/day-19/Cargo.toml b/day-19/Cargo.toml new file mode 100644 index 0000000..8455fe9 --- /dev/null +++ b/day-19/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "day-19" +version = "0.0.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +nom.workspace = true + +[dev-dependencies] +indoc.workspace = true diff --git a/day-19/src/bin/input.txt b/day-19/src/bin/input.txt new file mode 100644 index 0000000..d3d859c --- /dev/null +++ b/day-19/src/bin/input.txt @@ -0,0 +1,724 @@ +mn{s<3661:A,s>3705:A,m<1698:R,A} +jcj{x<2501:R,s<516:R,A} +lm{s>1017:R,a>470:R,x>159:A,R} +hfm{x<661:gm,fck} +gvr{x<1627:jlj,R} +xd{a<3515:A,x<1086:R,R} +gms{a<3153:tbr,x<1274:hgz,mkg} +nsv{a<1742:R,x>142:R,dvh} +gz{x<1839:R,x>1848:A,R} +lc{m<2328:A,x>3513:A,R} +qc{x<1673:A,A} +ndl{s>3705:tr,a<3474:zr,x<1760:pl,R} +vfz{a<3535:tpv,R} +ld{x<2662:kdb,x>2851:A,m<3657:gt,A} +jlj{a>2672:A,R} +nn{a<2837:mm,x>3088:zj,m>1332:zf,tn} +kfq{m>3404:R,m>3071:A,nh} +xl{m<1669:A,s>3278:kdg,pm} +tz{x>2729:A,a>1540:A,x<2269:ttv,tkd} +gf{a<1839:jjv,s>3144:tfn,x<1424:gpj,ztz} +zf{x<2559:R,a<3507:bg,a>3813:A,xsf} +rkm{x<2920:qpl,hq} +sh{s<950:R,s<1280:R,a>1876:A,A} +zm{a<3311:R,s<3539:R,R} +fd{s<1125:A,m>1688:R,A} +qr{a>1507:A,x<236:R,R} +tvj{s<1336:gqp,tv} +frn{x<3485:vfx,vgj} +sf{x<2428:R,s>1024:A,s<385:R,R} +tx{a<835:R,s>3130:skj,ct} +mrf{x>1667:A,a<3699:R,R} +jkr{m<2927:kxc,a>2049:R,sh} +sc{s>1038:A,R} +tzc{m>2622:R,s<1490:R,A} +cml{s<2768:R,R} +rp{a<3056:R,A} +cmn{m<1877:A,x>103:A,mxg} +dsf{m>720:A,A} +zvv{s>1686:df,a<1613:fc,nnt} +sb{a<157:xhk,x<1408:qdf,m<1174:ff,zp} +xk{a>390:A,x<198:R,a>189:A,A} +jf{x>441:zvv,a>2404:jqg,a>1410:bvc,mb} +ktt{a>231:R,R} +lvj{x>3711:zpn,x<3392:tlf,R} +fsj{x>3517:A,A} +vn{x>1525:jn,x<1345:zjl,s<1431:vh,gf} +nv{s>3581:R,s<3340:A,A} +rf{m>2639:A,s>3257:zm,jg} +rh{a>813:R,s>3042:A,s>2781:A,R} +dq{x<2671:rj,qz} +qpl{s<3540:mv,A} +mz{a<2856:R,a>3430:pvc,x<2330:ftt,pg} +ggm{s<2962:A,x>2214:A,A} +vf{s<349:R,x>1227:R,a<705:A,A} +mrc{a>3426:A,R} +zms{a>3329:A,R} +lf{m>2687:A,x<1481:A,m<2144:R,R} +kdb{s<3016:R,A} +ftv{m>2340:R,a<623:A,m<1159:A,A} +gph{x<123:A,R} +rhl{s>251:bc,m>3504:vfr,a<2788:hzr,zn} +kd{x>243:dc,m<3343:dvn,mjb} +fdf{m<1679:kdk,m>2987:R,gc} +ms{x<3198:R,A} +ph{m<1356:R,R} +smf{m<1642:A,m>2204:R,a>250:A,A} +crv{m>1119:vg,a>3589:djp,hqh} +cps{a<982:R,x>3117:R,x<2335:A,R} +pqh{s>328:A,m>3037:R,x>1636:A,A} +br{a>981:A,s<3008:R,A} +zdq{s>346:R,m>1682:R,a>2849:A,R} +tbr{s<2338:zfh,m>1880:ghf,nzj} +gmm{x<3087:A,A} +lzz{m<3111:ndn,fm} +pqm{a>3473:fr,R} +pmh{m<984:A,A} +dgt{s>1976:R,a>2943:A,m<250:A,A} +jvx{m<3147:R,s<322:R,A} +vhs{s>3174:dxt,zv} +dk{a>2545:A,x<2584:R,s<3184:A,R} +kkq{m<2016:R,x<1586:A,a<419:A,R} +ccn{x>1109:xjj,rb} +fsz{m<3908:R,m<3950:sml,a>3520:R,tcq} +lcr{m>849:R,a>1453:R,m<764:A,R} +vjc{a>2523:R,s>108:R,m>3085:R,R} +rz{x>1108:A,m>2183:R,m>1020:R,R} +xhk{x<1562:gkk,R} +lt{x>247:A,x<218:R,R} +sq{m<2979:xpl,s>1347:lx,m>3340:nsv,pf} +tt{x<1676:R,R} +xrp{x<177:rh,spb} +zvj{a<3736:A,s>168:R,m>520:R,A} +sth{x>1719:nbq,m>2754:lpz,s<346:cpt,kvp} +kl{x>812:A,tqn} +nzj{a<2917:zkq,a<2997:vkp,a>3090:tfb,fg} +gnt{x>1725:R,A} +tmh{m<1627:A,m<1805:A,a<756:R,A} +ttv{m>1339:A,A} +hhq{m<1659:jpj,x>1806:lh,ntr} +pk{a>2233:R,A} +lv{a<543:znq,a<825:A,x<3669:R,A} +bk{s>659:A,vf} +sj{x>1645:R,a>3807:nlm,A} +fm{a>3743:lq,s<2464:jl,s>3039:mhs,ts} +nbq{a<3565:R,hk} +ct{a<1076:A,s<2510:R,x>89:A,A} +znq{s>872:R,s>389:R,x<3462:A,R} +vkp{m>791:R,a<2954:mj,rl} +sjj{m>3095:R,s<922:R,R} +tqn{x<632:R,A} +xxd{a<937:cm,m<689:A,lcr} +gnv{s>881:R,x>1689:A,A} +cq{m>1527:A,x>369:R,A} +tp{m>3533:R,m<3498:A,A} +bl{x>1747:A,zvk} +rb{s>2690:xd,gp} +tq{x>99:A,s>780:A,gv} +tn{a>3559:lnp,m>860:dj,x>2439:xv,ghz} +fxp{x<3712:ccp,s<904:ss,shj} +rk{s>1884:kq,m>3604:lv,s>1153:fq,cdr} +hsz{a>1328:R,A} +qxn{x>1698:hhq,x<1660:sjv,tb} +cm{s>1819:A,x<2244:R,A} +gfq{s<2146:tq,a>1886:cmn,a>1662:pt,kmq} +ft{s<725:rhl,lff} +rc{s<102:R,R} +ss{x<3880:A,x>3942:R,s>475:A,A} +ztz{m>1355:lf,R} +pgd{a<3436:A,x<926:nhv,x>995:xmv,A} +tr{s<3868:A,x>1733:R,s>3944:A,R} +xv{a>3190:R,A} +hgr{m<3265:A,m<3624:A,m<3842:R,A} +qxm{s<2975:mlh,m>1465:lrh,R} +fq{m>3473:tp,m>3434:A,s>1511:A,A} +hk{a>3745:A,x>1782:R,x>1749:R,A} +gst{x<1764:A,s<2078:R,s<2479:R,A} +fqp{a<2237:mr,a<2303:R,A} +fmp{a<637:R,m>2055:R,R} +jjv{a<1298:bmj,x<1415:cd,A} +cl{x>327:R,a<662:R,A} +cvn{s<2271:R,x>1760:qx,R} +fqr{s>2475:lzt,a>3662:R,R} +jg{a>3308:A,a>3257:R,a<3243:A,R} +vm{x>1608:A,s>2267:R,R} +zzc{s<1510:xsq,s<2530:nk,xrp} +pg{x>2454:R,a<3237:A,A} +jt{a<2036:A,x>3568:R,R} +kp{s<3254:xcn,m<2368:xcv,A} +rkx{a<3478:R,x>1142:A,a>3606:R,A} +kqs{x<1646:R,a>3810:tdp,m<776:mrf,A} +mk{x<204:R,A} +mt{a<512:R,a>675:R,a<618:R,A} +cbq{a<3691:R,R} +lbg{x>1685:fll,x<1633:vm,s<2084:R,R} +nrd{x>3246:A,x>2349:R,smf} +zvk{s>3078:R,s>2987:R,a>3465:A,R} +mjb{m>3647:A,a<883:pz,mp} +db{a>1922:fqp,m>469:kqc,qj} +qbp{m<1961:A,s<3848:sp,m>2251:R,mfz} +cgg{s>166:A,R} +vfr{m>3672:R,x<3116:rc,R} +ff{a>278:jp,s>2093:ktt,m>425:R,R} +qtf{a<798:A,R} +kz{x<169:tx,m>726:fj,qh} +vtk{a<3490:A,R} +bjc{s>1024:hnt,R} +nr{x<217:A,x<248:R,A} +bvc{x>285:ths,m>2387:sq,m<1094:db,gfq} +tcq{x>1748:R,x<1691:A,R} +zd{m>3496:R,m<3436:R,A} +gl{s<3344:R,s>3741:R,m<3609:R,R} +djm{m<1932:A,A} +jbv{a>1587:A,m>698:R,s<2324:R,A} +rzh{s>2629:A,a<1890:A,x<1182:A,A} +spb{s<3380:R,A} +lcf{s>1018:A,a>721:R,fmp} +mfz{s<3933:R,R} +kxn{x>2596:R,m>3047:R,a>2293:R,A} +cnh{s<2989:R,s<3391:R,a>1818:A,R} +jqg{s<2459:hzs,vhs} +lnp{s<1688:R,s>2271:A,s>1968:R,R} +lpz{a>3507:pqh,m>2945:A,zms} +pxm{a>2777:R,a>2129:R,m<412:A,R} +ndn{a>3628:sz,m>2877:kkt,gmm} +pf{s<504:jvx,m>3148:mh,m>3049:sjj,A} +tbx{s>3338:R,x>2728:A,x<2208:A,R} +cjh{m>3506:A,m<3434:A,A} +tl{x>2730:qtf,xxd} +qs{a>2177:A,a>1953:R,a<1811:A,R} +vsh{a>3395:mf,tg} +gkk{s<2039:R,a>94:R,R} +dg{s<3005:R,A} +sjv{a<2806:gvr,m<1615:mkc,m>2717:jvk,fn} +rjl{s<1499:A,a<517:A,m>1643:R,R} +bdb{x>2480:R,R} +lz{m<2165:A,m>2321:R,s<2840:R,R} +fkh{a<3538:hvr,tkl} +ljp{s>1134:bzg,kkq} +jp{a<325:R,a>333:R,a>330:A,R} +qk{a>3005:R,m<2895:R,R} +tqs{x>1231:A,A} +jd{x<720:A,A} +pmf{x>1307:R,R} +jx{m>3503:R,R} +xcv{x>1264:A,s>3562:A,R} +ffc{s>1660:dl,x<1559:dqk,x>1746:mmg,btt} +vkk{m<3367:qqx,x<3176:tqb,a<1238:rk,dr} +kdf{s>2631:R,R} +dkq{m<2342:A,x<836:A,x<910:A,A} +zqt{x<1765:R,x>1814:R,R} +cd{a<1640:A,s<2718:A,A} +xmv{a>3790:A,x<1023:R,A} +kdg{x>1759:A,m>2736:R,R} +xvt{a>3623:nx,A} +trl{x>770:A,m>2294:jh,hsz} +zr{x>1726:A,R} +vq{m<2151:R,s>837:A,bm} +zbr{a>3598:qdp,vsh} +ts{x>2576:A,x<2156:A,R} +xb{x<1323:kdz,s<2020:A,mvt} +vr{a<3735:qdr,x>1746:dst,s<1998:pjn,A} +btt{m<2603:hg,a>189:dct,bhr} +zz{m<2544:R,a<2964:A,s<1093:R,A} +zv{x>188:jxt,x<78:hp,R} +kqc{a>1656:A,x<181:R,a<1532:R,jbv} +ksl{x>1716:A,R} +lrh{x<1401:A,a>789:R,A} +qj{s<1997:A,nzf} +nsp{x<355:R,A} +jz{a<3613:pp,lk} +fck{s>2679:A,A} +vfx{x>3110:A,m<3382:R,a<3064:R,A} +vl{s<2867:R,x<3226:tbx,m<143:fsj,A} +fdq{a<2937:R,m>1742:A,m>699:A,R} +djp{s>588:R,s<375:zvj,R} +hg{s<941:R,a<158:R,s>1333:R,A} +nhl{a<842:jdc,m>1845:vq,a<1264:tk,tz} +skj{x<80:A,R} +nnt{m<1816:zrl,a<2781:jkr,s>660:hr,kl} +knb{a>1181:qc,A} +kvp{m<2615:xc,a<3542:xvf,A} +mkg{x>1475:fgc,vxx} +ghz{s<1263:A,a>3172:R,R} +qdr{m>2023:A,x<1754:A,R} +qhd{x<255:R,a>1141:R,R} +dqk{m>3212:R,s>1016:A,pls} +rfx{s<2820:A,A} +np{x>1370:lcf,bk} +gtj{x<196:R,s>1193:A,s<927:R,R} +cc{s>2568:R,R} +zt{a>2797:R,s>2797:R,a<2702:R,A} +vxx{x>1390:xvt,a<3702:kc,xb} +rvf{m<3175:R,m<3678:gg,dk} +tg{m>3363:R,m<2905:A,m>3162:A,R} +hb{x<3265:A,m<2201:A,s>3582:A,lc} +rtx{a<714:lm,s>1097:qhd,R} +pls{m>2456:A,s>426:R,m>2194:R,A} +hrv{a<3514:R,A} +vh{x<1421:cff,kf} +ds{s>2587:rvf,kfq} +cff{a<1614:jxg,nc} +bps{m<507:rtx,jq} +zjl{m<2130:hxr,s<1643:zmk,x<1224:rx,fx} +jxt{s<2705:A,R} +tv{a>3495:tqs,m<1901:A,zck} +gg{x>3270:A,a>2494:A,R} +qv{s>1679:R,R} +dt{a>2086:R,s>126:R,R} +tfz{x<1427:R,a>497:R,x>1670:R,R} +tpn{s>1975:R,s<1639:R,a<2071:R,A} +bhr{s>992:A,x>1683:A,m<3407:A,A} +nx{s>2469:R,a<3826:R,A} +mvt{a>3819:R,s<2734:A,x<1357:A,A} +qrv{s<2662:cnk,s>3212:A,m<2188:R,A} +gp{x>1091:A,m>2260:A,R} +xsq{m<2092:tmh,s>766:gtj,a<651:xk,A} +xnx{s>1313:R,R} +nhv{s>2972:A,A} +gpj{a>2285:R,s>2372:R,tpn} +bmj{m<1925:R,a>1048:A,R} +rm{s>1123:A,A} +rj{m<1592:ggm,x>2353:fs,s>2993:A,A} +dm{a<3662:rz,x<1113:R,x>1142:xtp,xlf} +tj{a>3586:mk,a<3287:mht,R} +kc{m>2340:hrv,s>1715:A,R} +fdt{m<1287:R,a>3344:R,R} +pvc{s<1234:R,m>3049:R,a<3802:R,A} +zp{a>258:R,x>1647:A,jj} +qn{m<1271:A,A} +tgj{a<1770:R,A} +mj{s<2970:R,x<1353:A,A} +bh{s<2666:nn,a>2622:dlf,m<1714:vlj,rkm} +bc{x>2604:jx,x>2331:jcj,a<2724:A,R} +hh{a<3215:qxn,s<1521:lr,s<2817:jz,fkh} +xcn{m<1831:R,x>1275:A,m>2825:A,A} +dr{s<1876:fxp,rhj} +nlm{s<3380:A,s<3708:R,R} +fzl{x>187:R,a<1934:R,A} +ths{s<1404:bp,fms} +mht{s>1243:A,A} +dlg{m>871:A,a>1668:A,R} +vxz{s>126:R,a<3458:R,a<3681:A,A} +bm{x<2634:A,R} +cdr{x>3527:zd,cb} +sp{a<1106:A,x>2784:A,s>3808:A,A} +lg{s<901:jb,s>1546:rn,a>482:fd,ljp} +qdf{s<1591:R,a<256:A,lvs} +xz{m<1481:cps,a>972:lcp,s<3564:A,mn} +lcp{x<2839:R,a>1232:A,x>3245:R,R} +kxc{x>774:R,A} +mv{s>3013:A,x>2298:A,s<2800:R,A} +rx{m<3079:mrk,a>1474:R,R} +bbm{m<3755:R,R} +hd{x<1703:bbm,m>3786:cbq,m<3748:R,R} +mb{m>2654:kd,m>1299:zzc,s<1993:bps,kz} +fvx{s>864:dm,x>1121:jbq,vfz} +bp{s>707:nsp,cq} +gb{a<3053:R,a<3115:R,A} +tkl{x>1688:xl,m>1977:sj,kqs} +xpl{a<1817:tzc,x>169:nr,a>2176:R,R} +gm{x<546:R,s>3053:A,a>3376:A,A} +hx{s>2045:vl,x>3142:lvj,pbp} +fc{a<1041:fv,trl} +gqp{a<3558:xcj,s<462:R,s>988:R,R} +mkc{m<632:dgt,m>995:gb,s<2449:R,A} +hp{s<2877:R,m>1762:R,R} +shj{x<3833:A,a>1667:A,s<1535:R,A} +fv{s<624:ftv,s>1101:A,a>691:A,R} +rkt{m<2656:R,R} +jbq{m>1513:A,s<563:A,hzq} +sml{m>3925:R,a>3709:A,a>3380:A,A} +xtp{m<2367:A,A} +pl{x>1653:R,R} +gt{a>700:R,A} +vg{m>1872:gnv,s>989:zqt,gh} +jpj{x<1767:gnt,A} +kmq{x>151:qr,m<1575:A,s>3253:cmd,A} +hzs{m>2250:sl,a>3055:tj,dxk} +in{x>1863:xq,gx} +dj{x<2303:A,x>2600:R,A} +lh{a<2846:A,m>2459:ptx,s>1865:lz,gz} +pr{m<3049:R,R} +dz{a<713:nrd,qbp} +mrk{m>2755:A,A} +ks{x>2852:R,zlt} +tkd{x>2536:A,R} +gx{x<1056:jf,a<2531:xxv,x>1588:hh,gms} +nzf{m>296:R,a<1691:A,R} +tqb{x<2363:pb,s>2261:ld,ks} +fx{m<3263:cnh,a<1482:A,A} +cnz{a>2636:A,A} +rqc{s<2857:A,R} +tpv{s<353:R,s<530:R,s<748:A,A} +zn{m>2957:vxz,cgg} +ptx{m>3400:A,x<1841:A,s>2075:R,A} +nk{s<2082:A,s>2236:R,A} +nc{s>803:R,a<2184:A,m>1658:A,A} +mhg{a<1907:A,m>740:A,m>407:A,R} +hzr{a>2332:vjc,a<2223:dt,kxn} +fg{m>1182:rp,m<530:A,m<823:A,R} +xlf{m>1757:R,a>3792:A,A} +qz{a<1148:R,a<1473:rd,x<3400:A,R} +vvs{m<1832:gst,x>1728:xkp,x>1651:zgj,R} +px{m>1343:R,A} +cg{a>2956:R,R} +xc{m>2487:A,A} +zfh{s<1106:srk,djm} +gc{a>3568:R,R} +mf{m>3369:A,m>3034:R,s<1159:A,R} +zck{m<2862:R,a<3295:R,R} +mh{s>829:A,s<690:R,A} +zdt{m<3707:vtk,m>3837:fsz,hd} +zkq{s<3264:rqc,R} +mxg{m>2191:A,s>2784:R,a>2067:R,R} +rr{a>3120:A,a>3101:R,x<1787:R,R} +qrl{a>2765:rkt,cnz} +lvs{x>1273:A,R} +cz{s>3104:R,a<1812:A,R} +lr{m<2420:crv,s>569:zbr,m<3184:sth,zdt} +ghf{x<1244:vbq,zk} +hzq{s<705:A,a<3489:A,A} +hxr{a<1675:R,a<2007:rzh,pk} +jvk{m>3317:A,s>1927:R,a>2952:R,szx} +mp{s<2457:R,s<3073:R,A} +tk{a>1095:fsb,R} +hn{a>2033:R,s<2640:A,m<1587:dlg,cz} +nh{m>2777:R,a>2450:A,x<3023:R,A} +lq{m<3533:A,s>2891:A,s>1978:R,R} +srk{s<564:zdq,A} +jxg{x<1373:A,m>2224:A,a<1304:A,A} +dxk{x<291:gph,R} +pt{x<188:tgj,m<1898:lt,s<2956:lgr,A} +lff{x>2601:frn,m<3372:mz,bjc} +tb{s<1696:xm,x>1678:qrl,x<1672:rdg,hzb} +lzt{m>1509:R,x>1505:A,m<537:R,A} +rq{a>1733:bh,m>996:qm,bd} +tlf{x<3232:A,m<228:R,m>301:R,R} +ml{s<3209:dzn,cr} +qqx{x>3015:qv,pr} +fs{s<3056:A,a>1067:A,A} +kf{s<815:A,a>1938:R,nm} +pz{x<109:A,a<462:A,m>3455:R,R} +nm{s>1143:A,a>1477:A,a>1181:R,A} +kdk{s<1608:R,a<3613:R,A} +xxv{a>872:vn,a>348:vk,dnq} +qx{s>2554:R,a>3943:A,A} +lgr{m<2196:R,R} +zk{m>2885:qt,s>3306:A,zt} +mm{a>2237:kv,x>2878:sc,m<1672:mhg,qp} +dnq{m>1899:ffc,sb} +ntr{a<2924:R,x<1760:mqf,a<3066:A,rr} +qm{s<2346:nhl,s<3437:dq,s<3753:dtt,dz} +bd{m<353:hx,tl} +fj{x>267:cl,s>3135:A,a>576:A,A} +cmd{a<1530:R,a<1617:R,R} +cpt{m>2566:R,x<1640:A,R} +zgj{s>1980:A,a<3427:R,A} +hvr{a<3425:rf,s<3426:bl,ndl} +jq{a<541:pmh,a<926:R,A} +ccp{m>3658:R,m>3555:A,A} +dvn{s>1767:R,a>522:A,R} +vvm{s>2965:A,A} +hgz{x>1160:tvj,s<1847:fvx,ccn} +jfl{a>629:qxm,x<1525:kp,a>532:ksl,qrv} +xq{m>2576:ffn,rq} +hr{a<3242:zz,m>2967:rtl,dkq} +jl{s>1964:R,R} +pp{m>2274:mrc,m<1108:lbg,m>1498:vvs,thr} +qt{m>3464:A,R} +rtl{m>3647:A,R} +jb{x<1581:pmf,m>2361:A,R} +dl{a<118:R,a>235:R,dg} +mr{s<2296:A,A} +zpn{s>1287:R,A} +zmk{m>3101:R,a>1862:R,A} +fll{m>559:R,R} +dlf{x>3210:dcg,pqm} +jj{s>1976:R,s<735:A,R} +xjj{a<3697:rkx,A} +pjn{a<3809:A,x<1689:A,a>3843:R,R} +gzx{m>3247:A,R} +vk{s>1922:jfl,a<588:lg,np} +fms{a<1845:rfx,s<2483:dx,a<2108:R,R} +mmg{s<872:A,x<1817:R,A} +lx{m<3512:cml,s>2892:R,fzl} +hq{s>3232:qs,m>2220:jt,a>2077:A,R} +dtt{m>1833:hb,xz} +vlj{a<2140:ml,a>2383:dgd,jm} +cr{a<1904:R,m>976:A,s>3736:R,R} +lnn{a<3317:ds,lzz} +dc{x<363:A,s>1439:hgr,m>3285:A,kbg} +jm{s>3456:A,s>2930:A,x>2786:ms,R} +vbx{a>3526:R,x<1759:A,A} +fgc{x<1525:fqr,fdf} +xsf{a>3670:A,x<2866:A,A} +lgf{s>352:A,R} +mqf{x<1738:R,R} +bdx{a>1373:R,R} +pm{s>3040:R,s>2959:R,x<1767:R,A} +dgd{m<919:xs,x>3141:ph,R} +kv{m>1662:R,R} +dvh{a>2032:R,a<1895:R,s<700:R,R} +cb{m<3466:R,x<3395:A,R} +mlh{s>2509:R,A} +df{a<2667:sm,x>794:pgd,hfm} +gh{x>1717:A,a>3671:A,s>547:A,A} +dxt{m<2555:R,A} +pb{s<2328:R,a<1018:gl,m>3696:bdx,A} +dzn{x>2899:A,a>1917:A,R} +cnk{x<1638:R,s<2322:A,x<1784:A,A} +rdg{x>1665:R,x<1662:R,R} +xkp{x<1813:R,a<3429:A,A} +vgj{x<3716:R,R} +rl{m>294:A,R} +tfb{s<3203:R,x<1370:R,s<3645:A,vs} +kq{m>3723:R,a<811:mt,br} +ck{m>2095:A,a<2991:A,A} +qdp{a<3818:gzx,A} +mhs{m>3601:R,m<3327:R,x>2985:A,A} +hnt{s<1237:A,x<2124:A,A} +qh{x>294:A,vvm} +kdz{a>3816:A,s<2322:R,s<2913:R,A} +xm{s<626:fdq,a<2958:xnx,s<1218:R,R} +jh{s<911:A,m>3035:R,x>622:A,A} +bzg{s<1344:R,A} +dct{x<1655:R,s>598:A,m>3271:R,A} +pbp{m<220:sf,m>275:bdb,s<889:R,A} +thr{a<3473:fdt,s<2291:px,x>1738:qn,A} +rd{x>3336:R,a>1276:A,a<1192:A,R} +jdc{x>2745:rjl,A} +sz{s<2641:A,m<2766:R,s>3431:A,R} +gv{x>40:R,a<2021:R,m<1655:A,A} +tdp{s>3500:A,a<3931:R,A} +xs{x<3279:R,x>3661:A,A} +kbg{s>778:A,A} +jn{a<1479:knb,hn} +szx{s>690:A,m<2955:R,x<1617:A,A} +zlt{x<2589:R,a>907:A,a<376:R,R} +fsb{s>1096:A,m>1470:A,s<415:R,R} +ffn{a<2017:vkk,s<1515:ft,lnn} +bg{m>1789:A,m<1559:R,x<2819:A,R} +sl{m>3167:A,m>2576:qk,A} +xvf{m<2675:A,a>3418:A,x<1671:R,R} +fr{a>3763:R,m<1443:A,R} +kkt{a>3472:A,a>3382:A,s>2345:A,A} +xcj{s<881:A,R} +hqh{m<502:R,s>575:R,a<3429:lgf,vbx} +tfn{x<1411:R,A} +dst{a>3822:R,m>1505:A,R} +ftt{s>1217:A,a<3222:R,A} +rhj{s<3065:A,m<3720:cjh,nv} +rn{m<2545:R,a<457:R,a>540:R,tfz} +zj{m>1037:A,m>471:dsf,x>3609:R,rm} +fn{x<1616:ck,x<1634:R,R} +dcg{x<3587:R,A} +vbq{s<3443:R,R} +vs{s>3829:A,x>1496:A,m>721:R,R} +zrl{m>712:jd,pxm} +lk{a>3868:cvn,vr} +sm{x<753:cc,kdf} +dx{x<387:R,x>406:R,s<1958:A,R} +qp{s>1439:R,x<2270:R,x<2617:R,A} +hzb{m<2387:cg,tt} + +{x=1353,m=3037,a=1714,s=2238} +{x=608,m=1974,a=1157,s=1316} +{x=1225,m=1440,a=80,s=1364} +{x=4,m=1245,a=948,s=147} +{x=30,m=2538,a=1716,s=823} +{x=626,m=128,a=1042,s=519} +{x=182,m=87,a=1114,s=123} +{x=3097,m=2262,a=60,s=505} +{x=700,m=1844,a=30,s=185} +{x=88,m=2157,a=39,s=1966} +{x=703,m=305,a=704,s=1759} +{x=400,m=1034,a=1947,s=1104} +{x=27,m=1959,a=87,s=1404} +{x=1654,m=351,a=1498,s=605} +{x=546,m=629,a=1120,s=776} +{x=1467,m=1402,a=2819,s=652} +{x=395,m=710,a=37,s=426} +{x=165,m=986,a=3316,s=3628} +{x=119,m=2580,a=477,s=1134} +{x=4,m=44,a=760,s=216} +{x=1633,m=3445,a=1494,s=1396} +{x=670,m=1082,a=708,s=290} +{x=2566,m=2148,a=99,s=3038} +{x=107,m=1631,a=2,s=293} +{x=2292,m=984,a=3360,s=124} +{x=2624,m=501,a=1111,s=1114} +{x=1217,m=1508,a=2880,s=1744} +{x=1705,m=623,a=271,s=3} +{x=3043,m=25,a=2091,s=1193} +{x=1566,m=53,a=418,s=6} +{x=1438,m=255,a=1726,s=1265} +{x=77,m=326,a=486,s=795} +{x=31,m=836,a=596,s=327} +{x=477,m=1056,a=1680,s=2268} +{x=898,m=647,a=66,s=244} +{x=3627,m=2071,a=96,s=625} +{x=1149,m=1690,a=79,s=237} +{x=710,m=847,a=2859,s=618} +{x=20,m=1793,a=1189,s=207} +{x=10,m=337,a=1006,s=127} +{x=184,m=113,a=945,s=1385} +{x=913,m=448,a=458,s=384} +{x=1236,m=181,a=1480,s=273} +{x=3386,m=4,a=297,s=2045} +{x=106,m=846,a=1723,s=415} +{x=1888,m=1035,a=375,s=17} +{x=496,m=3286,a=1123,s=225} +{x=1322,m=104,a=670,s=584} +{x=544,m=293,a=14,s=350} +{x=3419,m=469,a=3627,s=594} +{x=447,m=78,a=518,s=479} +{x=2602,m=700,a=536,s=1356} +{x=956,m=95,a=1599,s=492} +{x=1,m=1709,a=117,s=141} +{x=83,m=1970,a=143,s=411} +{x=479,m=1316,a=1129,s=953} +{x=1389,m=1084,a=1747,s=1196} +{x=792,m=1456,a=3617,s=278} +{x=306,m=2611,a=1080,s=601} +{x=310,m=118,a=2829,s=2395} +{x=249,m=295,a=1027,s=1016} +{x=117,m=793,a=935,s=2867} +{x=266,m=32,a=164,s=286} +{x=71,m=1881,a=474,s=223} +{x=519,m=1971,a=390,s=713} +{x=530,m=1052,a=826,s=732} +{x=2082,m=3165,a=1378,s=2921} +{x=281,m=2172,a=687,s=1294} +{x=822,m=217,a=322,s=540} +{x=53,m=2695,a=3592,s=63} +{x=323,m=219,a=1463,s=65} +{x=41,m=248,a=774,s=1178} +{x=641,m=155,a=1850,s=53} +{x=1305,m=253,a=2104,s=404} +{x=2832,m=2439,a=893,s=996} +{x=3936,m=107,a=419,s=221} +{x=1350,m=2275,a=42,s=856} +{x=1405,m=360,a=1360,s=1224} +{x=1558,m=488,a=2624,s=1172} +{x=2773,m=515,a=1302,s=115} +{x=240,m=1969,a=1655,s=164} +{x=105,m=2654,a=709,s=2241} +{x=140,m=1403,a=299,s=145} +{x=1173,m=747,a=121,s=1231} +{x=826,m=2987,a=931,s=658} +{x=752,m=8,a=3101,s=129} +{x=1980,m=131,a=1929,s=2282} +{x=433,m=2,a=1493,s=1029} +{x=104,m=317,a=856,s=1780} +{x=116,m=2665,a=584,s=835} +{x=1988,m=283,a=2314,s=569} +{x=270,m=381,a=308,s=369} +{x=1058,m=360,a=75,s=872} +{x=359,m=906,a=1329,s=144} +{x=1920,m=533,a=1340,s=63} +{x=713,m=133,a=332,s=2928} +{x=345,m=2121,a=493,s=1699} +{x=177,m=711,a=86,s=601} +{x=1141,m=890,a=2322,s=3109} +{x=52,m=189,a=1216,s=2289} +{x=671,m=13,a=14,s=783} +{x=2194,m=312,a=343,s=1076} +{x=895,m=768,a=634,s=679} +{x=294,m=2318,a=1300,s=434} +{x=72,m=59,a=1540,s=166} +{x=248,m=2740,a=183,s=1876} +{x=1749,m=525,a=1176,s=113} +{x=1446,m=3065,a=223,s=932} +{x=1863,m=448,a=2911,s=608} +{x=245,m=1250,a=19,s=696} +{x=61,m=746,a=2942,s=113} +{x=214,m=107,a=1544,s=3227} +{x=393,m=1357,a=68,s=264} +{x=16,m=1376,a=180,s=329} +{x=28,m=793,a=234,s=219} +{x=382,m=2129,a=1963,s=1348} +{x=280,m=374,a=1653,s=961} +{x=1252,m=352,a=824,s=116} +{x=133,m=192,a=970,s=735} +{x=940,m=828,a=102,s=1516} +{x=993,m=2165,a=27,s=379} +{x=514,m=257,a=1094,s=1268} +{x=317,m=3266,a=2567,s=754} +{x=2893,m=3393,a=121,s=1018} +{x=978,m=2629,a=68,s=566} +{x=436,m=225,a=1646,s=1042} +{x=2798,m=2503,a=697,s=79} +{x=160,m=800,a=189,s=2042} +{x=80,m=559,a=1355,s=557} +{x=26,m=774,a=75,s=992} +{x=252,m=1901,a=1329,s=2136} +{x=457,m=15,a=289,s=311} +{x=403,m=1377,a=399,s=1762} +{x=220,m=246,a=367,s=2416} +{x=172,m=137,a=1004,s=843} +{x=200,m=1046,a=343,s=743} +{x=220,m=80,a=389,s=683} +{x=3094,m=1241,a=71,s=1872} +{x=92,m=723,a=4,s=636} +{x=548,m=422,a=16,s=185} +{x=530,m=3498,a=619,s=399} +{x=2100,m=160,a=1497,s=1222} +{x=723,m=70,a=11,s=1267} +{x=85,m=240,a=545,s=2591} +{x=1937,m=1470,a=100,s=2233} +{x=141,m=100,a=2327,s=484} +{x=48,m=1999,a=346,s=692} +{x=81,m=728,a=777,s=1003} +{x=135,m=1121,a=1698,s=46} +{x=2398,m=720,a=222,s=2291} +{x=798,m=523,a=3130,s=834} +{x=934,m=398,a=58,s=3629} +{x=365,m=64,a=1860,s=891} +{x=743,m=203,a=1216,s=586} +{x=562,m=2230,a=428,s=1056} +{x=907,m=2499,a=2323,s=35} +{x=895,m=64,a=521,s=1616} +{x=2335,m=1661,a=705,s=1811} +{x=3875,m=2100,a=726,s=82} +{x=478,m=3106,a=1652,s=145} +{x=394,m=1255,a=391,s=256} +{x=1074,m=306,a=110,s=560} +{x=1099,m=1158,a=2338,s=1562} +{x=1030,m=2433,a=783,s=3066} +{x=2587,m=17,a=739,s=2788} +{x=1876,m=1459,a=145,s=3440} +{x=97,m=230,a=722,s=622} +{x=2634,m=222,a=1941,s=3208} +{x=1410,m=1860,a=1561,s=27} +{x=104,m=1735,a=947,s=146} +{x=323,m=576,a=139,s=1924} +{x=381,m=20,a=1266,s=2119} +{x=287,m=154,a=524,s=69} +{x=718,m=2618,a=138,s=373} +{x=864,m=416,a=1637,s=3088} +{x=848,m=1992,a=400,s=2460} +{x=1486,m=180,a=1061,s=144} +{x=1435,m=2279,a=1417,s=2800} +{x=438,m=289,a=384,s=231} +{x=853,m=157,a=2367,s=608} +{x=1214,m=631,a=195,s=620} +{x=238,m=501,a=241,s=275} +{x=458,m=255,a=1644,s=2634} +{x=2638,m=508,a=947,s=1523} +{x=1069,m=1215,a=248,s=556} +{x=746,m=1738,a=2812,s=1901} +{x=231,m=721,a=179,s=179} +{x=103,m=234,a=808,s=1723} +{x=1818,m=2372,a=64,s=10} +{x=784,m=1447,a=483,s=188} +{x=1495,m=244,a=1788,s=1054} +{x=152,m=618,a=908,s=324} +{x=3083,m=1473,a=645,s=1293} +{x=64,m=1650,a=171,s=1497} +{x=1708,m=1167,a=1002,s=628} +{x=808,m=1930,a=1475,s=2057} +{x=1690,m=89,a=1585,s=460} +{x=2422,m=1317,a=246,s=2592} +{x=526,m=250,a=410,s=709} +{x=273,m=222,a=117,s=989} \ No newline at end of file diff --git a/day-19/src/bin/part1.rs b/day-19/src/bin/part1.rs new file mode 100644 index 0000000..f78e1e1 --- /dev/null +++ b/day-19/src/bin/part1.rs @@ -0,0 +1,243 @@ +use std::collections::HashMap; + +use nom::{ + branch::alt, + character::complete::{self, alpha1, line_ending, one_of}, + combinator::{map, value}, + multi::{count, separated_list1}, + sequence::{delimited, pair, separated_pair, tuple}, + IResult, +}; + +fn main() { + println!("{}", part1(include_str!("./input.txt"))); +} + +fn part1(input: &str) -> u32 { + let (workflows, parts) = input_parser(input).expect("invalid input").1; + + let starting_workflow = workflows.get("in").expect("no starting workflow"); + + parts + .into_iter() + .filter(|p| { + let mut current_workflow = starting_workflow; + let mut current_rule = 0; + loop { + let rule = current_workflow.rules.get(current_rule); + if let Some(rule) = rule { + let part_value = p.get(rule.category); + let condition = rule.condition; + if (condition == Condition::GreaterThan && part_value > rule.value) + || (condition == Condition::LessThan && part_value < rule.value) + { + if rule.target == "A" { + return true; + } + if rule.target == "R" { + return false; + } + current_workflow = + workflows.get(rule.target).expect("invalid target workflow"); + current_rule = 0; + } else { + current_rule += 1; + } + } else { + if current_workflow.finally == "A" { + return true; + } + if current_workflow.finally == "R" { + return false; + } + current_workflow = workflows + .get(current_workflow.finally) + .expect("invalid finally workflow"); + current_rule = 0; + } + } + }) + .map(|p| p.x + p.m + p.a + p.s) + .sum() +} + +type WorflowsAndParts<'a> = (HashMap<&'a str, Workflow<'a, 'a>>, Vec); +fn input_parser(i: &str) -> IResult<&str, WorflowsAndParts> { + separated_pair( + map( + separated_list1(line_ending, workflow_parser), + HashMap::from_iter, + ), + count(line_ending, 2), + separated_list1(line_ending, part_parser), + )(i) +} + +fn workflow_parser(i: &str) -> IResult<&str, (&str, Workflow)> { + map( + pair( + alpha1, + delimited( + complete::char('{'), + separated_pair( + separated_list1(complete::char(','), rule_parser), + complete::char(','), + alpha1, + ), + complete::char('}'), + ), + ), + |(label, (rules, finally))| (label, Workflow { rules, finally }), + )(i) +} + +fn rule_parser(i: &str) -> IResult<&str, Rule> { + map( + tuple(( + category_parser, + alt(( + value(Condition::GreaterThan, complete::char('>')), + value(Condition::LessThan, complete::char('<')), + )), + complete::u32, + complete::char(':'), + alpha1, + )), + |(category, condition, value, _, target)| Rule { + category, + condition, + value, + target, + }, + )(i) +} + +fn category_parser(i: &str) -> IResult<&str, Category> { + map(one_of("xmas"), |c| { + Category::try_from(c).expect("invalid category") + })(i) +} + +fn part_parser(i: &str) -> IResult<&str, Part> { + map( + delimited( + complete::char::<&str, nom::error::Error<&str>>('{'), + separated_list1( + complete::char(','), + separated_pair(category_parser, complete::char('='), complete::u32), + ), + complete::char('}'), + ), + |v| { + Part::new( + v.iter() + .find(|(c, _)| c == &Category::ExtremelyCoolLooking) + .unwrap() + .1, + v.iter().find(|(c, _)| c == &Category::Musical).unwrap().1, + v.iter() + .find(|(c, _)| c == &Category::Aerodynamic) + .unwrap() + .1, + v.iter().find(|(c, _)| c == &Category::Shiny).unwrap().1, + ) + }, + )(i) +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +enum Category { + ExtremelyCoolLooking, + Musical, + Aerodynamic, + Shiny, +} +impl TryFrom for Category { + type Error = (); + + fn try_from(value: char) -> Result { + match value { + 'x' => Ok(Self::ExtremelyCoolLooking), + 'm' => Ok(Self::Musical), + 'a' => Ok(Self::Aerodynamic), + 's' => Ok(Self::Shiny), + _ => Err(()), + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +struct Part { + x: u32, + m: u32, + a: u32, + s: u32, +} +impl Part { + pub fn new(x: u32, m: u32, a: u32, s: u32) -> Self { + Self { x, m, a, s } + } + + pub fn get(&self, category: Category) -> u32 { + match category { + Category::ExtremelyCoolLooking => self.x, + Category::Musical => self.m, + Category::Aerodynamic => self.a, + Category::Shiny => self.s, + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +struct Workflow<'a, 'b> { + rules: Vec>, + finally: &'a str, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +struct Rule<'a> { + category: Category, + condition: Condition, + value: u32, + target: &'a str, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +enum Condition { + GreaterThan, + LessThan, +} + +#[cfg(test)] +mod tests { + use super::*; + use indoc::indoc; + + #[test] + fn test_part1() { + assert_eq!( + part1(indoc!( + " + px{a<2006:qkq,m>2090:A,rfg} + pv{a>1716:R,A} + lnx{m>1548:A,A} + rfg{s<537:gd,x>2440:R,A} + qs{s>3448:A,lnx} + qkq{x<1416:A,crn} + crn{x>2662:A,R} + in{s<1351:px,qqz} + qqz{s>2770:qs,m<1801:hdj,R} + gd{a>3333:R,R} + hdj{m>838:A,pv} + + {x=787,m=2655,a=1222,s=2876} + {x=1679,m=44,a=2067,s=496} + {x=2036,m=264,a=79,s=2244} + {x=2461,m=1339,a=466,s=291} + {x=2127,m=1623,a=2188,s=1013} + " + )), + 19114 + ); + } +} diff --git a/day-19/src/bin/part2.rs b/day-19/src/bin/part2.rs new file mode 100644 index 0000000..afd3e2e --- /dev/null +++ b/day-19/src/bin/part2.rs @@ -0,0 +1,263 @@ +use std::collections::{hash_map::RandomState, HashMap}; + +use nom::{ + branch::alt, + character::complete::{self, alpha1, line_ending, one_of}, + combinator::{map, value}, + multi::separated_list1, + sequence::{delimited, pair, separated_pair, tuple}, + IResult, +}; + +fn main() { + println!("{}", part2(include_str!("./input.txt"))); +} + +fn part2(input: &str) -> u64 { + let workflows: HashMap<&str, Workflow<'_, '_>, RandomState> = map( + separated_list1(line_ending, workflow_parser), + HashMap::from_iter, + )(input) + .expect("invalid input") + .1; + + let starting_workflow = workflows.get("in").expect("no starting workflow"); + + let mut stack = vec![(starting_workflow, Part::new())]; + + let mut possibilities = 0; + + while let Some((workflow, part)) = stack.pop() { + let mut pass_on_part = part; + for rule in &workflow.rules { + let mut local_part = pass_on_part; + let (split_a, split_b) = pass_on_part + .get(rule.category) + .split(rule.value, rule.condition); + pass_on_part.set(rule.category, split_a); + local_part.set(rule.category, split_b); + + if !local_part.get(rule.category).is_empty() { + match rule.target { + "A" => { + possibilities += local_part.combination_count(); + continue; + } + "R" => {} + target => { + stack.push((workflows.get(target).expect("invalid target"), local_part)) + } + } + } + if local_part.get(rule.category).is_empty() { + continue; + } + } + + match workflow.finally { + "R" => continue, + "A" => possibilities += pass_on_part.combination_count(), + target => stack.push(( + workflows.get(target).expect("invalid finally"), + pass_on_part, + )), + } + } + + possibilities +} + +fn workflow_parser(i: &str) -> IResult<&str, (&str, Workflow)> { + map( + pair( + alpha1, + delimited( + complete::char('{'), + separated_pair( + separated_list1(complete::char(','), rule_parser), + complete::char(','), + alpha1, + ), + complete::char('}'), + ), + ), + |(label, (rules, finally))| (label, Workflow { rules, finally }), + )(i) +} + +fn rule_parser(i: &str) -> IResult<&str, Rule> { + map( + tuple(( + category_parser, + alt(( + value(Condition::GreaterThan, complete::char('>')), + value(Condition::LessThan, complete::char('<')), + )), + complete::u16, + complete::char(':'), + alpha1, + )), + |(category, condition, value, _, target)| Rule { + category, + condition, + value, + target, + }, + )(i) +} + +fn category_parser(i: &str) -> IResult<&str, Category> { + map(one_of("xmas"), |c| { + Category::try_from(c).expect("invalid category") + })(i) +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +enum Category { + ExtremelyCoolLooking, + Musical, + Aerodynamic, + Shiny, +} +impl TryFrom for Category { + type Error = (); + + fn try_from(value: char) -> Result { + match value { + 'x' => Ok(Self::ExtremelyCoolLooking), + 'm' => Ok(Self::Musical), + 'a' => Ok(Self::Aerodynamic), + 's' => Ok(Self::Shiny), + _ => Err(()), + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +struct ValueRange { + min: u16, + max: u16, +} +impl ValueRange { + fn new(min: u16, max: u16) -> Self { + Self { min, max } + } + + fn combination_count(&self) -> u64 { + (self.max + 1 - self.min) as u64 + } + + fn split(&self, threshold: u16, cond: Condition) -> (ValueRange, ValueRange) { + match cond { + Condition::GreaterThan => ( + ValueRange::new(self.min, threshold), + ValueRange::new(threshold + 1, self.max), + ), + Condition::LessThan => ( + ValueRange::new(threshold, self.max), + ValueRange::new(self.min, threshold - 1), + ), + } + } + + pub fn is_empty(&self) -> bool { + self.min > self.max + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +struct Part { + x: ValueRange, + m: ValueRange, + a: ValueRange, + s: ValueRange, +} +impl Part { + pub fn new() -> Self { + Self { + x: ValueRange::new(1, 4000), + m: ValueRange::new(1, 4000), + a: ValueRange::new(1, 4000), + s: ValueRange::new(1, 4000), + } + } + + pub fn get(&self, category: Category) -> ValueRange { + match category { + Category::ExtremelyCoolLooking => self.x, + Category::Musical => self.m, + Category::Aerodynamic => self.a, + Category::Shiny => self.s, + } + } + + pub fn set(&mut self, category: Category, range: ValueRange) { + match category { + Category::ExtremelyCoolLooking => self.x = range, + Category::Musical => self.m = range, + Category::Aerodynamic => self.a = range, + Category::Shiny => self.s = range, + } + } + + pub fn combination_count(&self) -> u64 { + self.s.combination_count() + * self.a.combination_count() + * self.m.combination_count() + * self.x.combination_count() + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +struct Workflow<'a, 'b> { + rules: Vec>, + finally: &'a str, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +struct Rule<'a> { + category: Category, + condition: Condition, + value: u16, + target: &'a str, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +enum Condition { + GreaterThan, + LessThan, +} + +#[cfg(test)] +mod tests { + use super::*; + use indoc::indoc; + + #[test] + fn test_part2() { + assert_eq!( + part2(indoc!( + " + px{a<2006:qkq,m>2090:A,rfg} + pv{a>1716:R,A} + lnx{m>1548:A,A} + rfg{s<537:gd,x>2440:R,A} + qs{s>3448:A,lnx} + qkq{x<1416:A,crn} + crn{x>2662:A,R} + in{s<1351:px,qqz} + qqz{s>2770:qs,m<1801:hdj,R} + gd{a>3333:R,R} + hdj{m>838:A,pv} + + {x=787,m=2655,a=1222,s=2876} + {x=1679,m=44,a=2067,s=496} + {x=2036,m=264,a=79,s=2244} + {x=2461,m=1339,a=466,s=291} + {x=2127,m=1623,a=2188,s=1013} + " + )), + 167409079868000 + ); + } +}