#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
typedef bool wire;
typedef struct {
wire *value;
} reg;
#define CLOCK for (; ; END_CYCLE)
#define NAND(X, Y) (!((X) && (Y)))
#define NOT(X) (NAND(X, 1))
#define AND(X, Y) (NOT(NAND(X, Y)))
#define AND3(X, Y, Z) AND(AND((X), (Y)), (Z))
#define AND4(X, Y, Z, W) AND3(AND((X), (Y)), (Z), (W))
#define OR(X, Y) (NAND(NOT(X), NOT(Y)))
#define OR3(X, Y, Z) OR(OR((X), (Y)), (Z))
#define OR4(X, Y, Z, W) OR(OR((X), (Y)), OR((Z), (W)))
#define XOR(X, Y) OR(AND(X, NOT(Y)), AND(NOT(X), Y))
#define END_CYCLE ({ end_cycle(); putchar('\n'); fflush(stdout); sleep(1); })
#define PRINT(X) printf(#X " = %d; ", X)
wire X, Y, Z, W, X1, Y1, Z1, W1, A, B, C, D, E, F, G;
reg b[4] = {{.value=&W},
{.value=&Z},
{.value=&Y},
{.value=&X}};
void end_cycle() {
PRINT(A); PRINT(B); PRINT(C); PRINT(D);
PRINT(E); PRINT(F); PRINT(G);
}
int main() {
CLOCK {
X1 = NOT(X);
Y1 = NOT(Y);
Z1 = NOT(Z);
W1 = NOT(W);
A = AND(OR4(AND(Z, W1), XOR(X, Z), AND(Y, OR(X, W)), AND3(Y1, Z1, W1)), \
NOT(AND4(X,Y, Z1, W)));
B = OR(OR(AND(X1, Y1), AND3(X, Z1, W)), \
OR(AND3(X, Y1, W1), AND3(X1, Y, OR(AND(Z1, W1), AND(Z, W)))));
C = OR4(XOR(X, Y), AND3(X1, Y1, Z1), AND4(X1, Y1, Z, W), AND4(X, Y, Z1, W));
D = OR4(AND(X, Z1), AND3(Y, Z, W1), AND3(Y1, Z, W), \
OR(AND3(X1, Y1, W1), AND4(X1, Y, Z1, W)));
E = OR4(AND(Z, W1), AND3(X, Z, W), AND3(X, Y, Z1), AND3(Y1, Z1, W1));
F = OR4(AND(X,Y1), AND(Z1, W1), AND(X, Z), OR(AND3(X1, Y, Z1), AND3(Y, Z, W1)));
G = OR4(AND(X, OR3(Y1, W, Z)), AND(Z, W1), AND3(X1, Y, Z1), AND3(X1, Y1, Z));
wire c = 1;
wire value;
for (int i = 0; i < 4; ++i) {
value = XOR(c, *b[i].value);
c = AND(c, *b[i].value);
*b[i].value = value;
}
}
}