Generic rules to build numeric multipliers from truth tables - javascript

I have some truth tables, mostly AND, based on 0, 1, -1 which I am using for Math operations:
Example 1:
var a,b,c;
if(a == 1 && b == 1) c = 0;
if(a == 1 && b == 0) c = 0;
if(a == -1 && b == 1) c = 0;
if(a == -1 && b == 0) c = 1;
Example 2:
var a,b,c;
if(a === 1 && b === 1) c = 1;
if(a === 1 && b === 0) c = 1;
if(a === -1 && b === 1) c = 1;
if(a === -1 && b === 0) c = -1;
For instance, the first one could be expressed as follows:
c = (a>>1)*(b-1);
I would like to convert also the second truth table using only Math or Bitwise Operators, how can it be done?
Is there any generic rule to easily create such kind of one-line expression?

You can use a generic superoptimizer such as this one I wrote (unfortunately not very user friendly): https://github.com/falk-hueffner/sematrope
This will give you (a + b) >>> 31 for your first example and ((a + b) | b) & a for the second.
For a more systematic approach, you can convert -1/1 to 0/1 by (x >> 1) + 1, do regular logic operations with |&^, and then (if needed) convert 0/1 to -1/1 by x ^ (x - 1).

If a is always 1 or -1 and b is always 1 or 0, and you're OK to use a boolean operator (||), then
c = b || a
should do it...
const c = (a, b) => b || a
console.log(c( 1, 1)) // 1
console.log(c( 1, 0)) // 1
console.log(c(-1, 1)) // 1
console.log(c(-1, 0)) //-1

Related

JavaScript return condition

Is it possible to have conditions in return in JavaScript?
Like in this case:
if
(A > 0 || B > 0)
return "A";
else return "C"
As long as A or B is > 0 return the one that is > 0 (so A or B). Is that possible? Like another condition as return, for example?
Maybe this is similar to what you are trying to do. My function eval() takes two parameters A and B, and checks different conditions to see which is the positive number. I am using the Logical AND && instead of || because I want my code to know the value of each parameter in each condition.
function eval(A, B) {
if (A > 0 && B <= 0) {
return 'A';
}
if (A <= 0 && B > 0) {
return 'B';
}
if (A > 0 && B > 0) return "Both A and B are positive numbers";
}
console.log(eval(2, -5));
console.log(eval(0, 8));
console.log(eval(1, 1));
Try this.
return (A > 0 || B > 0) ? "A" : "C"
It's a ternary operator. Here you have more information:
Conditional (ternary) operator
if(A > 0 || B > 0)
return A > 0 ? "A" : "B";
else return "C";

Evaluate triangle by its side

My question is about using Javascript to do triangle evaluation by its sides. The following code is very initial version even it works. I'd like to know whether it could be more simplifying or there is other way to achieve the same result.
Thanks!
let a = Number(prompt('Please input the the first side (a)'))
let b = Number(prompt('Please input the the second side (b)'))
let c = Number(prompt('Please input the the third side (c)'))
if (a + b <= c || b + c <= a || c + a <= b || Number.isNaN(a) || Number.isNaN(b) || Number.isNaN(c) || a == "" || b == "" || c == ""){
console.log("invalid")
}
else if ((a > 0 && b >0 && c >0 ) && (a == b && b == c && c == a)){
console.log("equilateral triangle")
}
else if ((a > 0 && b >0 && c >0 ) && (a == b || b == c || c == a)){
console.log("isosceles triangle")
}
else {
console.log("scalene triangle")
}
Another way could be to explicitly convert the lengths to a number (0 for NaN) and sort them first. And a ternary operator can be useful here also:
let [d, e, f] = [a, b, c].map(a => +a || 0).sort((a, b) => a-b);
let result = d + e <= f ? "invalid"
: d === f ? "equilateral"
: d < e && e < f ? "scalene"
: "isosceles";
console.log(result);
This will not be the fastest when doing many thousands of them, but I like the look of it.
Explanation
[a, b, c] turns the three values into an array.
.map is a method available for arrays. For each original value in [a, b, c] the following (arrow) function is executed,
a => +a || 0
map creates a new array consisting of the results of calling that function on each separate value (so first with a, then with b and finally with c)
+a uses the unary plus as a short way of turning a value into a number, which means that you could omit the Number() calls you did in the first three lines of your code. When the result of this is NaN or 0, then || 0 will kick in: instead of NaN or 0, 0 will be taken instead (|| is a logical OR operator and 0 will only be used when the left side is considered "falsy"). This practically means that NaN is replaced by 0.
So up to now the code has roughly done something similar to the following:
let newarray = [];
newarray[0] = +a;
if (Number.isNaN(newarray[0])) newarray[0] = 0;
newarray[1] = +b;
if (Number.isNaN(newarray[1])) newarray[1] = 0;
newarray[2] = +c;
if (Number.isNaN(newarray[2])) newarray[2] = 0;
Then another array method is called on that array returned by .map(): the method .sort(). That method will use the provided callback function (a, b) => a-b to make comparisons in the array and sort it based on the values returned by such calls. It is up to the sort method to decide for which pairs this function is called. When the returned value is negative, it means the compared values are already in increasing order. When positive, they should be rearranged. When zero, they should be considered equal to the sort algorithm.
So... we now have an array that consists of numbers which are guaranteed to no longer have a NaN, and which are sorted in ascending order.
Then that array is assigned using so-called destructuring:
let [d, e, f] =
This means that the individual values of the sorted array are assigned one by one to three new variables. So this is roughly short for:
let d = new_sorted_array[0];
let e = new_sorted_array[1];
let f = new_sorted_array[2];
Because these values are now ordered, we can use them for much simpler comparisons to decide on the shape of the triangle. What follows is an expression using a chain of ternary operators which much resemble an if (...) ... else if ... chain. So:
let result = d + e <= f ? "invalid"
: d === f ? "equilateral"
: d < e && e < f ? "scalene"
: "isosceles";
... is short for this:
let result;
if (d + e <= f) result ="invalid"
else if (d === f) result = "equilateral"
else if (d < e && e < f) result = "scalene"
else result = "isosceles";
You can reduce alot of bulk and change the implementation:
You can make the user input a function call
You can place the input into an array
You can use every to make sure every value is greater than 0
You can use a new Set to remove duplicates, if the size is 1, then all sides are the same, if it's 2, then 2 sides are the same, if it's 3, all sides are different
const getSide = l => Number(prompt(`Please input the the second side (${l})`))
const sides = [getSide('a'), getSide('b'), getSide('c')]
if (sides.every(el => el > 0)) {
const size = new Set(sides).size
if (size === 1) console.log("equilateral triangle")
else if (size === 2) console.log("isosceles triangle")
else console.log("scalene triangle")
} else {
console.log("invalid")
}
Test cases:
const test = sides => {
if (sides.every(el => el > 0)) {
const size = new Set(sides).size
if (size === 1) console.log("equilateral triangle")
else if (size === 2) console.log("isosceles triangle")
else console.log("scalene triangle")
} else {
console.log("invalid")
}
}
test([0,1,2]) // invalid
test([NaN,NaN,NaN]) // invalid
test(['',1,2]) // invalid
test([3,3,3]) // eq
test([2,2,3]) // iso
test([1,2,3]) // sca

