int f_and (int i, int n) {return (i & 1) & ((i >> 1) & 1);}
int f_or (int i, int n) {return (i & 1) | ((i >> 1) & 1);}
int f_user(int i, int n) {
int j, in[n], out;
for (j = 0; j < n; j++) in[j] = (i >> j) & 1;
out = in[0] & in[1] & in[2];
return out;
}
int main()
{
struct {int (*f)(int, int); int n; char *s;} g[] = {
{f_and, 2, "AND"}, {f_or, 2, "OR"}, {f_user, 3, "USER"},
};
int i, j, h, m;
for (j = 0; j < sizeof(g) / sizeof(g[0]); j++) {
for (i = 0, h = 0, m = 1 << g[j].n; i < m; i++) h += g[j].f(i, g[j].n);
printf("%s: %f\n", g[j].s, (double) h / m);
}
return 0;
}
enum {cmd_and, cmd_or, cmd_p, cmd_end};
int sp;
int s[1000];
int push(int i) { return s[sp++] = i; }
int pop(void) { return s[--sp]; }
int circuit(int i, int *cmd)
{
int n, *c = cmd;
while (*c++ != cmd_end);
for (c--, sp = 0; c >= cmd; c--) {
switch (*c) {
case cmd_p:
n = *(--c);
push((i >> (n - 1)) & 1);
break;
case cmd_and:
push(pop() & pop());
break;
case cmd_or:
push(pop() | pop());
break;
}
}
return pop();
}
int main(int argc, char* argv[])
{
int v;
int cmd[1000];
int *c = cmd;
int i, h, n, np;
char *p;
double r;
if (argc < 4) {
fprintf(stderr, "usage: %s AND P1 OR P2 P3...\n", argv[0]);
return 1;
}
np = 0;
while (--argc) {
if (!strcmp(*(++argv), "AND")) {
*c++ = cmd_and;
} else if(!strcmp(*argv, "OR")) {
*c++ = cmd_or;
} else if(**argv == 'P') {
v = (int) strtol(*(argv) + 1, &p, 0);
if (!*p && v > 0) {
*c++ = v;
*c++ = cmd_p;
if (v > np) np = v;
} else {
fprintf(stderr, "invalid port number\n");
return 1;
}
} else {
fprintf(stderr, "unknown command\n");
return 1;
}
}
*c = cmd_end;
for (i = 0, h = 0, n = 1 << np; i < n; i++) h += circuit(i, cmd);
r = (double) h / n;
printf("%f\n", 1 - r);
printf("%f\n", r);
return 0;
}
int gate_status(struct gate *gate)
{
int i, j;
if (gate->type == IN) {
i = port_num(gate);
return in_stat >> i & 1;
}
j = gate_status(gate->input[0]);
for (i = 1; i < gate->num_inputs; i++) {
switch (gate->type) {
case AND:
case NAND:
j &= gate_status(gate->input[i]); break;
case OR:
case NOR:
j |= gate_status(gate->input[i]); break;
case EXOR:
case EXNOR:
j ^= gate_status(gate->input[i]); break;
}
}
return j ^ (gate->type & 1);
}
int main(int argc, char *argv[])
{
int i, j;
int num_inputs=0, num_stats;
for (i = 0; i < sizeof(gates)/sizeof(gates[0]); i++) {
for (j = 0; j < gates[i].num_inputs; j++) {
if (gates[i].input[j]->type == IN) {
int n = port_num(gates[i].input[j]);
if (n > num_inputs) num_inputs = n;
}
}
}
num_inputs++;
num_stats = 1 << num_inputs;
for (i = 0; i < sizeof(gates)/sizeof(gates[0]); i++) {
double op = 0.0;
for (in_stat = 0; in_stat < num_stats; in_stat++) {
double p = 1.0;
for (j = 0; j < num_inputs; j++) {
if (in_stat >> j & 1)
p *= 1-ports[j].p0;
else
p *= ports[j].p0;
}
if (gate_status(&gates[i])) op += p;
}
printf("gate%d: p0=%f p1=%f\n",i,1-op,op);
}