I just notice the if condition below:
//1
if ((i >= 0) != (j >= 0))
return false;
is just a short way for:
//2
if((i>=0 && j < 0) || (i < 0 && j >=0))
return false;
Going from 1. to 2. takes some time to figure out, but how do we deduce the logic to go from 2. to 1.?
If you have any two boolean statements A and B then A != B means that they are different. I.e. either A is true and B is false, or A is false and B is true. This goes also the other way if A is true and B is false, or A is false and B is true, then A does not equal B.
In other words (A != B) = ((A && !B) || (!A && B)). Therefore, statement 1 and 2 are the same
If you feel my argumentation is imprecise, you can use truth tables to proof it rigorous mathematically:
A
B
A!=B
(A && !B)
(!A && B)
(A && !B) || (!A && B))
true
true
false
false
false
false
true
false
true
true
false
true
false
true
true
false
true
true
false
false
false
false
false
false
If we call (i >= 0) something arbitrary like A and (j >= 0) something else like B then it stands to reason that (i < 0) is just Not A (often shown as !A) and (j < 0) would be Not B or !B
Meaning this block:
if((i>=0 && j < 0) || (i < 0 && j >=0))
return false;
Can be represented as:
if ((A && !B) || (!A && B))
return false;
else // you haven't specified this part but it's implied
return true;
Now, if we approach this as:
How do we get to the true value?
Then you realise it's the same as:
if ((A && B) || (!A && !B))
return true;
else
return false;
Then we can call (A && B) something else like C; so it becomes:
if (C || !C)
return true;
else
return false;
So, expanding out again, we can get:
if (A && B)
return true;
else if (!(A && B))
return true;
else
return false;
So, that's:
if ((i >= 0) && (j >= 0))
return true;
else if (!( (i >= 0) && (j >= 0) ) )
return true;
else
return false;
Which can evaluate to:
if (True && True)
return true;
else if (False && False)
return true;
else
return false;
Showing that it's as simple as:
if ( (i >= 0) == (j >= 0) )
return true;
else // if ( (i >= 0) != (j >= 0) )
return false;
So, we've gone around the houses but we've worked our way down from statement 2 to statement 1.
NOTE: Adam's answer is more concise and is accurate from a pure logic perspective; this is more to provide a broader overview as I know that some people learn better when they can see the process.
Related
Q: Given the roots of two binary trees p and q, write a function to check if they are the same or not.
solution:
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
// p and q are both null
if (p == null && q == null) return true;
// one of p and q is null
if (q == null || p == null) return false;
if (p.val != q.val) return false;
return isSameTree(p.right, q.right) &&
isSameTree(p.left, q.left);
}
}
I am confused about the "return isSameTree(p.right, q.right) &&
isSameTree(p.left, q.left);" what is the meaning of it, and why there is no condition like "else" before it ??? what it return finally ?
I have created this function that takes number and return TRUE or FALSE depending whether the number is prime or not.
is.prime <- function(num) {
if (num == 2) {
TRUE
} else if (any(num %% 2:(num-1) == 0)) {
FALSE
} else {
TRUE
}
}
However, this function takes only one value, for example this works fine:
> is_prime(17)
[1] TRUE
If I plug in a vector, I want to see TRUE or FALSE for each element. For example,
> is_prime(c(17,5,10,22,109,55))
[1] TRUE
Warning messages:
1: In if (x == 1) { :
the condition has length > 1 and only the first element will be used
2: In 2:(floor(x/2)) :
numerical expression has 6 elements: only the first used
3: In x%%2:(floor(x/2)) :
longer object length is not a multiple of shorter object length
This is evaluated for the first element, but I would want to see
TRUE TRUE FALSE FALSE TRUE FALSE
for the vector
is_prime(c(17,5,10,22,109,55))
How would I modify the function to vectorize using the same algorithm?
Half Vectorized
It is possible to vectorize some of the function by dealing with even numbers (and a few other numbers) in a vectorized fashion. The rest is taken care of using vapply.
helper <- function(x) {
for (k in seq(3, round(sqrt(x)) + 1, 2)) {
if (x %% k == 0)
return(FALSE)
}
return(TRUE)
}
is.prime <- function(v) {
out <- rep(TRUE, length(v))
out[v %% 2 == 0 | v %in% c(1)] <- FALSE
out[v %in% c(2, 3, 5)] <- TRUE
indices <- which(v > 5 && v == FALSE)
out[indices] <- vapply(v[indices], helper, logical(1))
return(out)
}
is.prime(c(17,5,10,22,109,55))
# [1] TRUE TRUE FALSE FALSE TRUE FALSE
Full Vectorized
If performance is at stake, you might consider using `Rcpp`:
c++ file
#include <Rcpp.h>
#include <math.h>
using namespace Rcpp;
bool is_prime(int n) {
if ((n == 2) || (n == 3) || (n == 5)) {
return true;
}
if ((n % 2 == 0) || (n == 1)) {
return false;
}
int i = 3;
while (i < round(sqrt(n)) + 1) {
if (n % i == 0) {
return false;
}
i += 2;
}
return true;
}
// [[Rcpp::export]]
LogicalVector is_prime(IntegerVector v) {
int n = v.length();
LogicalVector out = LogicalVector(n);
for (int i = 0; i < n; i++) {
out[i] = is_prime(v[i]);
}
return out;
}
R File
library(Rcpp)
sourceCpp('prime_fun.cpp') # if cpp file in same dir
is_prime(c(17,5,10,22,109,55))
# [1] TRUE TRUE FALSE FALSE TRUE FALSE
Technically, you cannot vectorize the function but you can use methods to apply is.prime function to vectors.
For example, use sapply :
sapply(c(17,5,10,22,109,55), is.prime)
#[1] TRUE TRUE FALSE FALSE TRUE FALSE
Or use Vectorize which is a wrapper around mapply :
vec.is.prime <- Vectorize(is.prime)
vec.is.prime(c(17,5,10,22,109,55))
#[1] TRUE TRUE FALSE FALSE TRUE FALSE
R is an inherently vectorized language, you just have to not break that when you write functions...
is.prime <- function(num){
res<-rep(TRUE, length(num))
for(i in 2:(max(num)-1) ){
res[(i < num) & ((num %% i) == 0) ] <- FALSE
}
return(res)
}
x<-c(2, 5, 17, 109, 10, 22, 55, 93)
print("Primes:")
print(x[ is.prime(x) ] )
Output:
> source('~/.active-rstudio-document')
[1] "Primes:"
[1] 2 5 17 109
i <- 2
j <- 0
for (i in 2:1000) {
if(return.prime(i)){j = j + 1}
i = i + 1
}
I want to check how many prime numbers there are in 1 to 1000 using my own function return.prime which returns TRUE when the number input is a prime and FALSE when the number input is not prime. The return.prime function is the function below and it is correct.
return.prime <- function(d){
if(d ==1 ){print(FALSE)}
if (d == 2){
print(TRUE)
}
if(d !=2 && d!=1){
if(any(d %% (2:(d-1)) == rep(0,d-2))==TRUE){
print(FALSE)}
else
print(TRUE)
}
}
The problem is when I run my program it says:
[1] TRUE
Error in if (return.prime(i)) { : argument is of length zero
I do not know what causes the length zero.
R doesn't work that way. You're just having the function print the word "TRUE" or "FALSE". Instead, you need to ?return TRUE or FALSE. Consider:
return.prime <- function(d){
if(d==1){ return(FALSE) }
if(d==2){ return(TRUE) }
if(d !=2 && d!=1){
if(any(d %% (2:(d-1)) == rep(0,d-2))==TRUE){
return(FALSE)
} else{
return(TRUE)
}
}
}
i <- 2
j <- 0
for (i in 2:1000) {
if(return.prime(i)){j = j + 1}
i = i + 1
}
j # [1] 168
what is the base case here ?? This is fully functional but how it's working?
int isPali(char *s, int l, int r)
{
return ((l == r) || (s[l] == s[r] && isPali(s, l+1, r-1)));
}
int main()
{
char str[100];
scanf("%s", str);
if(isPali(str, 0, strlen(str)-1))
printf("Palindrome\n");
else
printf("Not palindrome\n");
}
It's in the only line of the function. Remember short-circuit logic in evaluating expressions. The or can be changed to
if (l == r)
return True;
else
return (s[l] == s[r] && isPali(s, l+1, r-1));
Of course, you can now apply the short-circuit to that else part:
else
if s[l] == s[r]
return isPali(s, l+1, r-1);
else
return False;
So I was writing a rock paper scissors game when I came to writing this function:
a is player one's move, b is player two's move. All I need to figure out is if player one won, lost, or tied.
//rock=0, paper=1, scissors=2
processMove(a, b) {
if(a == b) ties++;
else {
if(a==0 && b==2) wins++;
else if(a==0 && b==1) losses++;
else if(a==1 && b==2) losses++;
else if(a==1 && b==0) wins++;
else if(a==2 && b==1) wins++;
else if(a==2 && b==0) losses++;
}
}
My question is: What's the most elegant way this function can be written?
Edit: I'm looking for a one-liner.
if (a == b) ties++;
else if ((a - b) % 3 == 1) wins++;
else losses++;
I need to know exactly which language you are using to turn it into a strictly one-liner...
For JavaScript (or other languages with strange Modulus) use:
if (a == b) ties++;
else if ((a - b + 3) % 3 == 1) wins++;
else losses++;
A 3x3 matrix would be "more elegant", I suppose.
char result = "TWLLTWWLT".charAt(a * 3 + b);
(Edited: Forgot that a and b were already zero-origin.)
I suppose you could use the terniary operator like this -
if (b==0) a==1? wins++ : loss++;
if (b==1) a==1? loss++ : wins++;
if (b==2) a==1? loss++ : wins++;
You can do it with a simple mathematical formula to get the result and then compare with if like this:
var moves = {
'rock': 0,
'paper': 1,
'scissors': 2
};
var result = {
'wins': 0,
'losses': 0,
'ties': 0
};
var processMove = function (a, b) {
var processResult = (3 + b - a) % 3;
if (!processResult) {
++result['ties'];
} else if(1 == processResult) {
++result['losses'];
} else {
++result['wins'];
}
return result;
};
jsFiddle Demo
One line processMove function without return:
var processMove = function (a, b) {
((3 + b - a) % 3) ? 1 == ((3 + b - a) % 3) ? ++result.losses : ++result.wins : ++result.ties;
};
how do you do it in java?
result = (comp - x ) % 3 ;
System.out.println (result);
if (result == 0 )// if the game is tie
{
System.out.println ("A Tie!") ;
}
else if (result == 1 || result == 2 )
{
//System.out.println (user + " " + "beats" + " " + computer_choice + " you win" );
System.out.println ("comp win");
}
else
{
System.out.println ("you win");
//System.out.println (computer_choice + " " + "beats" + " " + user + "you lose");
}