175 lines
2.9 KiB
C
175 lines
2.9 KiB
C
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
#include <stdint.h>
|
|
#include <math.h>
|
|
|
|
|
|
bool SolveFor(char* func, uint32_t vars, uint8_t* varMap)
|
|
{
|
|
char stack[1024];
|
|
int stackPtr;
|
|
int ptr;
|
|
bool valueA;
|
|
bool valueB;
|
|
|
|
stackPtr = 0;
|
|
ptr = 0;
|
|
|
|
while (func[ptr] != 0)
|
|
{
|
|
switch (func[ptr])
|
|
{
|
|
case '~':
|
|
{
|
|
assert(stackPtr > 0);
|
|
valueA = stack[stackPtr - 1];
|
|
stack[stackPtr-1] = !valueA;
|
|
break;
|
|
}
|
|
|
|
case '&':
|
|
{
|
|
assert(stackPtr > 1);
|
|
|
|
valueA = stack[--stackPtr];
|
|
valueB = stack[stackPtr-1];
|
|
|
|
stack[stackPtr - 1] = valueA && valueB;
|
|
break;
|
|
}
|
|
|
|
case '|':
|
|
{
|
|
assert(stackPtr > 1);
|
|
|
|
valueA = stack[--stackPtr];
|
|
valueB = stack[stackPtr-1];
|
|
|
|
stack[stackPtr - 1] = valueA || valueB;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
if (func[ptr] == '0') stack[stackPtr++] = 0;
|
|
else if (func[ptr] == '1') stack[stackPtr++] = 1;
|
|
else if (func[ptr] >= 'a' && func[ptr] <= 'z')
|
|
{
|
|
assert(varMap[func[ptr] - 'a'] != 255);
|
|
stack[stackPtr++] = (vars >> varMap[func[ptr] - 'a']) & 0x01;
|
|
}
|
|
else assert(false);
|
|
break;
|
|
}
|
|
}
|
|
ptr++;
|
|
}
|
|
|
|
assert(stackPtr == 1);
|
|
return stack[stackPtr-1] != 0;
|
|
}
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
char* formula = "p&q|a&b&~d&c|e&f|x&y|z|g&h&i&j";
|
|
int ptr;
|
|
char stack[1024];
|
|
char output[1024];
|
|
int stackPtr;
|
|
int outPtr;
|
|
int varCount;
|
|
uint8_t varMap[26];
|
|
|
|
ptr = 0;
|
|
stackPtr = 0;
|
|
outPtr = 0;
|
|
memset(varMap, 255, 26);
|
|
varCount = 0;
|
|
|
|
while(formula[ptr] != 0)
|
|
{
|
|
switch (formula[ptr])
|
|
{
|
|
case '~':
|
|
{
|
|
stack[stackPtr] = formula[ptr];
|
|
stackPtr++;
|
|
break;
|
|
}
|
|
|
|
case '&':
|
|
{
|
|
if (stackPtr > 0 && stack[stackPtr-1] == '~')
|
|
{
|
|
output[outPtr++] = stack[--stackPtr];
|
|
}
|
|
|
|
stack[stackPtr] = formula[ptr];
|
|
stackPtr++;
|
|
break;
|
|
}
|
|
|
|
case '|':
|
|
{
|
|
if (stackPtr > 0)
|
|
{
|
|
output[outPtr++] = stack[--stackPtr];
|
|
}
|
|
|
|
stack[stackPtr] = formula[ptr];
|
|
stackPtr++;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
if (formula[ptr] >= 'a' && formula[ptr] <= 'z')
|
|
{
|
|
/** we got a variable **/
|
|
output[outPtr] = formula[ptr];
|
|
outPtr++;
|
|
if (varMap[formula[ptr] - 'a'] == 255)
|
|
varMap[formula[ptr] - 'a'] = varCount++;
|
|
}
|
|
else if (formula[ptr] == '0' || formula[ptr] == '1')
|
|
{
|
|
output[outPtr] = formula[ptr];
|
|
outPtr++;
|
|
}
|
|
else
|
|
{
|
|
printf("Unknown symbol %c!\n", formula[ptr]);
|
|
assert(false);
|
|
}
|
|
}
|
|
}
|
|
ptr++;
|
|
}
|
|
|
|
while (stackPtr > 0)
|
|
{
|
|
output[outPtr++] = stack[--stackPtr];
|
|
}
|
|
|
|
output[outPtr] = 0;
|
|
|
|
// print pretty header
|
|
for (int i = 0; i < 26; i++)
|
|
if (varMap[i] != 255)
|
|
printf("%c ", 'a'+i);
|
|
printf("Result\n");
|
|
|
|
// dirty hack
|
|
for (uint32_t i = 0; i < pow(2, varCount); i++)
|
|
{
|
|
// pretty printing
|
|
for (int j = 0; j < 26; j++)
|
|
if (varMap[j] != 255)
|
|
printf("%i ", (i >> varMap[j]) & 0x01);
|
|
printf("%i\n", SolveFor(output, i, varMap));
|
|
}
|
|
|
|
return 0;
|
|
}
|