mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 14:16:09 -06:00
84 lines
1.7 KiB
C++
84 lines
1.7 KiB
C++
#include "gen.h"
|
|
|
|
void Circuit::Evaluate(byte *value) const
|
|
{
|
|
byte newvalue[COUNT];
|
|
for(int i = 0; i < COUNT; i++) {
|
|
const Nand& n = nand[i];
|
|
newvalue[i] = ~(value[n.i1] & value[n.i2]);
|
|
}
|
|
memcpy(value, newvalue, COUNT);
|
|
}
|
|
|
|
void Circuit::SetRandom()
|
|
{
|
|
for(int i = 0; i < COUNT; i++) {
|
|
Nand& n = nand[i];
|
|
n.i1 = (word)Random() % COUNT;
|
|
n.i2 = (word)Random() % COUNT;
|
|
}
|
|
}
|
|
|
|
void Breed(Circuit& d, const Circuit& a, const Circuit& b)
|
|
{
|
|
for(int i = 0; i < COUNT; i++)
|
|
d.nand[i] = Random() & 1 ? a.nand[i] : b.nand[i];
|
|
}
|
|
|
|
int Compute(const Circuit& c, byte *out, int outcount, const byte *in, int incount, int limit = 100)
|
|
{
|
|
byte value[COUNT];
|
|
memset(value, 0, COUNT);
|
|
int w = 0;
|
|
for(int i = 0; i < incount; i++)
|
|
for(int q = 0x80; q; q >>= 1)
|
|
value[w++] = !!(q & in[i]);
|
|
|
|
memset(out, 0, outcount);
|
|
for(int ii = 0; ii < limit; ii++) {
|
|
c.Evaluate(value);
|
|
Buffer<byte> nout(outcount, 0);
|
|
int r = w;
|
|
for(int i = 0; i < outcount; i++) {
|
|
nout[i] = 0;
|
|
for(int q = 0x80; q; q >>= 1)
|
|
if(value[r++])
|
|
nout[i] |= q;
|
|
}
|
|
if(memcmp(out, ~nout, outcount) == 0)
|
|
return ii;
|
|
memcpy(out, ~nout, outcount);
|
|
}
|
|
return limit;
|
|
}
|
|
|
|
int Test(Circuit& c, bool print)
|
|
{
|
|
int bad = 0;
|
|
for(int x = 0; x < 8; x++) {
|
|
for(int y = 0; y < 8; y++) {
|
|
byte in[2];
|
|
in[0] = x;
|
|
in[1] = y;
|
|
byte out;
|
|
Compute(c, &out, 1, in, 2);
|
|
if(print)
|
|
LOG((int)x << '+' << (int)y << '=' << (int)out);
|
|
bad += x + y != out;
|
|
}
|
|
}
|
|
return bad;
|
|
}
|
|
|
|
CONSOLE_APP_MAIN
|
|
{
|
|
Circuit h;
|
|
for(;;) {
|
|
h.SetRandom();
|
|
int b = Test(h, false);
|
|
DDUMP(b);
|
|
if(b != 63)
|
|
break;
|
|
}
|
|
Test(h, true);
|
|
}
|