Recursively find combinations of three numbers that sum up to given number - java

Given a number between 1 and 30, find all three-number combinations that sum up to this number and return the amount of combinations without using loops.
for example, given 5, print
1 + 1 + 3
1 + 2 + 2
1 + 3 + 1
2 + 1 + 2
2 + 2 + 1
3 + 1 + 1
This is what I have right now, using Java.
private static int numbers(int num, int num1, int num2, int num3){
boolean valid_solution = num1+num2+num3 == num;
int counter = 0;
if (valid_solution){
System.out.println(num1+" + "+num2+" + "+num3);
counter++;
}
if (num1>10 || num2>10 || num3>10 || num1+num2+num3>num){
return counter;
}
counter += numbers(num, num1 + 1, num2, num3)+numbers(num, num1, num2 + 1, num3)+numbers(num, num1, num2, num3 + 1);
return counter;
}
public static int solutions(int num){
if (num < 0 || num > 30) return 0;
return numbers(num, 1, 1, 1);
}
I seem to get duplicates, for example for 5-
3 + 1 + 1
2 + 2 + 1
2 + 1 + 2
2 + 2 + 1
1 + 3 + 1
1 + 2 + 2
2 + 1 + 2
1 + 2 + 2
1 + 1 + 3
edit - I'm also not allowed to use global variables.

You can see why the duplicates are happening if you add a little logging
1:1:1
2:1:1
3:1:1
3 + 1 + 1
4:1:1
3:2:1
3:1:2
2:2:1
2 + 2 + 1
3:2:1
2:3:1
2:2:2
2:1:2
2 + 1 + 2
3:1:2
2:2:2
2:1:3
1:2:1
2:2:1
2 + 2 + 1
3:2:1
2:3:1
2:2:2
1:3:1
1 + 3 + 1
2:3:1
1:4:1
1:3:2
1:2:2
1 + 2 + 2
2:2:2
1:3:2
1:2:3
1:1:2
2:1:2
2 + 1 + 2
3:1:2
2:2:2
2:1:3
1:2:2
1 + 2 + 2
2:2:2
1:3:2
1:2:3
1:1:3
1 + 1 + 3
2:1:3
1:2:3
1:1:4
counter:9
so since you are making recursive calls on incrementing numbers, when you're recursively calling num2+1, you want to make sure that num1 is less than or equal to num2 in order to avoid duplicates

I have a suspicions that this code of mine is far from being a good solution, but who knows, may be it will be helpful for you in some way.
public class FindSumCombinations {
static int start = 5;
static int comb1 = 0;
static int comb2 = 0;
public static void main(String[] args) {
comb1(start);
}
public static int comb1(int x){
if(x == 0) return 0;
comb1 = x;
comb2(x);
return comb1(x-1);
}
public static int comb2(int x){
if(x == 0) return 0;
comb2 = x;
comb3(x);
return comb2(x-1);
}
public static int comb3(int x){
if(x == 0) return 0;
if(x + comb2 + comb1 == start){
System.out.println(comb1 + "+" + comb2 + "+" + x);
System.out.println(x + "+" + comb1 + "+" + comb2);
System.out.println(comb2 + "+" + x + "+" + comb1);
}
return comb3(x-1);
}
}

Related

Backtracking Min options to sum a number using 1, 5 and 7 via recursion - JAVA

