Bigger value without greater than or less than operators - algorithm

this is just for fun.
Can you give me a way to determine the greater value of two numbers? You can use other operators except greater than or less than operator.
Use any tool you like (programming language, pencil paper, etc.).
And another thing you cannot do the following:
int main()
{
int num1, num2;
cin >> num1 >> num2;
if( (num1-num2) + abs(num1-num2) )
cout << num1 << " is bigger" << endl;
else
cout << num2 << " is bigger" << endl;
return 0;
}

Well, if you assume two's complement arithmetic:
int highBit = ~INT_MAX;
int rslt = num1 - num2;
if (rslt & highBit)
// num2 > num1
else if (rslt)
// num1 > num2
else
// num1 == num2
This will only work when both numbers are positive. For example, if num1 is positive and num2 is negative, then num1-num2 could overflow, causing the result to be negative, which would erroneously report that num2 > num1. If both numbers are negative, this will report the opposite (i.e. -12 will be reported greater than -1).

Ok, I would transform them to binary code and walk from the left byte-by-byte. Whichever first has 1 when the other one has not (means: has 0), this is greater.
So if you go from left to right and:
both have 0 at the current position: go to the next position,
both have 1 at the current position: go to the next position,
first one has 1 at the current position and the second one has 0: the first one is bigger,
second one has 1 at the current position and the first one has 0: the second one is bigger,
If you determine that 3. or 4. is matched, you have the result. If 1. or 2. is matched, repeat the same for the next position. If you have walked through all the bytes and did not determine that one of them is bigger, then both are equal.

#include <algorithm>
cout << std::max(num1, num2) << " is bigger" << endl;

Logarithm of a negative value is undefined; different languages/frameworks process it differently. This solution is for C#:
using System;
public class Test
{
public static bool gt( double a, double b ) {
return Double.IsNaN(Math.Log(b - a));
}
public static void report_gt( double a, double b) {
if( gt(a,b) )
Console.WriteLine("{0} is greater than {1}", a, b);
else
Console.WriteLine("{0} is less than or equal to {1}", a, b);
}
public static void Main()
{
Test.report_gt(-1, 0);
Test.report_gt(1, 0);
Test.report_gt(1, 2);
Test.report_gt(-1, -2);
}
}
Output:
-1 is less than or equal to 0
1 is greater than 0
1 is less than or equal to 2
-1 is greater than -2
A similar solution for C could use floating point exceptions. Unfortunately, C++ does not throw an exception for a negative argument to log2() for a nice try-catch solution in this fun contest :).

This works for positive integers:
#! /usr/bin/python
import math
def bigger (a, b):
length = int (math.log (a, 2) + math.log (b, 2) + 1)
a = toFixedBitString (a, length)
b = toFixedBitString (b, length)
print a, b
while a:
if a [0] == '1' and b [0] == '0':
print "First number is bigger."
return
if a [0] == '0' and b [0] == '1':
print "Second number is bigger."
return
a = a [1:]
b = b [1:]
print "Numbes are equal."
def toFixedBitString (a, length):
retVal = ''
for x in range (length): retVal = ['0', '1'] [a >> x & 1] + retVal
return retVal

Warning: Untested code.
num2 ~= num2;
++num2;
num1 += num2;
rotate_left(num1, 1);
if (num1 == 0)
std::cout << "num1 == num2";
else if (num1 & 1)
std::cout << "num1 < num2";
else
std::cout << "num1 > num2";
I haven't thought about it a lot, but there are probably combinations that will fail due to overflow.

#include <limits>
int a = -1;
int b = -11;
// true for positive difference
bool dpos = ~(unsigned int)(a - b) >> numeric_limits<int>::digits; // 31 for 32-bit
cout << "Problem : a = " << a << " and b = " << b << endl;
if (a == b)
cout << " a == b " << endl;
else if (dpos)
cout << " a > b " << endl;
else
cout << " a < b " << endl;

