:- use_module(library(pio)). :- use_module(library(dcg/basics)). :- initialization(main, main). % This code was only used to confirm the theory. Don't run it. Look at part2.txt. run_until(Circuit, _, Node, State, N) :- member(_-Node-State-_, Circuit), write(N), nl, !. run_until(Circuit, Init, Node, State, N) :- maplist(extract(Circuit), [xr, qv, gx, vh, qn, lz, xv, zk, lv, mj, hb, vj], S1), maplist(extract(Circuit), [nj, kp, xx, vp, sj, mt, mx, rv, rr, bq, xb, gr], S2), maplist(extract(Circuit), [hx, xq, rm, tp, kh, qc, xh, vm, jm, cq, tg, fb], S3), maplist(extract(Circuit), [kb, cv, vx, pt, qq, rz, tz, kn, gg, cp, rd, xk], S4), write(N), write(": "), string_codes(Str1, S1), string_codes(Str2, S2), string_codes(Str3, S3), string_codes(Str4, S4), write(Str1), write(" "), write(Str2), write(" "), write(Str3), write(" "), write(Str4), nl, run([Init], Circuit, CircuitNext), NextN is N + 1, run_until(CircuitNext, Init, Node, State, NextN). extract(Circuit, Cell, AsciiState) :- member(_-Cell-StateX-_, Circuit), AsciiState is StateX + 48. % code to run one circuit run([], Circuit, Circuit) :- !. run([Src-Level-Target|Pulses], CircuitIn, CircuitOut) :- ( member(Type-Target-State-Dests, CircuitIn) -> /*write([Src, Level, Target]), write(" -> "), write([Type, Target, State, Dests]), write(" = "),*/ call(Type, Src, Level, State, NewState, Out), send(Target, Out, Dests, AdditionalPulses), % write(NewState-AdditionalPulses), nl, select(Type-Target-State-Dests, CircuitIn, Type-Target-NewState-Dests, Circuit1), append(Pulses, AdditionalPulses, NewPulses), run(NewPulses, Circuit1, CircuitOut) ; run(Pulses, CircuitIn, CircuitOut) ). broadcaster(_, l, x, x, l). ff(_, h, State, State, none). ff(_, l, 0, 1, h). ff(_, l, 1, 0, l). nand(Src, Level, State, NewState, OutLevel) :- select(Src-_, State, Src-Level, NewState), (maplist([_-h]>>(true), NewState) -> OutLevel = l; OutLevel = h). send(_, none, _, []). send(From, Level, Dests, Pulses) :- \+ Level = none, maplist({Level}/[Dest, From-Level-Dest]>>(true), Dests, Pulses). % input initialization prefill_nands([], Circuit, Circuit). prefill_nands([_-Src-_-Dests|Nodes], CircuitIn, CircuitOut) :- convlist( {CircuitIn}/[Dest, Dest]>>(member(nand-Dest-_-_, CircuitIn)), Dests, NandDests), foldl(fill_one_nand(Src), NandDests, CircuitIn, Circuit1), prefill_nands(Nodes, Circuit1, CircuitOut). fill_one_nand(Src, Nand, CIn, COut) :- select(nand-Nand-State-Dests, CIn, nand-Nand-[Src-l|State]-Dests, COut). % input parsing stuff below input(FileName, Circuit) :- phrase_from_file(modules(EmptyCircuit), FileName), prefill_nands(EmptyCircuit, EmptyCircuit, Circuit). modules([]) --> eos, !. modules([Module|Modules]) --> module(Module), "\n", modules(Modules). module(broadcaster-broadcaster-x-Dests) --> "broadcaster -> ", dests(Dests). module(ff-Name-0-Dests) --> "%", node(Name), " -> ", dests(Dests). module(nand-Name-[]-Dests) --> "&", node(Name), " -> ", dests(Dests). dests([Dest]) --> node(Dest). dests([Dest|Dests]) --> node(Dest), ", ", dests(Dests). node(Name) --> string_without(", \n", NameStr), {atom_codes(Name, NameStr)}.