Bool A, B and C truth combination - c++

I need to combine 3 bools to test for the entire truth table (8 combinations) in c++.
I have 2 special cases that need to be attended to, they are a, b and c are all true, and a, b are true but c is false.
The rest don't need to be catered for specifically (they will work automatically together without case-specific instructions)
is there a way to only test for these two cases, and then the individual cases but still allow the individuals to work together?
Such as,
if(a && b && c)
and if(a && b && !c)
then if a, if b, if c respectively
I think it uses if else, but I'm having no luck, the way I have it now performs some operations twice as "a" is true in a b c, a b !c and also in a.
I hope this is clear enough, my first time posting here so apologies if it is not.

Your two special cases can be handled something like:
if (a && b)
if (c)
all_true();
else
ab_true_c_false();
Another possibility would be to combine the three arithmetically, then use the result as an index:
typedef void (*action)();
// handlers for the individual cases:
void all_false() { std::cout << "all_false"; }
void a_true() { std::cout << "a true"; }
// ...
// table of handlers. The order of handlers in the array is critical.
static const action actions[] = {
all_false, a_true, b_true, ab_true,
c_true, ac_true, bc_true, abc_true };
// Create index into array
int x = a | (b << 1) | (c << 2);
// invoke correct handler:
actions[x]();

Related

How to get truth table of function (( c + ~d ) * b ) * ~( d + a * e )