SSE 4.1 solution
#include <smmintrin.h>
#include <iostream>
using namespace std;
int main()
{
int num1, num2, test;
__m128i v1, v2, vcmp;
cin >> num1 >> num2;
v1 = _mm_set1_epi32(num1);
v2 = _mm_set1_epi32(num2);
vcmp = _mm_cmpgt_epi32(v1, v2);
test = _mm_testz_si128(vcmp, vcmp);
if (test == 0)
{
cout << "num1 is bigger" << endl;
}
else
{
cout << "num2 is bigger" << endl;
}
return 0;
}
$ g++ -Wall -msse4.1 cmpgt.cpp -o cmpgt
$ ./cmpgt
-10 10
num2 is bigger
$ ./cmpgt
10 -10
num1 is bigger

Related

Why this code is not working for sum of even integers?

I am trying to find the sum of even integers, but it is not working. It only works for sum of integers after removing the if condition.
main()
{
int number, sum, upperlimit;
number=1;
sum=0;
std :: cout << "Please enter the number of digits:";
std :: cin >> upperlimit;
while(number<=upperlimit)
{
if(number%2==0)
{
sum = sum + number;
number = number + 1;
}
}
std :: cout << "sum of 1st " << upperlimit <<" Even digits is:" << sum;
}
When I am entering the digits not going any where.
if(number%2==0)
{
sum = sum + number;
number = number + 1;
}
Having the number+=1condition inside that ifmeans that it will only move on if the number is even. So once you reach 1, for example, it will stay as a 1 for ever.
main()
{
int number, sum, upperlimit;
number=1;
sum=0;
std :: cout << "Please enter the number of digits:";
std :: cin >> upperlimit;
while(number<=upperlimit)
{
if(number%2==0)
{
sum = sum + number;
}
number = number + 1;
}
std :: cout << "sum of 1st " << upperlimit <<" Even digits is:" << sum;
}

Minimum number of operations to get from source to target.

