diff --git a/day-23/input.txt b/day-23/input.txt new file mode 100644 index 0000000..ed21170 --- /dev/null +++ b/day-23/input.txt @@ -0,0 +1,3380 @@ +qk-cr +xp-qj +tt-ub +po-nu +te-cg +en-uc +mc-jp +gl-oq +xb-rr +id-by +xp-nj +fi-yy +aj-cr +xk-oi +bs-nb +dj-at +gr-ng +wz-pe +ra-ju +ru-ey +ur-qa +oz-fe +kj-vn +us-dm +gj-jg +nq-se +vy-kv +li-yd +do-tn +vb-xy +za-gb +it-jh +sw-fg +hl-fo +jj-ce +fy-sn +ol-xl +kr-ef +ux-ta +qw-ry +am-ny +xh-td +vn-lm +hc-re +iy-ki +sf-ej +lz-zc +ye-tj +st-na +nb-pm +ns-ww +xc-yv +ay-je +pl-er +zq-ww +wk-wm +iy-ua +qa-mf +up-qg +yw-yu +pt-tf +rz-va +ti-fc +op-qu +fq-hm +ka-vr +nc-fb +uy-ma +kp-vf +cy-jn +aq-lh +ct-zn +dp-pp +ir-hr +pa-ri +rr-zq +dl-oa +xs-mb +mu-jg +oi-no +is-mw +hj-aq +nt-qu +io-tn +fh-ef +gk-wx +ly-bn +at-vo +hq-og +bi-xl +az-gv +xe-ot +fc-pj +lg-le +ji-eo +hn-gq +xa-oa +lq-jm +hs-uq +yc-mu +os-pe +fd-oh +id-cx +gu-km +hc-qs +ao-tf +nd-gc +ei-fm +dg-yw +he-tj +bj-wx +kw-cg +ki-ya +dm-qr +br-ko +ah-qn +qc-he +fo-in +yc-hk +cx-ct +po-kl +ir-ek +nf-fl +xj-gy +dn-zi +ip-px +ka-st +dq-dy +ub-yq +yw-jh +ej-gv +kv-sy +tm-so +ti-mx +de-te +fc-kt +bb-zs +qy-fs +yu-it +ha-qz +fr-kj +uo-gg +zc-bp +wg-tt +pl-mf +kh-nq +if-kj +ey-ku +mc-yq +yh-bu +xf-gv +te-nc +hs-qd +in-yp +wi-zu +hf-em +ku-ud +ca-ba +rk-xj +vx-ye +eg-sy +co-ec +mc-wg +wi-kg +xz-wt +mu-xz +rp-ww +jm-at +ug-eb +qz-jo +dj-sj +bb-gl +hc-on +dj-lq +qj-ml +dx-pg +vb-wh +tl-ub +ke-ek +vo-fz +ee-of +zs-oh +tp-yk +ak-yj +kj-yy +sd-du +fa-zg +nu-mb +bv-mq +zb-gb +oi-lf +qp-xo +mq-se +lo-kp +gy-rp +ac-sl +ly-yd +gg-fo +ya-ou +fz-jm +bt-ri +we-nb +je-ya +pm-gb +ei-nz +kc-rx +yn-ww +pb-nj +cy-lm +kj-iz +gk-po +up-vf +hq-zh +lc-cx +lr-qt +pr-pm +hm-mz +ww-ht +qn-uw +qq-ib +aa-oh +le-xa +mm-or +oz-fa +or-qg +cv-kz +op-fg +cp-gw +ke-jj +ew-vc +al-qm +eg-zf +ec-qu +em-bh +ig-dy +ky-ql +ab-ld +cj-ld +sd-ub +ta-nr +xm-pv +wk-fb +ka-vu +xa-fq +ji-ra +yj-pu +nt-fg +mo-ay +ef-ie +ou-pq +lr-tz +yv-vp +ja-ha +bz-js +kg-ld +ec-nt +ri-mi +rz-pm +yc-xz +as-js +ez-el +ia-aq +cp-wz +ro-us +vl-pg +ud-lu +kd-ho +qn-cj +ar-po +qj-nj +ee-qc +ui-dh +ps-tp +hg-ux +pl-gw +dp-dj +jg-bd +ek-hr +nc-mv +cc-jj +ca-nh +ly-mq +vs-ka +qy-qc +rd-lm +rz-uk +ox-dn +id-sn +lf-sy +tz-xu +yd-gv +hq-qu +ay-yj +es-ru +cp-pd +tb-na +hn-kp +gd-dx +fx-sr +pj-lk +hd-ii +jz-wc +yy-qh +gv-uy +pd-ur +yt-of +ff-ij +ui-ff +bj-dz +ig-de +gl-so +ac-ei +lr-ng +wh-tp +sx-yh +uk-ka +vy-do +ys-wz +ua-mo +rl-dw +vx-ij +ra-oy +ly-li +gf-eb +bv-xv +di-ms +vs-ym +yg-ps +te-dy +og-sz +xo-yf +jq-ze +gc-gr +rx-xc +cu-en +ry-es +np-nc +ok-ai +gm-qr +rr-yn +kv-xq +bn-uy +zi-xo +ab-ah +jq-yk +pz-fb +vz-uk +uz-zn +dl-xa +am-wk +ke-bm +wl-fb +io-xy +yj-ws +bs-fx +op-cv +mb-jm +zc-cg +xy-qz +wa-by +ky-rs +af-yu +ly-jp +yf-kl +ko-qo +dw-ry +gv-ma +ws-je +zn-hl +af-ku +gi-tp +pt-gd +fz-dj +rd-fr +ju-td +oi-ex +qt-ng +do-oi +ia-nd +qr-lv +gs-kz +hz-ns +gb-sr +hh-yh +hw-zf +oz-is +gs-dr +cr-px +oc-vn +bp-cg +mb-pp +ib-hd +bq-io +ou-ak +hf-ce +qk-fm +np-wm +pt-sa +kr-fh +ze-tu +qg-lo +zf-hl +gq-pc +ll-xm +lr-ln +tn-hn +dh-xj +ue-vu +eg-as +xf-ej +up-gq +by-zn +zj-ba +df-mr +lv-ez +wo-lg +qe-hs +hk-bd +rv-kg +ml-ku +dj-ny +pc-kp +qk-jf +em-oq +jm-vo +ew-jy +cz-pm +cn-ex +gf-ho +la-ma +kd-xh +yi-sy +xv-qb +pq-jd +fi-kj +os-pl +cv-nh +ok-bb +eq-xl +gc-qt +uh-lb +aj-xa +jj-uh +rh-na +re-sm +qk-sl +pj-xm +am-hv +eo-iu +kd-ug +hm-dl +wv-jg +hj-qz +ec-hq +pm-bs +vc-is +qa-uj +sz-nt +ou-mo +lb-hk +mt-yi +lk-kt +mb-lq +qf-wa +am-wm +ib-fs +bu-ds +ge-oa +es-hh +qz-sf +kz-ba +nb-rz +qo-ta +pu-je +lu-ml +fz-at +cv-it +op-zh +lk-hj +ry-rb +qc-fs +vo-nu +tg-sl +fy-bc +fm-gx +ys-cp +ys-os +ke-hr +li-bn +kr-sa +du-eq +ak-iy +gr-ia +yf-dn +qe-cq +kv-oi +xs-vo +cq-ag +aa-tq +ha-wf +te-zc +br-wx +sr-xp +da-qf +fl-vc +ud-lt +ai-so +ma-bn +fg-ec +oc-rd +bm-hr +lb-ke +nf-vc +wl-hv +hj-io +ox-xo +mm-up +bf-rb +xy-wh +gi-jq +gw-ur +mb-dp +tr-iu +by-sn +dg-nh +te-kw +am-fa +cp-qa +rs-jq +lo-vf +ru-ku +qs-rp +cx-by +uz-bc +mo-yj +hm-tr +pg-fr +fe-vc +hs-ri +il-kg +ya-nb +ol-gq +ey-qj +uh-hr +al-qb +wh-ja +lk-mx +al-to +ru-kf +hi-gx +ir-ql +gb-rw +lx-nc +hn-pc +mc-ub +yw-gs +ml-yz +yt-gi +dp-fz +ds-hh +ec-zh +wx-pz +gc-lr +le-tr +tr-fq +uc-lk +lv-nk +eg-js +pa-uq +gy-ip +ie-gd +tt-ol +mv-np +sz-zh +pr-kj +uh-ke +tm-oq +tj-ff +bm-jj +qj-kf +xp-ru +da-ri +bm-bh +ud-xp +mz-ye +ih-no +ps-sh +uy-xf +oc-if +cy-hn +ex-ar +sa-ef +bz-zf +ar-ox +zb-pm +qs-lw +xs-sj +ak-ay +eb-xh +ug-eo +gd-ef +ze-rs +wz-gw +vl-iv +ih-oi +rw-zb +ef-iv +nf-fe +al-bv +ms-jd +hi-px +sj-jm +cn-yf +bz-gg +po-ox +eo-xh +qg-jn +bh-ek +da-pa +qe-qd +rp-ht +ei-yg +uz-lc +hd-fs +te-dq +ps-gi +oj-hd +ln-aq +it-yw +zc-ig +ya-pu +vz-vs +ao-ef +ez-gz +rd-fi +tm-tq +ol-sd +px-nz +rr-xj +kl-sn +dr-ba +sh-rs +uh-ot +mw-bz +cc-bv +tr-dl +hi-ac +kz-dr +gs-zj +ky-yk +pl-ds +bs-sr +pp-lq +xz-jg +bu-be +mi-pa +ut-di +ry-sx +fs-oj +fx-ju +se-rc +tu-rs +fa-fl +ll-st +up-or +ou-ua +oh-wo +fa-nf +mt-sy +vn-if +wf-bq +wl-jt +oq-tq +da-bt +bp-lz +tl-iw +vg-el +dq-zc +co-nt +df-zg +pb-lt +tw-wo +ar-gk +ca-jh +he-ij +qi-cq +us-yl +zg-nf +mi-hp +fl-is +ok-mc +ha-io +px-fd +kg-ah +dw-qw +yd-xf +tv-ux +fm-sl +jh-dg +ce-bh +ei-fd +je-iy +ff-ms +sk-kw +pj-pv +sz-qu +re-uw +wo-oq +un-cr +df-mw +st-tb +wf-qz +lg-ge +dr-dg +en-xm +rb-sx +lj-fy +al-nq +no-yi +pz-yz +jq-tu +nh-jh +vb-ja +at-xs +rx-qs +sj-fz +rk-ht +dw-es +cf-hv +yn-xb +pc-up +fz-bt +su-cj +rh-ll +em-ir +dq-nw +ba-cv +lu-ey +fc-om +cu-lr +hm-xa +gy-ht +xo-dn +lf-do +jg-yc +eq-yq +we-zb +ut-jo +ej-az +nc-wm +co-qu +bt-qe +zj-jh +om-pv +sw-op +px-sl +de-lz +ax-sq +yj-ng +np-jt +nb-fx +jy-oz +tv-pz +yi-xq +wf-ja +yy-ja +yq-sd +wl-am +sz-ec +tg-cr +dn-gk +iu-xe +nu-dj +ui-ij +eb-ho +yd-jp +zg-oz +sn-wa +uc-om +ff-km +mi-ag +bc-by +mc-wd +ta-wx +zf-gg +uh-bm +tj-ms +hp-ag +cf-np +nq-cx +eq-ol +ej-bn +rx-vp +td-ra +ay-pu +qr-el +pa-qi +gv-la +dm-lv +be-ds +yf-ex +mf-er +lv-el +hi-nz +ay-fg +eg-gd +og-zh +mr-zg +zg-fe +px-qk +lf-no +hp-pa +il-sm +uo-fo +tu-sh +yq-wg +la-yd +sy-oi +hf-lb +nt-og +li-fl +bb-tq +fx-rw +ns-rk +zx-zu +ai-tm +vu-tb +ih-kv +qs-zr +cj-re +bd-mu +fg-og +gf-zs +fq-dl +nr-tv +as-fo +nr-wx +pb-ud +bi-kj +wx-ux +fq-mz +xa-in +hj-ja +ii-qy +po-xo +zn-wa +ui-ut +uz-bj +hf-ot +zf-js +gd-pg +zc-de +ue-ka +tx-bn +rs-ql +xz-km +ht-pt +fs-zx +sl-hi +wt-im +ft-sa +as-hl +ax-sw +vr-vu +rc-qm +bb-wo +jz-lz +mi-hs +xq-vy +gx-tg +ya-ua +na-ka +qm-mq +mc-ol +kg-jf +gj-im +oz-vc +pz-ko +dw-be +sj-vo +tb-vz +pr-fr +yv-zr +vy-no +ux-br +gz-ro +mo-ak +hx-xk +ph-ja +ri-qd +lv-gm +mb-fz +mw-fl +td-ux +pj-zp +oy-gf +ak-sf +kc-pi +ew-mr +ze-tx +rv-wt +mo-ya +qc-hd +ml-ud +nk-kt +iw-du +qn-kg +cf-jt +jd-vh +gz-yl +ra-eb +nw-te +qd-hp +bv-an +wl-mv +wm-hv +uz-qf +ly-ma +ee-ii +vz-ll +cp-pl +rc-zb +vu-vs +st-uk +zi-yf +nj-lt +sq-sw +yd-az +an-se +wc-sj +or-lo +vn-lh +bz-uo +so-aa +rl-pp +jt-fb +rb-be +vp-zr +pb-kf +xk-kv +zs-ok +qe-uq +ln-xu +qg-tu +ys-pd +td-jl +lr-ia +yp-fn +ws-ki +wc-vo +xc-hc +sx-ta +aq-ng +rh-ym +kp-tz +ol-wg +tg-fd +va-cz +zq-rk +ax-ec +hm-lg +ng-tz +yi-dz +fe-qj +vn-pr +fq-ge +qf-zn +hl-eg +zx-of +eg-fo +af-ud +vr-ue +gi-yg +nf-jy +ie-iv +ro-gm +tn-mm +xz-bd +uo-wm +vh-pq +fg-sz +iz-yy +xp-pb +cz-gb +ds-rl +wd-tt +rk-xb +or-jn +sq-sz +ao-sa +fa-vc +ya-yj +ur-vs +pu-iy +cg-sk +dp-wc +jz-cg +ps-ze +ps-yk +yq-tt +dp-lt +vv-lh +fg-qu +rp-yn +ey-ml +jj-ir +ge-aj +vr-ll +mz-ge +lm-fi +vs-na +xu-nd +vb-ha +lz-ig +yz-tv +ju-ho +if-iz +mt-oi +om-en +uh-ek +ki-mo +al-rc +jo-xy +xb-ip +jj-ek +ie-tf +vx-jd +qe-ag +rc-an +kl-ar +uz-fy +dm-el +yg-tu +jy-df +tz-aq +sh-tx +ll-ym +vh-ff +vr-ym +uq-qi +fz-nu +eg-fn +bh-iv +lh-az +sj-at +lc-sn +tz-lh +cu-fc +zp-pv +dl-of +nu-jm +ut-vx +fr-oc +by-ct +pd-pe +bp-jz +pi-vp +ig-nw +uy-ej +nz-ac +vc-df +hp-cq +bf-yh +bp-qi +xx-qs +qp-gk +xc-xx +yi-xk +gs-ba +em-jj +zg-vc +kr-vl +xj-ww +kg-ab +dr-cv +kr-iv +ef-pg +ny-np +nj-af +xj-ip +ip-ns +vf-or +gd-vl +up-lo +mo-ws +ca-dg +vx-vh +oz-yw +id-wa +ez-qr +qh-rd +xa-tr +bc-wa +bi-vn +kp-or +st-vs +bc-id +cr-nz +le-dl +qd-ag +di-mt +li-jp +zf-fo +pe-gw +sx-rl +id-lc +im-gu +fz-wc +gi-tu +qa-er +wi-cj +tv-qo +mf-ys +ja-yx +lq-sj +xl-wd +xb-ht +bn-wp +dy-nw +bi-pr +zj-ca +be-df +rc-nq +pb-af +dx-vl +kr-gd +gy-dh +du-yq +il-wi +ou-ws +nk-gz +yp-gg +qz-yx +ms-ui +vb-ph +vb-yx +kr-dx +bd-im +ce-ke +ww-ip +hp-bt +nd-gr +pv-lk +jf-wi +so-zs +pq-ye +tn-or +qh-if +pb-ey +uo-zf +gg-eg +ah-re +kw-de +kf-xp +ye-he +ux-ko +xj-yn +gu-rv +cp-uj +zg-mw +yh-qw +vv-ng +ti-xm +ys-uc +nb-gb +ax-sz +wf-jo +yy-pr +bu-sx +fp-lv +sl-fd +io-wh +gz-fp +tj-di +fe-jy +ti-lk +qo-wx +sn-qf +ue-rh +gl-oh +lf-fy +xe-aj +bc-ct +uy-la +yn-ip +yu-gs +ok-tw +lb-ot +qq-qc +el-ro +rw-cz +fp-qr +ih-hx +ay-sf +rx-xx +om-pj +zp-ar +mm-rx +cu-lk +fm-fd +yc-rv +ub-eq +vz-ym +vo-tv +vy-oi +ih-xk +zg-is +bt-qd +zf-fn +tj-ui +di-vh +sq-qu +rk-hf +tm-aa +dy-cg +px-ac +un-gx +ac-gx +lc-wa +os-pd +lw-ft +va-fx +kv-yi +fi-if +kz-yu +ud-qj +ac-cr +dh-ns +qw-ds +al-kh +gf-td +qf-by +we-cz +ps-ij +nk-yl +be-es +hg-fo +ru-ml +sy-ih +qg-gq +jp-az +rz-za +ek-em +pc-tn +pd-wz +fm-ac +tp-tx +qp-dn +wi-re +za-rw +hm-ge +cv-yw +lx-jt +tn-cy +wt-yc +fp-nk +sh-gi +dh-rk +df-fl +qn-ab +bb-tm +gm-dz +xk-qu +ge-tr +an-to +wc-xs +iv-gd +zg-fl +vp-hc +pq-gx +qo-dz +qr-gz +wc-dj +jt-mv +pp-at +ue-vz +iv-ao +do-xq +ny-jt +ih-yi +xe-dl +bm-zr +yy-yl +ax-hq +be-rl +xq-lf +vs-uk +ug-xh +ig-jz +xe-xa +ly-gv +jt-am +tb-rh +va-sr +dq-bp +uy-wp +xo-ar +ek-hf +rb-hh +fs-ii +gv-vl +zh-sq +id-zn +qe-ri +ie-ao +aa-wo +ka-ym +xc-zr +ub-iw +mt-no +du-mc +tb-ka +iv-pg +ds-dw +fe-mr +zc-nw +vh-tj +tm-tw +tq-ai +gz-gm +dl-rh +bs-zb +iu-le +dr-it +tf-kr +hr-hf +fy-cx +ws-sf +xo-ex +dq-kw +ug-ji +pq-vx +gg-as +bp-sk +po-zi +rd-yy +ug-oy +gg-in +ha-xy +ac-ba +fa-mw +yh-rb +gl-aa +lu-ru +cn-ar +nt-xo +po-qp +op-sq +qd-mi +mb-dj +dh-yn +qu-ax +ir-bh +rh-vu +oa-iu +qf-lj +ug-ho +mr-nf +zx-ib +js-gg +qw-rb +at-dp +wl-lx +il-cj +di-on +zh-nj +tt-du +za-pm +fd-gx +ah-uw +ff-jd +vh-ij +sh-xc +in-zf +mi-bt +cr-hi +hl-gg +he-jd +ft-rx +bu-qw +ha-hj +kl-gk +hv-mv +bn-az +oi-hx +wh-ph +sk-yp +xy-hj +ww-rk +bj-pz +fh-dx +ti-zp +nh-kz +jp-gv +ur-uj +ns-ht +jl-ra +zh-nt +cj-jf +zp-xm +ys-uj +xb-ns +ej-li +cj-ah +yp-eg +fb-lx +cy-or +zu-ii +yc-wv +ab-jf +he-vx +rc-kh +ih-zj +qy-ib +lr-lh +ln-gc +cj-sm +rz-bs +rz-rw +ek-ot +mi-cq +bb-oh +az-ly +sj-mb +fa-df +nq-cc +iy-ay +vh-ui +ll-vs +rl-ry +bn-gv +nk-vg +qm-qb +pv-ti +jn-pc +hg-wx +kf-ml +ym-vu +yz-ux +qg-kp +qu-sw +tt-xl +wz-wp +ba-jh +bu-es +xx-pi +gj-gu +ej-yd +pp-gg +kf-af +jn-kp +ps-tu +wk-hv +np-wl +to-xv +yc-im +ud-kf +ke-ot +jg-km +if-fr +km-wt +iu-mz +mu-rv +iu-fq +lw-pi +fb-am +hd-el +fh-ao +re-qn +ah-sm +fy-lc +bm-ld +wt-wv +fs-qq +bh-hr +hv-np +de-cg +ok-aa +no-xk +we-pm +fr-vn +of-fs +rk-rp +uo-as +rv-jg +ay-ua +kw-nw +wv-gj +vv-qt +ek-lb +lx-wk +qg-tn +jq-ql +ce-ek +jn-tn +fi-oc +sy-xk +rh-vr +pp-wc +sh-ze +qn-su +tg-fm +qe-hp +vf-cy +yp-hl +ao-gd +jn-up +hq-mb +an-al +kd-ju +ig-sk +qb-mq +no-kv +ri-uq +sk-dq +fc-uc +tg-ei +ih-vy +qq-yt +zh-fg +km-im +ax-zh +co-fg +of-qq +ij-ut +dm-tw +pz-ta +wd-iw +qm-nq +vh-he +mx-wg +lj-bc +wp-ma +cy-pc +jf-qn +xo-kl +es-yh +vp-on +bj-qo +lv-us +xz-wv +pv-uc +pi-qs +mw-vc +vg-ek +ox-cn +lm-kj +rz-fx +nr-ko +jy-fl +eb-un +hf-ke +rs-yg +ra-ug +qm-se +pv-fc +az-li +gr-tq +bi-iz +rd-vn +vu-ll +ia-ln +dz-wx +op-sz +eo-eb +cp-er +qf-bc +vl-tf +zu-oj +za-nb +gq-jn +kf-ey +gz-vg +ge-le +qm-to +ng-ln +tb-vr +st-ym +at-lq +az-la +uz-id +bf-es +lt-lu +ug-wv +bu-vy +va-zb +ak-ki +nb-cz +ol-wd +px-ei +mz-xa +wx-tv +yl-dm +nf-mw +mm-lo +bu-dw +tw-bb +kt-zp +gq-tn +jt-wk +it-ca +io-yx +su-ld +ho-xh +xu-vv +aj-fq +lj-lc +bb-so +be-sq +kt-pj +ki-sf +kl-dn +dx-sa +tw-gl +qb-an +zi-kl +pa-qo +mi-qi +wo-so +ms-ij +pe-cp +fx-cz +lt-qj +gd-za +pj-ti +fe-fa +it-gs +mv-ny +gu-bd +mr-xs +yt-fs +gw-os +ti-uc +ao-dx +ye-jd +so-oh +dy-jz +gi-ky +mc-tl +tq-tw +hc-pi +qc-oj +pu-sf +st-wt +nt-op +vg-qr +qz-bq +yi-lf +el-gm +us-ez +lj-zn +aa-oq +lo-pc +kc-on +ir-lb +kf-lu +ws-ua +ab-ge +oh-ai +sm-ld +zs-wo +uh-bh +vp-xx +di-vx +fq-lg +ew-df +ej-wp +rd-if +gm-yl +ng-ia +zh-sw +ge-xa +qi-ag +ys-pe +xk-xq +yq-xl +zs-ai +gk-ex +gu-jg +or-hn +ny-wl +qp-hz +hm-aj +fs-ra +gq-cy +kt-uc +xe-lg +wf-xy +ib-yt +vv-xh +an-kh +jf-il +dn-cn +cr-gx +ok-oq +sa-pg +gc-tz +lx-cf +np-fb +xz-im +bs-we +dq-cg +tl-wd +gf-kd +rv-km +jm-pp +hh-bf +sl-hr +tl-yq +zq-ip +un-sl +ma-jp +ca-kz +ko-it +xp-af +ze-ky +lw-vp +tf-fh +we-za +ie-kr +fn-in +ll-ue +zu-ib +rk-yn +km-hk +uc-xm +we-rw +dn-hz +qi-bt +ki-yj +zx-yt +sl-cr +io-vb +va-pm +vf-mm +gz-lv +br-qo +ya-ay +jh-cv +wk-np +bi-rd +uk-vu +fd-hi +tx-jq +wf-hj +ew-fa +ld-uw +pq-ms +tw-so +rk-rr +dx-tf +uh-em +gw-mf +ip-rp +ry-be +ef-dx +zn-lc +rr-ww +qk-un +pb-qj +mu-gu +il-uw +bq-jo +bd-km +ie-sa +gf-jl +hl-uo +pm-rw +kd-gz +mu-im +dy-sk +vl-pt +wh-hj +we-sr +lz-dq +zr-rx +em-ce +rw-bs +zr-on +ql-tp +hd-qq +im-jg +ub-wd +vp-qs +lq-nu +iy-mo +nj-ey +ot-em +kl-cn +cq-uq +np-id +uw-jf +iz-tq +oh-ok +tj-ij +uk-vr +ft-rw +cq-hh +zx-ee +wa-fy +ce-qy +mv-wk +hi-qk +uy-li +zj-dg +dw-rb +lf-vy +cp-os +bu-ry +ha-ph +on-rx +pl-wz +qc-zx +ag-hs +oj-ib +ar-qp +us-gz +mf-zx +ca-gs +bh-lb +dn-ex +un-px +os-va +gl-tq +vu-us +pp-xs +ta-br +gu-hk +tl-xl +ji-xh +ky-tp +fh-pt +qs-yv +ai-oq +fh-ie +ux-nf +se-cc +zq-gy +ft-xc +ey-ud +da-mi +nk-el +iy-sf +fi-fr +rd-kj +he-ui +mx-zp +qn-sm +qe-pa +ld-jf +nw-de +gx-qk +un-fm +do-mt +gs-cv +is-fe +ym-ue +iz-rd +iy-ws +xl-wg +qi-ri +em-hr +sn-uz +qh-vn +pa-ag +tr-oa +za-va +xu-yv +lw-sj +cx-uz +it-ba +zj-nh +vy-hx +oy-kd +iw-eq +jm-wc +mt-lf +kf-nj +he-pq +ju-gf +ip-rk +yv-xx +no-do +oy-ju +rc-cc +oz-df +zc-kw +dh-ip +ph-bq +nj-ku +ak-ya +sa-vl +td-eo +ao-pt +nu-at +re-kg +gx-nz +al-mq +lz-sk +ef-vl +eo-gf +zc-fa +fi-en +js-in +ot-hr +yt-qc +ct-lc +iy-yj +fn-fo +ub-du +cc-kh +iw-wg +fx-za +kt-az +fi-pr +wi-rh +bu-rl +is-hs +fb-cf +da-hp +xb-gy +wl-wk +tl-tt +uw-sj +mf-uj +ei-cr +wc-lq +gu-bb +ku-lu +ct-uz +yn-zq +hw-fn +at-wc +bv-kh +dh-ht +yg-yk +xf-ly +ol-iw +xb-ww +tv-dz +cn-gk +ko-ta +pu-jq +wz-mf +cf-wk +tz-vv +tu-ql +yl-vg +pe-pl +yk-ze +pe-qa +ro-lv +ey-xp +dy-bp +vu-na +zg-wa +va-rw +gb-bs +ei-un +cr-fd +uc-mx +cf-ny +nb-zb +mz-xe +oc-ct +cr-fm +fm-hi +mv-wm +tx-yk +sk-de +hn-qg +yq-iw +tg-nz +ms-he +at-gs +er-wz +kj-oc +ab-uw +oj-ii +px-tg +ki-ua +xf-ph +mx-pj +wv-gu +ye-di +ye-ff +kt-pv +lm-oc +ud-lc +tu-ef +op-mi +zg-jy +qp-ox +ex-zi +oq-bb +hc-yv +bf-ds +xj-xb +gz-dm +yz-ta +sr-rz +nq-xv +rh-uk +ze-xz +js-ey +gy-ns +du-ji +je-mo +dp-xs +st-ia +ky-rc +dj-vo +gw-pd +or-gq +ah-su +qs-on +yd-bn +lr-vv +yn-ht +rr-dh +aq-gr +to-bv +hw-yp +kw-dy +ux-pz +ee-yt +qh-fi +we-gb +nr-yz +ay-ki +co-sz +xf-li +bj-ko +yh-dw +ug-td +wi-ah +df-fe +ib-qc +ja-qz +nt-hq +dj-jm +dp-nu +oq-zs +xs-lq +sm-wi +ac-un +rr-ip +pe-mf +df-nf +fa-mr +nk-qr +rv-bd +og-ax +yy-oc +qq-ee +lm-fr +yg-ky +ir-bm +ph-bp +ln-nd +pt-iv +sr-cz +xf-la +qt-ln +om-ti +xj-rp +yp-js +og-co +mr-vc +vn-yy +td-eb +pv-so +eg-hw +tj-ut +cv-dg +uc-cu +yj-ou +ia-qt +rr-ht +mf-os +bf-lx +sd-tt +dl-mz +lh-ia +lk-om +gi-ql +rb-ds +hc-kc +ex-qp +lt-ru +la-wp +do-ih +qp-kl +vz-wo +xu-ia +do-hx +zs-tm +ys-qa +bt-cq +hp-zf +tw-zs +og-sw +bi-yy +rk-gy +ps-ql +yq-us +cc-xv +cq-ri +at-mb +ti-kt +dy-zc +wc-nu +hc-zr +jo-ph +pd-uj +jo-vb +dn-ar +mv-sz +ko-yz +cn-qp +qf-fy +wv-bd +mv-lx +bp-de +ub-xl +id-qf +bj-ux +ge-xe +pr-iz +fb-wm +yx-ph +cx-sn +xu-qt +cy-mm +ru-nw +se-to +pa-qd +yg-ze +ky-sh +ew-fl +vz-rh +tb-ue +vf-pc +yt-oj +qu-zh +iy-ou +vr-vs +te-sk +xu-aq +rz-cz +hz-cn +tl-wg +ys-pl +ew-zg +uc-pj +wt-mu +ly-la +is-ew +dg-gs +xc-pi +ww-su +ca-bc +bs-fc +by-lj +xl-sd +zb-rz +oj-zx +tx-ky +xf-jp +do-sy +pi-rx +iv-sa +uw-cj +mq-to +uo-hw +hx-xq +fd-un +px-fm +ld-wi +nh-vr +sx-bf +wm-lx +wa-uz +rv-hk +sw-co +xv-mq +bn-la +pg-kr +oh-tq +pd-qt +du-ol +gj-yc +ai-aa +lu-nj +ww-gy +wd-du +xv-an +fc-xm +ro-vg +eq-tt +ka-ll +yz-hg +zc-jz +dm-vg +na-ym +dy-lz +dg-it +sm-tm +lh-gc +af-lu +by-ig +wv-rv +pc-mm +lg-xa +qw-bf +wv-km +wo-tm +pv-mx +ah-il +jp-uy +du-xl +tt-iw +oc-iz +ra-ho +ln-gr +jh-dr +fg-sq +po-cn +qa-os +ib-of +ff-di +cn-xo +xh-jl +om-tg +cg-ig +cf-wm +qn-wi +gj-mu +rs-tx +fs-zu +kc-qs +ra-xh +og-sq +ao-vl +co-zh +ag-bt +qa-wz +xx-zr +zx-hd +gj-km +qd-uq +hz-cf +ln-lh +jy-mw +fp-gm +yn-gy +hf-ir +lw-hc +if-yy +zu-of +ma-li +gm-dm +cj-ab +ok-tq +ur-pe +oz-nf +tw-ai +cu-kt +ro-nk +pg-tf +iw-xl +uq-mi +qq-oj +pt-kr +vh-ye +be-sx +sn-zn +ki-pi +qo-nr +sx-hh +cx-lj +hr-lb +bm-ek +ll-tb +bi-fr +un-nz +tp-zq +er-uj +tw-aa +to-kh +su-sm +pl-ur +nq-mq +tn-vf +og-op +sm-uw +ge-wv +lj-sn +hk-qq +ra-eo +ih-mt +sf-je +sa-gd +vf-ao +al-se +yp-uo +ou-sf +hf-bh +by-lc +sw-nt +ji-kd +bz-as +qj-ru +lq-vo +lz-nw +yz-dz +lq-dp +jy-fa +pl-uj +es-qw +yn-xv +qr-ro +ct-qf +ee-oj +we-rz +fn-hl +sa-fh +xe-tr +wt-gj +eo-ho +sd-tl +ja-jo +xb-dh +uk-ue +ra-gf +iw-le +ui-vx +mr-oz +nd-ng +yf-ar +gb-va +jh-yu +jn-mm +uk-ll +rc-bv +of-qy +jm-by +qg-mm +fq-gy +ju-xh +ke-bh +jn-uy +ku-lt +xu-lr +mc-iw +pa-cq +gm-nk +rs-kf +qd-cq +jt-nc +qy-oj +nw-cg +ce-lb +tb-vs +am-lx +xh-oy +mf-cp +da-cq +hs-cq +hz-yf +hw-in +uh-ce +ri-hp +es-rb +vp-xc +ff-he +vx-tj +oc-pr +xh-gf +ig-te +zp-om +og-qu +hh-qw +lj-ct +fz-xs +cy-qg +bf-be +dm-fp +qm-kh +lz-te +dg-dn +qk-ac +tz-ln +no-xq +io-qz +bj-hg +ms-ye +bz-in +zp-en +ku-qj +ie-pg +mu-wv +ee-zu +ny-wk +ql-yg +fs-ee +ou-ay +il-qn +qa-gw +lf-hx +re-il +pm-fx +we-va +fy-rb +xm-om +gm-ez +kp-cy +sm-jf +dz-ta +fd-qk +ec-sq +ky-ps +tr-lg +ub-ol +us-nk +vu-vz +xq-mt +aj-mz +zi-ar +bi-fi +lo-jn +tu-yk +gc-ia +tl-cz +gw-ys +vb-qz +lq-kv +ok-so +hl-hw +dx-pt +mo-pu +hs-da +rx-hc +ft-on +ah-ld +uj-wz +fy-zn +ht-zq +yw-ba +hg-ko +qm-an +vg-us +jf-re +oi-yi +qw-rl +cx-bc +bp-ig +if-bi +pp-nu +vh-ms +ws-ak +lc-qf +qy-mq +lx-hv +hm-xe +qe-zi +jy-mr +qh-pr +ju-ji +pq-ut +sk-jz +ab-re +mc-sd +lr-aq +xy-ja +nf-is +wt-jg +je-ou +ps-tx +ft-pi +ll-na +br-nr +fi-iz +iz-lm +er-ys +de-dr +yn-ns +yc-gu +hr-ce +wg-ub +az-xf +qe-qi +nh-gs +tj-pq +gl-zs +fx-we +ub-ec +tq-so +nt-ax +uk-na +lb-jj +tm-gl +qp-zi +aq-vv +tf-iv +aj-oa +fx-zb +ys-ur +la-jp +td-ji +mc-tt +aa-bb +bj-yz +cc-qm +ab-su +jp-bn +im-hk +ma-yd +dm-nk +yv-kc +wh-bq +is-jy +vy-xk +tb-eq +zr-pi +an-vx +mw-fe +mi-qe +nr-pz +le-xe +qd-jh +pv-cu +kd-jl +gx-ei +wo-ai +tg-qk +up-vh +lk-fc +lh-ng +ox-gk +ax-fg +gr-vv +xx-qb +xx-on +bv-nq +oc-bi +kp-mm +ak-je +re-su +bz-fo +ct-id +ry-kz +oa-lg +hw-js +nd-lr +zj-yw +ja-io +lx-np +ct-sn +pz-qo +as-yp +as-co +ir-ke +vl-fh +ej-jp +iu-aj +qr-us +tl-du +zb-za +jz-de +hw-bz +hk-xz +gi-ze +js-uo +yk-rs +mu-hk +zu-hd +mt-ri +zp-uc +wx-yz +su-il +tx-yg +rr-rp +ws-ya +wh-ha +rp-zq +mr-mw +ya-iy +hs-hp +kl-hz +st-vr +zi-cn +ds-yh +dh-rp +tz-qt +eb-ji +yi-hx +jq-tp +td-kd +ki-pu +es-sx +xm-lk +vf-jn +ng-gc +qg-vf +gi-yk +mv-cf +hj-vb +yg-jq +pb-qp +da-qe +ue-vs +nw-jz +bq-ja +br-yz +vv-ln +ha-yx +ta-hg +hz-xo +fe-ew +lt-ey +sy-vy +kz-it +en-pj +wi-uw +kd-rd +le-aj +ct-fy +if-lm +tx-tu +bh-jj +vn-fi +wd-wg +fh-bv +er-os +hd-of +gu-wt +wl-nh +uw-kg +ia-vv +jl-ho +nz-qk +pb-ml +is-df +qt-lh +uh-ir +wp-az +cu-pj +wk-nc +lv-yl +qj-af +ex-po +sh-yk +ro-ez +dw-sx +dp-jm +hn-jn +qh-ak +kd-eo +ca-yw +kj-qh +fp-el +qi-hp +bn-xf +oa-er +hm-en +sq-hq +yv-lw +ry-bf +ml-lt +tu-ky +lm-qh +po-yf +ft-yv +wp-jp +ds-sx +ua-fh +ag-uq +im-to +xf-wp +bc-zn +oy-jl +nz-ka +mt-hx +oh-tm +pl-pd +rl-hh +lk-en +al-je +fn-gg +eo-ju +gl-ai +oy-eb +pb-ru +lu-qj +ho-oy +bm-hf +tp-sh +oz-mw +ac-tg +sr-pm +us-el +mb-wc +bj-tv +lj-ec +jf-su +gr-qt +gc-aq +ur-os +mo-ti +rl-es +rc-to +il-ab +li-wp +if-la +fp-il +xj-ht +yx-jo +ip-ht +ns-rr +ue-na +xv-al +ya-sf +gg-hw +pp-fz +ky-jq +yy-fr +vn-iz +og-nr +yw-nh +ho-qa +pg-pt +jo-hj +ma-ej +dz-pz +he-ut +iw-sd +vz-st +kz-zj +pa-hs +pr-rd +lf-xk +be-yh +ej-la +su-uw +tp-rs +wm-wl +im-wv +ar-hz +ds-ry +or-qm +ff-pq +ko-wx +op-co +ke-am +nu-sj +da-qi +yx-hj +mu-km +tb-uk +ca-cv +sd-wd +mx-kt +nq-an +tl-ol +wf-wh +tr-ro +pu-ou +gj-rv +hd-qy +se-bv +nt-sq +oa-fq +uy-nb +gq-kp +is-cn +sy-xq +iu-lg +ki-je +qb-cc +hh-ry +lo-gq +vg-gm +pt-ie +dx-vb +vv-nd +bb-ai +tr-aj +pe-gm +bq-yx +be-qw +ec-og +ax-lz +tr-mz +hv-fb +nw-sk +qy-ee +qt-nd +dm-ez +hx-sy +hi-uj +do-kv +kl-ex +ib-aa +jz-te +rv-xz +de-dq +fh-pg +mx-en +fm-lv +xq-ih +iu-ge +vb-wf +yi-do +sd-mo +lg-mz +ji-gf +hl-bz +hq-op +bc-lc +wh-qz +ji-jl +vo-mb +ze-ql +ws-ay +br-tv +mc-eq +io-ph +kp-up +se-kh +ml-af +pa-bt +ei-sl +px-gx +pr-lm +ha-bq +ut-jd +sq-co +nw-bp +td-oy +eq-sd +uj-gw +wa-lj +br-bj +la-li +kw-ig +ak-ua +tt-ln +sr-nd +xf-ma +yp-fo +dr-ca +ql-tx +uy-ly +br-hg +ql-yk +yv-rx +ki-ou +xy-yx +eq-wd +xb-oj +bd-yc +hp-uq +kv-hx +rl-rb +jd-ij +by-uz +oh-tw +vp-ft +kj-ur +le-mz +xj-up +yi-vy +mq-an +hi-ei +js-fn +zs-tq +gk-yh +cx-qf +hk-jg +wd-cp +or-pc +fn-as +xx-lw +us-fp +ff-ut +pu-ak +ie-jd +bf-rl +tj-jd +oq-so +jl-ju +ue-st +ns-xj +yu-nh +oz-fl +yw-kz +lb-bm +kf-lt +bs-cz +mm-gq +xp-lt +ua-yj +om-cu +zr-kc +gc-xu +uk-ym +as-hw +tm-ok +vx-ff +gs-jh +ca-yu +pi-yv +it-bz +dh-zq +wt-bd +cu-mx +gi-rs +oq-tw +ny-fb +kr-ab +iy-hn +di-ij +bq-hj +zp-fc +yd-wp +nb-va +ka-vz +en-fc +dj-pp +xb-zq +om-mx +az-ma +mr-is +kc-ft +sw-hq +zx-ii +en-ti +hk-gj +yc-km +cj-kg +bq-xy +rs-ps +il-ld +jh-kz +yf-hw +cc-an +gv-li +tf-gd +bi-qh +on-lw +yp-bz +cv-zj +sl-nz +dz-hg +hr-jj +vo-dp +gj-vp +cc-to +hn-mm +ce-ot +ye-ij +cy-lo +uh-tj +xb-rp +jm-xs +ti-cu +fb-mv +vg-ez +yj-je +lv-vg +qq-qy +ww-dh +cv-yu +qt-aq +aj-lg +wo-gl +oa-le +vf-gq +cz-za +zi-hz +dg-yu +ui-pq +wm-ny +qh-fr +oy-ji +eq-tl +gc-vv +uo-fn +qw-fn +ju-ug +pd-er +uh-hf +ue-ii +co-hq +un-tg +le-hm +we-yx +ru-nj +po-dn +ot-jj +sz-hq +yd-kc +op-ax +bs-va +bf-dw +lw-rx +vb-bq +tv-ko +bv-qm +ym-lm +ag-ri +vz-vr +nf-ew +hg-pz +of-oj +qn-ld +sm-ab +xv-rc +dr-yw +he-di +ah-ms +ju-eb +fz-lq +vy-mt +da-ag +ur-er +gk-xo +nu-xs +mx-fc +qa-pl +tf-xu +vh-ut +ce-bm +jz-kw +qc-ii +zb-cz +xj-zq +ua-sf +yl-fp +jj-hf +lr-gr +ps-jq +on-pi +ey-af +io-wf +gx-sl +jt-hv +jl-eo +qy-zu +yl-qr +xp-lu +cc-mq +ye-ut +wp-gv +up-cy +kc-xx +bs-za +dm-ro +tz-nd +qo-ux +iu-xa +kg-sm +yf-ox +nr-bj +ez-nk +ru-ud +dp-sj +je-ua +nj-ml +na-vr +bd-qk +tg-hi +kh-xv +mf-ur +wl-cf +hd-yt +ef-tf +nb-rw +da-uq +gz-el +ku-kf +ez-fp +qb-nq +ly-wp +tv-ta +sw-jy +hx-no +du-wg +zs-aa +xc-lw +fq-xe +as-in +ws-pu +sw-ec +fn-bz +uy-yd +ft-xx +xm-kt +yl-ro +na-vz +zi-ox +sw-sz +xs-dj +ku-no +ws-gw +qo-hg +ph-xy +ze-tp +ry-yh +aq-nd +vf-hn +tf-sa +qo-yz +vx-ms +wz-os +bt-hs +kz-dg +ft-hc +xz-gu +mx-xm +tv-hg +oq-oh +ot-bh +eb-jl +ao-pg +gy-rr +bv-qb +vc-yt +iu-hm +nz-fm +ui-di +fr-iz +vp-kc +ba-yu +ui-ye +wm-jt +sy-no +fd-ac +qz-ph +zf-yp +ko-dz +uq-lu +qq-zu +na-ra +nc-ny +qb-rc +om-kt +hz-ex +yt-ii +yt-zu +pd-mf +wi-su +vs-rh +hv-ny +hm-oa +ie-vl +am-cf +js-fo +hx-ew +ft-zr +xm-cu +se-xv +fg-hq +dl-lg +qs-xc +dq-ig +ud-nj +oy-pj +ml-xp +bu-rb +fo-hw +fl-mr +mw-ew +kc-lw +qn-yk +cg-kv +sh-yg +eb-kd +qi-hs +eg-uo +lo-tn +ld-re +cf-nc +fp-vg +aj-dl +bc-sn +lz-kw +pp-vo +ms-ut +br-kw +oz-ew +yg-tp +rr-jg +ot-ir +qc-zu +xk-mt +zr-lw +qh-iz +en-pv +js-hl +sh-jq +wf-yx +su-kg +os-uj +qc-of +pu-ua +lf-kv +zb-sr +gb-rz +wl-nc +qq-ii +uz-lj +lb-em +xu-gr +hc-xx +er-gw +mz-oa +bi-lm +jt-xq +nc-hv +ok-wo +ot-bm +ns-bq +io-jo +hv-af +uj-pe +ba-nh +hl-in +hz-ox +dy-de +qi-qd +ha-qs +ih-lf +eo-oy +kp-tn +ee-hd +iv-fh +ql-sh +oc-qh +wt-hk +ok-gl +gc-mv +zn-cx +lk-zp +oa-xe +dr-nh +uo-in +el-yl +to-nq +za-sr +yh-rl +am-nc +dx-ie +ka-rh +bf-bu +wk-ag +pb-ku +fy-id +wg-sd +xy-kh +se-cj +ii-of +ei-ee +jo-ha +yl-ez +lj-id +on-yv +dz-nr +ba-dg +qb-to +se-qb +xp-ku +xz-gj +ho-td +ta-bj +ee-ib +hn-up +rv-im +tz-ia +ef-pt +dz-br +lh-nd +wd-yq +pc-qg +ct-wa +ng-xu +br-pz +fe-fl +ii-ib +dr-yu +pc-em +ah-jf +mq-kh +vu-st +ox-ex +hz-po +fp-ro +cg-lz +nr-ux +pq-ij +pb-lu +ce-ir +ke-em +zc-sk +gk-yf +xc-on +co-ax +xk-do +np-am +zq-ns +tx-gi +zj-yu +eg-in +dl-iu +lx-ny +lo-gb +iv-dx +dw-hh +dy-dw +oi-xq +hh-bu +it-zj +fq-le +qp-yf +cx-wa +gr-lh +gl-hh +kc-xc +ej-ly +zx-qy +xv-qm +ox-kl +ur-cp +lt-af +gk-zi +yc-kw +jo-wh +er-pe +jz-dq +sx-qw +nz-fd +gr-tz +tb-ym +ui-jd +ug-gf +cu-zp +di-jd +yj-sf +bd-gj +rp-qr +vc-jy +qd-da +kh-qb +pr-if +yx-wh +jl-ma +ao-kr +ox-dq +yq-ol +zf-as +pd-qa +ez-mu +nr-hg +cc-al +ho-ji +ph-wf +rw-sr +hn-lo +bt-uq +wg-eq +jl-ug +bp-te +zx-qq +dr-zj +ai-wz +ds-es +hi-un +wf-xl +fx-gb diff --git a/day-23/main.c b/day-23/main.c new file mode 100644 index 0000000..903d26b --- /dev/null +++ b/day-23/main.c @@ -0,0 +1,356 @@ +#include "aoc.h" +#include + +typedef struct Node { + str label; + i32 index; +} Node; + +// Represent edges of graph by an adjacency matrix. +typedef struct BitMatrix { + i32 size; + u64 *data; +} BitMatrix; + +typedef DYNAMIC_ARRAY(Node) Nodes; + +typedef struct Graph { + Nodes nodes; + BitMatrix edges; +} Graph; + +typedef struct BitSet { + i32 size; + i32 array_size; + u64 *data; +} BitSet; + +typedef struct BitSetIter { + BitSet *bs; + i32 u64_index; + u64 current_u64; +} BitSetIter; + +static void +bm_init(Arena *arena, BitMatrix *bm, i32 size) { + bm->size = size; + isize alloc_size = (bm->size * bm->size + 63) / 64; + bm->data = ARENA_ALLOC_ARRAY(arena, u64, alloc_size); +} + +static u8 +bm_at(BitMatrix *bm, i32 row, i32 col) { + i32 u64_index = (row * bm->size + col) / 64; + i32 bit_index = (row * bm->size + col) % 64; + u64 mask = 1ULL << bit_index; + return (bm->data[u64_index] & mask) != 0; +} + +static void +bm_set(BitMatrix *bm, i32 row, i32 col, u8 bit) { + i32 u64_index = (row * bm->size + col) / 64; + i32 bit_index = (row * bm->size + col) % 64; + u64 mask = 1ULL << bit_index; + if (bit) { + bm->data[u64_index] |= mask; + } + else { + bm->data[u64_index] &= ~mask; + } +} + +BitSet make_bitset(Arena *arena, i32 size) { + isize array_size = (size + 63) / 64; + BitSet set = { + .size = size, + .array_size = array_size, + .data = ARENA_ALLOC_ARRAY(arena, u64, array_size) + }; + return set; +} + +static bool +bs_empty(BitSet *bs) { + for (i32 i = 0; i < (bs->size + 63) / 64; i++) { + if (bs->data[i] != 0) { + return false; + } + } + return true; +} + +static void +bs_set(BitSet *bs, i32 index) { + i32 u64_index = index / 64; + i32 bit_index = index % 64; + bs->data[u64_index] |= 1ULL << bit_index; +} + +static void +bs_clear(BitSet *bs, i32 index) { + i32 u64_index = index / 64; + i32 bit_index = index % 64; + bs->data[u64_index] &= ~(1ULL << bit_index); +} + +static u32 +bs_get(BitSet *bs, i32 index) { + i32 u64_index = index / 64; + i32 bit_index = index % 64; + return (bs->data[u64_index] & (1ULL << bit_index)) != 0; +} + +BitSetIter +bs_iter(BitSet *bs) { + BitSetIter iter = { + .bs = bs, + .u64_index = -1, + .current_u64 = 0, + }; + return iter; +} + +static bool +bsi_next(BitSetIter *iter, i32 *index) { + while (iter->current_u64 == 0) { + iter->u64_index++; + if (iter->u64_index >= iter->bs->array_size) { + return false; + } + iter->current_u64 = iter->bs->data[iter->u64_index]; + } + i32 bit_index = __builtin_ctzll(iter->current_u64); + *index = iter->u64_index * 64 + bit_index; + iter->current_u64 &= ~(1ULL << bit_index); + return true; +} + +static BitSet +bs_copy(Arena *arena, BitSet *bs) { + BitSet copy = make_bitset(arena, bs->size); + memcpy(copy.data, bs->data, bs->array_size * sizeof(bs->data[0])); + return copy; +} + +static BitSet +bs_intersect(Arena *arena, BitSet *a, BitSet *b) { + BitSet result = make_bitset(arena, a->size); + for (i32 i = 0; i < a->array_size; i++) { + result.data[i] = a->data[i] & b->data[i]; + } + return result; +} + +static i32 +bs_count(BitSet *bs) { + i32 count = 0; + for (i32 i = 0; i < bs->array_size; i++) { + count += __builtin_popcountll(bs->data[i]); + } + return count; +} + +static i32 +cmp_i32(const void *p1, const void *p2) { + i32 a = *(i32 *)p1; + i32 b = *(i32 *)p2; + return a - b; +} + +static inline bool +graph_connected(Graph *graph, i32 a, i32 b) { + bool result = bm_at(&graph->edges, a, b); + return result; +} + +static Node * +graph_get_or_insert(Arena *arena, Graph *graph, str label) { + Node *result = NULL; + for (isize i = 0; i < graph->nodes.len; i++) { + if (str_eq(graph->nodes.data[i].label, label)) { + result = &graph->nodes.data[i]; + break; + } + } + if (!result) { + Node node = { .label = label, .index = graph->nodes.len }; + *push(&graph->nodes, arena) = node; + result = &graph->nodes.data[graph->nodes.len - 1]; + } + return result; +} + +static i32 +str_cmp(str a, str b) { + i32 res = memcmp(a.data, b.data, MIN(a.len, b.len)); + if (res == 0) { + return a.len - b.len; + } + else { + return res; + } +} + +static i32 +cmp_str(const void *p1, const void *p2) { + str *s1 = (str *)p1; + str *s2 = (str *)p2; + return str_cmp(*s1, *s2); +} + +static BitSet +get_neighbors(Arena *arena, Graph *graph, i32 node) { + BitSet neighbors = make_bitset(arena, graph->nodes.len); + for (i32 i = 0; i < graph->nodes.len; i++) { + if (graph_connected(graph, node, i)) { + bs_set(&neighbors, i); + } + } + return neighbors; +} + +typedef void(CliqueCallback)(BitSet *set, bool maximal, void *context); + +static void +bron_kerbosch(Arena *arena, Graph *graph, BitSet R, BitSet P, BitSet X, bool only_maximal, CliqueCallback *callback, void *context) { + if (bs_empty(&P) && bs_empty(&X)) { + if (callback) { + callback(&R, false, context); + } + } + else { + if (!only_maximal) { + if (callback) { + callback(&R, false, context); + } + } + BitSet P_copy = bs_copy(arena, &P); + BitSetIter iter = bs_iter(&P_copy); + i32 node; + + void *watermark = arena->top; + while (bsi_next(&iter, &node)) { + bs_set(&R, node); + + BitSet neighbors = get_neighbors(arena, graph, node); + BitSet P_intersect_v = bs_intersect(arena, &P, &neighbors); + BitSet X_intersect_v = bs_intersect(arena, &X, &neighbors); + + bs_intersect(arena, &P, &P_intersect_v); + bron_kerbosch(arena, graph, R, P_intersect_v, X_intersect_v, only_maximal, callback, context); + // undo + bs_clear(&R, node); + + bs_clear(&P, node); + bs_set(&X, node); + } + arena->top = watermark; + } +} + +typedef struct { + i32 count; + Graph *graph; +} Part1_Context; + +static void +clique3_callback(BitSet *set, bool maximal, void *context) { + Part1_Context *p1 = context; + if (bs_count(set) == 3) { + i32 node = 0; + BitSetIter iter = bs_iter(set); + bool starts_with_t = false; + while (bsi_next(&iter, &node)) { + Node *n = &p1->graph->nodes.data[node]; + if (n->label.data[0] == 't') { + starts_with_t = true; + break; + } + } + p1->count += starts_with_t; + } +} + +static i32 +count_cliques_of_size_3_with_t(Arena *arena, Graph *graph) { + BitSet P = make_bitset(arena, graph->nodes.len); + BitSet R = make_bitset(arena, graph->nodes.len); + BitSet X = make_bitset(arena, graph->nodes.len); + + // create set of all nodes which start with a 't' + for (i32 i = 0; i < graph->nodes.len; i++) { + bs_set(&P, i); + } + + Part1_Context context = { + .count = 0, + .graph = graph + }; + bron_kerbosch(arena, graph, R, P, X, false, clique3_callback, &context); + return context.count; +} + +static void +largest_clique_callback(BitSet *set, bool maximal, void *context) { + BitSet *largest = context; + if (bs_count(set) > bs_count(largest)) { + memcpy(largest->data, set->data, set->array_size * sizeof(set->data[0])); + } +} + +static void +find_largest_clique(Arena *arena, Graph *graph) { + BitSet P = make_bitset(arena, graph->nodes.len); + BitSet R = make_bitset(arena, graph->nodes.len); + BitSet X = make_bitset(arena, graph->nodes.len); + + for (i32 i = 0; i < graph->nodes.len; i++) { + bs_set(&P, i); + } + + BitSet result = make_bitset(arena, graph->nodes.len); + bron_kerbosch(arena, graph, R, P, X, true, largest_clique_callback, &result); + + i32 count = bs_count(&result); + str *labels = ARENA_ALLOC_ARRAY(arena, str, count); + i32 node; + BitSetIter iter = bs_iter(&result); + i32 counter = 0; + while (bsi_next(&iter, &node)) { + labels[counter++] = graph->nodes.data[node].label; + } + qsort(labels, count, sizeof(labels[0]), cmp_str); + for (i32 i = 0; i < count; i++) { + printf(STR_FMT ",", STR_ARG(labels[i])); + } +} + +int main(int argc, char **argv) { + Arena *arena = make_arena(Megabytes(2)); + Tokens input = read_lines(arena, argv[1]); + /* printf("# of edges: %td\n", input.len); */ + + Graph graph = {0}; + bm_init(arena, &graph.edges, input.len); + + for (isize i = 0; i < input.len; i++) { + str line = str_trim(input.tokens[i]); + if (line.len == 0) { + continue; + } + str a, b; + str_split(line, STR("-"), &a, &b); + + Node *node_a = graph_get_or_insert(arena, &graph, a); + Node *node_b = graph_get_or_insert(arena, &graph, b); + bm_set(&graph.edges, node_a->index, node_b->index, 1); + bm_set(&graph.edges, node_b->index, node_a->index, 1); + } + + // Part 1 + i32 result = count_cliques_of_size_3_with_t(arena, &graph); + printf("%d\n", result); + + // Part 2 + find_largest_clique(arena, &graph); +} diff --git a/day-23/test.txt b/day-23/test.txt new file mode 100644 index 0000000..3d49766 --- /dev/null +++ b/day-23/test.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