I want to create a recursion function that returns the minimum options to create a certain number using numbers 1, 5 and 7 (Fixed predetermined numbers). It is important that this is done only by recursion without loops at all.
For example:
if n = 10 then it is given to the scheme by 5 + 5 which is 2 numbers, so this is the minimum and this is what we will get (as opposed to 7 + 1 + 1 + 1 or 5 + 1 + 1 + 1 + 1 + 1 that is 4 or 6 Options that are longer).
If n = 6 then we get a result of 2 (because it is given as a sum of 1 + 5).
If n = 5 (or 7 or 1) then we get a result of 1 (because it is given by the number only).
class TEST {
static int countMin( int S[], int m, int n ,int min)
{
if (n == 0)
return 1;
if (n < 0)
return 0;
if (m <=0 && n >= 1)
return 0;
return Math.min(min,countMin( S, m - 1, n ,min-1) + countMin( S, m, n-S[m-1],min-1 ));
}
public static int f(int n) {
int arr[] = {1, 5, 7};
return countMin(arr, arr.length, n,n);
}
public static void main(String[] args)
{
int n = 10;
System.out.println("The number "+n+ " - " + f(n) + " minimum options to create");
int n2 = 7;
System.out.println("The number "+n2+ " - " + f(n2) + " minimum options to create");
int n3 = 6;
System.out.println("The number "+n3+ " - " + f(n3) + " minimum options to create");
}
}
I get for n = 10 and n = 5 for the correct result but not for n = 6 which should return 2.
*I've used this link: https://www.geeksforgeeks.org/coin-change-dp-7/
Think of a tree where each node has a value and has 3 children with its value decremented respectively by 7, 5, and 1
So node with total 15 would have children with values 8, 10, 14
We can start with first node having your total, and calculate each level and stop when we find a child worth 0. We also stop looking at a child if its value is less than 0.
For 10 for example:
10
/ | \
3 5 9
/ | \ / | \ / | \
-4 -2 2 -2 0 4 2 4 1
We find zero at depth 2
private static int calculate(int total, int depth) {
if (total == 0)
return depth;
else {
int i = total - 7 >= 0 ? calculate(total - 7, depth+1) : Integer.MAX_VALUE;
int j = total - 5 >= 0 ? calculate(total - 5, depth+1) : Integer.MAX_VALUE;
int k = total - 1 >= 0 ? calculate(total - 1, depth+1) : Integer.MAX_VALUE;
return Collections.min(Arrays.asList(i, j, k));
}
}
This
int n = 10;
System.out.println("The number "+n+ " - " + calculate(n, 0) + " minimum options to create");
n = 7;
System.out.println("The number "+n+ " - " + calculate(n, 0) + " minimum options to create");
n = 6;
System.out.println("The number "+n+ " - " + calculate(n, 0) + " minimum options to create");
n = 18;
System.out.println("The number "+n+ " - " + calculate(n, 0) + " minimum options to create");
Outputs this
The number 10 - 2 minimum options to create
The number 7 - 1 minimum options to create
The number 6 - 2 minimum options to create
The number 18 - 4 minimum options to create
EDIT:
The same in a funky lambda style:
private static int calculate(int total, int depth) {
return total == 0 ?
depth :
Stream.of(7, 5, 1)
.map(i -> total - i >= 0 ? calculate(total - i, depth+1) : Integer.MAX_VALUE)
.min(Integer::compare)
.get();
}

Java println weird output

I'm getting a weird output from running this simple java program.
The output is: 0 4 2 -6
Why does the x++ print 0, it should be printing 4.
import java.util.*;
import java.io.*;
public class Java1 {
public static void main(String[] args) throws IOException {
int x = 4;
int y = -5;
System.out.println(x++ + " " + func(x++, y) + " " + --y);
}
public static int func(int work, int y) {
int z = work + y;
work++;
y++;
System.out.print(z + " ");
return z + work + y;
}
}
Okay, here is what's going on: First x++ is evaluated, returning 4 (which is later printed) and leaving x at 5. Then x++ is evaluated again, passing 5 to func. Then func is evaluated with 5 and -5 parameters. In here z is 0 (5 + (-5) = 0) which is then printed (BEFORE the println in the main method. func then returns 2 (0 + 6 + (-4)) which is also added to the string. Finally --y results in -6. Now the println in the main method prints its string (4 2 -6).
func(x++, y) is executed first, so 0 comes from System.out.print(z + " "); in func.
System.out.print(z + " ");
is executed before
System.out.println(x++ + " " + func(x++, y) + " " + --y);
So the 0 comes from z, not x.
I have mentioned the flow of points from 0 to 7 in the comments
public static void main(String[] args) throws IOException {
int x = 4;
int y = -5;
System.out.println(x++ + " " + func(x++, y) + " " + --y);
// thus 0]4 6]2 (value returned as z) 7] localvalue of --y as -6
}
//1] x++ makes x as 5 when it is passed to func()
public static int func(int work, int y) {
int z = work + y;
//2] z = 5 + -5 = 0
work++;
//3] work which was x as 5 is now 6
y++;
//4] y will be -4 now
System.out.print(z + " ");
return z + work + y;
//5] z = 0 + 6 + -4 = 2 and is returned to func() caller
}
import java.util.*;
import java.io.IOException;
public class Java1
{
public static void main(String args[])
{
int x = 4;
int y = -5;
System.out.println("x = "+ (x++ ) +" func = "+ (func(x++, y) ) + " y = "+ --y);
}
public static int func(int work, int y)
{
int z = work + y;// 5+-5 = 0
work++; //6
y++; //-4
System.out.print("Z = " + z + " ");//0
return z + work + y; //0 + 6+-4 = 2
}
}
OUTPUT :
Z = 0 x = 4 func = 2 y = -6
Here the func() is executed first and hence the value of variable z is printed as 0 and then the x++ value is printed as 4.