I came across this question during an interview -
Convert a number source to target in the minimum number of operations.
Allowed Operations
Multiplied by 2.
Addition by 1.
subtraction by 1.
0 < source, target <= 1000.
I tried going the naive recursive route(O(3^n)) ie. subtract 1, add 1 and multiply by 2 at each level to try and find a solution that I could extend to Dynamic Programming but couldnt because of an infinite loop.
//Naive approach Via Recursion
int minMoves(int source, int target){
if(source <1 || source > target){
return -1;
}
int moves =0;
// Potential infinite loop - consider 3,6-> 2,6- >1,6->(0,6)x (2,6)->1,6->(0,6)x (1,6)->(0,6)x (2,6)->1,6..
int movesLeft = minMoves(source -1, target) ==-1? Integer.MAX_VALUE:minMoves(source -1, target);
int movesRight = minMoves(source +1, target) ==-1? Integer.MAX_VALUE:minMoves(source +1, target);
int moves2X = minMoves(2*source, target) ==-1? Integer.MAX_VALUE:minMoves(2*source, target);
moves = 1+ Math.min(Math.min(movesRight,movesLeft), moves2X);
return moves;
}
Any ideas on how I can tweak my solution? Or possibly a better way to solve it?
If you think about your solution like a graph traversal, where each node is an intermediate value you can produce, your recursive solution is like a depth first search (DFS). You'll have to fully expand until you've tried all solutions from that "branch" of the search space before you can proceed anywhere else. If you have an infinite loop, this means it will never terminate even if a shorter path exists, and even if you don't have an infinite loop, you still have to search the rest of the solution space to make sure its optimal.
Instead, consider an approach similar to breadth first search (BFS). You expand outward uniformly, and will never search a path longer than the optimal solution. Just use FIFO queue to schedule which node to access next. This is the approach I've taken with my solver.
from queue import Queue
def solve(source, target):
queue = Queue()
path = [source]
queue.put(path)
while source != target:
queue.put(path + [source * 2])
queue.put(path + [source + 1])
queue.put(path + [source - 1])
path = queue.get()
source = path[-1]
return path
if __name__ == "__main__":
print(solve(4,79))
One way in which you can speed up(and possibly fix) this code, while maintaining the recursive implementation, is to use memoization.
The issue here is that you are recalculating the same value many times. Instead you can use a map to store the results that you already calculated, and reuse them when you need it again.
This problem can be solved constructively. First, the easy cases. If s=t, the answer is 0. If s > t, the answer is s-t because subtraction by 1 is the only operation that lowers s, and the other two can only increase the number of subtractions required.
Now let's assume s < t. Since s>0 is given, doubling will always be the fastest way to increase (if s is 1, it's tied with incrementing). So if the challenge was to make s >= t, the answer would always be the number of doublings required to do that. This procedure may overshoot t, but the first doubling greater than t and the last doubling not greater than t must be within a factor of 2 of t.
Let's look at the effect of when we do an addition or subtraction. First, look only at addition:
(((s*2) * 2) * 2) + 1 = 8s + 1
vs:
((((s+1)*2) * 2) * 2) = 8s + 8
Putting an addition before n doublings makes the final result 2^n bigger. So consider if s is 3 and t is 8. The last double not bigger than 8 is 6. This is 2 off, so if we put an addition 1 double before the last double, we get what we want: (3+1) * 2. Alternatively we could try overshooting to the first double greater than 8, which is 12. This is 4 off, so we need to put a subtraction two doublings before the last : (3-1)*2*2 = 8
In general if we are x below the target, we need to put a +1 at n doublings before the last if the binary representation of x has a 1 at the nth place.
Similarly, if we are x above the target, we do likewise with -1's.
This procedure won't help for the 1's in x's binary representation that are at a position more than the number of doublings there are. For example, if s = 100, t=207, there is only 1 doubling to do, but x is 7, which is 111. We can knock out the middle one by doing an addition first, the rest we have to do one by one (s+1)*2 + 1 + 1 + 1 + 1 + 1.
Here is an implementation that has a debug flag that also outputs the list of operations when the flag is defined. The run time is O(log(t)):
#include <iostream>
#include <string>
#include <sstream>
#define DEBUG_INFO
int MinMoves(int s, int t)
{
int ans = 0;
if (t <= s)
{
return s - t; //Only subtraction will help
}
int firstDoubleGreater = s;
int lastDoubleNotGreater = s;
int nDouble = 0;
while(firstDoubleGreater <= t)
{
nDouble++;
lastDoubleNotGreater = firstDoubleGreater;
firstDoubleGreater *= 2;
}
int d1 = t - lastDoubleNotGreater;
int d2 = firstDoubleGreater - t;
if (d1 == 0)
return nDouble -1;
int strat1 = nDouble -1; //Double and increment
int strat2 = nDouble; //Double and decrement
#ifdef DEBUG_INFO
std::cout << "nDouble: " << nDouble << "\n";
std::stringstream s1Ops;
std::stringstream s2Ops;
int s1Tmp = s;
int s2Tmp = s;
#endif
int mask = 1<<strat1;
for(int pos = 0; pos < nDouble-1; pos++)
{
#ifdef DEBUG_INFO
if (d1 & mask)
{
s1Ops << s1Tmp << "+1=" << s1Tmp+1 << "\n" << s1Tmp+1 << "*2= " << (s1Tmp+1)*2 << "\n";
s1Tmp = (s1Tmp + 1) * 2;
}
else
{
s1Ops << s1Tmp << "*2= " << s1Tmp*2 << "\n";
s1Tmp = s1Tmp*2;
}
#endif
if(d1 & mask)
strat1++;
d1 = d1 & ~mask;
mask = mask >> 1;
}
strat1 += d1;
#ifdef DEBUG_INFO
if (d1 != 0)
s1Ops << s1Tmp << " +1 " << d1 << " times = " << s1Tmp + d1 << "\n";
#endif
mask = 1<<strat2;
for(int pos = 0; pos < nDouble; pos++)
{
#ifdef DEBUG_INFO
if (d2 & mask)
{
s2Ops << s2Tmp << "-1=" << s2Tmp-1 << "\n" << s2Tmp-1 << "*2= " << (s2Tmp-1)*2 << "\n";
s2Tmp = (s2Tmp-1)*2;
}
else
{
s2Ops << s2Tmp << "*2= " << s2Tmp*2 << "\n";
s2Tmp = s2Tmp*2;
}
#endif
if(d2 & mask)
strat2++;
d2 = d2 & ~mask;
mask = mask >> 1;
}
strat2 += d2;
#ifdef DEBUG_INFO
if (d2 != 0)
s2Ops << s2Tmp << " -1 " << d2 << " times = " << s2Tmp - d2 << "\n";
std::cout << "Strat1: " << strat1 << "\n";
std::cout << s1Ops.str() << "\n";
std::cout << "\n\nStrat2: " << strat2 << "\n";
std::cout << s2Ops.str() << "\n";
#endif
if (strat1 < strat2)
{
return strat1;
}
else
{
std::cout << "Strat2\n";
return strat2;
}
}
int main()
{
int s = 25;
int t = 193;
std::cout << "s = " << s << " t = " << t << "\n";
std::cout << MinMoves(s, t) << std::endl;
}
Short BFS algorithm. It finds the shortest path in graph where every vertex x is connected to x + 1, x - 1 and x * 2; O(n)
#include <bits/stdc++.h>
using namespace std;
const int _MAX_DIS = 2020;
const int _MIN_DIS = 0;
int minMoves(int begin, int end){
queue<int> Q;
int dis[_MAX_DIS];
fill(dis, dis + _MAX_DIS, -1);
dis[begin] = 0;
Q.push(begin);
while(!Q.empty()){
int v = Q.front(); Q.pop();
int tab[] = {v + 1, v - 1, v * 2};
for(int i = 0; i < 3; i++){
int w = tab[i];
if(_MIN_DIS <= w && w <= _MAX_DIS && dis[w] == -1){
Q.push(w);
dis[w] = dis[v] + 1;
}
}
}
return dis[end];
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cout << minMoves(1, 1000);
return 0;
}

