I'm completely new in Java. I am writing an Android game, and I need to generate an array of int arrays that contains all possible sums (excluding combinations that contains number 2 or is bigger than 8 numbers) that add up to a given number.
For example:
ganeratePatterns(5)
must return array
[patternNumber][summandNumber] = value
[0][0] = 5
[1][0] = 1
[1][1] = 1
[1][2] = 1
[1][3] = 1
[1][4] = 1
[2][0] = 3
[2][1] = 1
[2][2] = 1
[3][0] = 4
[3][1] = 1
I already try to do this like there Getting all possible sums that add up to a given number but it's very difficult to me to make it like this http://introcs.cs.princeton.edu/java/23recursion/Partition.java.html
Solution
int n = 10;
int dimension = 0;
//First we need to count number of posible combinations to create a 2dimensionarray
for(List<Integer> sumt : new SumIterator(n)) {
if(!sumt.contains(2) && sumt.size() < 9) {
dimension++;
}
}
int[][] combinationPattern = new int[dimension][];
int foo = 0;
for(List<Integer> sum : new SumIterator(n)) {
if(!sum.contains(2) && sum.size() < 9) {
System.out.println(sum);
combinationPattern[foo] = toIntArray(sum);
foo++;
}
}
It's work not 100% correctly, and very pretty, but it is enough for my game
I have used SumIterator class from here SumIterator.class
I have to changed this code for(int j = n-1; j > n/2; j--) {
to this for(int j = n-1; j >= n/2; j--) {
because old version doesn't return all combinations (like [5,5] for 10)
And I used toIntArray function. I have founded hare on StackOverflow, but forget a link so here it's source:
public static int[] toIntArray(final Collection<Integer> data){
int[] result;
// null result for null input
if(data == null){
result = null;
// empty array for empty collection
} else if(data.isEmpty()){
result = new int[0];
} else{
final Collection<Integer> effective;
// if data contains null make defensive copy
// and remove null values
if(data.contains(null)){
effective = new ArrayList<Integer>(data);
while(effective.remove(null)){}
// otherwise use original collection
}else{
effective = data;
}
result = new int[effective.size()];
int offset = 0;
// store values
for(final Integer i : effective){
result[offset++] = i.intValue();
}
}
return result;
}
This is not the most beautiful code, but it does what you would like, having modified the code you referenced. It is also quite fast. It could be made faster by staying away from recursion (using a stack), and completely avoiding String-to-integer conversion. I may come back and edit those changes in. Running on my pretty outdated laptop, it printed the partitions of
50
(all 204226 of them) in under 5 seconds.When
partition(N)
exits in this code,partitions
will hold the partitions ofN
.First, it builds an ArrayList of string representations of the sums in space-delimited format (example:
" 1 1 1"
).It then creates a two-dimensional array of ints which can hold all of the results.
Let me know if you have any questions!