diff --git a/src/holt59/aoc/2024/day23.py b/src/holt59/aoc/2024/day23.py index 07e201e..851ba89 100644 --- a/src/holt59/aoc/2024/day23.py +++ b/src/holt59/aoc/2024/day23.py @@ -1,7 +1,36 @@ +from collections import defaultdict from typing import Any, Iterator from ..base import BaseSolver +from ..tools.graphs import iter_max_cliques class Solver(BaseSolver): - def solve(self, input: str) -> Iterator[Any]: ... + def solve(self, input: str) -> Iterator[Any]: + connections: dict[str, set[str]] = defaultdict(set) + for row in input.splitlines(): + src, dst = row.split("-") + connections[src].add(dst) + connections[dst].add(src) + + if self.files: + content = "graph G {\n" + for row in input.splitlines(): + src, dst = row.split("-") + content += f"{src} -- {dst}\n" + content += "}" + self.files.create("graph.dot", content.encode(), False) + + cliques: set[frozenset[str]] = set() + + for node1, neighbors in connections.items(): + for node2 in neighbors: + for node3 in connections[node2].intersection(neighbors): + cliques.add(frozenset({node1, node2, node3})) + + self.logger.info(f"found {len(cliques)} cliques of size 3") + yield sum(any(node.startswith("t") for node in clique) for clique in cliques) + + # clique = max(nx.algorithms.clique.find_cliques(G), key=len) + clique = max(iter_max_cliques(connections), key=len) + yield ",".join(sorted(clique)) diff --git a/src/holt59/aoc/inputs/holt59/2024/day23.txt b/src/holt59/aoc/inputs/holt59/2024/day23.txt index e69de29..6f6dd8f 100644 --- a/src/holt59/aoc/inputs/holt59/2024/day23.txt +++ b/src/holt59/aoc/inputs/holt59/2024/day23.txt @@ -0,0 +1,3380 @@ +xt-qh +dq-ci +rc-py +co-kk +vy-aw +gi-eu +ql-hh +xp-hr +kb-xu +zd-sc +fi-rl +fu-nd +nk-if +dl-lm +mt-qx +yl-gl +lu-yh +tz-pz +nv-id +qc-ng +lt-vp +pj-lb +dm-mj +ax-ch +oa-fc +ys-eo +rb-ci +az-qj +yt-mg +wh-wb +zm-di +wn-gr +xp-du +mn-fi +ds-el +uk-pw +lk-fi +wt-fu +pe-lg +pd-ly +di-do +hp-lr +nu-hr +yw-an +wy-jc +ub-rg +wx-ol +ia-fm +mn-yr +od-pa +ve-bf +bv-co +fa-kh +hu-dc +bh-wi +av-um +wl-mh +zl-zx +wq-ic +zi-xu +rq-gp +cf-yh +rf-vt +ur-gf +oq-kd +xr-yr +vb-kq +fr-qy +qd-zm +au-ma +qn-sk +sw-wq +km-vp +kf-kt +ck-lb +om-dh +wz-pi +zm-ys +ax-ww +op-ly +dm-ma +zo-dl +tx-hb +ii-en +bz-dd +rh-rr +qc-xi +rv-vr +no-im +pm-wa +br-ot +zs-sz +wy-jq +ss-qc +oi-yl +rl-hn +sl-ur +fu-vp +rx-md +bz-ox +nt-uj +em-yv +nb-dc +vg-tc +kp-pv +jb-ql +hg-hr +vk-us +pn-ca +qm-xr +oy-ha +pd-qz +en-cg +sz-gw +ut-sd +me-tj +if-kh +ip-qf +ua-co +va-kp +up-wx +lu-uc +bu-bg +ln-fl +yo-ns +tm-tt +kw-sz +dg-ru +wm-yr +py-pg +qw-hj +im-yf +um-mj +vp-nd +lc-qh +om-qc +ri-gw +iy-qx +er-qh +ks-wo +oi-pp +dg-fy +fq-tt +ct-lb +cw-sv +vs-of +nf-fa +jm-fy +py-ib +sl-pe +tx-jf +vo-nr +kl-lp +lp-yw +ry-jx +jy-zx +zx-on +js-no +vg-xw +tt-no +oc-ru +oj-yn +rg-od +nc-tc +du-vu +cg-gs +ec-oo +ki-gy +wh-mu +pr-lb +md-bw +ye-vl +pj-ct +hv-zs +kq-um +vx-un +tu-je +oq-dt +nf-kz +li-ly +co-fp +az-qw +zg-xk +fi-lp +jb-ko +jd-jo +nh-fn +co-gb +ui-me +ty-eb +ll-fs +bx-pc +tj-qm +yp-qd +wm-qm +dl-qb +se-jr +xs-dc +qj-sp +gs-xc +ve-bj +cu-ay +dg-ai +si-hk +mk-on +cu-zw +uc-gd +hq-ck +qe-gb +wz-is +de-ck +qg-yw +hu-pc +iu-ow +ls-tn +id-kl +ny-yo +oc-vq +xd-ez +pm-se +nt-xy +bv-cg +dc-yj +bv-gb +wz-st +px-hq +vu-in +vs-qa +wb-zd +zu-xm +en-pq +hj-ce +ti-vs +uq-kb +ga-zs +er-as +vd-lx +bw-ga +zj-hc +cm-fc +wc-yz +hq-ct +hk-tm +wx-bz +di-yp +ng-xi +ee-lp +ci-uo +ow-vw +ip-st +xu-cs +qo-ue +gy-ll +wu-ws +um-rj +qc-iv +vz-hx +qy-ov +gi-ve +gn-qc +bn-xe +ns-va +dx-eo +pb-qk +zt-tf +vt-pn +ut-ej +rw-tn +kq-un +og-sb +xm-pg +vm-im +qt-ty +au-rj +ed-ko +oi-cb +uc-yh +sc-gt +iy-lk +kz-cl +nh-it +cn-hv +bf-gi +la-gf +xq-co +cg-pq +af-up +ft-yr +vz-mh +vm-am +rb-za +nv-db +wb-sg +yq-fq +ki-ij +vd-sy +gl-iw +po-je +rl-qx +gl-hs +tf-cy +zx-oo +aq-ea +ap-jk +sk-mj +nf-ge +cy-ob +sk-dm +wc-pw +xt-wo +kf-ds +nt-xm +tx-wn +us-dw +kd-hz +kl-kp +lt-aw +sh-fm +uc-uu +ww-hz +aj-ln +ly-jl +xn-hw +dk-ip +es-mx +wi-bn +km-ke +sh-ia +wr-fh +oy-og +es-ju +pe-rr +qd-az +ol-dd +ik-dl +si-tt +wn-fa +hv-hy +bc-wu +wm-wr +le-hc +pr-fb +dt-is +mz-yv +zk-aw +hh-mh +jt-nt +hr-ho +br-cm +ed-hh +en-xc +hu-nb +tx-th +cv-sh +rh-qk +hg-ot +dd-ux +jo-ea +vb-dm +yf-cj +dt-hw +yb-xe +sy-gp +yo-qh +rf-ca +hb-wn +ky-se +un-dm +cy-pn +ij-yt +zq-kx +qy-bf +gp-qp +ws-sb +vk-eg +de-hq +wb-ae +uj-py +mp-ty +py-xy +wq-th +ne-ru +ub-ea +it-ax +vr-ul +oj-oc +tp-lx +gl-rd +af-bz +ii-xc +zt-ci +vi-pn +hy-qc +ti-ll +od-gc +ys-lk +dl-ya +kr-ur +yj-ot +ik-rx +nt-me +dv-ly +ti-gy +sk-ld +ho-yb +db-mf +ej-sy +sp-az +ui-py +un-cw +xq-ja +jq-mp +gc-yy +ap-vb +ge-wn +gs-cr +wt-nd +so-wg +jo-vr +un-rj +sy-qp +zp-ih +er-xt +ga-hv +iw-mk +qw-pu +as-ix +vz-jb +mi-rr +li-dv +mj-ma +ey-ye +cl-ib +oq-fn +qy-oe +vw-cb +xi-gn +jl-pd +ns-cw +gf-pe +dx-iy +ch-ww +tk-mh +hr-in +fy-ru +qk-sl +bc-vg +tz-ha +wa-se +vn-pt +ih-id +je-up +fp-gb +ox-je +vx-mj +kz-me +qm-vi +si-xs +nf-tx +ft-qm +yn-zo +lg-jh +wn-jf +va-qa +hh-wl +ze-kw +un-ma +bn-vf +bf-eu +hp-fq +oe-fr +pq-gd +qg-uo +eo-mt +ai-zn +px-lr +bq-zi +ze-sz +mu-pa +ye-xu +pc-nb +qj-zm +sy-lx +ut-hs +fj-ca +is-fn +es-xo +wp-xo +fp-xq +ri-hv +vs-ij +ve-nu +bj-oe +st-qf +jz-ky +ri-sh +uy-fj +jf-fa +dt-ch +ju-gs +vr-gl +cy-rb +cm-hu +yo-va +dx-kx +jw-pj +qa-xt +hg-yv +kx-hn +ln-gd +lk-qx +ca-cv +qh-ix +rc-cl +da-ow +zq-qx +no-si +ey-kb +nk-cr +yl-uk +ok-kh +qw-ce +pd-li +mo-je +lg-la +yp-do +ic-fa +mv-zx +oi-hs +ik-pw +kh-oh +cm-gu +ae-ef +ih-lu +aj-gd +tn-wy +iv-om +kn-yf +hc-jz +wz-qf +pc-gu +ar-zd +yw-kl +pn-ia +ow-cb +pg-kz +ae-mu +cm-oa +zo-vq +bv-ji +pb-sl +ne-zo +zz-kh +uj-uy +tm-js +uj-jt +um-vx +cy-uo +pv-ms +ua-yu +vo-op +ef-vp +ef-nd +pw-qb +mt-kx +rc-xy +og-pc +bj-nu +lg-mi +hv-tl +yz-dl +kw-gw +pz-og +fx-nr +dt-eq +fs-vs +fs-gy +if-dk +cf-gd +jb-on +fp-ao +bq-rn +xe-ho +qn-vb +mx-ju +uk-yz +jm-oj +rx-pw +sw-qt +ql-vz +jv-ot +jv-nb +lp-kp +ye-kb +ow-iw +hj-zm +ci-be +ba-zo +kd-fn +ap-hk +fl-lu +ec-zk +le-zj +ee-ji +lf-if +rn-ey +wu-vg +xd-zi +vn-sb +ka-vp +vl-uq +ci-cy +vu-xp +fv-yq +jh-rr +vq-oj +rd-jx +le-zg +ho-ej +rv-pa +in-hg +zq-ys +uu-gd +gp-ej +la-kr +lb-mc +br-fc +gw-bg +hk-yf +ji-wo +qf-ok +rg-rv +pq-gs +hr-yb +mo-im +su-jc +bs-uh +az-hj +rc-ib +bc-cc +yj-qp +tu-wx +lu-uu +ja-bv +fj-xg +wc-uk +zp-ya +kc-qd +vk-tn +zo-jm +oq-it +en-ju +bh-du +sw-ge +vf-vu +ya-md +cg-mx +in-bh +cj-kn +sd-gp +af-ue +wl-gv +pp-hs +hb-fa +tk-wl +qb-rx +ry-ve +uw-lm +yj-cm +ib-jt +bd-sc +rh-gf +oe-ry +wc-lm +rp-gw +qe-co +zq-lo +ce-az +sv-ns +yw-db +as-ny +cm-pc +kq-qn +wq-nf +ti-ij +hb-ic +te-cy +mc-cj +tc-ws +mu-wb +ti-zw +wy-eg +za-dq +ax-dt +tp-ut +rw-jq +cr-ju +nk-cg +dq-de +vp-zk +qj-hj +cn-gw +se-hc +rb-uo +tg-be +br-hu +uh-ih +ua-ja +nd-uw +pn-fj +ub-vr +ah-xr +bv-wo +ne-ba +fr-ry +ah-ft +fq-qo +su-am +kr-yp +bq-ey +sj-ry +vr-gc +yn-fy +eq-ih +qz-cu +en-gs +ef-zk +lc-yo +yn-ru +tn-eg +su-qc +oy-nc +pv-an +ja-co +fm-fj +ws-ha +wa-zj +kl-ee +lx-nn +yo-xt +hj-pu +ch-is +ih-gd +vw-pp +fu-aw +qp-sd +cs-kb +ah-yr +zl-mk +it-ch +uw-km +rv-cc +te-uo +ut-nn +pq-xo +ms-db +bg-ze +mo-po +oq-is +or-ed +kc-hj +de-ct +uq-so +am-jg +iu-hs +nh-qd +zk-vy +us-jc +nk-es +kd-ch +ii-cr +qa-fm +zt-tg +dv-vo +hw-ww +vk-ty +xe-wi +xq-ks +hx-ko +el-kf +lo-iy +pi-oh +ns-xt +rq-jn +bx-cm +eu-ry +sm-fr +sc-he +cn-ri +qx-kx +of-mg +tj-wm +qf-if +wn-mi +gc-aq +cy-dq +la-sl +rn-mv +uk-ik +xk-le +oi-rd +md-bp +ij-mg +gi-sj +fh-ft +qg-lp +jh-la +ik-ya +nk-fs +vk-qt +nh-ww +uy-xg +lu-eq +he-zd +jr-xk +wq-ni +qm-fh +ql-tk +va-ny +tn-us +md-uk +km-aw +zu-ll +oh-st +tn-eb +ul-ub +ai-vd +vz-hh +gc-ub +iu-rd +ez-jz +zx-ec +ny-ol +bw-rq +sd-bw +hk-im +yb-du +em-on +wa-zg +lp-pv +ze-tl +la-qk +zu-vs +fa-gr +tg-xs +nu-fr +ki-vs +dh-ms +hn-mt +ip-oh +au-um +wq-tx +wp-mx +ly-cu +ux-ox +lf-wz +po-tu +ka-zk +ya-bp +vi-rf +qt-tn +ox-up +km-vy +yy-ul +xt-ix +vn-bd +aq-od +yw-mf +uc-fl +zu-ij +bc-nc +rb-be +cr-xo +ki-ti +xi-dh +qc-jg +me-ib +du-ow +ja-ao +ja-ji +ls-jk +uw-ke +mf-ms +fl-aj +ju-nk +iv-ng +ln-cf +ql-gv +fq-fv +aj-uh +gp-ut +ye-so +fc-zl +of-zu +gw-hv +eo-lo +hs-iw +hp-ue +hp-xo +mi-ur +rh-hq +sm-eu +nm-hc +zx-nw +jb-jd +gt-wh +lc-ny +xw-em +ki-ll +sh-ca +rg-yy +pi-if +cy-za +xn-ch +mu-pt +da-vw +bp-lm +ts-wr +qz-vo +en-ko +vo-fx +ho-du +qc-dh +jk-tm +fy-oj +fw-qo +oy-sj +ih-uu +nm-jr +cj-hk +uo-dq +kr-pb +pa-jo +zx-mk +ls-yf +yu-ib +lb-do +xs-be +uh-uc +ki-of +vq-ba +ho-vf +id-qg +sm-oe +zu-bz +xw-og +zd-wh +nd-aw +fx-dv +jg-xi +vp-uw +yp-qj +zd-mu +eo-fi +hp-kf +kz-rc +ij-zw +qy-eu +kd-dw +se-nm +kw-cn +sh-kk +wz-dk +pm-ez +en-mx +th-sw +so-bq +au-mj +kp-id +ai-ru +ad-wm +in-ho +xk-ky +rn-qb +zw-gy +tt-cj +pi-st +tm-qj +hh-gv +cb-jx +do-zm +vw-iw +ny-ix +xw-wu +zu-zw +md-ik +er-ix +pw-dl +ms-id +xu-vl +kc-qw +wc-na +eo-qx +rp-hv +tp-qp +ww-dt +cu-li +ne-yn +ds-fv +bq-ye +je-ph +xq-ki +yy-od +nw-hm +yu-qe +tc-tz +as-ci +fm-kk +eg-mp +mn-qm +pg-uj +zg-hc +tp-sy +ln-uh +ye-rn +yp-sp +eu-ov +wa-rb +wi-vf +rc-xm +xn-ww +dq-xs +sp-hc +el-bs +gn-jg +kf-yq +bw-ej +nh-is +yb-vu +mv-mz +wz-oh +wc-dl +mc-de +vf-pi +yt-vs +qz-ay +cr-cg +ut-qp +rq-lx +ur-qk +zc-lb +pv-id +eu-sj +aw-ke +pc-br +km-ef +bu-gw +sg-mu +jr-hc +tn-dw +tk-vz +zm-az +kn-jk +ur-rh +qz-jn +rg-cc +zj-se +fy-zo +uq-ye +xd-rv +rf-cv +sw-fa +oo-nw +vt-vi +mh-or +cv-fj +dv-pd +pn-fm +vt-kk +nm-cf +gc-ea +yr-ts +ry-bf +kq-rj +nm-xk +gy-vs +yb-vf +eb-us +au-av +yt-fs +gl-vw +xm-ib +hg-yb +jz-zj +rv-ub +eq-aj +ln-eq +sj-oe +jq-eb +tz-og +ai-ne +if-ld +pd-op +ao-qe +ce-zm +xo-ii +tx-gr +qb-lm +vg-og +ea-vr +wa-jr +qy-ry +tm-iy +uh-fl +jf-ni +bn-yb +ny-ns +pu-az +es-cr +aw-vp +cn-tl +qn-gt +ft-ts +oy-vg +mu-gt +do-qw +yz-ik +wu-tc +dg-zn +hh-jd +ya-uk +el-lr +sv-er +ry-bj +sv-qa +ih-uc +hz-ax +pd-fx +ux-ph +sb-vg +hy-rf +yz-tc +pp-cb +wy-rw +iv-dh +yp-kc +rh-la +xk-se +lr-ue +tf-tg +ah-wr +xe-hg +im-ap +oi-iu +rz-ej +ar-pt +dv-cu +gd-zp +kt-lr +jq-eg +xi-uo +lu-aj +jd-vz +ju-pq +ky-pm +ow-jx +ds-hp +pb-ur +qo-el +yh-gd +rq-rz +um-wy +wn-ic +gg-mg +hm-zl +gn-ss +xt-lc +qf-kh +gs-xo +nd-ke +cu-op +eg-jc +kb-vl +sc-mu +wc-qb +vw-nb +ce-qj +ha-sb +ws-bc +bu-zs +er-qa +in-xp +se-ez +st-ok +py-me +st-if +fx-cu +ua-ks +ok-ld +qh-as +qo-kf +pm-jz +au-vb +ah-ab +fs-zw +pu-yp +ke-fu +ox-po +av-sk +ne-dg +xm-kz +yr-wr +pv-ee +xn-kn +sb-wq +ne-zn +qy-br +ec-on +vf-hg +rb-tf +uk-bp +ec-nw +mi-jh +pg-nt +ax-fn +rr-fn +vp-wt +vm-iv +gb-zz +cm-jv +le-ky +hw-fn +le-pm +bg-dv +gr-vo +ru-jm +fp-ji +kc-do +pi-dk +ds-lr +ca-kk +wm-fh +fp-wo +fp-ks +se-le +ss-hy +vs-ll +sl-lg +yj-jv +aw-uw +qg-pv +et-if +gv-ed +qe-xq +jo-ub +fq-kf +tz-oy +nm-zj +mh-jb +ax-au +jq-qt +ee-ms +lg-jl +kf-fw +db-pv +nn-ej +zi-vl +te-tf +ab-te +di-qd +kc-jc +ds-fw +db-ee +kh-wz +ci-te +qo-kt +yj-br +ys-kx +xm-ui +pr-mc +oi-js +uy-kk +gi-nu +kb-zd +ef-ka +du-xe +tn-mp +rh-jh +zq-mg +jd-tk +kn-si +tj-wr +zt-te +hm-mk +cc-jo +fw-bs +gl-oi +ot-dc +hw-it +ob-tg +jv-oa +km-ka +ua-fp +yv-mv +ok-lf +bs-ue +rq-ej +vx-ma +nn-rz +ga-sz +ub-pa +lo-cv +be-zt +lt-ke +zk-lt +jf-nf +ng-vm +mt-iy +jm-yn +nv-jt +tj-ad +wg-yn +ck-ct +jr-zj +wu-sb +bu-kw +dk-kr +he-bd +jo-gc +kp-yw +yy-rv +vm-gn +ob-dx +yo-cw +su-om +ti-of +ov-gi +an-db +kw-rp +ok-dk +xw-nc +ef-aw +oe-ov +ap-no +wi-in +ne-oc +fy-ai +mi-qk +no-kn +ao-xq +aj-ss +ge-th +rb-zt +aq-yy +xt-sv +kc-di +nb-bx +uj-rc +tz-nc +qy-nu +oo-mz +vn-wh +as-sv +el-hp +dq-be +hk-ju +oj-dg +no-tm +fc-gu +cs-wg +vz-gv +or-jd +om-hy +xk-hc +lu-tg +lb-jw +bd-wh +hy-iv +qc-mt +wq-ge +wl-ql +hm-wh +zc-px +rr-qk +iy-kx +wl-ed +kq-av +vu-hr +za-zt +qz-li +jl-ay +oj-yy +ur-la +pw-md +sk-au +vo-jl +bg-qw +er-lc +oe-bf +ck-mc +mc-fb +kh-lf +ec-hm +vx-au +da-rd +ih-ln +yl-pp +tg-dq +qo-jr +ts-ad +ny-xt +dt-nh +do-sp +ib-pg +ut-rq +li-op +ls-tt +sl-rr +di-qw +di-iv +um-dm +sc-sm +oq-xn +xw-oy +lg-rh +pm-jr +gn-am +mv-oo +hx-fr +qz-dv +hn-iy +jr-jz +pz-ha +sw-jf +yf-no +hu-ot +ng-hy +rx-qy +jw-mc +gr-jf +uw-fu +nr-pd +ds-yq +pz-sb +sg-pt +gv-jb +ss-dh +br-bx +qx-dx +sz-ri +br-oa +rv-ea +mv-nw +bw-rz +fp-fx +ob-be +un-um +uq-xu +zs-cn +iy-eo +uo-tg +di-pu +nb-yj +ck-px +ot-nb +bp-yz +me-cl +dw-jq +xr-tj +ii-wp +ct-pr +hy-jg +jw-de +xd-xu +ld-qf +fq-el +nw-yv +mz-mk +mc-ct +jc-tn +pz-bc +fx-ly +sp-di +zi-cs +jx-da +pt-wb +md-qb +yh-zp +ov-sj +hq-pj +hs-ow +hb-th +wx-po +py-xm +lf-ld +pi-ip +ly-ay +da-gl +ze-le +rw-eb +ji-yu +zz-lf +ld-pi +sb-tc +ty-wy +qh-sv +li-ay +nf-hb +ts-ah +ti-lf +yh-pu +do-pu +vt-uy +jf-er +ar-wb +wl-vz +cm-dc +vo-qt +ms-lp +px-lb +wh-ar +dl-md +on-nw +ze-rp +jd-ko +cn-ze +rw-fy +ub-cc +lk-eo +da-iw +ok-jt +qp-lx +pe-kr +yu-gb +cl-nt +ts-ab +ge-jw +wl-jd +du-vf +nv-kp +pb-pe +ul-od +tu-up +kz-xy +bv-xq +sj-qy +ae-he +zp-fl +ri-rp +oo-zl +no-ls +oa-gu +gc-rg +rd-cb +ua-sz +ao-yu +ql-pb +hx-gv +js-cj +lu-zp +wy-us +gu-jv +iv-jg +qe-ks +hj-sp +ft-ab +tm-si +vf-hr +vd-qp +vy-ef +po-dd +ws-pz +ol-af +nw-gy +yl-rd +he-ar +tu-ox +dc-bx +bz-je +qb-bp +su-ng +kx-wx +kp-an +gl-ow +ob-dq +mk-nw +aq-zx +yf-tt +hj-yp +ut-bw +nv-an +dc-br +na-ya +cv-uy +pp-ow +db-qg +mj-vb +hu-oa +ej-sd +gr-ic +sv-va +cf-ih +fi-zq +om-jg +gg-zw +gf-kr +mg-ll +bf-bj +hz-fn +up-mo +tl-bu +lk-dx +ux-mo +zl-yv +px-mc +xg-sh +do-ce +om-am +af-wx +zt-ob +xp-yb +oh-ld +qj-qd +lc-ix +zc-ck +ap-kn +lk-rl +ed-jd +di-ce +zk-uw +hz-nh +md-na +da-yl +si-ap +ty-jq +ia-vi +on-mz +dm-rj +el-ue +zu-gg +xw-tz +xc-ju +lt-wt +op-jl +ds-kt +tc-bc +nv-kl +ic-nf +th-gr +ni-hb +fa-tx +ny-cw +ys-dx +xo-mx +cs-vl +av-qn +ni-fa +oq-ax +vn-zd +wz-ip +zn-zo +ad-fh +si-im +yh-eq +id-yw +ul-ea +rl-eo +vt-ca +bp-dl +mz-jy +vd-ut +xs-zt +jh-sl +wu-ha +su-xi +ty-jc +kt-el +tf-za +pw-bp +tk-hx +dm-kq +ke-wt +lm-rx +tz-ru +jy-nw +sk-ma +yy-pa +th-fa +kz-ui +ws-xw +lk-hn +fm-uy +wg-rn +ic-th +ap-tt +bg-tl +xy-av +tu-af +gp-rz +li-rj +ms-kl +vt-xg +rv-aq +ok-ip +wb-vn +xn-it +pb-la +qg-an +et-px +xd-ye +ty-xo +og-ws +gv-ko +eb-et +hn-eo +jh-gf +jm-dg +gf-mi +uo-be +ho-bn +sw-ni +wx-ox +sp-kc +ty-us +uy-vi +an-ms +pj-ww +lf-oh +bz-ph +kt-fq +ib-xy +ed-ql +ki-fs +hw-ax +sv-ix +pb-rh +un-av +mg-vs +hj-do +tj-ft +ko-hh +xg-fm +wq-jf +vq-ru +fl-ih +kr-sl +po-ol +pa-vr +nd-zk +op-xc +vi-xg +rd-vw +jb-tk +ft-xr +pu-ce +fu-cb +or-tk +na-rx +sj-fr +he-wh +dw-eb +mk-mv +yp-ce +iw-jx +eb-wy +ez-zj +am-iv +ct-cr +uq-ey +sz-bu +vu-xe +ni-ic +yu-wo +un-sk +yv-mk +ui-uj +el-yq +rh-kr +qt-eb +cc-yy +ed-tk +ja-wo +jo-rv +kd-nh +gs-wp +sm-gi +ga-ze +rh-sl +bq-cs +zz-ok +ix-qa +pu-sp +hn-xq +wg-bq +tz-sb +ia-vt +kl-an +hg-wi +fc-yj +ct-px +yn-dg +ua-gb +xe-xp +wp-nk +ls-kn +ni-tx +jw-et +op-fx +gf-lr +ze-zs +qk-kr +bd-pt +bh-hg +hg-du +vr-rg +vd-sd +wq-fa +sk-vx +af-po +nd-vy +jk-no +ov-fr +wm-ah +gt-vn +qm-ab +sl-gf +nc-ha +mf-ee +vu-ho +qb-uk +ve-sm +fb-jw +nr-jn +sm-ov +wc-md +kc-az +zz-wz +xm-xy +et-lb +pt-vq +kp-mf +pv-az +yt-hb +ae-ar +pa-aq +sy-nn +ds-dm +mp-jc +jq-sl +yo-ix +wi-sg +xu-ey +hc-pm +ii-pq +za-uo +zn-oj +du-hr +hm-jm +bw-lx +hv-sz +om-ka +zt-mo +qe-ji +ab-xr +iw-iu +wp-cg +uh-uu +eo-zq +ya-wc +pv-fj +mv-hm +nh-ch +nc-da +ad-mn +ye-wg +gl-cb +gu-br +im-tt +pb-gf +rf-fj +su-iv +nf-ni +ca-fm +in-bn +pe-ur +hw-oq +ye-cs +xs-rb +or-vl +lu-ln +bz-tu +ol-mo +ng-jg +im-js +cw-as +lu-uh +ke-zk +bh-ub +ib-uj +yw-gw +oh-ok +fv-fw +vd-gc +on-jy +jd-mh +ld-st +zs-ri +gt-pt +ss-su +kt-yq +ik-yb +xi-ss +yr-nr +oh-qf +uk-dl +jx-pp +it-ja +bw-tp +gy-zu +af-ux +st-lf +xe-cs +rv-ul +of-gg +kd-it +od-ea +tx-ge +su-hy +dg-ba +ma-gg +ob-tf +bx-ot +la-mi +kt-fw +qk-pe +jk-js +ej-lx +cc-vr +bn-hg +dh-vm +hp-qo +pg-cn +wo-co +ot-pc +jg-dh +zi-rn +om-vm +it-fn +po-uy +ws-tz +de-zc +mh-ko +wo-gb +li-jn +cc-gc +nu-sj +ww-kd +uu-ln +xn-hz +hy-vm +xy-ui +fc-bx +el-fv +jr-ez +yj-oa +nh-oq +gv-tk +zq-hn +pp-da +xw-tc +wr-ao +us-mp +ga-bu +fn-xn +aq-cc +ap-ls +fq-mp +wm-bu +sh-vt +bz-up +vu-bh +qd-ce +zq-dx +md-yz +ny-er +is-hw +ue-fv +zg-zj +jw-ck +ej-qp +zl-ec +of-fs +pw-ea +ck-ve +pi-lf +jx-vw +na-qb +yh-fl +yv-hm +wc-rx +rv-od +de-px +fc-pc +sl-mi +eu-rg +xp-vf +as-xt +wx-dd +ba-zn +fi-qx +cm-nb +eb-eg +eq-cf +hs-vw +pq-es +zd-pt +bc-oy +lk-mt +ci-za +pg-xy +ks-gb +mv-em +ay-op +ma-av +oq-ic +yr-ab +jv-wc +jl-fx +pg-ui +zp-uu +si-ls +ec-mz +tl-be +nu-sm +bg-cn +hy-gn +fb-zc +lc-hn +sc-ae +te-be +wt-in +ov-bj +xp-bh +dg-zo +xo-cg +yq-qo +ax-xn +bn-bh +lm-ya +nt-kz +kb-bq +xr-wm +lp-mf +am-ss +id-mf +nk-ii +bw-sy +jg-su +rc-mi +ng-dh +oe-ba +rf-xg +pj-et +sg-bd +ey-zi +et-zc +ji-ua +ve-sj +fi-lo +ca-ok +cj-si +fv-lr +cg-es +us-st +fr-bf +ru-ba +ka-aw +ks-ji +ah-tj +db-id +ka-ke +yh-ih +lk-zq +fx-ay +ln-vk +rp-zs +tx-ic +hk-no +mv-zl +mj-ic +fi-dx +sw-nf +jb-hx +lt-od +kc-ce +ah-qm +dg-oc +sg-wh +lt-km +rf-fm +eu-nu +dc-gu +qw-qd +nu-ov +vu-mh +js-tt +et-mc +ky-zj +cm-bd +ky-hc +bs-hp +vt-fm +pe-rh +fc-hu +le-jr +kt-hp +dw-mp +jf-xg +ox-ol +qt-us +rg-ul +wh-pt +sm-qy +dg-vq +bv-yu +fy-ba +cv-vt +of-kw +gv-or +vm-xi +gd-fl +ne-up +rp-tl +ej-tp +ao-ks +mx-nk +cf-uh +po-up +cc-ea +ey-cs +cv-fm +ar-mu +yq-lr +iw-oi +cv-vi +jh-gs +fj-kk +dm-av +vy-fu +kr-lg +ye-zi +mz-zl +oo-yv +jn-vo +la-rr +fr-gi +pe-jh +be-za +hc-ez +cw-ix +bj-sm +lf-ip +oa-pc +xy-uj +wr-ab +ma-um +ko-wl +ea-yy +cy-zt +js-si +pj-zc +ej-vd +wy-vk +wa-ky +ld-wz +ba-yn +mo-af +zc-dh +cn-bu +gp-vd +wr-xr +mj-kq +on-yv +mf-an +mo-dd +qt-rw +zg-jr +yf-pe +zw-mg +bg-ga +jl-nr +qz-ly +je-ol +qh-cw +em-mz +qh-cl +pz-nc +ft-ad +le-jz +og-wu +zk-wt +lc-as +bf-vy +je-dd +hw-ch +mi-pb +hk-tt +wa-qk +fb-lb +jb-hh +dl-rx +pv-yw +ey-so +wp-th +nd-ka +fu-km +wi-vu +kd-xn +va-er +ja-gb +or-jb +ib-kz +wl-hx +jd-hx +km-jv +ti-fs +gv-mh +ay-ia +up-ph +pu-zm +wm-ft +fb-de +ho-jm +fl-ox +ni-gr +nd-ha +ih-aj +tj-ab +wo-ao +ed-hx +ub-od +ds-ue +yu-ks +kl-pv +nn-tp +pq-nk +bx-vz +bg-kw +ty-tn +tf-xs +za-xs +rl-mt +yh-uu +aj-eo +tj-fh +pq-xc +au-un +jo-ul +af-je +oj-ne +kq-sk +th-jf +rr-gf +lr-kf +hq-et +mo-wx +oh-dk +kb-wg +hb-wq +cw-lc +gi-ry +wo-ua +sd-nn +zn-jm +qe-tx +ve-fr +jc-jq +cc-ul +ae-vn +sb-nc +ul-aq +ya-qb +uy-ia +en-es +tj-mn +ni-ab +th-wn +ls-js +xp-hg +xo-en +zd-gt +mk-ec +pj-pr +ts-qm +vb-un +yz-pw +so-vl +qx-lo +zz-qf +tt-jk +zd-bd +jn-dv +sk-vb +pj-px +vk-rw +ao-bv +mx-pq +hb-gr +rp-ga +ub-yy +zk-km +ph-pm +ki-gg +nw-zl +qg-ee +pi-kh +bc-tz +md-oo +vg-ha +ad-qm +mn-wr +jm-ai +fq-ue +kw-ri +he-pt +ov-gp +wx-ux +dw-qt +pu-qj +rq-qp +rr-kr +vg-ws +em-hm +vf-bh +oh-if +qc-am +rj-sk +yn-ai +gn-fw +lm-pw +qg-mf +aj-uu +rn-vl +nd-lt +qk-jh +as-qa +xs-te +ed-mh +gp-lx +dt-fn +oq-hz +rq-vd +rc-jt +pu-qd +ai-ba +es-vx +px-jw +um-qn +wp-xc +yu-co +fq-ds +uy-ca +nb-fc +vz-ed +tp-vp +am-xi +cw-va +py-jt +kx-lk +sg-he +or-wl +rz-lx +sg-ae +uq-zi +yo-as +jt-me +uw-ka +zp-eq +qa-yo +bx-jv +ij-fs +cf-uc +ue-fw +oo-jy +qb-ik +or-ko +zu-fs +zx-mz +zz-ld +hw-nh +vk-dw +mp-rw +mj-rj +yl-jx +jz-zg +lc-ns +st-kh +dl-na +dv-ay +su-vm +zn-fy +kc-qj +hn-dx +gl-jx +wp-pq +au-qn +xu-wg +yn-vq +js-hk +dq-rb +wb-lx +ve-oe +mp-qt +gr-wq +tl-ri +hh-hx +sd-rq +og-nc +zg-ky +ui-cl +se-jz +cb-hs +zc-ct +rq-tp +on-gi +ju-cg +bq-bc +ip-zz +bf-sm +eq-uh +bs-lr +qx-zs +kp-db +gd-lu +jc-rw +wt-km +bj-kt +yn-zn +vw-oi +fy-oc +if-wz +xq-wo +ru-oj +jg-ss +un-mj +mh-hx +ea-rg +mf-nv +ww-is +cy-xs +ve-eu +ng-om +cl-pg +vo-li +yj-pc +eg-qt +ll-zw +rl-zq +xd-so +vy-ba +dm-qn +is-kd +fp-qe +vu-hg +oc-zo +nv-ux +ua-xq +lt-hz +bg-sz +ot-oa +lp-db +gc-ul +xk-pm +bw-qp +qk-gf +pa-cc +uu-eq +ft-mn +ge-gr +bc-ha +ks-ja +rg-pa +da-oi +sj-sm +ls-cj +le-ez +eg-us +xk-ez +jh-kr +yr-tj +iu-vw +co-ji +ds-qo +yb-in +zs-kw +mx-cr +yz-lm +zk-fu +nn-rq +ik-bp +jt-ui +mj-qn +ui-rc +cn-rp +ef-wt +pj-de +mh-ql +ga-tl +ms-yw +ww-oq +bg-hv +va-ix +zu-ki +tu-dd +rw-dw +dv-nr +vi-sh +jw-zc +so-rn +wu-tz +bu-hv +oc-ba +cy-be +hh-wh +vp-ke +ld-kh +pn-sh +qe-ja +ys-iy +tf-az +ts-fh +ii-ju +jv-br +kk-ia +ux-po +nn-mz +ve-xu +kp-ee +rd-he +ux-bz +fw-hp +oy-ws +ph-mo +ts-jy +dc-jv +fi-ys +av-rj +hs-jx +vx-av +tu-ph +rj-vb +te-rb +ot-cm +vx-qn +pw-na +sw-gr +fv-bs +ye-vt +zc-hq +gu-yj +ha-tc +kb-xd +af-dd +sd-sy +ef-fu +bp-na +vg-pz +lc-sv +qw-qj +xu-rn +gt-wb +js-yf +hm-mz +hr-xe +as-ns +zt-uo +sd-tp +nr-qz +ju-xo +nr-li +vi-fm +py-nt +so-kb +nk-xc +px-pr +fy-vq +yl-vw +cl-xm +ge-fa +fc-lk +fi-iy +na-uk +jx-oi +ae-na +bd-ae +uk-rx +he-vn +ma-qn +zw-yt +kn-tm +bc-xw +hy-am +uq-cs +vy-uw +vy-ke +kk-cv +je-ux +xk-wa +jl-li +pn-rf +jk-si +yo-er +jg-je +pw-ya +nw-mz +lg-qk +fb-ct +ti-yt +er-cw +ux-ol +qc-vm +em-jy +wa-jz +vd-nn +zg-ez +ko-tk +lc-va +xg-kk +ch-hz +cn-ga +zz-dk +ny-qa +oh-zz +dk-qf +rz-sd +nk-en +rp-bu +wg-xd +bg-zs +ni-ge +ct-jw +pd-py +gt-he +ia-rf +of-ij +bn-hr +bd-wb +ai-oj +zg-se +og-ha +xt-cw +ln-yh +jl-qz +zw-of +tf-be +ln-zp +pa-ea +zm-yp +sw-tx +fs-mg +fl-eq +cw-qa +ua-ao +ik-lm +yl-iw +aq-jo +ki-yt +xw-pz +oc-yn +ol-bz +im-ls +fj-vi +wn-wq +lb-hq +ab-fh +og-tc +hj-qd +cr-wp +xi-om +ty-rw +fr-eu +vk-mp +ca-vi +zp-uh +kx-fi +cl-py +eu-bj +nt-ui +ts-wm +cv-xg +ko-vz +bw-gp +di-az +vq-ne +rn-cs +rz-tp +pg-rc +pg-me +lt-ef +ji-xp +so-aw +zn-oc +wt-uw +vp-vy +cf-lu +xr-ad +sh-rf +fc-ot +ll-pn +gg-gy +rz-sy +jl-jn +nc-wu +co-ks +zj-xk +sg-vn +tp-vd +oj-zo +ae-gt +it-hz +wg-zi +hs-yl +ic-sw +vl-wg +tu-rp +sw-wn +xd-bq +ns-ix +kq-vx +gy-mg +wb-sc +ib-ui +ax-nh +zn-vq +uu-ur +wn-nf +ed-jb +ob-rb +yw-ee +um-vb +xn-is +dk-ld +fb-et +kn-js +uj-xm +bn-du +bp-rx +vg-nc +el-za +sp-ce +mg-ti +mt-zq +jz-nm +ms-kp +kp-qg +bs-kf +yb-wi +zs-gw +dg-gv +ab-wm +pm-nm +nn-gp +xr-fh +pt-sc +vb-av +oj-ba +nt-rc +ql-ko +aj-uc +fq-fw +rz-vd +eg-zj +uo-tf +ut-rz +ty-dw +hz-hw +ti-zu +bs-qo +vf-in +da-hs +dx-mt +zz-if +vq-jm +mu-vn +nv-ms +dh-su +cr-pq +ct-et +um-sk +uj-kz +xd-ey +ce-da +th-ni +ls-hk +ns-ri +za-te +eg-ty +tl-kw +nk-gs +vy-wt +cy-tg +es-gs +nf-th +bn-vu +ph-ox +la-pe +ar-vn +yq-bs +kf-fv +iu-tk +gt-ar +aq-rg +ri-bu +lf-dk +uq-hu +gb-xq +aj-cf +gu-ot +kl-qg +kn-hk +vs-gg +on-mv +mo-ox +dd-ph +bq-vl +kd-dt +me-xm +bn-xp +zl-on +uq-wg +av-mj +or-hx +xn-nh +jn-pd +kq-au +yq-hp +zd-ae +hb-sw +am-ah +kx-eo +pr-qn +em-mk +oa-bx +ij-xr +mk-oo +hz-is +wp-en +zi-so +gl-pp +rl-kx +qx-hn +uh-yh +ic-ge +sz-rp +bh-hr +cl-xy +jl-cu +sh-uy +aq-ub +xi-hy +pp-iw +pn-cv +mt-ys +pi-qf +dc-oa +ys-qx +bf-sj +yz-na +zn-ru +qh-ns +sc-vn +qo-lr +bx-hu +jb-wl +fx-li +ib-nt +ky-jr +mv-ec +sy-or +it-is +wc-bp +jn-cu +gn-su +ru-zo +ql-or +nr-op +fb-px +ch-oq +uq-rn +pz-tc +hh-or +lg-gf +hw-mx +kd-ax +zl-em +zp-cf +ci-tf +am-dh +ij-gg +wh-sc +sg-gt +yt-db +wu-an +sz-tl +ho-bh +ma-vb +dw-wy +hp-fv +oh-ix +im-kn +ho-wi +ey-wg +ww-fn +mn-xr +uc-zp +ph-wx +iv-ss +vf-xe +ns-qa +rf-uy +sc-ar +dt-hz +zs-tl +ci-ob +uh-gd +vo-ay +ux-up +jh-ur +tj-ts +wl-lm +fb-pj +bj-fr +yr-ad +wz-ok +ni-wn +qe-ua +ca-xg +sv-ny +ey-cb +bz-po +vi-kk +cc-od +gg-ti +yp-qw +ws-nc +ay-jn +pd-cu +ab-mn +me-xy +wx-je +xc-es +qy-bj +it-kf +dd-up +tg-te +mu-he +ji-gb +eg-rw +cf-uu +jl-dv +gr-nf +ij-ll +mf-pv +iu-yl +ap-js +zg-no +iu-pp +hb-jf +bd-ar +iw-rd +yz-rx +yo-sv +cs-xd +ap-cj +dv-op +hm-oo +fx-qz +yq-yp +jy-ec +uc-eq +az-do +mn-fh +ws-bn +ii-cg +zj-pm +ki-zw +eg-dw +et-de +jy-zl +lc-qa +bh-yb +lr-fw +vo-cu +hq-fb +xg-ia +rj-vx +xq-yu +fj-sh +pm-zg +cj-im +id-lp +ze-ri +yr-qm +wi-du +yo-ly +ez-ky +vg-tz +oc-ai +mt-lo +od-vr +ly-jn +sd-pz +tt-kn +kz-py +kq-ks +gi-qy +ze-gw +ka-fu +ha-xw +ss-ng +pj-mc +vq-ai +ka-lt +qp-rz +gb-ao +of-ll +jc-dw +zm-sp +ft-wr +jt-kz +yz-ya +vg-ed +te-dq +zt-dq +hn-lo +pg-bp +nv-lp +zq-iy +fw-el +em-ec +sy-rq +rl-dx +va-xt +uu-fl +xk-rl +zc-mc +ov-ve +kf-ue +od-jo +ez-wa +em-nw +og-bc +ur-lg +sp-qw +hs-rd +ip-ly +yt-gy +jc-vk +sg-zd +jm-oc +bz-mo +ck-pr +xg-pn +vz-ke +lm-uk +jo-rg +ll-yt +tc-oy +ia-cv +tf-dq +gv-jd +dt-xn +dd-hj +op-qz +pb-jh +yf-jk +lb-de +mn-wm +pz-wu +lt-fu +sy-ut +ga-kw +do-qd +nm-le +rd-pp +nb-oa +bv-fp +zx-em +jd-ql +la-un +gd-eq +ry-nu +pr-jw +lo-rl +mg-zu +jy-yv +tg-rb +pa-gc +tm-cj +tp-gp +fq-bs +jt-cl +qo-fv +ee-nv +yf-si +ka-vy +mk-jy +vx-vb +ip-kh +gy-ij +gu-nb +up-ol +di-qj +ww-it +lo-ys +mn-ah +ls-tm +ec-yv +jo-yy +in-xe +pa-ul +pr-de +wr-ad +bj-sj +dc-pc +zg-nm +br-nb +nv-qg +lx-ut +uw-ef +ow-rd +me-rc +am-ng +qe-wo +oa-oc +em-oo +ma-kq +qh-ad +om-ss +an-ee +jc-eb +jx-iu +hu-gu +ao-ji +ee-id +jy-mv +dk-kh +wb-he +rp-bg +ap-yf +gi-bj +ay-nr +fj-ia +pr-jz +ah-fh +jg-vm +ja-yu +sg-sc +ka-wt +ld-ip +qf-fv +mu-bd +ya-rx +ck-et +cb-iu +uc-ln +jz-xk +en-cr +sb-xw +pz-oy +nr-cu +vr-aq +cr-xc +ri-ga +ga-gw +ao-co +wi-hr +ql-hx +so-xu +uq-xd +kx-lo +ge-hb +gl-iu +qh-ny +kt-ue +kk-pn +ob-xs +as-va +nv-yw +uw-lt +yt-of +ng-ky +ci-tg +tg-za +yy-vr +kd-hw +ux-tu +fy-ne +wr-qm +ad-le +jk-hk +ki-mg +ky-nm +xy-jt +tu-ol +aw-wt +oo-on +cg-xc +xc-xo +lx-sd +dc-fc +cn-sz +us-jq +cb-yl +bx-gu +gw-tl +ox-af +kt-fv +ch-ui +sm-ry +vl-xd +tm-ap +rj-qn +eu-oe +hh-tk +ol-ph +me-uj +rf-kk +bs-kt +ow-oi +gt-bd +mn-ts +zn-pp +ur-rr +ul-gu +ua-bv +bh-xe +rj-ma +ii-mx +us-rw +ob-za +ch-fn +iw-cb +fw-yq +jv-pc +an-id +zo-ai +ci-xs +st-dk +zz-pi +pd-vo +qh-va +pd-ay +yj-hu +ii-es +kc-pu +sg-ar +iv-gn +nu-oe +lo-dx +lg-rr +in-du +ia-ca +ik-na +wc-ik +qd-sp +dt-qz +ob-uo +gg-ll +lk-lo +mf-se +kl-db +st-zz +ov-ry +gg-fs +km-nd +ae-pt +fb-zp +ey-vl +dh-gn +ms-qg +rv-gc +pb-rr +iu-da +zw-vs +hq-jw +om-gn +fp-yu +vx-dm +qp-nn +ad-ah +zi-rz +pr-hq +vt-fj +mp-eb +vk-jq +ks-bv +bx-yj +ue-yq +kl-fh +op-jn +ob-te +qj-do +yz-qb +jn-fx +ez-nm +pr-zc +ge-jf +ze-bu +hm-jy +zm-kc +qe-bv +qf-lf +bw-nn +ii-nt +ov-bf +ck-fb +lg-pb +zx-hm +ar-sv +nu-bf +dd-ox +vk-eb +ly-nr +ef-ke +ft-tu +ii-gs +ng-gn +ck-pj +yv-zx +hj-di +is-ax +hv-ze +mx-gs +zi-kb +vm-ss +ok-pi +jk-im +ne-jm +cj-jk +uc-jk +lp-an +yh-aj +na-lm +mx-xc +of-gy +ju-wp +tm-yf +er-ns +wp-es +kw-hv +fi-mt +wa-nm +mc-hq +cf-fl +yt-gg +xi-iv +dm-au +if-ip +xu-bq +yr-fh +wy-mp +bq-uq +cj-no +xp-wi +sb-oy +cs-so +rh-mi +fp-ja +ds-bs +ys-rl +hu-jv +jq-tn +xp-ho +wa-hc +af-ph +yl-ow +mi-pe +wy-qt +ph-po +rn-kb +oy-wu +mf-kl +uj-cl +rl-iy +ys-hn +oe-gi +xr-ts +xm-jt +qw-zm diff --git a/src/holt59/aoc/inputs/tests/2024/day23.txt b/src/holt59/aoc/inputs/tests/2024/day23.txt index e69de29..3d49766 100644 --- a/src/holt59/aoc/inputs/tests/2024/day23.txt +++ b/src/holt59/aoc/inputs/tests/2024/day23.txt @@ -0,0 +1,32 @@ +kh-tc +qp-kh +de-cg +ka-co +yn-aq +qp-ub +cg-tb +vc-aq +tb-ka +wh-tc +yn-cg +kh-ub +ta-co +de-co +tc-td +tb-wq +wh-td +ta-ka +td-qp +aq-cg +wq-ub +ub-vc +de-ta +wq-aq +wq-vc +wh-yn +ka-de +kh-ta +co-tc +wh-qp +tb-vc +td-yn diff --git a/src/holt59/aoc/tools/graphs.py b/src/holt59/aoc/tools/graphs.py index e475025..35f8154 100644 --- a/src/holt59/aoc/tools/graphs.py +++ b/src/holt59/aoc/tools/graphs.py @@ -1,5 +1,13 @@ import heapq -from typing import Callable, Iterable, TypeVar, overload +from typing import ( + Callable, + Iterable, + Iterator, + Mapping, + TypeVar, + cast, + overload, +) _Node = TypeVar("_Node") @@ -116,3 +124,63 @@ def dijkstra( return preds return preds.get(target, None) + + +def iter_max_cliques( + neighbors: Mapping[_Node, Iterable[_Node]], nodes: Iterable[_Node] | None = None +) -> Iterator[list[_Node]]: + """ + Find max cliques from the given set of neighbors containing the given set of nodes. + + This is simply the networkx implementation with typing (and using a simple mapping + to avoid requiring networkx). + """ + if len(neighbors) == 0: + return + + # remove the node itself from the neighbors + adj = {u: {v for v in neighbors[u] if v != u} for u in neighbors} + + # Initialize Q with the given nodes and subg, cand with their nbrs + Q: list[_Node | None] = list(nodes or []) + cand = set(neighbors) + for node in Q: + if node not in cand: + raise ValueError(f"The given `nodes` {nodes} do not form a clique") + cand &= adj[node] + + if not cand: + yield cast(list[_Node], Q[:]) + return + + subg = cand.copy() + stack: list[tuple[set[_Node], set[_Node], set[_Node]]] = [] + Q.append(None) + + u = max(subg, key=lambda u: len(cand & adj[u])) + ext_u = cand - adj[u] + + try: + while True: + if ext_u: + q = ext_u.pop() + cand.remove(q) + Q[-1] = q + adj_q = adj[q] + subg_q = subg & adj_q + if not subg_q: + yield cast(list[_Node], Q[:]) + else: + cand_q = cand & adj_q + if cand_q: + stack.append((subg, cand, ext_u)) + Q.append(None) + subg = subg_q + cand = cand_q + u = max(subg, key=lambda u: len(cand & adj[u])) + ext_u = cand - adj[u] + else: + Q.pop() + subg, cand, ext_u = stack.pop() + except IndexError: + pass