Modify solution to use a single loop

I managed to solve this, below is my solution :
public class ProblemA001k {
public static void main(String[] args) {
System.out.println("Sum from 1" + " to " + divQ + ":" + sum2);
System.out.println();
divQ += q;
newQ += q;
sum1 = 0;
sum2 = 0;
}
key.close();
}
}
Now I was told to modify my solution so that it uses ONLY ONE LOOP.
I have 3 loops in the code above, even when I tried using only 2 loops I struggled. but ONE LOOP ? I don't know how to improve my code. Please help me.
This is a Mathematic problem.
If you know that you can find the sum of all integers from 1 to X, you just need to do X * (X+1) / 2.
You can find all the batch values easily.
Sum from 1 to 400: 80200
Sum from 401 to 450: 21275
Sum from 1 to 450: 101475
Will be found like this :
450 * 451 / 2 = 101475 (1 to 450)
400 * 401 / 2 = 80200 (1 to 400)
101475 - 80200 = 21275 (401 to 450)
With this, you can limit the loop to just calculate the values from q to n by incrementing by q
And a quick code to do it :
static void sum(int n, int q){
int i = q;
int sum, tmp=0;
while(i < n){
sum = i * (i+1) / 2;
System.out.println(String.format("Sum from %d to %d : %d", i-q+1 , i, sum - tmp));
System.out.println(String.format("Sum from %d to %d : %d", 1, i, sum));
tmp = sum;
i += q;
}
}
And I run it with
public static void main(String[] args){
sum(500, 50);
}
to have this result
Sum from 1 to 50 : 1275
Sum from 1 to 50 : 1275
Sum from 51 to 100 : 3775
Sum from 1 to 100 : 5050
Sum from 101 to 150 : 6275
Sum from 1 to 150 : 11325
Sum from 151 to 200 : 8775
Sum from 1 to 200 : 20100
Sum from 201 to 250 : 11275
Sum from 1 to 250 : 31375
Sum from 251 to 300 : 13775
Sum from 1 to 300 : 45150
Sum from 301 to 350 : 16275
Sum from 1 to 350 : 61425
Sum from 351 to 400 : 18775
Sum from 1 to 400 : 80200
Sum from 401 to 450 : 21275
Sum from 1 to 450 : 101475
The good think with this solution is the number of loop, this will increment by q instead of 1
Note : The solution is a quick implementation, this could be done better.
EDIT :
Thanks to Margaret Bloom in the comments to point out the name of this formula :) For more information, you are welcome to look at Triangular Number
This should do it:
int totalSum = 0;
int batchSum = 0;
for (int i = 1; i <= n; i++) {
totalSum += i;
batchSum += i;
if (i % q == 0) {
System.out.println("Sum from " + (i - q + 1) + " to " + i + ":" + batchSum);
System.out.println("Sum from 1 to " + i + ":" + totalSum);
batchSum = 0;
}
}
Edit:
The better Math way:
int lastTotalSum = 0;
for (int i = 1; i <= n / q; i++ ) {
int top = i * q;
int totalSum = top * (top + 1) / 2;
int batchSum = totalSum - lastTotalSum;
System.out.println("Sum from " + (top - q + 1) + " to " + top + ":" + batchSum);
System.out.println("Sum from 1 to " + top + ":" + totalSum);
lastTotalSum = totalSum;
}
I found a nice solution with java8 Streams:
int n=1000;
int q=50;
int length = n/q -1;
int[] previousSum={0};
IntStream.range(0, length).map(i -> (i+1)*q).forEach(s -> {
int sum=(s*(s+1))/2;
int batch = sum - previousSum[0];
previousSum[0] = sum;
System.out.println("Sum from " + (s - q + 1) + " to " + s + ":" + batch);
System.out.println("Sum from 1 to " + s + ":" + sum);
});
Do one loop iterating entire range and use indexes to decide whether to add, reset or print your sums.
Hope this gives your right idea, if you still dont know I can illustrate it a bit more.