Visual Studio 2017 C++Debug/Release different output

I've implemented a Kolakoski's sequence with a low memory footprint, using the reference from Wikipedia
#include <iostream>
#include <iomanip>
#include <vector>
int IncrementPointer(std::vector<int>& vec, int k)
{
if (vec.size() <= k)
{
vec.push_back(22);
}
if (vec[k] == 11)
{
vec[k] = 1;
return 1;
}
else if (vec[k] == 22)
{
vec[k] = 2;
return 2;
}
else if (vec[k] == 1)
{
vec[k] = IncrementPointer(vec, k + 1) == 1 ? 2 : 22;
return 2;
}
else if (vec[k] == 2)
{
vec[k] = IncrementPointer(vec, k + 1) == 1 ? 1 : 11;
return 1;
}
return 0;
}
int main()
{
long long iteration = 2;
long long nextPowOf10 = 10;
long long numOf1s = 1;
std::vector<int> vec;
std::cout << std::setw(15) << 'n' << std::setw(15) << "#1s" << std::setw(8) << "P(n)\n";
std::cout << std::setw(15) << 1 << std::setw(15) << numOf1s << '\n';
while (iteration++ <= 100'000'000'000'000)
{
int retvalue = IncrementPointer(vec, 0);
if (retvalue == 1)
++numOf1s;
if (iteration % nextPowOf10 == 0)
{
std::cout << std::setw(15) << nextPowOf10 << std::setw(15) << numOf1s << std::setw(8) << vec.size() << '\n';
nextPowOf10 *= 10;
}
}
return 0;
}
Now, the program internally calculates right elements of the sequence in Debug Mode and outputs expected results. So far, so good.
The problem starts in Release mode, vector gets optimized away (how could it be?), and the elements calculated are now wrong.
The expected sequence is [[1 2] 2 1 1 2 1 2 2 etc.], with first two are preset.
and in release mode the elements are [1 2] 2 1 1 1 1 1 2 ... Clearly, something wrong went on. And subsequently the output is unexpected, and the program crashes, with calling to malloc (so it does have somewhere vector reallocated).
What am I doing wrong? Is it simultaneous push_back to vector and update to the element of vector?
I believe a construct like this exhibits undefined behavior:
vec[k] = IncrementPointer(vec, k + 1) == 1 ? 2 : 22;
It is unspecified whether vec[k] or IncrementPointer(vec, ...) gets evaluated first. vec[k] returns a reference to the corresponding element. If IncrementPointer is called later, it may push new elements into vec which in turn may cause it to reallocate, whereupon that reference becomes dangling.
Make it
int val = IncrementPointer(vec, k + 1);
vec[k] = val == 1 ? 2 : 22;