SO I have the equation (( c + ~d ) * b ) * ~( d + a * e ) of which I'm trying to generate a truth table but I'm unsure how I would even start with getting the program to compute whether or not the the variable should be equal to true or false according to the truth table. Any suggestions as how to do this? Thank you in advance.
#include<iostream>
using namespace std;
bool checkBoolTF(int a){
bool TF;
if(a == 0){
TF = false;
}
else{
TF = true;
}
return TF;
}
int main()
{
int a,b,c,d,e;
bool aBool, bBool, cBool, dBool, eBool;
string equation = "(( c + ~d ) * b ) * ~( d + a * e )";
bool equationTF;
//LOOP TO TRUTH TABLE - FINAL VALUES
cout << "----------------------------------------------------------------------" << endl;
cout << "| a | b | c | d | e | " << equation << " |" << endl;
cout << "----------------------------------------------------------------------" << endl;
for(a=0;a<=1;a++){
checkBoolTF(a);
for(b=0;b<=1;b++){
checkBoolTF(b);
for(c=0;c<=1;c++){
checkBoolTF(c);
for(d=0;d<=1;d++){
checkBoolTF(d);
for(e=0;e<=1;e++){
checkBoolTF(e);
cout << "| " << a << " | " << b << " | " << c << " | " << d << " | " << e << " | " << equationTF << " |" << endl;
cout << "----------------------------------------------------------------------" << endl;
}
}
}
}
}
return 0;
}
Step 1: Tokenize.
enum class TokenType {
bracket, binop, binaryop, var, literal
};
struct Token {
TokenType type;
char value;
};
convert the string to a vector of token.
You aren't using literal yet: it is the values 0 or 1. You'll use it later.
Write code that pretty prints a vector of tokens.
Step 2: make a simple tree.
struct Tree {
bool is_token=true;
Token token;
std::vector<Tree> tree;
};
change your first code to generate a tree, containing a vector of tokens.
Write code that pretty prints it. Test.
Step 3: Reduce the tree
Step 3a: Brackets
Now do a reduction step; walks a vector of trees and generates one. It copies everuthing that isn't a bracket blindly to the output. If it sees a ( it copies everything until the matching ) (count open and closed) into a sub-tree, then copies that sub-tree into the output.
It takes "a ( b c )" and makes it a then b c in a subtree.
Write code that can pretty print subtrees. Test.
Step 3b: nested brackets
Next, recurse on the subtree you make, so its nested brackets also get put into subtrees.
Step 3c: operators
Next, work on operators. ~ is easy: it swallows the next tree in the vector. As + binds loser than *, for each + make two subtrees; one for everything before, one for everything after. Then do a pass dping the same for *.
After all this, you turn
a+(b+c)*~(d+e)
into
+ (a , ( * (+ (b, c), ~(+(d,e))))
Step 4: substitute
Map a std::map that maps the variable to a value. Take a copy of a tree, and walk it replacing each variable with a literal equal to its value.
Step 5: evaluate
For each operator, evaluate the subtree(s) then apply the operator.
The result should be a 0 or a 1.
4 and 5 can be done independently by starting with a literal expression.
So I have a personal program that implements this for a strings with a form
"Ab|c(d|E)|fa"
my full source code is a complete mess and contains serveral other things I'm trying to do at the same time (failling to simplify the expression by circling kmaps and stuff)
However I can walk through what I've done if it helps
its setup to be easier for me to parse with capitals representing positive and lower case letters representing negation/not () representing sub expressions and [] representing negated sub expressions
so the input string `"ABC(DEF)G(HI(KK)S[as][ge])S" is converted into this .repr() structure
AND(
A
B
C
AND( D E F )
G
AND(
H
I
AND( K K )
S
NAND( !A !S )
NAND( !G !E )
)
S
)
and something like "Ab|cb" is
OR(
AND( A !B )
AND( !C !B )
)
I have a object (I call expression) that contains information about its type stored in something like the following
namespace xpr { //expression types
enum typ {
identity_,
negation_,
and_,
or_,
nand_,
nor_
};
}
class expression{
...
xpr::typ type = xpr::identity_;
char value = ' ';
std::vector<expression> sub_expressions;
...
};
and either a char that is its value or a vector of expressions. (and or nor nand expressions)
Parsing it into this expression form is done through nested constructors that keep passing the current position in the string as well as its level.
finally to answer your question
std::vector<char> vars = trackUsed();
// equivalent to a set but more efficent to do the sort/unique at the end one time.
removeDuplicates(vars);
const auto truth_table_width = vars.size();
const auto truth_table_size = (size_t)std::pow((size_t)2, truth_table_width); // 2^width
expression::test_type test; // abc through !a!b!c
test.reserve(truth_table_width);
for ( const auto &v : vars ) {
// value_type is value: 6, sign: 2 so character has to fit in 6bits and sign in 2.
// minus 'A' to make A-Z 0-26
test.emplace_back(v - 'A', xpr::negative);
}
for ( size_t i = 0; i < truth_table_size; i++ ) {
for ( size_t j = 0; j < truth_table_width; j++ ) {
// converts 0 to negative and 1 to positive
test[j].sign = (xpr::sign_type)((i >> j) & 0x1);
}
bool valid = testValues(test);
if ( valid ) {
sum_of_products.push_back(test);
}
}
I set up a truth table by extracting all the characters used removing duplicates and sorting them. making a vector<vector< implmentation defined object >>
incrementing a value to the max truth table width and using the sign bit of that value to populate the truth table - 0 = [0, 0, ... 1 = [1, 0, ... 2 = [0, 1, ... etc
and then looping through the outer vector and sending the inner vector to a "testValues" member function that is specialized for each expression type
// given A true B true C true see if whole expression evaluates to true.
bool expression::testValues(const potion::test_type& values) const {
if ( this->is_simple() ) {
auto val = std::lower_bound(values.begin(), values.end(),
this->value,
[ ](potion::val_type lhs, char rhs) -> bool {return lhs < rhs; }
);
if ( type == xpr::identity_ ) return (*val).sign;
if ( type == xpr::negation_ ) return !(*val).sign;
}
if ( type == xpr::and_ || type == xpr::nand_ ) {
const bool is_and = type == xpr::and_; //used to combine and and nand expressions and return the oposite val for nand
for ( const auto& e : sub_expressions ) {
if ( e.testValues(values) == false ) return !is_and; // short circuit- if b is false then abc is false
}
return is_and;
}
if ( type == xpr::or_ || type == xpr::nor_ ) {
const bool is_or = type == xpr::or_; //used to combine or and nor and return the oposite val for nor
for ( const auto& e : sub_expressions ) {
if ( e.testValues(values) == true ) return is_or; // short circuit- if b is true then a|b|c is true
}
return !is_or;
}
throw std::runtime_error("Expression can't be simplified. Type not valid"); //should never happen
return false;
}
There's obviously tons and tons of boilerplate code/ parsing code that's probably not the best. And if you want to parse strings using the "custom language" you are defining "(( c + ~d ) * b ) * ~( d + a * e )"
then the parsing code will obviously be a lot different.
Anyway I hope this is helpful for your project. TLDR: might be a bit harder to implement than you initially thought. Although everything I've done is functional the code isn't the cleanest and its heavly setup for my specific case- only obtaining the truth table entries that have are positive and storing them in a sum of product that can be processed further.
For a start, you can simplify the checkBoolTF function to something like:
bool checkBoolTF (int a)
{
return !(a==0);
}
Secondly, it seems like in the for loops, the values returned by this function are not being assigned to anything and are therefore lost. So you probably want to define an aux variable:
bool auxA = checkBoolTF(a);
and so on..
I would like to show an additional, already existing solution. It is well structured and commented. It is published at github. Please see here
The intended purpose of this program is to calculate MCDC test pairs. But it does of course also all that you want. I do not recommend to copy and paste, but you could read and learn, how to do your implementation.
This code reads exactly the strings that you specified. It also creates a truth table. But this is only a minor part of the whole functionality.
So, what you need to do, is, to compile the string in something that could can be evaluated as a boolean expression.
For that, I first defined the input alphabet and the language, described by a grammar. Then, I created a compiler, consisting of a scanner (lexer), parser and code generator. Actually I created 2 compilers, with the same front end and 2 different back ends. So, 2 different code generators. One, for a virtual machine that can evaluate the boolean expression for any combination of input variables. And, the 2nd backend, will create an abstract syntax tree, with which I evaluate all possible MCDC test pairs.
As said, the first code generator creates Op code for a virtual machine. With this machine, the truth table and with that all minterms are calculated. Then Quine and McCluskey is used (2 different implementations) to minimize the boolean expression. And at the end, and optimzed version of Petricks method is used to solve the unate coverage problem and identify the minimum set of prime implicants.
The MCDC part is maybe a little bit too complex to explain here.
But the main message is, that you first need to parse your string and convert it in something executable.
Then you can evaluate whatever you want.

Shorten If Statement And Making It Less Redundant

New here. I was just wondering if it's possible to make this if statement shorter and less redundant.
if (!a && b)
{
if (c == d && e > 0)
{
return;
}
}
else if (a && !b)
{
if (c != d)
{
return;
}
}
else if (!a && !b)
{
return;
}
Here's what I've ended up with
if ((!a && b && c == d && e > 0) || (a && !b && c != d) || (!a && !b))
{
return;
}
All I did was join nested if statements with an && operator, and if-else if statements with || operator. Now I'm stuck, is it possible to make this even shorter? If you could share some tips or your way of approaching this kind of scenario, I'd be glad to hear it out.
Neither of the approaches is readable. It will be better to create a function that indicates the kinds of checks you are performing.
if ( !my_very_sensible_special_conditions_are_met(a, b, c, d, e) )
{
return;
}
After that, whether you use the first approach or the second approach in the implementation of the function is less of an issue.
condition ladder(if,else if) shortening
As you mentioned, in all blocks(if, else if) if you are just having the same set of statements then you can put all the conditions with a single if statement with proper conditions with appropriate brackets.By doing this lines of code will get reduced But you will have some disadvantages as per my point of view
Readability will get reduced
In future, if you want to change your code for a particular condition, it will take some time to change.it is not that much easy as you do in condition ladder
if you are not having any problem with the above two points, you can go with your approach itself.But code your conditions as atomic as possible.it will help you out in a long run.
Given the number and complexity of conditions, I'd at least consider making it table driven. For the moment, I've assumed that a and b are actually ints containing either a 0 or a 1.
int index = a | (b<<1) | (int(c==d)<<2) | (int(e>0) << 3);
static const bool should_return[] = {
1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0
};
if (should_return[index])
return;
The table is still basically incomprehensible, but at least it encodes that incomprehensibility fairly compactly, and makes it easy for the code to use it.
Since you commented that you are always returning, and since your code does not specify if you do anything else in these if - else cases why not do just
if (! (a && b) )
{
return;
}
You can shorten it a tiny bit further:
if (!a && !b || !b && c != d || !a && c==d && e> 0) {
return;
}
But that doesn't increase readability and most likely also not performance. What I would focus on is, what reads most natural with the real variable names.
As a general advice, I'd start with checking the simpler / shorter conditions first. That makes it often more easier to see if you make redundant checks in the following ones.
In any case, as #R.Sahu suggested, a complex condition like that belongs into a separate, named and commented function. If you don't find a good name for it use something generic like e.g. check_<main_function>_preconditions.
EDIT:
Sorry, I can't resist: If you wan to go overboard, you can make it pretty compact by throwing in a trinary statement:
if (!a && !b || c != d ? !b : !a && e> 0) {
return;
}
DON'T do that in production code!

Simple way to check a large number of similar conditions?

I am working on a game, and I am finding myself very often checking that certain quantities are in the bounds of the indexes accepted by the vector that represents my world:
if(a >= 0 && a < 16 && b >= 0 && b < 16 && c >= 0 && c < 16 &&
d >= 0 && d < 16 && e >= 0 && e < 16)
{
//do things with vector[a][b][c][d][e]
}
I often have to check even more conditions than this. Is there a way that I can make these checks more concise and/or easier to read?
Alternatively, is there a way that I can avoid doing the checks entirely? The vector is 16x16x16x16x16; can I make it so that if I were to give it a 16 as an index, it would do nothing rather than segfault?
You could write a variadic check function:
bool check(int a) {
return 0 <= a && a < 16;
}
template<typename... Args>
bool check(int a, Args... args) {
return check(a) && check(args...);
}
You can use it like check(a, b, c, d, e, ...). It also has the advantage of being able to take any number of conditions.
Here's a demo
Here's a compact and efficient way to do the check. It assumes two's complement arithmetic.
bool IsInBounds(int a, int b, int c, int d, int e)
{
// Make sure only bits 0-3 are set (i.e. all values are 0-15)
return ((a | b | c | d | e) & ~0xf) == 0;
}
This works by noting that all values outside the 0-15 range all have a bit set that isn't one of the four least significant ones, and all values inside the range don't.
Of course it's only worth using this sort of optimization if the gains in efficiency outweigh the loss of code readability.
The point of functions is reusability. If you find yourself writing certain long expressions or groups of statements repeatedly, it might be time to refactor it out.
In this case, I would write a simple function to do the bounds checking:
bool isInBounds(int a, int b, int c, int d, int e)
{
return a >= 0 && a < 16 &&
b >= 0 && b < 16 &&
c >= 0 && c < 16 &&
d >= 0 && d < 16 &&
e >= 0 && e < 16;
}
Then use it instead of your long condition:
if (isInBounds(a, b, c, d, e))
{
// do things with array[a][b][c][d][e]
}
You can store your variables as elements in a std::vector rather than separate variabes like this:
bool test(const std::vector<int>& values)
{
for(auto v: values)
if(v < 0 || v >= 16)
return false;
return true;
}
Alternatively if you are using C++11 or later you can use std::all_of:
if(std::all_of(std::begin(values), std::end(values),
[](int i){ return i >= 0 && i < 16; }))
{
// do stuff with values
}
In that case you may also be able to use a std::array.
You could combine the 5 integers making up your index into one std::array or your own class.
using Index5 = std::array<int, 5>;
Then you can write a function like:
bool contains(Index5 bounds, Index5 point) {
for (Index5::size_type d = 0; d != bounds.size(); ++d) {
if ((unsigned)point[d] > bounds[d]) // using the trick mentioned in comments
return false;
}
return true;
}
Then use it like this:
auto bounds = Index5{16, 16, 16, 16, 16};
auto point = Index5{a, b, c, d, e};
if (contains(bounds, point)) {
// do things with point
}
Generally, I would suggest using something like Index5 instead of managing five integers.
If the quantities a, b, c, d, and e are something that occur
together quite frequently and all need to stay within the bounds
of your "world" (e.g. they represent the "state" of something in that world)
then it might make sense to define a class whose primary purpose is
to hold one "state" consisting of those five quantities.
Then make sure that if any code ever tries to store values in an object
of that class that are not within the bounds, something reasonable
(not a segfault) happens instead,
and no out-of-bounds values are ever stored there.
That way, an object of that class is safe to pass to any function that
requires a, b, c, d, and e to be within bounds,
and there is no need for any such function to do bounds-checking
on those five values.

How does that recursive function work?

Might be a very basic question but I just got stuck with it. I am trying to run the following recursive function:
//If a is 0 then return b, if b is 0 then return a,
//otherwise return myRec(a/2, 2*b) + myRec(2*a, b/2)
but it just gets stuck in infinite loop. Can anybody help me to run that code and explain how exactly that function works? I built various recursive functions with no problems but this one just drilled a hole in my head.
Thanks.
Here is what I tried to do:
#include<iostream>
int myRec(int a, int b){
if (a==0){
return b;
}
if (b==0){
return a;
}
else return myRec(a/2, 2*b) + myRec(2*a, b/2);
}
int main()
{
if (46 == myRec(100, 100)) {
std::cout << "It works!";
}
}
Well, let us mentally trace it a bit:
Starting with a, b (a >= 2 and b >= 2)
myRec(a/2, 2*b) + something
something + myRec(2*a', b'/2)
Substituting for a/2 for a' and 2*b for b', we get myRec(2*(a/2), (b*2)/2), which is exactly where we started.
Therefore we will never get anywhere.
(Note that I have left out some rounding here, but you should easily see that with this kind of rounding you will only round down a to the nearest even number, at which point it will be forever alternating between that number and half that number)
I think you are missing on some case logic. I last program in C ages ago so correct my syntax if wrong. Assuming numbers less than 1 will be converted to zero automatically...
#include<iostream>
int myRec(int a, int b){
// Recurse only if both a and b are not zero
if (a!=0 && b!=0) {
return myRec(a/2, 2*b) + myRec(2*a, b/2);
}
// Otherwise check for any zero for a or b.
else {
if (a==0){
return b;
}
if (b==0){
return a;
}
}
}
UPDATE:
I have almost forgot how C works on return...
int myRec(int a, int b){
if (a==0){
return b;
}
if (b==0){
return a;
}
return myRec(a/2, 2*b) + myRec(2*a, b/2);
}
VBA equivalent with some changes for displaying variable states
Private Function myRec(a As Integer, b As Integer, s As String) As Integer
Debug.Print s & vbTab & a & vbTab & b
If a = 0 Then
myRec = b
End If
If b = 0 Then
myRec = a
End If
If a <> 0 And b <> 0 Then
myRec = myRec(a / 2, 2 * b, s & "L") + myRec(2 * a, b / 2, s & "R")
End If
End Function
Sub test()
Debug.Print myRec(100, 100, "T")
End Sub
Running the test in Excel gives this (a fraction of it as it overstacks Excel):
T: Top | L: Left branch in myRec | R: Right branch in myRec
The root cause will be the sum of the return which triggers more recursive calls.
Repeating of the original values of a and b on each branch from level 2 of the recursive tree...
So MyRec(2,2) = MyRec(1,4) + MyRec(4,1)
And MyRec(1,4) = MyRec(.5,8) + MyRec(2,2)
So MyRec(2,2) = MyRec(.5,8) + MyRec(2,2) + MyRec(4,1)
Oops.
(The .5's will actually be zeroes. But it doesn't matter. The point is that the function won't terminate for a large range of possible inputs.)
Expanding on gha.st's answer, consider the function's return value as a sum of expressions without having to worry about any code.
Firstly, we start with myRec(a,b). Let's just express that as (a,b) to make this easier to read.
As I go down each line, each expression is equivalent, disregarding the cases where a=0 or b=0.
(a,b) =
(a/2, 2b) + (2a, b/2) =
(a/4, 4b) + (a, b) + (a, b) + (4a, b/4)
Now, we see that at a non-terminating point in the expression, calculating (a,b) requires first calculating (a,b).
Recursion on a problem like this works because the arguments typically tend toward a 'base case' at which the recursion stops. A great example is sorting a list; you can recursively sort halves of the list until a list given as input has <= 2 elements, which is trivial without recursion. This is called mergesort.
However, your myRec function does not have a base case, since for non-zero a or b, the same arguments must be passed into the function at some point. That's like trying to sort a list, in which half of the list has as many elements as the entire list.
Try replacing the recursion call with:
return myRec(a/2, b/3) + myRec(a/3, b/2);

Advice for POUR1 on SPOJ?

I need help with this problem POUR1. I think
it can be solved with bruteforce approach, but I read that it is a graph problem (BFS). I solved problems like ABCPATH, LABYR1, PT07Y, PT07Z, BITMAP, ...
But I don't know how to approach POUR1 in BFS manner.
Can someone give me some advice?
Problem statement:
Given two vessels, one of which can accommodate a litres of water and the other - b litres of water, determine the number of steps required to obtain exactly c litres of water in one of the vessels.
At the beginning both vessels are empty. The following operations are counted as 'steps':
emptying a vessel,
filling a vessel,
pouring water from one vessel to the other, without spilling, until one of the vessels is either full or empty.
Input:
An integer t, 1<=t<=100, denoting the number of testcases, followed by t sets of input data, each consisting of three positive integers a, b, c, not larger than 40000, given in separate lines.
Output:
For each set of input data, output the minimum number of steps required to obtain c litres, or -1 if this is impossible.
Example:
Sample input:
2
5
2
3
2
3
4
Sample output:
2
-1
This question has a simpler solution. No need for BFS. Ad-hoc would do good.
method 1 - fill A, empty it into B. whenever A becomes empty fill it back, whenever B becomes full empty it. (all the above-mentioned actions count as individual moves). Continue this process until you arrive at the required amount of water in any one of the vessels. Get the number of moves here. (say C1).
method 2 - fill B, empty it into A. whenever B becomes empty fill it back, whenever A becomes full empty it. Continue this until you arrive at the required amount. Get the number of moves say C2).
The answer is min(C1,C2).
Source code in C++:
#include < cstdio >
#include < algorithm >
using namespace std;
int pour(int A, int B, int C) {
int move = 1, a = A, b = 0, tfr;
while (a != C && b != C) {
tfr = min(a, B - b);
b += tfr;
a -= tfr;
move++;
if (a == C || b == C)
break;
if (a == 0) {
a = A;
move++;
}
if (b == B) {
b = 0;
move++;
}
}
return move;
}
/** Reason for calculating GCD of a,b is to check whether an integral solution of
* equation of form ax + by = c exist or not, to dig deeper read Diophantine Equations
*/
int gcd(int a, int b) {
if (b == 0)
return a;
return gcd(b, a % b);
}
int main() {
int t, a, b, c;
scanf("%d", & t);
while (t--) {
scanf("%d%d%d", & a, & b, & c);
if (c > a && c > b)
printf("-1\n");
else if (c % gcd(a, b) != 0)
printf("-1\n");
else if (c == a || c == b)
printf("1\n");
else
printf("%d\n", min(pour(a, b, c), pour(b, a, c)));
}
return 0;
}
Consider the set of all a priori possibles states (eg [3, 7] meaning Vessel1 contains 3 litters and vessel2 contains 7 litters). You have a directed graph whose vertices are those states and whose edges are the possible moves. The question is to find a path in the graph joining the state [0, 0] to either a state of type [c, ?] or a state of type [?, c]. Such a path is typically searched by a BFS.