Finding MAX of numbers without conditional IF statements c++ [duplicate] - c++

This question already has answers here:
Mathematically Find Max Value without Conditional Comparison
(18 answers)
Closed 9 years ago.
So i have too get two numbers from user input, and find the max of the two numbers without using if statements.
The class is a beginner class, and we have too use what we already know. I kinda worked something out, but it only works if the numbers are inputted with the max number first.
#include <iostream>
using namespace std;
int main()
{
int x = 0, y = 0, max = 0;
int smallest, largest;
cout << "Please enter 2 integer numbers, and i will show you which one is larger: ";
cin >> x >> y;
smallest = (x < y == 1) + (x - 1);
smallest = (y < x == 1) + (y - 1);
largest = (x < y == 1) + (y - 1);
largest = (y > x == 1) + (x + 1 - 1);
cout << "Smallest: " << smallest << endl;
cout << "Largest: " << largest << endl;
return 0;
}
Thats what i have so far, but after putting different test data in, i found out it only works for numbers such as 4,5 or 6,7. But numbers with more then 2 spaces between eachother they dont such as, 4,8 or 5, 7. Any help would be appreciated.

I saw this question in Cracking the Coding interview book.
Let’s try to solve this by “re-wording” the problem We will re-word the problem until we get something that has removed all if statements
Rewording 1: If a > b, return a; else, return b
Rewording 2: If (a - b) is negative, return b; else, return a
Rewording 3: If (a - b) is negative, let k = 1; else, let k = 0 Return a - k * (a - b)
Rewording 4: Let c = a - b Let k = the most significant bit of c Return a - k * c
int getMax(int a, int b) {
int c = a - b;
int k = (c >> ((sizeof(int) * CHAR_BIT) - 1)) & 0x1;
int max = a - k * c;
return max;
}
Source: http://www.amazon.com/Cracking-Coding-Interview-Programming-Questions/dp/098478280X
Edit: This code works even when a-b overflows.
Let k equal the sign of a-b such that if a-b >=0, then k is 1, else k=0.Let q be the inverse of k. Above code overflows when a is positive or b is negative, or the other way around. If a and b have different signs, then we want the k to equal sign(a).
/* Flips 1 to 0 and vice-versa */
public static int flip(int bit){
return 1^bit;
}
/* returns 1 if a is positive, and 0 if a is negative */
public static int sign(int a){
return flip((a >> ((sizeof(int) * CHAR_BIT) - 1)) & 0x1);
}
public static int getMax(int a, int b){
int c = a - b;
int sa = sign(a-b); // if a>=0, then 1 else 0
int sb = sign(a-b); // if b>=1, then 1 else 0
int sc = sign(c); // depends on whether or not a-b overflows
/* If a and b have different signs, then k = sign(a) */
int use_sign_of_a = sa ^ sb;
/* If a and b have the same sign, then k = sign(a - b) */
int use_sign_of_c = flip(sa ^ sb);
int k = use_sign_of_a * sa + use_sign_of_c * sc;
int q = flip(k); //opposite of k
return a * k + b * q;
}

Here is a funny solution:
int max_num = (x>y)*x + (y>=x)*y;

Assuming that you have covered bitwise operators already you can do this:
max = a-((a-b)&((a-b)>>(sizeof(int)*8-1)));
This is based off of the solution from Mathematically Find Max Value without Conditional Comparison that #user93353 pointed out in the comments above.
This may be overkill if you really are just trying to avoid if statements, not comparisons in general.

You can try this code to find max and min for two input variables.
((a > b) && (max = a)) || (max=b);
((a < b) && (min = a)) || (min=b);
For three input variables you can use similar method like this:
int main()
{
int a = 10, b = 9 , c = 8;
cin >> a >> b >> c;
int max = a, min = a;
// For Max
((a > b) && (a > c) && (max=a)) ||
((b > c) && (b > a) && (max=b)) ||
(max=c) ;
// For min
((a < b) && (a < c) && (min=a)) ||
((b < c) && (b < a) && (min=b)) ||
(min=c) ;
cout << "max = " << max;
cout << "and min = " << min;
return 1;
}
One run is:
:~$ ./a.out
1
2
3
max = 3 and min = 1
Edit
Thanks to #Tony D: This code will fail for negative numbers.
One may try this for negative numbers for two inputs to find max(not sure for this):
((a > b) && ( a > 0 && (max = a))) || ((b > a) && (max = b)) || (max = a);

Related

what will be the value of (a*b*c )%k?

