Can't understand this why we use (S-X)/2 - java

Given the sum and xor of two numbers X and Y, we need to find the numbers.
I came across a solution in GeeksForGeeks (https://www.geeksforgeeks.org/find-two-numbers-sum-xor/).
In this I don't understand why they did A=(S-X)/2 inside compute function. Why not trying to find from S directly? Can any one please explain that?
// Java program to find two numbers with
// given Sum and XOR such that value of
// first number is minimum.
class GFG {
// Function that takes in the sum and XOR
// of two numbers and generates the two
// numbers such that the value of X is
// minimized
static void compute(long S, long X)
{
long A = (S - X)/2;
int a = 0, b = 0;
final int LONG_FIELD_SIZE = 8;
// Traverse through all bits
for (int i=0; i<8*LONG_FIELD_SIZE; i++)
{
long Xi = (X & (1 << i));
long Ai = (A & (1 << i));
if (Xi == 0 && Ai == 0)
{
// Let us leave bits as 0.
}
else if (Xi == 0 && Ai > 0)
{
a = ((1 << i) | a);
b = ((1 << i) | b);
}
else if (Xi > 0 && Ai == 0)
{
a = ((1 << i) | a);
// We leave i-th bit of b as 0.
}
else // (Xi == 1 && Ai == 1)
{
System.out.println("Not Possible");
return;
}
}
System.out.println("a = " + a +"\nb = " + b);
}
// Driver function
public static void main(String[] args) {
long S = 17, X = 13;
compute(S, X);
}
}

Related

Java manual overflow handling undesired output

I have the following program
The sum of squares 1^2 + 2^2 + … + N^2 is calculated as:
Example output:
java SumSquares 2 = 5
java SumSquares 3 = 14
java SumSquares 1000000 = 333333833333500000
Here's what I have so far:
int N = Integer.parseInt(args[0]);
int sum = 0;
long R;
for (int i = 1; i <= N; i++) {
R = i * i;
if (i != R / i) {
System.err.println("Overflow at i = " + i);
System.exit(1);
}
sum += R;
}
System.out.println(sum);
My output is java SumSquares 100000000
Overflow at i = 46341
As 46341^2 passes MAX INT.
I just can't get the program to out put the below instructions, any ideas on how to get
java SumSquares 100000000
Overflow at i = 3024616
I could change the ints to longs but that would negate the need for the overflow checking.
From specification:
The computation will overflow. I need to exactly determine the point in the summation where the overflow happens, via checking whether the new sum is (strictly) less than the old sum.
java SumSquares 100000000
Overflow at i = 3024616
Note that the above must be achieved by a general overflow-handling in the loop, not by some pre-determined input-testing. So that when the integer-type used for the summation is replaced by some bigger type, your program will fully use the new extended range.
Just to clarify:
Is it possible to get the output
java SumSquares 100000000
Overflow at i = 3024616
As per the specification.
You have 2 errors:
R = i * i still performs the multiplication using int math, and doesn't widen the value to long until after multiplication has already overflowed to a negative value.
You need to cast at least one of them to long, e.g. R = i * (long) i.
if (i != R / i) is not the right test for overflow. Simply check if the long value exceeds the range of int: if (r > Integer.MAX_VALUE)
static int sumOfSquares(int n) {
int sum = 0;
for (int i = 1; i <= n; i++) {
long r = i * (long) i;
if (r > Integer.MAX_VALUE) {
System.err.println("Overflow at i = " + i);
System.exit(1);
}
sum += r;
}
return sum;
}
Test
System.out.println(sumOfSquares(2));
System.out.println(sumOfSquares(3));
System.out.println(sumOfSquares(1000000));
Output
5
14
Overflow at i = 46341
Another way to guard against overflow is to use the Math.multiplyExact() and Math.addExact() methods.
static int sumOfSquares(int n) {
int sum = 0;
for (int i = 1; i <= n; i++) {
int r = Math.multiplyExact(i, i);
sum = Math.addExact(sum, r);
}
return sum;
}
Output
5
14
Exception in thread "main" java.lang.ArithmeticException: integer overflow
at java.base/java.lang.Math.addExact(Math.java:825)
at Test.sumOfSquares(Test.java:12)
at Test.main(Test.java:6)
Or catch the exception if you want a better error message:
static int sumOfSquares(int n) {
int sum = 0;
for (int i = 1; i <= n; i++) {
try {
int r = Math.multiplyExact(i, i);
sum = Math.addExact(sum, r);
} catch (#SuppressWarnings("unused") ArithmeticException ignored) {
System.err.println("Overflow at i = " + i);
System.exit(1);
}
}
return sum;
}
Output
5
14
Overflow at i = 1861
Without having to use longs, you can check if the multiplication of two integers will overflow before actually doing the operation:
int a = 500000; //or -500000
int b = 900000; //or -900000
System.out.println(isOverflowOrUnderflow(a, b));
//Returns true if multiplication of a, b results in an overflow or underflow..
public static boolean isOverflowOrUnderflow(int a, int b) {
return ((a > Integer.MAX_VALUE / b) || (a < Integer.MIN_VALUE / b) || ((a == -1) && (b == Integer.MIN_VALUE)) || ((b == -1) && (a == Integer.MIN_VALUE)));
}
Example using your code:
public class Main {
public static void main (String[] args) {
int N = Integer.parseInt(args[0]); //Where args[0] = "1000000"..
int sum = 0;
long R;
for (int i = 1; i <= N; i++) {
if (Main.isOverflowOrUnderflow(i, i)) {
System.err.println("Overflow at i = " + i);
System.exit(1);
}
R = i * i;
sum += R;
}
System.out.println(sum);
}
public static boolean isOverflowOrUnderflow(int a, int b) {
return ((a > Integer.MAX_VALUE / b) || (a < Integer.MIN_VALUE / b) || ((a == -1) && (b == Integer.MIN_VALUE)) || ((b == -1) && (a == Integer.MIN_VALUE)));
}
}
Outputs:
Overflow at i = 46341
Command exited with non-zero status 1

Optimizing the largest palindrome from product of two three digit numbers?

I am working on an interview question which I was asked in which I was supposed to write a program to find the largest palindrome from product of two three digit numbers.
Here is the question
I came up with this brute force approach which starts from bottom.
public class LargestPalindromeQuestion {
public static void main(String[] args) {
int value = 0;
for (int i = 100; i <= 999; i++) {
for (int j = i; j <= 999; j++) {
int value1 = i * j;
if (isPalindrome(value1) && value < value1) {
value = value1;
}
}
}
System.out.println(value);
}
private static boolean isPalindrome(final int product) {
int p = product;
int reverse = 0;
while (p != 0) {
reverse *= 10;
reverse += p % 10;
p /= 10;
}
return reverse == product;
}
}
They asked me what are the optimizations I can do in this program? I mentioned that we can try pruning the search space and optimize checking step for each item in the search space but then I am confuse how would I make this work in my above solution?
What are the optimizations we can do in this program? Right now it is executing 810000 steps to find the largest palindrome.
What is the least number of steps we can execute to find the largest palindrome in two three digit numbers?
The program looks very good to me. I would make the i loop count from 999 down to 100, and I would only check j values that would actually give a larger product than the current maximum.
This program is able to finish surprisingly soon, at i == 952 to be precise. The mathematical reason for this is that once the solution 906609 (993 * 913) is found, it will no longer be possible to find a larger palindrome where the larger factor is less than the square-root of 906609, which is 952.160....
public static void main(String[] args) {
int value = 0;
for (int i = 999; i >= 100; i--) {
int r = value / i;
if (r >= i) {
System.out.println("We broke at i = " + i);
break;
}
for (int j = i; j > r; j--) {
int value1 = i * j;
if (isPalindrome(value1)) {
value = value1;
break;
}
}
}
System.out.println(value);
}
One pretty simple way of optimizing this would be to simply start with the highest 3-digit numbers instead of the smallest. Since the solution will most likely be closer to the pair (999 , 999) than to (100 , 100).
One useful mechanism to prune the search tree is to notice that the highest digit of the product a * b doesn't change often. E.g.
a = 111; b = 112 a*b = 12432
; b = 113 a*b = 12543
; b = 114 a*b = 12654
; ...
; b = 180 a*b = 19980
; b = 181 a*b = 20091 = (19980 + a)
Thus, for all the values in between (a = 111, a < b < 181), one already knows the MSB, which must equal to the LSB or (a % 10) * (b % 10) % 10 == MSB.
e.g.
LSB = 1 --> a % 10 == 1, b % 10 == 1
OR a % 10 == 3, b % 10 == 7
OR a % 10 == 7, b % 10 == 3
OR a % 10 == 9, b % 10 == 9
Most of the time there's either none, or just one candidate in set 'b' to be checked for any pair MSB, a % 10.
The least number of steps I could get to is 375. Consider multiplying the three-digit number, a1a2a3, by the three-digit number, b1b2b3:
JavaScript code:
var modHash = new Array(10);
var iterations = 0;
for (var i=1; i<10; i++){
modHash[i] = {0: [0]}
for (var j=1; j<10; j++){
iterations ++;
var r = i * j % 10;
if (modHash[i][r])
modHash[i][r].push(j);
else
modHash[i][r] = [j];
}
}
var highest = 0;
function multiples(x,y,carry,mod){
for (var i in modHash[x]){
var m = (10 + mod - i - carry) % 10;
if (modHash[y][m]){
for (var j in modHash[x][i]){
for (var k in modHash[y][m]){
iterations ++;
var palindrome = num(9,modHash[y][m][k],x,9,modHash[x][i][k],y);
if (x == 3 && mod == 0){
console.log(x + " * " + modHash[x][i][j] + " + "
+ y + " * " + modHash[y][m][k] + ": " + palindrome);
}
var str = String(palindrome);
if (str == str.split("").reverse().join("") && palindrome > highest){
highest = palindrome;
}
}
}
}
}
}
function num(a1,a2,a3,b1,b2,b3){
return (100*a1 + 10*a2 + a3)
* (100*b1 + 10*b2 + b3);
}
var a3b3s = [[7,7,4],[9,1,0],[3,3,0]];
for (var i in a3b3s){
for (var mod=0; mod<10; mod++){
var x = a3b3s[i][0],
y = a3b3s[i][1],
carry = a3b3s[i][2];
multiples(x,y,carry,mod);
}
}
console.log(highest);
console.log("iterations: " + iterations);
Output:
3 * 0 + 3 * 0: 815409
3 * 7 + 3 * 3: 907809
3 * 4 + 3 * 6: 908109
3 * 1 + 3 * 9: 906609
3 * 8 + 3 * 2: 907309
3 * 5 + 3 * 5: 908209
3 * 2 + 3 * 8: 907309
3 * 9 + 3 * 1: 906609
3 * 6 + 3 * 4: 908109
3 * 3 + 3 * 7: 907809
906609
iterations: 375
First optimize isPalindrome by seperating 6 digits as 3 digits. i.e. N = ABCDEF => a = ABC = N/1000, b = DEF = N%1000; Then reverse b and return a==reversed_b;
Secondly while producing palindromes loop through till max_palindrome_so_far/999 which is the minimum value that you would use. max_palindrome_so_far is initially equals N.
public class Solution {
public static boolean isPalindrome(int n){
int a = n/1000;
int b = n%1000;
int d, r = 0, i = 3;
while(i-- > 0){
d = b%10;
r = r*10 + d;
b = b/10;
}
if (a == r)
return true;
return false;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int t = in.nextInt();
for(int a0 = 0; a0 < t; a0++){
int n = in.nextInt();
int r=0, m=n;
int i,j;
for(i = 999;i>=100;i--){
for(j = 999;j>=m/999;j--){
if (i*j < n && i*j > 100000 && isPalindrome(i*j)){
r = Math.max(i*j, r);
m = r;
}
}
}
// System.out.println(i + " * " + j + " = " + i*j);
System.out.println(r);
}
}
}

finding the sum of number dividsable by x using recursion

I want to find the sum of numbers that is divisible by x using recursive method
Ex if n= 10, x=3, the code should return sum of 3+6+9
Write a recursive method sumDivByX(n, x), which finds the sum of all
numbers from 0 to n that are divisible by x.
I asked my teacher about it and he told me "Firstly, total should be global. You should return 0 if n or x == 0. I only care if n is divisible by x. So I only add n to total (total+=n) if (n%x==0) otherwise do nothing. And do recursion sumDivByX(n-1,x) and return total as usual." I tried to correct it.
public static int sumDivByX(int n, int x) {
int total = 0;
if (n == 0 || x == 0) {
return -1;
}
if (n % x >= 1) {
return total = 0;
} else if (n % x == 0) {
return total += n;
}
return total + sumDivByX(n - 1, x);
}
When I run the program I get 0.
Eliminate the returns inside your second and third if statements
public static int sumDivByX(int n, int x) {
int total = 0;
if (n == 0 || x == 0) {
return 0;
}
if (n % x >= 1) {
total = 0;
} else if (n % x == 0) {
total += n;
}
return total + sumDivByX(n - 1, x);
}
For a cuter, more compact version
public static int sumDivByX(int n, int x) {
if (n == 0 || x == 0) {
return 0;
}
return (n % x == 0 ? n : 0) + sumDivByX(n - 1, x);
}
Note - depending on the semantics you intend, you might want to have separate checks for x<=0 (possibly and error?) and n==0 (base case).
Step through your code and you'll see that it never recurses when n ==10 and x==3, since (10 % 3 == 1)
When a method gets to a "return" statement it ends, in your case at the second if.
Your total is initialized by 0 everytime the method runs, so you should consider making it global.
Your method generates an exception if you try to use negative numbers as paramethers
Try this:
int total=0;
public static int subDivByX(int n, int X) {
if (n>0 && x>0) {
if (n%x==0){
total += n;
}
return sumDivByX(n-1,x);
}
else return -1;
}
This seems to work
private static int sumDivByX(int n,int x) {
if (n < x || x < 1 ) {
return 0;
}
int d = n/x;
return (x * d) + sumDivByX(n - x , x);
}
Recursion could cause a stackoverflow.

Counting the number of digits in a natural number with recursion

I am trying to return the number of digits of a Natural Number and I am almost there. I don't know how to count the digits though.
private static int numberOfDigits(NaturalNumber n) {
NaturalNumber zero = new NaturalNumber2(0);
int a = 0;
if (n.compareTo(zero) != 0) {
a = n.divideBy10();
numberOfDigits(n);
}
return a;
}
I know I am returning the last remainder of n which is 0 but how do I count through the recursion?
If your current n is not zero, then you have one digit plus the number of digits in the number divided by 10. Hint: you don't need the a variable.
if (n.compareTo(zero) != 0)
{
// Return 1 for the last digit (1) + the rest.
return 1 + numberOfDigits(n.divideBy10());
}
// Base case.
return 0;
private static int numberOfDigits(NaturalNumber n) {
NaturalNumber zero = new NaturalNumber2(0);
if (n.compareTo(zero) == 0) {
return 0;
} else {
n.divideBy10();
return 1 + numberOfDigits(n);
}
}
If you want to cover zero, use the following.
private static int numberOfDigits(NaturalNumber n) {
if(n < 10) return 1;
return 1 + numberOfDigits(n/10);
}
Here it is in C++
int digits(int a, int c)
{
int d = -1;
if (a<10 && a>0)
{
c = c+1;
cout << "No of digits = " << c << endl;
}
else if (a%10 == 0) // correct
{
d = a/10;
c++;
if (d == 0)
{
cout << "No of digits = " << c+2 << endl;
return c;
}
else { digits(d,c); }
}
else if (a>10 && a%10 != 0)
{
d = a/10;
c++;
if (d == 0)
{
cout << "No of digits = " << c+2 << endl;
return c;
}
else { digits(d,c); }
}
return 0;
}
int main()
{
int n;
cin >> n;
int c1 = 0;
digits(n,c1);
return 0;
}

Summing integers recursive with Java

I have to calculate a sum of two integers by using a recursive algorithm, but sincerely i have no idea how to do so. Here are the conditions:
sum(x,y) = ?
if x = 0 then sum (x,y) = y otherwise sum(x,y) = sum(predecessor(x),successor(y)).
Does someone have an idea how i could write this in an algorithm? I would be glad about any advice.
I won't give you the code since this seems to be a homework but here is the rough algorithm:
predecessor(x) = x - 1
successor(x) = x + 1
sum(x, y) =
if x = 0
then y
otherwise sum(predecessor(x), successor(y))
That's the simplest I could immagine
public static void main(String[] args) {
System.out.println("4+5 = " + sum(4, 5));
System.out.println("4+(-5) = " + sum(4, -5));
System.out.println("-4+5 = " + sum(-4, 5));
System.out.println("-4+5 = " + sum(-4, -5));
}
public static int sum(int x, int y) {
if (x < 0) {
x *= -1;
y *= -1;
}
return (x == 0 ? y : sum(--x, ++y));
}
Here is my solution for i&j both >= 0. set sum = 0; and subtract 1 until it is <= 0
public static int sum(int i, int j){
return sum(i,j,0);
}
private static int sum(int i, int j, int sum) {
if (i <= 0 && j <= 0) {
return sum;
} else if (i <= 0) {
return sum(0, j - 1, sum + 1);
} else if (j <= 0) {
return sum(i - 1, 0, sum + 1);
} else {
return sum(i - 1, j - 1, sum + 2);
}
}
public static void main(String[] args) {
System.out.println(sum(60, 7));
}
To handle negative numbers based on #aioobe's answer.
sum(x, y): return x == 0 ? y : x < 0 ? ~sum(~x, -y) : sum(x-1, y+1)
Note: the rather optimisic use of ~ to avoid blowing up on x=MIN_VALUE. ;)
Javaish pseudo code corresponding to your code in your question
sum(x, y): return x == 0 ? y : sum(x-1, y+1)
Works for any pair of numbers where x is a non-negative integer.

Categories