Pairs x,y verify equation

I have to build a program as bellow:
User enters 3 Integers: a, b, c
User enters one integer n, and then n integers (ascending, and different numbers)
Program checks all possible pairs (x,y) (with x!=y) of the numbers entered if verifies the equation ax^2 + by^2 = c and prints all pairs which verifies the equation.
I done the program as bellow:
#include<iostream>
using namespace std;
int main() {
int a,b,c,n,i,j;
cin >> a;
cin >> b;
cin >> c;
cin >> n;
int num[n];
for(i=0;i<n;i++) {
cin >> num[i];
}
for (i=0;i<n;i++)
for (j=i+1;j<n;j++) {
if(a*num[i]*num[i]+b*num[j]*num[j] == c) {
cout << "(" << num[i] << "," << num[j] << ")";
}
if(a*num[j]*num[j]+b*num[i]*num[i] == c) {
cout << "(" << num[j] << "," << num[i] << ")";
}
}
return 0;
}
I made it by O(nlogn) with two 'for' statements but i know it could be done by O(n).
NOTE THAT MY PROGRAM WORKS AND I DON'T NEED TO ADD EXPECTED OUTPUT AND MY CURRENT OUTPUT AS YOU SAID IN THE COMMENTS. I ONLY WANT IT TO BE O(N) not O(nlogn) -> I WANT AN OPTIMIZED VERSION OF THE CODE!
How can I do this?
Example of running program: a=1, b=1, c=20
Then n = 5
Then n numbers: 2 3 4 9 18
Program will show all pairs (x,y) which verifies the equation x^2 + y^2 = 20. In this case it shows (2,4)
and (4,2).
Thank you!
Assuming 0 based index...
Set i=0
Set j=n-1
While i<n or j>=0
Set sum=a(num[i]^2)+b(num[j^2)
If sum==c then found pair, and increase i
If sum<c increase i
If sum>c decrease j
I found exactly this problem solved here: http://lonews.ro/educatie-cultura/22899-rezolvare-admitere-universitatea-bucuresti-2015-pregatire-informatica.html and changed a bit to show the pairs (it originally shows the number of pairs).
#include <iostream>
using namespace std;
int main()
{
int a, b, c, n, i=0;
cout << "a = ";
cin >> a;
cout << "b = ";
cin >> b;
cout << "c = ";
cin >> c;
cout << "n = ";
cin >> n;
int s[n];
for(i=0; i<n; i++) {
cout << "s[" << i+1 << "] = ";
cin >> s[i];
}
int j=n-1;
i = 0;
while(j>=0 || i<n) {
if(a*s[i]*s[i] + b*s[j]*s[j] == c) {
cout << "(" << s[i] << "," << s[j] << ") ";
i++;
}
if(a*s[i]*s[i] + b*s[j]*s[j] < c) {
i++;
}
if(a*s[i]*s[i] + b*s[j]*s[j] > c) {
j--;
}
}
return 0;
}

combination of n distinct numbers

I have a set of n case in the format a b what I have to do is I have to form number of distinct combination of numbers from a,b. for e.g.,
suppose n=4 and a,b are are follow
1 2
3 1
2 4
3 2
Now total there are 4 distinct number by seeing a,b, they are(1,2,3,4)
and two combination of all distinct numbers can be formed, they are (1,3,4,2) and (2,1,4,3) as follow :-
1 2
|
3 1
\
2 4
|
3 2
and
1 2
|
3 1
|
2 4
/
3 2
My problem is I am unable to think how to code, as n<=50 and a,b<=16 so I am not sure that how many distinct number can be there, if there are 16 numbers then I have to find all possible combination of 16 numbers, so guide me through this.
To form a list of distinct numbers just use a "unique set" and keep inserting all the numbers to it. In C++, std::set by definition stores only unique numbers.
To find the number of combinations of distinct sequences, you will have to keep a list of "candidate lists" and keep inserting numbers in them if they already don't have those numbers, else delete that particular candidate list.
Full code in C++:
#include <iostream>
#include <vector>
#include <set>
using namespace std;
int main() {
int n = 4;
set<int> uniqueNumbers; // ordered set of unique numbers
vector< set<int> > possibleLists( 1 );
set<int>::iterator it;
for ( int i = 0; i < n; i++ ) {
int num1;
int num2;
cin >> num1 >> num2;
// numbers will be inserted if not already present in set (by definition)
uniqueNumbers.insert( num1 );
uniqueNumbers.insert( num2 );
// make a copy for a possible new branch
vector< set<int> > possibleListsCopy( possibleLists );
//int size1 = possibleLists.size();
for ( int j = 0; j < possibleLists.size(); j++ ) {
it = possibleLists[j].find( num1 );
if ( it == possibleLists[j].end() ) {
possibleLists[j].insert( num1 ); // insert if not found
//cout << "inserted1 "<<endl;
}
else {
// erase this possible combination
possibleLists[j].clear();
possibleLists.erase( possibleLists.begin() + j );
j--;
}
}
//int size2 = possibleListsCopy.size();
for ( int j = 0; j < possibleListsCopy.size(); j++ ) {
;
it = possibleListsCopy[j].find( num2 );
if ( it == possibleListsCopy[j].end() ) {
possibleListsCopy[j].insert( num2 ); // insert if not found
}
else {
// erase this possible combination
possibleListsCopy[j].clear();
possibleListsCopy.erase( possibleListsCopy.begin() + j );
j--;
}
}
// concatenate both set of lists.
possibleLists.insert( possibleLists.end(),
possibleListsCopy.begin(),
possibleListsCopy.end() );
}
cout << " The unique list: ";
//output the unique list.
for ( it = uniqueNumbers.begin(); it != uniqueNumbers.end(); it++ )
cout << *it << " ";
/*cout << endl << endl;
cout << "Possible Lists:" << endl;
for ( int i = 0; i < possibleLists.size(); i++ ) {
for ( it = possibleLists[i].begin(); it != possibleLists[i].end(); it++ )
cout << *it << " ";
cout << endl;
}*/
cout << endl << "Total number of combinations: "
<< possibleLists.size() << endl;
return 0;
}
Input:
1 2
3 1
2 4
3 2
Output:
The unique list: 1 2 3 4
Total number of combinations: 2
Recursion is probably the easiest route when solving combinatorial problems like this one. The idea is that you consider all the possibilities for the current item, then pass off the rest of the work by recursing on the remaining items. In this case you need to pass along a bit of extra information about what items not to use.
It works something like this:
def DistinctChooseFromEach(listOfChoicePairs, alreadyUsed = {}):
if listOfChoicePairs is empty: return []
for value in listOfChoicePairs[0]:
if value in alreadyUsed: continue;
newUsed = union(alreadyUsed, value)
remainingChoices = listOfChoicePairs[1:];
tails = DistinctChooseFromEach(remainingChoices, newUsed)
for tail in tails:
yield concat(value, tail)

Resources