What means this kind of expression with logics operators

I have an boolean expression in javascript and i don't know what it means.
a = (b === LEFT && -2 || b === RIGHT && 2 || 0)
Please what does it mean ?
The && is a hacky shortcut if:
if (B === LEFT) {
a = -2;
} else if (B === RIGHT) {
a = 2;
} else {
a = 0;
}
one more shortcut with ternary operator
a = b === LEFT? -2: (b === RIGHT? 2 : 0)

Is >= equal to > || === or > || == in JavaScript? [duplicate]

This question already has answers here:
Why `null >= 0 && null <= 0` but not `null == 0`?
(6 answers)
Closed 4 years ago.
Is the below if statement
if (a >= b)
Equal to this?
if (a > b || a === b)
Or is it equal to this?
if (a > b || a == b)
It is equivalent to if(a > b || a == b)
var a = "2";
var b = 2;
console.log(a >= b); // true
console.log(a > b || a == b); // true (== compares value)
console.log(a > b || a === b); // false (=== compares value and type)
You can test it in the console:
var a = 0;
var b = '0';
a == b; // true
a === b; // false
a >= b; // true
Ergo, >= is equivalent to > || ==.
The actual result depend on the use case if the typeof both a & b is same then (a >= b) is same as (a > b || a === b). This is because == is equality with type coercion
var a = "2";
var b = "2";
console.log(a >= b); // true
console.log(a > b || a == b); // true
console.log(a > b || a === b); // true
var a = "4";
var b = 4;
console.log(a >= b); // true
console.log(a > b || a == b); // true
console.log(a > b || a === b); // false
Actually the first one
if(a >= b)
is similiar to
if(a > b || a == b)
but not equals to
if(a > b || a === b)
because in this last one you are even comparing the type of both the operands.
Example:
x = "5"
console.log(x==parseInt(x)) will return true
console.log(x===parseInt(x)) will return false
So, == does not consider the types of operands.
It depends. If before the statement you had defined a or b with a different type,
if(a > b || a === b)
will return false if the first clause is not true. However if you didn't define a or b before both will have the same type and both expressions are equivalent.
You can understand "===" as
(a == b && sameType(a,b))

jQuery if condition 1 or condition 2 is true than

I am trying to alert "yes" if ether of the conditions in my if statement are true:
var a = 2;
var b = 1;
if (a = 1 or b = 1 ) {
alert('yes');// should alert in this case
} else {
alert('no');
}
https://jsfiddle.net/90z7urvd/1/
What do I use for the if, if this is possible?
a = 1 will set the value 1 to variable a. It is not doing a comparison. For comparison, you use === or ==
=== (Identity operator) is the correct way to compare if both the types are same.
if (a === 1 || b === 1 ) {
=== operator won't do the type conversion before the comparison while == does the type conversion before the comparison.
For your or case, You may use || operator
var bootresul = someExpression || anotherExpression
Corrected code
var a = 2;
var b = 1;
if (a === 1 || b === 1 ) {
alert('yes');
} else {
alert('no');
}
You are assiging value rather then comparing
Try like this
if (a == 1 || b == 1)
To compare strictly use ===
Like this
if (a === 1 || b === 1)
JSFIDDLE
you can do this
var a = 2;
var b = 1;
if ((a == 1) || (b == 1 )) {
alert('yes');// should alert in this case
} else {
alert('no');
}
the == is one of the relational operator for checking equality and || is a logical operator that is a notion of logical OR
use this to compare just values
if (a == 1 || b == 1){
}
OR use this to compare values and type of variable
if (a === 1 || b === 1){
}
note : == will just check of values and === this will check value with type of variable
var a = 2;
var b = 1;
if (a == 1 || b == 1 ) {
alert('yes');// should alert in this case
} else {
alert('no');
}
I think you were doing assignment instead of comparison
Try using this:
if(a === 1 || b === 1){
alert('YES!')
}else{
alert('NO!')
}
OR you can use ternary operator condition instead of if else
(a == 1 || b == 1) ? alert('YES!') : alert('NO!')

Categories

Resources