i have searched it everywhere, i only find the solution for (ab)%k which is ((a%k)(b%k))%k.
i want to write the code for it . suppose i have been given an array of numbers a1 ,a2 , a3 , a4 ... , an. i have to find whether product of numbers any subset from the array is divisible by k .
if(ai *aj .. *am %k == 0)
return true;
i want the code in c++.
i have tried the code :
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int main() {
ll t;
cin >> t;
while(t--)
{
ll n , k ;
cin >> n >> k;
vector<ll>a;
ll product = 1;
int flag =0;
for(ll i =0 ; i < n ; i++)
{
int p;
cin >>p;
a.push_back(p);
if(p % k == 0)
{
flag = 1;
}
p = p%k; ................................(eqn 1)
product = product * p;
product = product %k; .................................(eqn 2)
}
if(flag == 1)
{
cout << "YES" << "\n";
continue;
}
product = product %k; ...............................(eqn 3)
if(product == 0)
{
cout << "YES" << "\n";
}
else
cout << "NO"<< "\n";
}
return 0;
}
This code passes all the test cases . if i remove the equation 1 from the code , it will pass all the testcases after it also .
but if i remove the equation 2 , the code gives it as wrong answer.
https://www.codechef.com/problems/DIVBYK
Can you tell me the concept behind it ?
The concept is that for a1,a2,b1,b2 satisfying:
a1 == b1 (mod k)
a2 == b2 (mod k)
it holds that
a1*a2 == b1*b2 (mod k)
In other words, the remainder of multiplying two numbers is the same as the remainder of multiplying just the remainders of the original numbers.
This is very handy because the latter does not suffer from overflow if k<sqrt(largest_representable_number).
One can prove by induction the same for product of N numbers.

Solution for equation of a line with 2 variables ax + by = c works in one case but fails in other case

I am trying to solve ax + by = n.
When I put n = 7, it solves the equation correctly as X = 2 and Y = 1.
But when I put n = 1, it does not solve the equation. Even though, this equation has valid integer solution, X = 17, Y = -11. here is my full program.
#include <iostream>
using namespace std;
void PrintXY(int a, int b, int n)
{
for (int i = 0; i * a <= n; i++) {
if ((n - (i * a)) % b == 0) {
cout << "x = " << i << ", y = "
<< (n - (i * a)) / b;
return;
}
}
cout << "No solution";
}
int main()
{
int a = 2, b = 3, n = 1;
PrintXY(a, b, n);
return 0;
}
Output when n = 7:
x = 2, y = 1
Output when n = 1:
No solution
Reasoning.
2*(2) + 3*(1) - 7 = 4 + 3 - 7 = 0
2*(17) + 3*(-11) - 1 = 34 - 33 - 1 = 0
Both equations solve to give 0. But what is wrong in my program that is causing it to give "No Solution".
The problem is with the termination condition:
i*a<=n
This(n>=a*i) need not be true, and is especially not true in case of the solution (ie X=17, Y=-11). Which seems reasonable - Without any bounds(limits) on the answer(either X or Y) , how would you find the solution to a linear equation(with an infinite possible range) in a closed for loop ?

C++ - Checking whether two substrings are equal using hashing

I'm taking a coursera course and one of the assignment is to process large number of queries(upto the order of 10^6) to check whether two substrings are equal or not from a single string(maximum length of string is 500000) using polynomial hashing. A single query includes index a and b and length l.
I've implemented a code that pre-computes hashes for the whole string twice(for two seperate modulo-n numbers) and computes two hashes for each substring. This is to reduce the number of collisions.
The code:
class Solver {
string s;
unsigned long long x, m1, m2;
vector<long long> h1, h2;
public:
Solver(string s) : s(s) {
// initialization, precalculation inside constructor
h1.resize(s.size() + 1); //first array to store precomputed hashes
h2.resize(s.size() + 1); //second array
x = 263; // random multiplier for polynomial hash and 0 < x < m1, m2
m1 = 1000000007;
m2 = 1000000009;
h1[0] = 0, h2[0] = 0;
for (size_t i = 1; i <= s.size(); ++i) {
h1[i] = ((x * h1[i - 1]) + s[i - 1]) % m1;
h2[i] = ((x * h2[i - 1]) + s[i - 1]) % m2;
}
}
bool ask(int a, int b, int l) {
if (a + l > s.size() || b + l > s.size())
return false;
long long y = 1, z = 1;
y = (long long)pow(x, l) % m1;
z = (long long)pow(x, l) % m2;
long long H1 = (((h1[a + l] - (y * h1[a])) % m1) + m1) % m1;
long long H2 = (((h1[b + l] - (y * h1[b])) % m1) + m1) % m1;
long long H3 = (((h2[a + l] - (z * h2[a])) % m2) + m2) % m2;
long long H4 = (((h2[b + l] - (z * h2[b])) % m2) + m2) % m2;
return ((H1 == H2) && (H3 == H4));
}
};
int main() {
ios_base::sync_with_stdio(0), cin.tie(0);
string s;
int q;
cin >> s >> q;
Solver solver(s);
for (int i = 0; i < q; i++) {
int a, b, l;
cin >> a >> b >> l;
cout << (solver.ask(a, b, l) ? "Yes\n" : "No\n");
}
}
sample output:
trololo
4 // number of queries
0 0 7 // a b l
2 4 3
3 5 1
1 3 2
yes
yes
yes
no
The code works for the above example. But when input for a is given as 0 and b a random value such that
on paper it's the right answer but the code outputs the wrong one and also for certain trivial strings like "abcabc", the code outputs the wrong answer.
example:
abcabcabc
4
0 3 3
1 7 2
2 8 1
1 4 4
no
no
no
yes
Where am I going wrong when a = 0 and are my trivial inputs like "thethethe" valid?
If the string is 500k in length, then there are hundreds of billions of substrings - far too many to prehash in advance and fit in memory.
Instead of doing that, you should create hashes from every starting point of length 1, 2, 4, 8, 16, ... There should only be on the order of 10 million of those.
And now given two substrings we can compare at least half of each of them with a single lookup. Which makes the comparison take logarithmic time.

