Reputation: 83
I'm writing a recursive program:
public static List<Integer> method(int n)
to determine whether a positive number n
is the total of cubes that are positive (> 0). Example: given n = 1944
(12^3 + 6^3), the program would return the list [12, 6]
in descending order. If n
is not the total of cubes the program should return an empty list.
The program should return the values that start with the highest possible value for the first element, and then follow the same rule for the rest of the elements. For example, when n = 1072
, the program would return [10, 4, 2]
instead of [9, 7]
.
The method where the recursion should occur:
private static boolean method(int n, int c, LinkedList<Integer> seen)
where c
is the highest number that is still allowed to be used and soFar
is the list of numbers that have already been seen.
My code covers the base cases and the recursion, but I'm having issues with the loop continuing. With the input, n = 1944
my program is returning the list [12]
instead of [12, 6]
.
public static List<Integer> method(int n)
{
LinkedList<Integer> result = new LinkedList<Integer>();
int c = (int) Math.cbrt(n);
result.add(c);
method(n, c, result);
return result;
}
private static boolean method(int n, int c, LinkedList<Integer> seen)
{
LinkedList<Integer> result = new LinkedList<Integer>();
boolean b = false;
if (n == 0)
{
return true;
}
else if (c == 0)
{
return false;
}
else
{
int sum = 0;
for (int i : seen)
{
sum += i*i*i;
}
while (b = false)
{
c = (int) Math.cbrt(n - sum);
seen.add(c);
method(n, c, seen);
if (sum == n)
{
result = seen;
return true;
}
else
{
return false;
}
}
}
return false;
}
Upvotes: 1
Views: 792
Reputation: 14593
Let's see your while loop:
LinkedList<Integer> result = new LinkedList<Integer>();
boolean b = false;
// Some code omitted here.
while (b = false)
{
c = (int) Math.cbrt(n - sum);
seen.add(c);
method(n, c, seen);
if (sum == n)
{
result = seen;
return true;
}
else
{
return false;
}
}
First, with a while
loop that always has false
as the condition for looping, it doesn't do anything at all.
Anyway, even if we pretend the loop runs, whatever is the branch took by the if
, a return
will be reached. So, your while
loop doesn't loop at all even if its condition was changed to always be true
. Further, the only value ever assigned for the b
variable is false
, and it isn't used for anything at all.
Also, the result
list in the second method is always empty. And, since the result = seen;
instruction is just right before the return
, it is an innocuous instruction which renders the result
simply being useless.
Also, look at the method(n, c, seen);
call. It don't do anything with its return value! So, even if it eventually returns true
, you still proceeds, which would then generate false
as a result.
Also, whenever you add a value to seen
, it will never be removed. Since the seen
is always the very same list in every of the recursive method calls, once a bad number is added there, it will never be removed to make the way for something else.
With this, I must conclude that your algorithm is so broken that it must be rewritten from scratch.
Also, although your question isn't very clear, I presume that the numbers found must all be different. Otherwise, one could make 2 = 13 + 13
and every number larger than one could be represented by the sum of a lot of cubed ones (i.e. n = 13 + 13 + 13 + ...
).
The algorithm is this:
for
counting i
down from cbrt(n)
to 1 trying to form cubes.n
and recursively try to find a cube sum for the resulting number.for
produced a bad number and we should try the next one (if we have a next one).for
ends without a cube forming, return an empty list.Here is the code:
import java.util.LinkedList;
import java.util.List;
public class Main {
public static List<Integer> findCubeSum(int n) {
return findCubeSum(n, n);
}
public static List<Integer> findCubeSum(int n, int max) {
if (n <= 0) return List.of();
int c = (int) Math.cbrt(n);
for (int i = Math.min(c, max); i > 0; i--) {
int x = i * i * i;
if (x == n) {
List<Integer> result = new LinkedList<>();
result.add(i);
return result;
}
List<Integer> result = findCubeSum(n - x, i - 1);
if (result.isEmpty()) continue;
result.add(0, i);
return result;
}
return List.of();
}
public static void main(String[] args) {
System.out.println(findCubeSum(8)); // [2]
System.out.println(findCubeSum(64)); // [4]
System.out.println(findCubeSum(1000)); // [10]
System.out.println(findCubeSum(1072)); // [10, 4, 2]
System.out.println(findCubeSum(1944)); // [12, 6]
System.out.println(findCubeSum(4)); // []
System.out.println(findCubeSum(0)); // []
System.out.println(findCubeSum(-1)); // []
System.out.println(findCubeSum(10)); // []
}
}
See it running at ideone.
Upvotes: 1
Reputation: 18792
The code as posted has many issues. However your question is about public static List<Integer> method(int n)
:
public static List<Integer> method(int n) {
LinkedList<Integer> seen = new LinkedList<>();
method(n, 0, seen);
return seen;
}
Consider changing
private static boolean method(int n, int c, LinkedList<Integer> seen)
To
private static boolean method(int n, LinkedList<Integer> seen)
because you recalculate the value of c
by c = (int) Math.cbrt(n);
Upvotes: 0