From 4e44650a01296d38cbe143c389482dbe89d5c370 Mon Sep 17 00:00:00 2001 From: dobiadi Date: Tue, 24 Dec 2024 16:03:40 +0100 Subject: [PATCH] Day24 --- day24/c/day24 | Bin 0 -> 20512 bytes day24/c/day24.c | 469 ++++++++++++++++++++++++++++++++++++++++++++++ day24/input.txt | 313 +++++++++++++++++++++++++++++++ day24/sample.txt | 10 + day24/sample2.txt | 47 +++++ day24/sample3.txt | 19 ++ 6 files changed, 858 insertions(+) create mode 100755 day24/c/day24 create mode 100644 day24/c/day24.c create mode 100644 day24/input.txt create mode 100644 day24/sample.txt create mode 100644 day24/sample2.txt create mode 100644 day24/sample3.txt diff --git a/day24/c/day24 b/day24/c/day24 new file mode 100755 index 0000000000000000000000000000000000000000..f6547b2285661b933614a7f7d3be1cdfacc31a00 GIT binary patch literal 20512 zcmeHP4|G(;xxc$vU=4BaYEjY_>sFUGwh|KrnpLd3unBYPU5Wfr`U);#laSPq#AMe7 z4#n^`i(D^D)4pnLk3B_CYdz{akJ>)0whe(m0&s$iT2Jl4kbeW5(>2{S2ffxn=$RGhUzH|^^LK%DQ#slrp%aD z+}cz;m5V@fQ5VRj=G?eYv9~MTgp>3(#m4jJ0Y}L$^0J)jPQXQKC;DY4jUyMfE?Jy+ z^Y!D7!bNo~{dkmiJX0e4@`Y7W6&#m)D+J=g zTqN?Bodf@+bKp(jJ-BkyzW^~3|8eKQ>*v7FKL`HjzB`Wf< z&(vc|*p)kxrzHKN)ZZrIhYtw9C-Id6&vNuF^WAeTel!P!E8~b=S@`UE)1QTxbCd`U zWZ}ni4%TfT3ty0hm*Y=ng;{uOep>~eEIhR# zQ&ARP>W<1vvhew`GGJL29s@U;Ml~?1fl&>NYG70YqZ;^spn-SP&z)lNH=WEJv+a6C zVTtajJ>AdZJDfed_vz`s2Rc3ZY24LI{dl5$9hD6Zq>(0Xr#yu?gZ(`J6y+(j8SLiy z$0<)C+2CfLe}wWBiVbe!`3EUaA6zUAN^ZfTHPa)1=GxC6EC1yG%d(gT% z{vY#HTdZE%!CR39u;*i?$pU_gdy5&l5p#5~d+VKnU-%71@ksztZ&w!gb)2l`H z2jYFU;QAsovOl0cvA}DqH7aeTdjsvOy<l8$yQx!6078H>GzdUD!q zX1r88JS6I+3QI2eKsS!)$?}hwaZv5D8{3j?KZ&Om%A+3jT0Qc&pOIZE*v1mOhr4vJ{Yk4!Q?t7C_(#KC zDpzv)RL=V}mzs+2%-4PIsR^=|E)NuA8Ken~ry9Y7nGF~Tb2WwqV^Rkdv2BOP=*c;G zdh(WhJsEcBNqr2QK|5%bfZC<##-Aa*QBg?3_a*CSIQ;Et2)~oYgA1>AbP#VbCi`^r z7c^^i;~@3hnDL2}w+c$;I~d!?%qNKwV*<*cahe%xoS+U0E4ZdAAk08CJ2BJj-q`*C zSz>oStP$7td@Zt$rYtkR%UQ;IfbGdoG8;2)b_a}&RHzxzUKr?I^o$bYJDkFZ_CY<5 zcM^5H*Q5LPsEN1v1ccsF`%k6QG$}5JPx6K$m?PacCJRoI|J2MfNZ?F)vDpgwcEyf% ztpX32;_t{t1D5yrq6)Uj>%NUMSUveu?_Jc2(OcS`>H=fStvG>8ZOvpA4^;_zm!=*C zjwPp85G@&a51&~nF9`aA-qq9!Gux@Z$il%9T^>uKh$Zj$(xfGVLOFkpH^A)3rwRKC z1Xx1cx#~a3P_LtL)_l*$4l;9rw~(1pubYH14Qe;VsC(uFFQ&0^H1&vEQ4-y1$3YYY zQFArCUi`E_mSB;^-XIy`(x<4m<)tTB@_agHWyvYGafx0ICL`&T@c|5py-Dv*SE5Rtmkk#V7@DA_9{QzuSR^$zavtJ#+wd<9Sw3$Vwi!1~HO zV58nVEeTJKdF6?@26thBQlF@vZ-5I?CO?z zc|(_ExzVi0PUC%JpYeNj3(I5iZj1Yy>Xu40+w6c)W6}JW?D|xzy$$W0u-3=ny!wP& z-Qu@n^w5#Yae?*z^9JvQ#;kf`G4v=3tjn1i0|gGFG^3AUWqnEMnncG#i(|XhO+JeY(L-z^z4k^@#3uYRQ5=t{>f;Se`hsrc5*E z!30kZ6=rpY<|E{HGT*l7MCNnHjE#Pd(9pg9P_oiZD_Ny(RC^aOU!U4>1Qe+2 z$Fg_kBo@ju%vkL$As!yhc=?Kxy0O4p7BXJPgdCUFl8)`97biwf&PUC-#SPnaYT)bE zeXy(O>X7*b&79-r(~0Jl24C*hK!{t|ozkE)4fD{A*shyJFzYpQEyG+c7y1Oq3pa=g~ns2HevAYb~Tp=pZp?r_KeeEoEcQgX~P z0=|>cixBGWK_v=x&r1)8b*x7~)c5iF)29-+0t0l6Z98&3+jcUK*?QTtXQC6p;Kzc2 zGd*C*CFx1N_UlfgSczS|kj1ZCMUTul96cZ5);?s?7uDgOia^-jG0)@CwxnlR-ku!$ zBz}X-QCG@m9B1ZNn3=D3ja9oYDC>_Es9hECb2r(_`lIJv(NCcl+&YkOfH&C*G0eTT zGjNNZ+)7?pgtN>zJ)apLVhgZHH)|*s)RG-ust`)Ns&+hx2TVk`d>AFdSZE_;#uP2N z(W-(;un<)=V>bn5#@iv|J$T=cu}3qPVC{-iEk?2HdBo8e3>n8m#!k)H6Egn7jQ>Kk z7&3Nc3D~J2jMS4Rr!!vCF^!y@{)b$Ps}U6%2v0~%1e(SlV1M661L^1-SgV(j$@q0l zjWU{2B{Z9g$ap;|ituPLVq~kBepCepTS5j~#HWF!H)c|c@ttrA&%_>th&lv?jTeTD zH+7TCrBi?uLOkXS^aXh2NYQP`_okZoDz#$#0bS&}cu_aG213TZ5UdUL{i6O()JF`q zkB1C=Rn$mxrzy-Em*Gma4y%c~Q7dG8#J%Km8kQYPtKFz+@gsS4-)S}B-{XUmzj=!K4}o~z!&z$4)(yF zZq}1`X1q6F?OLL=f4Fqb)c8;piyYES$BRTb6>{2OM4InN>_y#p zn7Yy1PLZrlO4kz~x_Fo(wr5zp)ZVvgv*CDA?J8GhE?wh_r>fX}V7+7LVeAVKa*EuK zvbsn1P7*#rO_7kNEg|P)_x5X8lxAM(WwaG>(aN2?$1=MHvZ23(3| zuACg?(OJlNjSLR%yTMzjnZ=ybGSp(pgyghHGv34|hU&o*;c`R98M1M1)btAq6O#l+ zi&z_`O01h<-I-dCKz3S2+C`4%9sA98J}D5bG2;L;3pvl(R6F@gt9>g%LHi-v z#bB|}jh}icXoay;sE5f-lb(9_2V`XLm~p?Cf*6tqD_BaW>9&*m6^40@cA_hoHAzW~ zO+-r5|F_E436gX_vZ)DEJg^@H*ARr}@+u zs<0Y?o6=276Vyj%YO-kT644meJqlcTaL}(Ne!}M!hJb`^M<3A~L>D5bUO!@q`U*i> zQpq7`z8z}fD}u0&7T0E3{|Qn5KSceaO#MG$8Dz!~?ZFno0CifVnfW{FX=*K}I+|K3 zs7iPo;OkWr?X<~618{EK5-ruFDp8U2!2|&oX7X#$U=cNgx_<6}&&U=o6)j8zw0zpT zYT^Lac}<9L<}J{z-9b|av6-B-f$-pA6ma{1+B{ac3rFgXpRz@##826yg}=riq!W8% z7nv1~%L5K9mzMn@do{8ddqjTxS$V$kN_4Mjgl9QDzx0rGSQUH;Bjh&cIpU|%Q6Dpz z)6^XC57N;oW?P}L@4P+nv@Lp(v9A;l_GrQ9f8WL1Ppd&JpKWgATaMI&WESxroA1Z# z(VaUVr8BQ@ERpNDgn?Vc(T|>-@;rX{!wC?{0VxWrb<@iOf10rf$lhhi#a?WVquz1D zD{jy@#ZM4u^W-7z83&nhgf>s-IJYRa_Q=O$hk^!9ItG||FO5DO>9FTg@d2AL%Mn;h zy}2{?AjMxnuQRg+iK*yC;qbWhq*lL)$Z1#{_`~7;Bm{> zx5le*c)V~*wWA0gHhai+zrllDYkrXP96wlr(AJ7ivZFcfUlY64jvv5)#S+ZdUn`(< zmYd~@7U?g?>?s38Gc39K1!ZVLmPD3|>!baTllDI}2Wa0a?O!(^p!FhvZ67oA7nE|N zoYsrz3z}JggS|Ik%;cnF=&Hs;r^N2qU0G~CE-wx@DVU>?(v0V`i( zVdk|st|FPEirZ2Mi?*0Q#P_dItIY;(L1_v41_x0LLx4peN7*G4uSE@ zRHK0Ui1M=1LkKV!Srs6H+SAMiW>{tfp92UE5N8}^IMJc)mBOno_WG$(A&nN+{nt~r zcVXHHd_ARa4Lbxnc*M&6KHSsV6fGCWb>p>9a8FlByFX+M@~DG*C&YCb=d>1U3(Wo@ z%U-RHU>U>i8(ThdSB31k*RYjJ-Tq-ZO(v7r-S(+Cwv|)V#MKCh;F9AXPFZu3W+n)d zQ<`xUli0gvDPLc>`?TbJ_VvFmui9}GwWQ4Z#auQ04jdjN#-laJQ$UMAPwZ#ZAPmD| z9_7s69@fV>U4h!sCYsQE`(w|OhTY)GFkQTr!h2(Y7MC9I&2p%Tdtr@e3Bxa1$|q{* z0jC6iR=aE?oc>POj%lEF_;@qhaIp4AItIO)>>3TxUS<(EE~cG&>4DFmD(&|L(9jeV zTX7Sa1u}HjVPo-=b~TaW>pv`nj43(WX8oeUiyjuCK?$wmWh_~4<0q3AT@5e9fd`IK z5T0l_8%|c(_@Sj$;WAYCHMKRk88@1bW*5nsnuY@(j9qg2J@^rW_W$pvE_jW`4}C6I zuoyOH4)J@*%Zff|g33T^)OFfn~^c-%%_ zX4Q^oP%&c{g9~A^rQH)6<^dm~%1gKzfND)LLIVssz%~Nb` zZrf)I#yP1i!qdA2n+MbBFHnWxI37BA@rW~7#fiRA0IIm$6|TasspG%pY*()T%(Y*- z+ItzHsq$i6&FJIRgg|1rnsMC^oCESHvs~`)*fm$-#=KcBPtq~VRkUGDz*VwtY|vE} zA2-LLB>um}wG?|S{9MKp;rekc2Cmpb;Y|!hc@`Ok8RC&6$P@|2#hCrX+eDvw6~GIxV#WzW1dFx zmXo}oT{kvh$$QL}cWs`l45$(1Z2&LjSUNoifKm~zcHm|Lw~`PyxZLaPL04fsufpZA zf8A9WaJd66C+q3ux_bf?OY05#*xrqxU_oggswCypVKUWYcB9JwOQP zC}~H(H{@Zk*3tOI$INk+++mGgKw1bJzmgAU1`+7#efk-gF<87y@`B$lGW;;68}fqL z{Oos*Kn_EUk6Gu~ke9TRTr{`bm~%D5e zr>Bx!Ac&7!H+I9Aq+?^=cX)e`p}Z62chf&)^Y*@$8UNwA!}YAY`fYiIW6|F1j~OGK z1Ms>15%^sQexKv*^`F%qp+?iF21Ye7s)11rjA~$11EU)Fzn}s6{+xVY4q-4)O9dXY}89lxSZ=iDEZOg%(gQ5>NucR!PmZFbH*d>K0J$_i$#+(?kIm353MA z3qhpZ2Sh#jE}(25XVknuDCSl1doIuW1wGCUd0y%n+ZUeqh;sY`9M4O+MKk|&Am1O) zZFmN4N{}i9yjj3n0q+oSoq+cW_>h1WHTJ%h*3+EXv#;?K;cewBJf+i$rxurbrj|^d zR#H|nT{%aQue3xm83B@B9m?Bu?0QzBakAr$%VWYo`Fp6m4c3>dHy@|CK#}jQ^DJ((U$Q9^Gj=KQ%kXd^XM>oizggIuJo8xz`~~*HjQvZRb%ZA;ONN9*TWCu62tJ;i@!bTx z8}E}Z%^8=UiTay_{PNu3QGqY{qQ#f*(eZeLz{~G<2(weR2>!X_wO!O75PIh4K;T2? zaAdb0(IDTG1OKeR`$c_z<^=o!f!`$b$RwUSyE?84BPrj_0VeZZwZcpSg0n zfhT$J(Gi|hK{W|@k9f`oGl0J=8zG)=B0hGkf*6|YbPM6L5%RgZYUR{v#Sx{YrnM$o z+>Dp?i%XRH)^Mb$rKKhkEsiubR4erQzV#Fie*MNkNSlo}?BN8% zJV&29E1-wxR#eO{Ul3jpn5CD8>7xMQsz|i{j;d%)b$B`Mt^8{Ne))nwy~~fb!}X2$ zbih>k{eZKIKlUwwOewwz@JZhR;2#ypROT(w_Y2O#glnp+qE!lgn4tb+A2!I;oCX=I zS|WAga|IbZ{}Mr%I9OjBP?q7l2+)5DsU5$>D5f&|;K-3F0iY zQrx<7MYL)eV6?@8b@B;cfv9O|R*D;&qBX_K8)L-~z8RfZnT1*wtH-xW>Z=7RFiV>f zty-?|>UCAEbxLvd%0@I{!Dx$Baz{-|YkgDWS(z}(T51}qh(J6wH$;_UE_ZRXrVY>B z6pCA#xM396)P-wXs#es5>#9L3a~4Ios->k0f)a&%2IHy~^%1n%1YWom^9C$t7&rw} zX~l|~#;BZwe+MLY4Oc_|X~|Qe2*f0m@vA82b>%Zba?=zuO8PQEFQFf0*-6He5;p@6 z+4OCKUP9p(W%bNDArV>*{r!SoLXWH{pj>Ap`W8IkXOSi;zl_Tzl}10?K6S#}~G+39vgsKQh3_}>p~HoZsCN!TgqBoM`!W`3SS-z_Rgc)Q#X3I-m@NWgyw z%x+)Cg%ZmBrzFdj|CfSZ>R-lF5>AnX0_M{HCWl_e?GirrSLk==&<~VY1QJflX;6-z zWcwT*5Vi0*KsdRtmfxewtuONuQd~~4j+pj}+;<w9hJ#?Mf7d?<3K#pJUayIENr7tNb^Q Ce{V1V literal 0 HcmV?d00001 diff --git a/day24/c/day24.c b/day24/c/day24.c new file mode 100644 index 0000000..4df018f --- /dev/null +++ b/day24/c/day24.c @@ -0,0 +1,469 @@ +#include +#include +#include +#include +#include + +#define CHARS_MAX 64 +#define MAX_GATES_PER_WIRE 16 +#define MAX_WIRES 16*1024 +#define MAX_GATES 8*1024 +#define c2i(a) ((a) >= 'a' ? ((a) - 'a') : ((a) - '0' + 26)) + + +int cmp(const void* a, const void* b) { + const char **pa = (const char**)a; + const char **pb = (const char**)b; + + if ((*pa)[0] != (*pb)[0]) { + return (*pa)[0] - (*pb)[0]; + } + + if ((*pa)[1] != (*pb)[1]) { + return (*pa)[1] - (*pb)[1]; + } + + return (*pa)[2] - (*pb)[2]; +} + +typedef struct node { + struct node *children[36]; + struct wire *value; + char key; + uint8_t is_leaf; +} node_t; + +node_t* create_node() { + node_t *node = calloc(1, sizeof(node[0])); + return node; +} + +node_t* search(node_t* root, char* word) { + node_t* node = root; + for (int i = 0; i < 3; i++) { + if (node->children[c2i(word[i])] == NULL) { + return NULL; + } + node = node->children[c2i(word[i])]; + } + return node; +} + +void insert(node_t* root, char* word, struct wire *value) { + node_t* node = root; + for (int i = 0; i < 3; i++) { + if (node->children[c2i(word[i])] == NULL) { + node->children[c2i(word[i])] = create_node(); + } + node = node->children[c2i(word[i])]; + } + node->value = value; + node->is_leaf = 1; +} + +void free_node(node_t* node) { + for (int i = 0; i < 36; i++) { + if (node->children[i] != NULL) { + free_node(node->children[i]); + } + } + + free(node->value); + free(node); +} + +typedef struct wire { + char name[3]; + int signal; + struct gate *gates[MAX_GATES_PER_WIRE]; + int output_gate_count; + struct gate *generator; +} wire_t; + +typedef enum { + AND, + OR, + XOR +} gate_type_t; + +typedef struct gate { + wire_t *inputs[2]; + wire_t *output; + gate_type_t type; +} gate_t; + +void process_wire(wire_t *wire); +uint64_t get_output(node_t *wires, char c); +void reset(node_t *wires); +void set_input1(node_t *wires, uint64_t value); +void set_input2(node_t *wires, uint64_t value); +void backtrack(node_t *wires, wire_t **list, int *list_count, wire_t* wire); +int is_correct(node_t *wires, int i, wire_t **initial_wires); +void get_activated_gates(node_t *wires, gate_t **list, int *list_count); + +int main() { + char *p, *buf, c; + + buf = calloc(CHARS_MAX, sizeof(char)); + p = buf; + + wire_t **initial_wires = calloc(MAX_WIRES, sizeof(wire_t*)); + int initial_wire_count = 0; + int reading_initial_wires = 1; + + char (*preparsed_gates)[10] = calloc(MAX_GATES, sizeof(preparsed_gates[0])); + int gate_count = 0; + + while ((c = getchar()) != EOF) { + *p++ = c; + if (c != '\n') { + continue; + } + if (reading_initial_wires) { + if (buf[0] == '\n') { + reading_initial_wires = 0; + memset(buf, 0, CHARS_MAX); + p = buf; + continue; + } + initial_wires[initial_wire_count] = calloc(1, sizeof(wire_t)); + initial_wires[initial_wire_count]->name[0] = buf[0]; + initial_wires[initial_wire_count]->name[1] = buf[1]; + initial_wires[initial_wire_count]->name[2] = buf[2]; + initial_wires[initial_wire_count++]->signal = buf[5] == '1' ? 1 : 0; + } else { + preparsed_gates[gate_count][0] = buf[0]; + preparsed_gates[gate_count][1] = buf[1]; + preparsed_gates[gate_count][2] = buf[2]; + preparsed_gates[gate_count][3] = buf[4] == 'A' ? AND : (buf[4] == 'O' ? OR : XOR); + p = buf; + while (*p++ != ' '); + while (*p++ != ' '); + preparsed_gates[gate_count][4] = p[0]; + preparsed_gates[gate_count][5] = p[1]; + preparsed_gates[gate_count][6] = p[2]; + while (*p++ != ' '); + while (*p++ != ' '); + preparsed_gates[gate_count][7] = p[0]; + preparsed_gates[gate_count][8] = p[1]; + preparsed_gates[gate_count][9] = p[2]; + gate_count++; + } + + memset(buf, 0, CHARS_MAX); + p = buf; + } + + free(buf); + + // Create trie of wires + node_t *wires = create_node(); + + // Insert initial wires + for (int i = 0; i < initial_wire_count; i++) { + insert(wires, initial_wires[i]->name, initial_wires[i]); + } + + // Go through gates and extract previously unknown wires + for (int i = 0; i < gate_count; i++) { + char* wire_name = &preparsed_gates[i][0]; + node_t *wire = search(wires, wire_name); + if (wire == NULL || wire->is_leaf == 0) { + wire_t *value = calloc(1, sizeof(wire_t)); + memcpy(value->name, wire_name, 3); + value->signal = -1; + insert(wires, value->name, value); + } + wire_name = &preparsed_gates[i][4]; + wire = search(wires, wire_name); + if (wire == NULL || wire->is_leaf == 0) { + wire_t *value = calloc(1, sizeof(wire_t)); + memcpy(value->name, wire_name, 3); + value->signal = -1; + insert(wires, value->name, value); + } + wire_name = &preparsed_gates[i][7]; + wire = search(wires, wire_name); + if (wire == NULL || wire->is_leaf == 0) { + wire_t *value = calloc(1, sizeof(wire_t)); + memcpy(value->name, wire_name, 3); + value->signal = -1; + insert(wires, value->name, value); + } + } + + // Now link everything together + gate_t *gates = calloc(MAX_GATES, sizeof(gates[0])); + for (int i = 0; i < gate_count; i++) { + // Link gate inputs/outputs + gates[i].type = preparsed_gates[i][3]; + wire_t *wire1 = search(wires, &preparsed_gates[i][0])->value; + gates[i].inputs[0] = wire1; + wire_t *wire2 = search(wires, &preparsed_gates[i][4])->value; + gates[i].inputs[1] = wire2; + wire_t *wire3 = search(wires, &preparsed_gates[i][7])->value; + gates[i].output = wire3; + + // Link wires to gates + wire1->gates[wire1->output_gate_count++] = &gates[i]; + wire2->gates[wire2->output_gate_count++] = &gates[i]; + wire3->generator = &gates[i]; + } + free(preparsed_gates); + + for (int i = 0; i < initial_wire_count; i++) { + process_wire(initial_wires[i]); + } + + uint64_t output = get_output(wires, 'z'); + + printf("%lu\n", output); + + char **part2 = calloc(8, sizeof(part2[0])); + int part2_c = 0; + wire_t **relevant_gates = calloc(MAX_GATES, sizeof(wire_t*)); + relevant_gates[0] = search(wires, "z00")->value; + int relevant_gate_count = 1; + int pc = 1; + for (int i = 1; i < 64; i++) { + char buf[4]; + sprintf(buf, "z%02d", i); + node_t *generator_node = search(wires, buf); + if (generator_node) { + backtrack(wires, relevant_gates, &relevant_gate_count, generator_node->value); + + if (!is_correct(wires, i, initial_wires)) { + gate_t **activated = calloc(MAX_GATES, sizeof(gate_t*)); + gate_t **switchable = calloc(MAX_GATES, sizeof(gate_t*)); + int activated_count = 0; + int switchable_count = 0; + get_activated_gates(wires, activated, &activated_count); + for (int j = 0; j < activated_count; j++) { + int found = 0; + for (int jj = 0; jj < pc; jj++) { + if (relevant_gates[jj] == activated[j]->output) { + found = 1; + break; + } + } + if (!found) { + switchable[switchable_count++] = activated[j]; + } + } + + // Try to switch each switchable + int br = 0; + for (int s1 = 0; s1 < switchable_count; s1++) { + for (int s2 = s1 + 1; s2 < switchable_count; s2++) { + wire_t *tmp = switchable[s2]->output; + switchable[s2]->output = switchable[s1]->output; + switchable[s1]->output = tmp; + // Check switched version + if (is_correct(wires, i, initial_wires)) { + part2[part2_c++] = switchable[s1]->output->name; + part2[part2_c++] = switchable[s2]->output->name; + br = 1; + break; + } + + switchable[s1]->output = switchable[s2]->output; + switchable[s2]->output = tmp; + } + if (br) { + break; + } + } + free(activated); + free(switchable); + } + pc = relevant_gate_count; + } + } + qsort(part2, part2_c, sizeof(char*), cmp); + + for (int i = 0; i < part2_c; i++) { + printf("%c%c%c", part2[i][0], part2[i][1], part2[i][2]); + if (i != part2_c - 1) { + printf(","); + } + } + printf("\n"); + + free(initial_wires); + free_node(wires); + free(gates); + free(relevant_gates); + free(part2); +} + +int eval_gate(gate_t gate) { + switch (gate.type) { + case AND: + return gate.inputs[0]->signal & gate.inputs[1]->signal; + case OR: + return gate.inputs[0]->signal | gate.inputs[1]->signal; + case XOR: + return gate.inputs[0]->signal ^ gate.inputs[1]->signal; + } + + return -1; +} + +void process_wire(wire_t *wire) { + // Try each of its outputs + for (int i = 0; i < wire->output_gate_count; i++) { + // Check if gate has both of it's outputs set + if (wire->gates[i]->inputs[0]->signal != -1 && wire->gates[i]->inputs[1]->signal != -1) { + wire->gates[i]->output->signal = eval_gate(*wire->gates[i]); + process_wire(wire->gates[i]->output); + } + } +} + +void set_input1(node_t *wires, uint64_t value) { + for (int i = 0; i < INT_MAX; i++) { + char buf[4]; + sprintf(buf, "x%02d", i); + node_t *node = search(wires, buf); + if (node == NULL) { + break; + } + node->value->signal = (value >> i) & 1; + } +} + +void set_input2(node_t *wires, uint64_t value) { + for (int i = 0; i < INT_MAX; i++) { + char buf[4]; + sprintf(buf, "y%02d", i); + node_t *node = search(wires, buf); + if (node == NULL) { + break; + } + node->value->signal = (value >> i) & 1; + } +} + +uint64_t get_output(node_t *wires, char c) { + uint64_t result = 0; + for (int i = 0; i < INT_MAX; i++) { + char buf[4]; + sprintf(buf, "%c%02d", c, i); + node_t *node = search(wires, buf); + if (node == NULL) { + break; + } + result += (uint64_t)node->value->signal << i; + } + return result; +} + +void reset(node_t *wires) { + if (wires == NULL) { + return; + } + + for (int i = 0; i < 36; i++) { + reset(wires->children[i]); + } + + if (wires->value != NULL) { + wires->value->signal = -1; + } +} + +void backtrack(node_t *wires, wire_t **list, int *list_count, wire_t* wire) { + if (wire == NULL) { + return; + } + + int found = 0; + for (int i = 0; i < *list_count; i++) { + if (wire == list[i]) { + found = 1; + break; + } + } + if (found) { + return; + } + list[*list_count] = wire; + (*list_count)++; + + if (wire->generator) { + backtrack(wires, list, list_count, wire->generator->inputs[0]); + backtrack(wires, list, list_count, wire->generator->inputs[1]); + } +} + +void get_activated_gates(node_t *wires, gate_t **list, int *list_count) { + if (wires == NULL) { + return; + } + + if (wires->value != NULL && wires->value->generator != NULL && wires->value->signal != -1) { + int found = 0; + for (int i = 0; i < *list_count; i++) { + if (wires->value->generator == list[i]) { + found = 1; + break; + } + } + if (!found) { + list[*list_count] = wires->value->generator; + (*list_count)++; + } + } + // Iterate each wire + for (int i = 0; i < 36; i++) { + get_activated_gates(wires->children[i], list, list_count); + } +} + +int is_correct(node_t *wires, int i, wire_t **initial_wires) { + for (int j = 0; j < 2; j++) { + for (int k = 0; k < 2; k++) { + for (int jj = 0; jj < 2; jj++) { + for (int kk = 0; kk < 2; kk++) { + reset(wires); + set_input1(wires, ((uint64_t)j << i) + ((uint64_t)k << (i-1))); + set_input2(wires, ((uint64_t)jj << i) + ((uint64_t)kk << (i-1))); + uint64_t e = ((uint64_t)j << i) + ((uint64_t)k << (i-1)) + ((uint64_t)jj << i) + ((uint64_t)kk << (i-1)); + char buf[4]; + for (int ii = 0; ii <= i; ii++) { + if (i == 45) { + continue; + } + sprintf(buf, "x%02d", ii); + wire_t *x = search(wires, buf)->value; + process_wire(x); + sprintf(buf, "y%02d", ii); + wire_t *y = search(wires, buf)->value; + process_wire(y); + } + + for (int ii = 0; ii < i-1; ii++) { + sprintf(buf, "z%02d", ii); + wire_t *z = search(wires, buf)->value; + if (z->signal != 0) { + return 0; + } + } + sprintf(buf, "z%02d", i-1); + wire_t *z = search(wires, buf)->value; + if (z->signal != (k ^ kk)) { + return 0; + } + sprintf(buf, "z%02d", i); + z = search(wires, buf)->value; + if (z->signal != ((j ^ jj) ^ (k & kk))) { + return 0; + } + } + } + } + } + + return 1; +} + diff --git a/day24/input.txt b/day24/input.txt new file mode 100644 index 0000000..4f639d7 --- /dev/null +++ b/day24/input.txt @@ -0,0 +1,313 @@ +x00: 1 +x01: 1 +x02: 1 +x03: 1 +x04: 0 +x05: 1 +x06: 0 +x07: 1 +x08: 0 +x09: 1 +x10: 1 +x11: 1 +x12: 1 +x13: 1 +x14: 1 +x15: 0 +x16: 0 +x17: 1 +x18: 0 +x19: 0 +x20: 1 +x21: 1 +x22: 0 +x23: 1 +x24: 1 +x25: 1 +x26: 1 +x27: 0 +x28: 0 +x29: 1 +x30: 0 +x31: 1 +x32: 0 +x33: 0 +x34: 1 +x35: 0 +x36: 1 +x37: 0 +x38: 1 +x39: 1 +x40: 0 +x41: 1 +x42: 0 +x43: 1 +x44: 1 +y00: 1 +y01: 1 +y02: 1 +y03: 1 +y04: 1 +y05: 0 +y06: 0 +y07: 0 +y08: 0 +y09: 0 +y10: 1 +y11: 0 +y12: 0 +y13: 1 +y14: 1 +y15: 0 +y16: 0 +y17: 0 +y18: 0 +y19: 0 +y20: 0 +y21: 1 +y22: 1 +y23: 1 +y24: 1 +y25: 1 +y26: 1 +y27: 0 +y28: 0 +y29: 0 +y30: 1 +y31: 1 +y32: 0 +y33: 1 +y34: 0 +y35: 1 +y36: 0 +y37: 0 +y38: 0 +y39: 0 +y40: 1 +y41: 1 +y42: 1 +y43: 0 +y44: 1 + +stn AND ffg -> tnr +y43 XOR x43 -> vfw +x37 AND y37 -> gnn +x12 AND y12 -> knv +hqw AND jmq -> djd +pqv AND kcv -> mnv +gtf OR jjt -> dfv +x38 AND y38 -> qjd +x40 AND y40 -> kqh +ghk XOR pnr -> z09 +vjd XOR kmb -> z10 +ftt XOR hwf -> z37 +x33 XOR y33 -> shg +shg AND gfm -> vqw +jvj OR bch -> jmq +y27 XOR x27 -> hqw +jsr XOR kph -> z13 +y35 AND x35 -> rkm +ccq OR hns -> vdt +x22 AND y22 -> hcv +x11 XOR y11 -> mws +ctp OR mdt -> nqv +y24 XOR x24 -> jjh +x43 AND y43 -> dkq +y13 AND x13 -> qmc +swk OR dgd -> tjh +jqm AND fjc -> ktw +fkq OR qfs -> dkn +sdn XOR hrm -> z14 +y22 XOR x22 -> hrj +mhm XOR mhc -> z34 +rbm OR bjj -> tmm +gqq OR nnk -> stv +jbc OR mnv -> z32 +y39 AND x39 -> gtf +crw OR bbv -> wvt +y05 AND x05 -> vfm +mjf OR srr -> dpv +y08 XOR x08 -> dnc +x01 XOR y01 -> qtg +y36 XOR x36 -> fjc +kdn XOR fvk -> z29 +msp AND shq -> dqc +vdt XOR rjv -> z25 +dpv AND mgr -> fvd +bqf AND vnc -> jjt +x09 XOR y09 -> ghk +ckj AND jjh -> hns +mpm XOR gtn -> z21 +x35 XOR y35 -> rpq +y16 XOR x16 -> btj +wkh XOR fhk -> z17 +y31 XOR x31 -> mbc +gsv AND qtg -> vjb +y23 AND x23 -> jmr +jpj XOR brn -> z18 +crb AND gqd -> fpk +x07 AND y07 -> hhm +spg XOR bfw -> z44 +djd OR wqf -> msp +gsv XOR qtg -> z01 +x10 XOR y10 -> vjd +x20 XOR y20 -> pwm +nct OR mmk -> gtn +hrj AND tjh -> wfs +y13 XOR x13 -> kph +pjv XOR bhn -> z05 +fhk AND wkh -> vpv +dnc XOR rtp -> cdj +x40 XOR y40 -> tqg +ckj XOR jjh -> z24 +x23 XOR y23 -> crb +y14 AND x14 -> vjh +tqg AND dfv -> dbc +y10 AND x10 -> fkq +kcv XOR pqv -> gfm +x18 XOR y18 -> brn +x02 AND y02 -> hjk +wdg XOR fbp -> z03 +y08 AND x08 -> z08 +x32 XOR y32 -> pqv +tqg XOR dfv -> z40 +jdh OR qrw -> z45 +x00 XOR y00 -> z00 +gtm OR mqp -> tfr +x12 XOR y12 -> dmv +mdr OR dqc -> fvk +dmv AND wvt -> tkv +gfm XOR shg -> z33 +dbc OR kqh -> tkw +x21 AND y21 -> swk +jhb XOR tkw -> z41 +dkn XOR mws -> z11 +x05 XOR y05 -> pjv +x04 AND y04 -> wmc +fgk AND jbp -> rdf +y16 AND x16 -> dwj +hqw XOR jmq -> z27 +gnn OR qmd -> kvn +msp XOR shq -> z28 +mhs AND pbn -> whd +pnr AND ghk -> kgf +y31 AND x31 -> tnf +pwm XOR cjh -> z20 +y19 AND x19 -> stp +tdc XOR scp -> z30 +y03 AND x03 -> tqj +fpk OR jmr -> ckj +skt OR cdj -> pnr +gtn AND mpm -> dgd +wmc OR whd -> bhn +dpv XOR mgr -> z19 +y17 XOR x17 -> fhk +y03 XOR x03 -> fbp +btj AND tmm -> z16 +stv XOR vfw -> z43 +tjh XOR hrj -> z22 +y11 AND x11 -> bbv +cpp OR tnf -> kcv +pbn XOR mhs -> z04 +x17 AND y17 -> pjm +bmh OR tqj -> mhs +fgk XOR jbp -> z06 +x25 XOR y25 -> rjv +kvn XOR qjd -> z38 +y21 XOR x21 -> mpm +qfv OR hjk -> wdg +y36 AND x36 -> jwh +knv OR tkv -> jsr +tnr OR hhm -> rtp +mhm AND mhc -> hsq +qjd AND kvn -> bgj +brn AND jpj -> srr +hwf AND ftt -> qmd +pjv AND bhn -> jnn +x42 AND y42 -> gqq +btj XOR tmm -> mrb +x28 AND y28 -> mdr +y39 XOR x39 -> vnc +dwj OR mrb -> wkh +rpq XOR pfh -> z35 +y25 AND x25 -> ctp +stp OR fvd -> cjh +cgp OR vjh -> gjd +crb XOR gqd -> z23 +x26 XOR y26 -> stc +y44 XOR x44 -> spg +nqv XOR stc -> z26 +bqf XOR vnc -> z39 +x42 XOR y42 -> msd +x00 AND y00 -> gsv +rpq AND pfh -> bdd +x01 AND y01 -> wcd +x02 XOR y02 -> vgg +x38 XOR y38 -> dhm +y09 AND x09 -> btq +wdg AND fbp -> bmh +x06 XOR y06 -> fgk +qpq OR vqw -> mhm +dmv XOR wvt -> z12 +y32 AND x32 -> jbc +rdf OR kcg -> ffg +ffg XOR stn -> z07 +sdn AND hrm -> cgp +scp AND tdc -> pkv +fvk AND kdn -> kvv +ktw OR jwh -> hwf +spg AND bfw -> qrw +x27 AND y27 -> wqf +rkm OR bdd -> jqm +x37 XOR y37 -> ftt +y30 AND x30 -> nmd +y07 XOR x07 -> stn +y41 XOR x41 -> jhb +vfw AND stv -> nfk +y04 XOR x04 -> pbn +rtp AND dnc -> skt +jrd OR qmc -> hrm +kmb AND vjd -> qfs +nmd OR pkv -> sjk +tkw AND jhb -> gtm +nfk OR dkq -> bfw +x29 AND y29 -> shs +jqm XOR fjc -> z36 +sjk AND mbc -> cpp +x20 AND y20 -> mmk +y33 AND x33 -> qpq +hsq OR fgq -> pfh +gbg XOR vgg -> z02 +jnn OR vfm -> jbp +pwm AND cjh -> nct +dkn AND mws -> crw +mbc XOR sjk -> z31 +dhm OR bgj -> bqf +y34 AND x34 -> fgq +x06 AND y06 -> kcg +x41 AND y41 -> mqp +kvv OR shs -> scp +btq OR kgf -> kmb +rjv AND vdt -> mdt +x15 AND y15 -> rbm +x44 AND y44 -> jdh +gbg AND vgg -> qfv +x18 AND y18 -> mjf +y19 XOR x19 -> mgr +msd XOR tfr -> z42 +y30 XOR x30 -> tdc +y24 AND x24 -> ccq +x28 XOR y28 -> shq +stc AND nqv -> bch +y14 XOR x14 -> sdn +gjd AND jfh -> bjj +x34 XOR y34 -> mhc +vpv OR pjm -> jpj +msd AND tfr -> nnk +x26 AND y26 -> jvj +kph AND jsr -> jrd +jfh XOR gjd -> z15 +x15 XOR y15 -> jfh +y29 XOR x29 -> kdn +vjb OR wcd -> gbg +hcv OR wfs -> gqd diff --git a/day24/sample.txt b/day24/sample.txt new file mode 100644 index 0000000..8e277c1 --- /dev/null +++ b/day24/sample.txt @@ -0,0 +1,10 @@ +x00: 1 +x01: 1 +x02: 1 +y00: 0 +y01: 1 +y02: 0 + +x00 AND y00 -> z00 +x01 XOR y01 -> z01 +x02 OR y02 -> z02 diff --git a/day24/sample2.txt b/day24/sample2.txt new file mode 100644 index 0000000..94b6eed --- /dev/null +++ b/day24/sample2.txt @@ -0,0 +1,47 @@ +x00: 1 +x01: 0 +x02: 1 +x03: 1 +x04: 0 +y00: 1 +y01: 1 +y02: 1 +y03: 1 +y04: 1 + +ntg XOR fgs -> mjb +y02 OR x01 -> tnw +kwq OR kpj -> z05 +x00 OR x03 -> fst +tgd XOR rvg -> z01 +vdt OR tnw -> bfw +bfw AND frj -> z10 +ffh OR nrd -> bqk +y00 AND y03 -> djm +y03 OR y00 -> psh +bqk OR frj -> z08 +tnw OR fst -> frj +gnj AND tgd -> z11 +bfw XOR mjb -> z00 +x03 OR x00 -> vdt +gnj AND wpb -> z02 +x04 AND y00 -> kjc +djm OR pbm -> qhw +nrd AND vdt -> hwm +kjc AND fst -> rvg +y04 OR y02 -> fgs +y01 AND x02 -> pbm +ntg OR kjc -> kwq +psh XOR fgs -> tgd +qhw XOR tgd -> z09 +pbm OR djm -> kpj +x03 XOR y03 -> ffh +x00 XOR y04 -> ntg +bfw OR bqk -> z06 +nrd XOR fgs -> wpb +frj XOR qhw -> z04 +bqk OR frj -> z07 +y03 OR x01 -> nrd +hwm AND bqk -> z03 +tgd XOR rvg -> z12 +tnw OR pbm -> gnj diff --git a/day24/sample3.txt b/day24/sample3.txt new file mode 100644 index 0000000..7709fe2 --- /dev/null +++ b/day24/sample3.txt @@ -0,0 +1,19 @@ +x00: 0 +x01: 1 +x02: 0 +x03: 1 +x04: 0 +x05: 1 +y00: 0 +y01: 0 +y02: 1 +y03: 1 +y04: 0 +y05: 1 + +x00 AND y00 -> z05 +x01 AND y01 -> z02 +x02 AND y02 -> z01 +x03 AND y03 -> z03 +x04 AND y04 -> z04 +x05 AND y05 -> z00