How do i get my System.out.prints to line up under each other?

I want all the responses to line up under each other
example:
x=y
y=x
ect...
not
x=y y=x ect...
// Julian Vizcarra
// Lab 05 question 2
public class Lab05_02 {
public static void main(String[] args) {
java.util.Scanner input = new java.util.Scanner(System.in);
// Enter an integer
System.out.print("Enter an integer: ");
int number = input.nextInt();
//compute math
int ok = number/5;
int ok2= number/6;
//If statement
if (number % 5 == 0 && number % 6 == 0){
System.out.print("Is " + number + " divisible by 5 and 6?" + " True " );}
else {System.out.print("Is " + number + " divisible by 5 and 6?" + " False " ); }
if (number % 5 == 0 || number % 6 == 0) {
System.out.print("Is " + number + " divisible by 5 or 6?" + " True " );}
else {System.out.print("Is " + number + " divisible by 5 or 6?" + " False " );}
if (number % 5 == 0 ^ number % 6 == 0) {
System.out.print("Is " + number + " divisible by 5 or 6, but not both" + " True");}
else {System.out.print("Is " + number + " divisible by 5 or 6, but not both" + " False");}
}
}
my output is:
Enter an integer: 60
Is 60 divisible by 5 and 6? True Is 60 divisible by 5 or 6? True Is 60 divisible by 5 or 6, but not both False
Use System.out.println() instead of System.out.print().
System.out.println() or System.out.println("\n") do what you want

Java Recursion method

The below method return 5 if you give n = 20.
My question is how is 1 incremented on each iteration?
mystery(10) + 1
= mystery(5) + 2
= mystery(2) + 3
= mystery(1) + 4
= mystery(0) + 5 = 5.
I am having some hard time with recursion.
public static int mystery(int n){
if(n <= 0){
return 0;
}else{
return mystery(n / 2 ) + 1;
}
}
mystery(20) = mystery(10) + 1
mystery(20) = (mystery(5) + 1) + 1
mystery(20) = ((mystery(2) + 1) + 1) + 1
mystery(20) = (((mystery(1) + 1) + 1) + 1) + 1
mystery(20) = ((((mystery(0) + 1) + 1) + 1) + 1) + 1
and we know that mystery(0) = 0.
mystery(20) = ((((0 + 1) + 1) + 1) + 1) + 1
mystery(20) = (((1 + 1) + 1) + 1) + 1
mystery(20) = ((2 + 1) + 1) + 1
mystery(20) = (3 + 1) + 1
mystery(20) = 4 + 1
mystery(20) = 5
Or, simply put, we get 1+1+1+1+1=5
Pretty good video on recursion here: https://www.youtube.com/watch?v=Mv9NEXX1VHc
Looking at the code should make it obvious that:
mystery(20) = mystery(10) + 1
mystery(10) = mystery(5) + 1
mystery(5) = mystery(2) + 1
mystery(2) = mystery(1) + 1
mystery(1) = mystery(0) + 1
mystery(0) = 0
Now go back and plug in all the values, e.g.
mystery(1) = mystery(0) + 1 = 0 + 1 = 1
mystery(2) = mystery(1) + 1 = 1 + 1 = 2
mystery(5) = mystery(2) + 1 = 2 + 1 = 3, etc.
Every time mystery() is called, it returns the value returned by calling itself, plus 1. So, for every call, the returned number gets incremented by 1.

Categories

Resources