I have the following rather verbose conditional, I'm trying to wrap my head around a simpler version but I'm not getting anywhere.
if( agent % $.settings.gridSize === 0 && value % $.settings.gridSize == 1 ){
// Dud
}else if(agent % $.settings.gridSize == 1 && value % $.settings.gridSize === 0){
// Dud
}else{
freeCells.push(value);
}
Is there a way I can achieve the same condition with a single if statement, rather than using the throw-away if else?
Something like:
if(!(a && b) && !(x && y)){
// Do stuff
}
Yes, it's possible and you've (almost) answered your question yourself.
You can do the following:
var gS = $.settings.gridSize;
if(!(agent % gS === 0 && value % gS == 1) && !(agent % gS == 1 && value % gS === 0)) {
freeCells.push(value);
}
Depending on the possible values of $.settings.gridSize etc., it's possible that what you are looking for is:
if (agent % $.settings.gridSize !== value % $.settings.gridSize) {
// Dud
} else {
which also makes the semantics clearer: the modulo involving agent should be "different" (in the 0/1 sense) from the module involving value.
if (
agent % $.settings.gridSize > 1
||
(agent + value) % $.settings.gridSize !== 1
) {
freeCells.push(value);
}
I think it's pretty self-explaining.
Edit
Seems like it isn't that self-explaining actually.
I made a few assumptions for the transformation.
// Dud means to do nothing.
$.settings.gridSize is a positive integer, henceforth referred to as gridSize.
agent and value are non-negative integers.
For a value not to be pushed agent % gridSize has to be either 0 or 1. Since there are no negative numbers or fractional parts involved this means the same as agent % gridSize <= 1. So if the remainder is greater than 1 then value gets pushed.
Otherwise agent % gridSize is either 0 or 1. And for the value not to be pushed value % gridSize has to take on the respective other value. In total this would mean that (agent + value) % gridSize === 1. So if it's not 1 then value gets pushed.
Related
Just going through some learning pains and wanted to know if anyone could help.
My current goal on the course I'm on is to return a bool value from a function depending on if the 2nd uint divides evenly into the first uint.
I have the correct false logic in place according to the site but it still fails on the true logic.
This is the current function I have created
function dividesEvenly(uint x, uint y) public pure returns(bool) {
if (y % x == 0) {
return true;
} else if (y % x != 0) {
return false;
}
}
One of the test cases is (4,2) which I input into it myself mainly and it does chuck out a false. However doing 4 % 2 provides 0 which should return true so I'm not entirely sure what I've done wrong here.
Any help appreciated.
The modulo operation in your snippet is reversed - y % x. So instead of 4 % 2 (result 0), it calculates 2 % 4 (result 2).
Solution: Reverse back the arithmetics
// the reminder after dividing 4 by 2 is 0
// 4 % 2 == 0
if (x % y == 0) {
return true;
}
So I had this bit of code in an if statement as follows
if (!inTime || !moment(inTime).format('m') % 15 === 0) {
doSomething();
}
The inTime getting passed in was 2018-10-11T20:00:25Z. for some reason that condition was met and the code in the if block was being called. After some tooling around I found two fixes for the issue as follows
if (!inTime || !(moment(inTime).format('m') % 15 === 0)) {
doSomething();
}
*note the parens after the bang and after the 0
or I could do this
if (!inTime || !moment(inTime).minute() % 15 === 0) {
doSomething();
}
I was curious to know if anyone knows why this happens?
The expression
!moment(inTime).format('m') % 15 === 0
is interpreted as if it were written
((!moment(inTime).format('m')) % 15) === 0
So its evaluation proceeds as
moment(inTime).format('m') gives the string "0"
!moment(inTime).format('m') gives boolean false, because "0" is truthy
((!moment(inTime).format('m')) % 15) gives the number 0, after false is converted to a number (0) and the modulus is computed
((!moment(inTime).format('m')) % 15) === 0 gives true
tl;dr the ! binds very tightly.
Since you've got an ISO date string, it might be simpler to just use the native Date API:
if (!inTime || new Date(inTime).getMinutes() % 15 !== 0)
I'm starting to learn javascript for front-end programming, being python my first language to learn completely.
So I'm trying to solve a while loop excersise that console-logs every number from 50-300 that is divisble by 5 and 3.
So in python i would do this:
i = 50
while i < 301:
if i % 5 == i % 3 == 0:
print(i)
i += 1
And works flawlessly. I know you could use and and operator but the whole point of this question is to avoid using it.
So I try the same thing in javascript
var i = 50;
while (i < 301){
if (i % 5 === i % 3 === 0){
console.log(i);
}
i ++;
}
And somehow that wont work. However, with an && operator it does. Are double equalities in javascript not allowed? If they are, what am I missing?
It's allowed, and it does exactly what you told it to do -- it's just that that's not the same as what you want it to do. i % 5 === i % 3 === 0 is the same as (i % 5 === i % 3) === 0 (because === is left-associative). (i % 5 === i % 3) evaluates to either true or false depending on the value of i, and true === 0 and false === 0 are both false, so the condition will always be false.
I just figured out how to test for certain conditions and modify output within a loop. But I noticed that testing for two conditionals with the && operator only works in an if/else if/else if/else chain if it's the first one tested for.
Can someone explain why this works:
var number = 0;
var counter = 0;
while (counter < 100) {
number ++;
counter ++;
if (number % 3 == 0 && number % 5 == 0)
console.log ("FizzBuzz");
else if (number % 3 == 0)
console.log("Fizz");
else if (number % 5 == 0)
console.log("Buzz");
else
console.log(number);
}
But this does not?:
var number = 0;
var counter = 0;
while (counter < 100) {
number ++;
counter ++;
if (number % 3 == 0)
console.log("Fizz");
else if (number % 5 == 0)
console.log("Buzz");
else if (number % 3 == 0 && number % 5 == 0)
console.log ("FizzBuzz");
else
console.log(number);
}
An else if, as the name suggests, will only execute when a previous if fails. So the statement else if (number % 3 == 0 && number % 5 == 0) will execute only when if (number % 3 == 0) and else if (number % 5 == 0) fail. If a number is a multiple of 3 and 5 both, then the first if gets successfully executed, and the rest ifs and else-ifs are ignored.
However, in code 1, the ordering of ifs and else-ifs is such that, if a number is divisible by both 3 & 5, then first if is executed, if it is divisible by the only 3, then first if is not executed, only else if (number % 3 == 0) is executed.
Let's make an example using the numbers 6, 10, 15.
The number 6 will execute - in your first example (the working example) - the second if block because in the first one the condition will not be satisfied while the third and fourth block will be ignored, and - in your second example (the not-working example) - will execute the first if block and ignore the other blocks that follow.
The number 10 will execute - in your first example - the third block because the first's and second's condition is not satisfied while the fourth block will be ignored, and - in your second example - will execute the second block, because the condition in the first block is not satisfied, while the blocks that follow will be ignored.
The number 15 will execute - in your first example - the first block and ignore the blocks that follow, and - in your second example - will also execute the first block because the condition is satisfied while the blocks that follow will be ignored.
So, to recap, in your second example, the third if block will never be executed because the condition for its execution is made up of an and of the first and second if block's conditions. In order for the third block to be executed you would need a case where the first if block's condition (let's say c1) and the second if block's condition (let's say c2) are false and c1 && c2 is true, but in order to have c1 && c2 to true you need c1 and c2 to be true, which leads to the execution of the first block and skipping of the rest.
You want to test for if the the number is divisible by three and five, but before you do that you test if it is just divisible by three.
It is, so it follows that branch of logic and never attempts to test if it is divisible by three and five.
Because in your test if the number is a multiple of 3 or 5 then the corresponding if statemetn will get executed before the number % 3 == 0 && number % 5 == 0 statement is reached so it will never get executed.
Let us assume the number is 33, the the first test will become success which is correct, but if the number if 15 then again the first if is success because 15 is a multiple of 3 so even though it is a multiple of 5 also the 3rd condition will not get a chance to execute
To get it correct you may need something like below, where if the number is a multiple of both the versions we skip first 2 conditions
var number = 0;
var counter = 0;
while (counter < 100) {
number++;
counter++;
if (number % 3 == 0 && number % 5 != 0) {
console.log("Fizz");
} else if (number % 5 == 0 && number % 3 != 0) {
console.log("Buzz");
} else if (number % 3 == 0 && number % 5 == 0) {
console.log("FizzBuzz");
} else {
console.log(number);
}
}
Everything that is either evenly divisible by 3 or evenly divisible by 5 has been removed in the second version. By the time it checks to see if a number is divisible by 3 and divisible by 5 there is no chance of it being true because one of the first two clauses already evaluated to be true.
Consider this pseudo code
if( A || B ) return;
if( A && B ) //this code will never execute
and then consider A to be number % 3 == 0 and B to be number % 5 == 0. This is essentially what is happening, and why the last if statement never executes.
What you actually want to test is
if (number % 3 == 0 && number % 5 == 0) …
else if (number % 3 == 0 && number % 5 != 0) …
else if (number % 3 != 0 && number % 5 == 0) …
else if (number % 3 != 0 && number % 5 != 0) …
if you'd write out the four cases.
Only you don't need to be that explicit, because when the previous conditions already did not match (and you are in the else branch), then those != 0 are implied and you can omit them. However, order matters, as the conditions are tested consecutively.
So if you have the fully qualified conditions, you can shuffle their order as you want:
if (number % 3 == 0 && number % 5 != 0) … // move to front
else if (number % 3 != 0 && number % 5 == 0) …
else if (number % 3 == 0 && number % 5 == 0) …
else if (number % 3 != 0 && number % 5 != 0) …
and then continue to simplify conditions, omitting the parts that are already implied by their parent cases:
if (number % 3 == 0 && number % 5 != 0)
console.log("Fizz");
else if (number % 3 != 0 && number % 5 == 0) // (an == instead of the && would suffice)
console.log("Buzz");
else if (number % 3 == 0) // as it didn't match the first condition, we know that % 5 == 0
console.log("FizzBuzz");
else // here we know that % 3 != 0 && % 5 != 0
console.log(numer);
Other permutations of the condition let us use as few as in your original example, like
if (number % 3 == 0 && number % 5 != 0)
console.log("Fizz");
else if (number % 3 == 0) // as it didn't match the first condition, we know that % 5 == 0
console.log("FizzBuzz");
else if (number % 5 == 0) // as it didn't match the first condition, we know that % 3 != 0
console.log("Buzz");
else // here we know that % 3 != 0 && % 5 != 0
console.log(numer);
And the minimum number of tests would be achievable by nesting them:
if (number % 3 == 0)
if (number % 5 == 0)
console.log("FizzBuzz");
else
console.log("Fizz");
else
if (number % 5 == 0)
console.log("Buzz");
else
console.log(numer);
I am writing a little script to find and print out all the prime numbers from X thru Y. Here is what I have written:
var numX = prompt('Enter a number greater than 0:','');
var numY = prompt('Enter a number greater than ' + numX + ':','');
while (numX <= numY) {
if (numX == 1 || numX == 2 || numX == 3) {
document.write(numX + '</br>');
} else if (numX % 2 === 0 || numX % 3 === 0 || numX % 5 === 0 || numX % 7 === 0){
document.write();
} else {
document.write(numX + '</br>');
}
numX++;
};
Now, this works just fine so long as the first number is 1. If, however, the first number is anything greater than 1 it does not print out anything. I am not sure if this is the right forum for this question (perhaps a math forum?), but I thought I would ask here on the off chance someone could help me out. I also know that a sieve is the better way to go about this, but I wanted to try and figure this out as a while loop first. Any and all help is appreciated!
While I understand what you are trying to do, I highly recommend taking a look at the Sieve of Eratosthenes. You really want to get the hang of knowing different algorithms to compute these things in case you decide to deal with really large numbers. While the way you go about it now might work in smaller ranges, bigger ranges are going to go crazy.
Also I believe this Stackoverflow question is very similar to this one and the answer for it is very well made:
finding sum of prime numbers under 250
You can try any of the options here : http://www.javascripter.net/faq/numberisprime.htm
Hi i have added bit change to ur code (added condition for 5 and 7 prime numbers) and its working...
var numX = prompt('Enter a number greater than 0:','');
var numY = prompt('Enter a number greater than ' + numX + ':','');
while (numX <= numY) {
if (numX == 1 || numX == 2 || numX == 3 || numX == 5 || numX == 7) {
document.write(numX + '</br>');
} else if (numX % 2 === 0 || numX % 3 === 0 || numX % 5 === 0 || numX % 7 === 0){
document.write();
} else {
document.write(numX + '</br>');
}
numX++;
};
Check the demo here
OK, turns out that I jumped the gun on asking this question. I was more concerned with getting the else if statement working that I failed to even note that my formula was seriously flawed!
The issue possibly could be with the second variable. If the first variable is 1 then the second variable can be any number. However, if the first variable is greater than 1 then the second variable has to be less than 100 or it will not work.