Substrings of equal length comparison using hashing

On an assignment that I have, for a string S, I need to compare two substrings of equal lengths. Output should be "Yes" if they are equal, "No" if they are not equal. I am given the starting indexes of two substrings (a and b), and the length of the substrings L.
For example, for S = "Hello", a = 1, b = 3, L = 2, the substrings are:
substring1 = "el" and substring2 = "lo", which aren't equal, so answer will be "No".
I think hashing each substring of the main string S and writing them all to memory would be a good aproach to take. Here is the code I have written for this (I have tried to implement what I learned about this from the Coursera course that I was taking):
This function takes any string, and values for p and x for hashing thing, and performs a polynomial hash on the given string.
long long PolyHash(string str, long long p, int x){
long long res = 0;
for(int i = str.length() - 1; i > -1; i--){
res = (res * x + (str[i] - 'a' + 1)) % p;
}
return res;
}
The function below just precomputes all hashes, and fills up an array called ah, which is initialized in the main function. The array ah consists of n = string length rows, and n = string length columns (half of which gets wasted because I couldn't find how to properly make it work as a triangle, so I had to go for a full rectangular array). Assuming n = 7, then ah[0]-ah[6] are hash values for string[0]-string[6] (meaning all substrings of length 1). ah[7]-ah[12] are hash values for string[0-1]-string[5-6] (meaning all substrings of length 2), and etc. until the end.
void PreComputeAllHashes(string str, int len, long long p, int x, long long* ah){
int n = str.length();
string S = str.substr(n - len, len);
ah[len * n + n - len] = PolyHash(S, p, x);
long long y = 1;
for(int _ = 0; _ < len; _++){
y = (y * x) % p;
}
for(int i = n - len - 1; i > -1; i--){
ah[n * len + i] = (x * ah[n * len + i + 1] + (str[i] - 'a' + 1) - y * (str[i + len] - 'a' + 1)) % p;
}
}
And below is the main function. I took p equal to some large prime number, and x to be some manually picked, somewhat "random" prime number.
I take the text as input, initialize hash array, fill the hash array, and then take queries as input, to answer all queries from my array.
int main(){
long long p = 1e9 + 9;
int x = 78623;
string text;
cin >> text;
long long* allhashes = new long long[text.length() * text.length()];
for(int i = 1; i <= text.length(); i++){
PreComputeAllHashes(text, i, p, x, allhashes);
}
int queries;
cin >> queries;
int a, b, l;
for(int _ = 0; _ < queries; _++){
cin >> a >> b >> l;
if(a == b){
cout << "Yes" << endl;
}else{
cout << ((allhashes[l * text.length() + a] == allhashes[l * text.length() + b]) ? "Yes" : "No") << endl;
}
}
return 0;
}
However, one of the test cases for this assignment on Coursera is throwing an error like this:
Failed case #7/14: unknown signal 6 (Time used: 0.00/1.00, memory used: 29396992/536870912.)
Which, I have looked up online, and means the following:
Unknown signal 6 (or 7, or 8, or 11, or some other).This happens when your program crashes. It can be
because of division by zero, accessing memory outside of the array bounds, using uninitialized
variables, too deep recursion that triggers stack overflow, sorting with contradictory comparator,
removing elements from an empty data structure, trying to allocate too much memory, and many other
reasons. Look at your code and think about all those possibilities.
And I've been looking at my code the entire day, and still haven't been able to come up with a solution to this error. Any help to fix this would be appreciated.
Edit: The assignment states that the length of the input string can be up to 500000 characters long, and the number of queries can be up to 100000. This task also has 1 second time limit, which is pretty small for going over characters one by one for each string.
So, I did some research as to how I can reduce the complexity of this algorithm that I have implemented, and finally found it! Turns out there is a super-simple way (well, not if you count the theory involved behind it) to get hash value of any substring, given the prefix hashes of the initial string!
You can read more about it here, but I will try to explain it briefly.
So what do we do - We precalculate all the hash values for prefix-substrings.
Prefix substrings for a string "hello" would be the following:
h
he
hel
hell
hello
Once we have hash values of all these prefix substrings, we can collect them in a vector such that:
h[str] = str[0] + str[1] * P + str[2] * P^2 + str[3] * P^3 + ... + str[N] * P^N
where P is any prime number (I chose p = 263)
Then, we need a high value that we will take everything's modulo by, just to keep things not too large. This number I will choose m = 10^9 + 9.
First I am creating a vector to hold the precalculated powers of P:
vector<long long> p_pow (s.length());
p_pow[0] = 1;
for(size_t i=1; i<p_pow.size(); ++i){
p_pow[i] = (m + (p_pow[i-1] * p) % m) % m;
}
Then I calculate the vector of hash values for prefix substrings:
vector<long long> h (s.length());
for (size_t i=0; i<s.length(); ++i){
h[i] = (m + (s[i] - 'a' + 1) * p_pow[i] % m) % m;
if(i){
h[i] = (m + (h[i] + h[i-1]) % m) % m;
}
}
Suppose I have q queries, each of which consist of 3 integers: a, b, and L.
To check equality for substrings s1 = str[a...a+l-1] and s2 = str[b...b+l-1], I can compare the hash values of these substrings. And to get the hash value of substrings using the has values of prefix substrings that we just created, we need to use the following formula:
H[I..J] * P[I] = H[0..J] - H[0..I-1]
Again, you can read about the proof of this in the link.
So, to address each query, I would do the following:
cin >> a >> b >> len;
if(a == b){ // just avoid extra calculation, saves little time
cout << "Yes" << endl;
}else{
long long h1 = h[a+len-1] % m;
if(a){
h1 = (m + (h1 - h[a-1]) % m) % m;
}
long long h2 = h[b+len-1] % m;
if(b){
h2 = (m + (h2 - h[b-1]) % m) % m;
}
if (a < b && h1 * p_pow[b-a] % m == h2 % m || a > b && h1 % m == h2 * p_pow[a-b] % m){
cout << "Yes" << endl;
}else{
cout << "No" << endl;
}
}
Your approach is very hard and complex for such a simple task. Assuming that you only need to do this operation once. You can compare the substrings manually with a for loop. No need for hashing. Take a look at this code:
for(int i = a, j = b, counter = 0 ; counter < L ; counter++, i++, j++){
if(S[i] != S[j]){
cout << "Not the same" << endl;
return 0;
}
}
cout << "They are the same" << endl;

Solving a dp problem from codeforces - Cut Ribbon

I was trying to solve this problem and from the comments section in the editorial, I was directed to the following solution :
#include <bits/stdc++.h>
using namespace std;
#define MAX(a,b,c) max(a,max(b,c))
int n,a,b,c,dp[4001];
int f(int x)
{
if (x == 0) return 0;
if (x < 0 || (x > 0 && x < a && x < b && x < c))
return 0xACCE97ED; // <- **I have doubt here**
if (!dp[x]) dp[x] = MAX(f(x-a),f(x-b),f(x-c)) + 1;
return dp[x];
}
int main()
{
cin >> n >> a >> b >> c;
memset(dp,0,sizeof(dp));
cout << f(n) << endl;
}
I wanted to know:
What is the need of the if statement that returns 0xACCE97ED for the test case:
4000 1 2 3. This test case dosen't work when that specific if statement is missing.
Why specifically 0xACCE97ED is being returned? Because when I tried to return any other number (say 9999), then the output is expected output + 9999.
if (x < 0 || (x > 0 && x < a && x < b && x < c))
return 0xACCE97ED; // -1395746835
Well looking at the dp function, it is basically maximizing values and this specific if statement is saying:
if x < 0
the length of the ribbon you cut is negative (which should be impossible)
or if x > 0 and x < a, b, c which means you can still cut X but all available sizes would result into having a ribbon of negative length
return 0xACCE97ED; return a random negative value which happens to spell out ACCEPTED because this state is invalid
And since the third if statement will try to get the max value, 0xACCE97ED will never be selected as the max value.
0xACCE97ED means "ACCEPTED" in the 1ee7 speech. nothing else specific about this value.
What is the need of the if statement that returns 0xACCE97ED for the test case: 4000 1 2 3
if (x < 0 || (x > 0 && x < a && x < b && x < c))
return 0xACCE97ED; // <- **I have doubt here**
because the function f is recursive, in the next line it calls itself:
if (!dp[x]) dp[x] = MAX(f(x-a),f(x-b),f(x-c)) + 1;
return dp[x];
with a smaller values for x so presumable it will eventually make that if statement true and will return "accepted" (0xACCE97ED).