Related
I am trying to find the sum of parts of a given array with a length that is the sum of the first N positive integers for some whole number N. The size of each part for which I am to find the sum are the numbers in said arithmetic sequence. For instance, for an array of length 10, I need to find the sum of the first number, the next two numbers, and so on, until the next N numbers.
Example Input:
[1,4,5,2,6,7,9,8,7,10]
Example Output:
[1,9,15,34]//1, 4+5, 2+6+7, 9+8+7+10
Explanation:
The first sum is 1, the first element (index 0). The sum of the next two numbers is 4 + 5 = 9 (index 1 and 2). The sum of the next three numbers is 2 + 6 + 7 = 15 (index 3, 4, and 5). The sum of the last four numbers is 9 + 8 + 7 + 10 = 34 (index 6, 7, 8, 9).
You can compute the size of the result array using the formula for the sum of an arithmetic sequence, i.e. n(n + 1) / 2.
A prefix sum array can be applied here so so that any range sum can be computed in O(1) time with O(n) precomputation time and space (which is also the overall complexity of this algorithm).
final int[] input = { 1, 4, 5, 2, 6, 7, 9, 8, 7, 10 };
// size * (size + 1) / 2 = input.length
final int size = (-1 + (int) Math.sqrt(1 + 8 * input.length)) / 2;
// derived by quadratic formula
final int[] result = new int[size];
final int[] sum = new int[input.length + 1];
for (int i = 1; i <= input.length; i++) {
sum[i] = sum[i - 1] + input[i - 1];
}
for (int i = 1, j = 0; i <= input.length; i += ++j) {
result[j] = sum[i + j] - sum[i - 1];
}
System.out.println(Arrays.toString(result));
Ideone Demo
The following algorithm is very efficient and does not rely on the summation formula to work (as you had asked about) other than to compute the length of the result array. This should not be a problem since it is basic algebra. If you use a List implementation you would not have to do that.
It also only sums only to the max allowed by the given array. So if you provide an array like
1 2 3 4 5 6 7 8 9 10 11 12 13
It will silently ignore 11 12 and 13 since they don't comprise enough values to continue.
Here is the algorithm with your original data set and the output.
int[] arr = { 1, 4, 5, 2, 6, 7, 9, 8, 7, 10 };
int start = 0; // start of group
int end = 0; // end of group
int[] sol = new int[(int)(-.5 + Math.sqrt(2*arr.length + .25))];
for (int i = 1; i <= sol.length; i++) {
// initialize the sum
int sum = 0;
// compute next end
end += i;
// and sum from start to end
for (int k = start; k < end; k++) {
sum += arr[k];
}
// old end becomes next start
start = end;
sol[i-1] = sum;
}
Prints
[1, 9, 15, 34]
I wanna create a program that generates sets of consecutive numbers that add up to form a number. For example. if the input number is 15, it should give -
7, 8
4, 5, 6
1, 2, 3, 4, 5
Some formula/algorithm/loop that can do something that fits in. It could generate an array or print it. This may seem a math problem or silly question but I can't actually figure out how to do that programmatically in Java.
Please try to give exact code that can do the thing.
Say your input is N. You know each set of k consecutive numbers will be centered around N/k. A solution exists for even k if N/k ends with 0.5, and odd k if N/k is an integer. The solution, if one exists, is the k integers centered around N/k.
k=1: 15/1 = 15, so 15 (trivial; may want to omit)
k=2: 15/2 = 7.5, so 7,8
k=3: 15/3 = 5, so 4,5,6
k=4: 15/4 = 3.75, so no solution
k=5: 15/5 = 3, so 1,2,3,4,5
k=6: 15/6 = 2.5, so 0,1,2,3,4,5
etc...
k=15: 15/15 = 1, so -6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8
You can easily modify this to limit to positive or nonnegative solutions.
I'll expand on #MBo's answer as it conveys a very clean algorithm. Wiki provides a good intro on arithmetic progressions, copied below for your convenience.
Sum
Derivation
The sum of a sequence starting with number a and consisting of n consecutive numbers:
S = (n/2) * [2 * a + (n-1) * d]
For consecutive numbers the step d is 1.
S = (n/2) * [2 * a + (n-1)]
Here we can transition to #MBo's post.
P = 2 * S = n * [2 * a + (n-1)]
We can iterate all possible counts of consecutive numbers n and check if the resulting a is valid (i.e. a is an integer).
Let's factor out a.
Say P = n * q => q = 2 * a + (n-1) => 2 * a = q - n + 1 => a = (q - n + 1) / 2
Filters
1) we mentioned we could iterate all possible counts of consecutive numbers n, but given p = n * q it's safe to say n needs to be a divisor of p.
p % n == 0
nMax = (int)Math.sqrt(p)
2) a is an integer and a = (q - n + 1) / 2 => (q - n + 1) is even => q - n is odd.
((q - n) & 1) == 1
Implementation
import java.util.*;
import java.lang.Math;
import java.util.stream.IntStream;
import static java.util.stream.Collectors.toList;
public class Progressions
{
public static void main(String[] args)
{
List<List<Integer>> list = Calculate(15);
System.out.print(list);
}
public static List<List<Integer>> Calculate(int s)
{
List<List<Integer>> list = new ArrayList<>();
int p = 2*s;
int nMax = (int)Math.sqrt(p);
for (int n=2; n<=nMax; n++) {
if(p % n == 0) {
int q = p / n;
if(((q - n) & 1) == 1) {
int a = (q - n + 1) / 2;
list.add(range(a,n));
}
}
}
return list;
}
public static List<Integer> range(int a, int n) {
return IntStream.range(a, a+n)
.boxed()
.collect(toList());
}
}
Consecutive numbers form arithmetic progression. If it starts from number a and has n members, it's sum is
S = n * (2 * b + (n-1)) / 2
so
P = 2 * S = n * (2 * b + (n-1))
So for given input S we can factorize 2*S into all possible pairs of integer factors P = n * q where n<=q, then get starting number
a = (q - n + 1) / 2
If a is integer (oddity of q and n differs) then pair (a, n) represents valid sequence starting from a with n members
Example for S = 15, 2S = 30:
30 = 2 * 15 => n = 2, a = 7 => (7,8)
30 = 3 * 10 => n = 3, a = 4 => (4,5,6)
30 = 5 * 6 => n = 5, a = 1 => (1,2,3,4,5)
Simple Python example:
import math
def getseqs(s):
print(s)
p = 2 * s
for n in range(2, math.ceil(math.sqrt(p))):
if (p % n == 0):
q = p // n
if (((q - n) & 1) == 1): #compare parity
a = (q - n + 1) // 2
seq = list(range(a, a+n))
print(seq, sum(seq))
getseqs(17)
getseqs(15)
getseqs(72)
17
[8, 9] 17
15
[7, 8] 15
[4, 5, 6] 15
[1, 2, 3, 4, 5] 15
72
[23, 24, 25] 72
[4, 5, 6, 7, 8, 9, 10, 11, 12] 72
Consider the int input is your input number (ex. 15) and List<int[]> list as a storage of the result consecutive numbers, here you go:
List<int[]> list = new ArrayList<>();
int lower = 1; // Start searching from 1
int upper = (int) Math.floor(input + 1 / 2); // Up to the half of input (8+9 > 15)
while (lower < upper) { // Iterate between the bounds
int sum = 0;
for (int i = lower; i <= upper; i++) { // Iterate and sum the numbers
sum += i;
if (sum == input) { // If it matches the input
// Add the range to the List
// You have to loop them by one and add to the
// List before version Java-8
list.add(IntStream
.range(lower, i + 1)
.toArray());
break; // Found, no reason to continue
}
if (sum > input) { // Terminate the loop if the sum overlaps
break;
}
lower++; // Increment and try the sums from
// a higher starting number
sum = 0; // Reset the sum
}
The result for the input 15 is a List of these arrays:
[1, 2, 3, 4, 5]
[4, 5, 6]
[7, 8]
Here's a suggestion:
For an input number N:
you only have to consider numbers between 1 and N.
you can maintain an interval that represents the current subset of [1,...,N]. Maintain the sum of the current interval. The first interval will be [1,1], and its sum is 1.
As long as the sum < N, increase the right end of the interval by one (for example, you start with the interval [1,1]. Since 1 < N, you extend it to [1,2].
If the sum of the current interval is equal to N, you add that interval to the output, remove the left end of the interval (also removing it from the current sum), and continue.
If the sum exceeds N, you also remove the left end of the interval (also removing it from the current sum), and continue.
You finish when the interval becomes [N,N] (which is the final interval you should add to the output).
For the input 15, here's how the interval will change over time:
Interval Sum
[1] 1
[1,2] 3
[1,2,3] 6
[1,2,3,4] 10
[1,2,3,4,5] 15 -> output [1,2,3,4,5]
[2,3,4,5] 14
[2,3,4,5,6] 20
[3,4,5,6] 18
[4,5,6] 15 -> output [4,5,6]
[5,6] 11
[5,6,7] 18
[6,7] 13
[6,7,8] 21
[7,8] 15 -> output [7,8]
[8] 8
[8,9] 17
[9] 9
[9,10] 19
[10]
...
[15] 15 -> output 15
You can probably make some optimization once the sum of two consecutive numbers becomes higher than the target sum, at which point you can terminate the loop, and just add the final set (which contains just the target sum).
It used a Window Sliding Technique/Algorithm. You can also google sliding window algorithm sum.
I am writing Implementation of the #Dave solution.
Try to Solve before asking... That's how we learn. (only if we can't get then ask)
Scanner s = new Scanner(System.in);
int inputNumber = s.nextInt();
int k = 1;
while(inputNumber/k >= .5){
Float sequenceMid = (float) inputNumber/k;
if( k%2 == 0 && (sequenceMid *2 == Math.ceil(sequenceMid *2)) ){
for(int i = ((int)Math.floor(sequenceMid) - (k/2)),count=0 ; count < k ; count++,i++ ){
System.out.print(i + " ");
}
System.out.println();
}else if( (k%2 == 1) && (sequenceMid == Math.ceil(sequenceMid))){
for(int i = (Math.round(sequenceMid) - ((k-1)/2)),count=0 ; count < k ; count++,i++ ){
System.out.print(i + " ");
}
System.out.println();
}
k++;
}
Here is an idea that is similar to Eran's solution.
Since we're dealing with consecutive numbers, a cummulative sum (cumsum) can usually help. The basic idea is that we want to find the difference between two cummulative sums that gives exactly K, where K is 15 in your example.
number: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
cumsum: 0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55
differences:
15 - 0 = 15 -> [1, 2, 3, 4]
21 - 6 = 15 -> [4, 5, 6]
36 - 21 = 15 -> [7, 8]
The cummulative sum starts from 0 so we can do 15 - 0 subtraction. The number included as the solution will be left-exclusive and right-inclusive. That just means add 1 to the left index (index starts from 0). Hopefully the pattern is quite clear.
The next task is to create an algorithm that does some sliding window with varying width across the cummulative sum. The idea is to search for the difference with the exact value of K. We can start at the beginning where the left and right side of the window points to 0. While the difference is <= K, we want to increase the right side of the window, enlarging the window and the difference.
number: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
cumsum: 0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55
1st: (] -> 0 - 0 = 0
2nd: (---] -> 3 - 0 = 3
3rd: (------] -> 6 - 0 = 0
Once the algorithm hit 15, it will print out the first answer, and then it will increase it one more time. However, once we have the difference > K, we want to increase the left number, reducing the difference.
number: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
cumsum: 0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55
1st: (-----------------] -> 15 - 0 = 15 <print>
2nd: (---------------------] -> 21 - 0 = 21
3rd: (-----------------] -> 21 - 1 = 20
Notice that the left side is bounded to be < K/2 since K//2 + (K//2 + 1) >= K (where the equality is possible due to integer division denoted by //). So we can stop the loop early when the left side reaches K//2 (due to left-exclusive).
public static int cumsum(int index) {
return index * (index + 1) / 2;
}
public static String printRange(int left, int right) {
StringBuilder buffer = new StringBuilder();
buffer.append('[');
for (int i=left+1;i<=right;i++) {
buffer.append(i);
buffer.append(',');
}
buffer.deleteCharAt(buffer.length()-1);
buffer.append(']');
return buffer.toString();
}
public static void main(String[] args) {
int K = 15;
int K_ov_2 = K/2;
int left_index = 0;
int right_index = 0;
int diff;
while (left_index < K_ov_2) {
diff = cumsum(right_index) - cumsum(left_index);
System.out.println("diff = " + diff + ", left = " + left_index + ", right = " + right_index);
if (diff == K) {
System.out.println(printRange(left_index,right_index));
}
if (diff <= K) {
right_index++;
} else {
left_index++;
}
}
}
I added the debug line so the output can become more obvious.
diff = 0, left = 0, right = 0
diff = 1, left = 0, right = 1
diff = 3, left = 0, right = 2
diff = 6, left = 0, right = 3
diff = 10, left = 0, right = 4
diff = 15, left = 0, right = 5
[1,2,3,4,5]
diff = 21, left = 0, right = 6
diff = 20, left = 1, right = 6
diff = 18, left = 2, right = 6
diff = 15, left = 3, right = 6
[4,5,6]
diff = 22, left = 3, right = 7
diff = 18, left = 4, right = 7
diff = 13, left = 5, right = 7
diff = 21, left = 5, right = 8
diff = 15, left = 6, right = 8
[7,8]
diff = 24, left = 6, right = 9
Given two numbers, s (sum)
and n (posit number, ii), there are several ways in which I can express and,
as a sum of n whole numbers, strictly positive.
for s = 7, n = 3; 7 = 4 + 2 + 1 and
7 = 1 + 4 + 2 are not considered distinct.
I have to calculate i th solution.
Example for input:
11
6
5
example for output:
11=3+2+2+2+1+1 (5th mode to compose the sum)
I tried to use backtraking to compose these sums but the algorithm does not produce all the solutions.
static boolean checkSum(int sum, int remPos, int elem) {
if (sum < remPos)
return false;
if (sum > remPos * elem)
return false;
return true;
}
private ArrayList<Integer> back(ArrayList<Integer> sol, int crtPos,
int sum, ArrayList<Integer> ans) {
//the solution was found
if (index == i) {
ans.addAll(sol);
return sol;
} else if (index > i) {
return null;
}
if (crtPos == k + 1) {
crtPos = 1;
index++;
}
for (int j = sol.get(crtPos - 1); j > 0; j--) {
//add to solution
sol.add(crtPos, j);
//decreases from the remaining sum
sum -= j;
//check
if (checkSum(sum, k - crtPos, j)) {
sol = back(sol, crtPos + 1, sum, ans);
}
//remove from solution
sol.remove(crtPos);
sum += j;
}
return sol;
}
Don't know what is wrong with your code, but let me give you an alternate algorithm that doesn't use recursion, and doesn't require boxing the values.
First, you said that order of values doesn't matter, e.g. 7 = 4 + 2 + 1 and 7 = 1 + 4 + 2 is the same solution. In the algorithm below, we ensure that by stating that values must be in ascending order, e.g. 7 = 1 + 2 + 4.
Let me illustrate algorithm using example of s=10, n=5, which for reference gives the following solutions:
10 = 1 + 1 + 1 + 1 + 6
10 = 1 + 1 + 1 + 2 + 5
10 = 1 + 1 + 1 + 3 + 4
10 = 1 + 1 + 2 + 2 + 4
10 = 1 + 1 + 2 + 3 + 3
10 = 1 + 2 + 2 + 2 + 3
10 = 2 + 2 + 2 + 2 + 2
First, build an int[] and fill it with 1's, except the last value is s - (n-1), aka s - n + 1 (where n-1 is the sum of the 1's):
[1, 1, 1, 1, 6]
That is your first solution.
Now we "increment" that to the next solution, where the last value is always calculated, i.e. the next solution is:
[1, 1, 1, 2, x] where x = s - (1+1+1+2) = 5
[1, 1, 1, 2, 5]
We continue that as long as last value >= second last value:
[1, 1, 1, 3, 4]
Next one would have been [1, 1, 1, 4, 3] but that violates our constraint, so be walk backwards to previous value, and increment that. Since values must be ascending, we will fill the following positions with the same value (represented as = below), except we calculate the last value (x):
[1, 1, 2, =, x] where x = s - (1+1+2+2) = 4
[1, 1, 2, 2, 4]
Next one is easy:
[1, 1, 2, 3, 3]
Now we can't increment the 3rd position from 2 to 3, because that would give us [1, 1, 3, 3, 2] so we walk back one more position:
[1, 2, =, =, x] where x = s - (1+2+2+2) = 3
[1, 2, 2, 2, 3]
Now we have to walk back one more time:
[2, =, =, =, x] where x = s - (2+2+2+2) = 2
[2, 2, 2, 2, 2]
And we're done, because we can't walk any further back.
Here is code in compact form:
public static void compose(int s, int n) {
if (s < n || n < 1)
throw new IllegalArgumentException();
int[] values = new int[n];
Arrays.fill(values, 1);
values[n - 1] = s - n + 1;
for (;;) {
printSolution(s, values);
int i = n - 1, remain = values[i];
for (; --i >= 0; remain += values[i])
if (--remain >= ++values[i] * (n - i - 1))
break;
if (i < 0)
break;
Arrays.fill(values, i + 1, n, values[i]);
values[n - 1] = remain - values[i] * (n - i - 2);
}
}
public static void printSolution(int s, int[] values) {
System.out.print(s + " = " + values[0]);
for (int i = 1; i < values.length; i++)
System.out.print(" + " + values[i]);
System.out.println();
}
Output from compose(7, 3)
7 = 1 + 1 + 5
7 = 1 + 2 + 4
7 = 1 + 3 + 3
7 = 2 + 2 + 3
Output from compose(10, 5) is already shown earlier.
If you just need the i'th solution, remove the printSolution call, change the forever loop to loop i-1 times, and return the values array.
So this is a recent interview question, Given a positive integer n, break it into the sum of at least two positive integers and maximize the product of those integers. Return the maximum product you can get.
For example, given n = 2, return 1 (2 = 1 + 1); given n = 10, return
36 (10 = 3 + 3 + 4).
I'm trying to solve it recursively, The approach is
first split the number into two halves and find the max product and keep splitting each half till we get the maximum.
This is my code,
private int integerBreak(int n, int maxProduct){
int index = 0;
for(int i=0; i<n; i++){
if((i * (n-i)) >maxProduct) {
maxProduct = i*(n-i);
index = i;
}
}
return integerBreak(index, index) * integerBreak(n - index, n-index);
}
public int integerBreak(int n) {
int maxProduct = 0;
return integerBreak(n, maxProduct);
}
Now I'm a little lost with the base condition as to how to terminate recursion. I'd appreciate if someone can help me with my approach rather than coming up with the completely different solution.
I wrote a straightforward Java application to calculate the maximum product for the sum of integers of the numbers 2 through 20. The first number is the sum. The middle numbers are the factors of the sum. The final number is the product of the factors. Here are the results.
2 [1, 1] 1
3 [2, 1] 2
4 [2, 2] 4
5 [3, 2] 6
6 [3, 3] 9
7 [4, 3] 12
8 [3, 3, 2] 18
9 [3, 3, 3] 27
10 [4, 3, 3] 36
11 [3, 3, 3, 2] 54
12 [3, 3, 3, 3] 81
13 [4, 3, 3, 3] 108
14 [3, 3, 3, 3, 2] 162
15 [3, 3, 3, 3, 3] 243
16 [4, 3, 3, 3, 3] 324
17 [3, 3, 3, 3, 3, 2] 486
18 [3, 3, 3, 3, 3, 3] 729
19 [4, 3, 3, 3, 3, 3] 972
20 [3, 3, 3, 3, 3, 3, 2] 1458
The calculateMaximumFactors method calculates the factors with the maximum product. The factor method generates the factors of the sum. The product method calculates the product of the factors. Here's the code:
package com.ggl.testing;
import java.util.Arrays;
public class MaximumProduct {
public static void main(String[] args) {
for (int sum = 2; sum <= 20; sum++) {
System.out.print(sum + " ");
System.out.println(calculateMaximumFactors(sum));
}
}
private static String calculateMaximumFactors(int sum) {
int[] previousFactors = new int[0];
int maxProduct = 0;
for (int i = 2; i <= sum; i++) {
int[] factors = factor(sum, i);
int product = product(factors);
if (product > maxProduct) {
maxProduct = product;
previousFactors = Arrays.copyOf(factors, factors.length);
}
}
return Arrays.toString(previousFactors) + " " + maxProduct;
}
private static int[] factor(int sum, int divisor) {
if (sum < divisor) {
return new int[0];
}
int num = sum / divisor;
int remainder = sum % divisor;
int[] result = new int[divisor];
for (int i = 0; i < divisor; i++) {
result[i] = num;
if (remainder > 0) {
result[i]++;
remainder--;
}
}
return result;
}
private static int product(int[] factors) {
int product = 1;
for (int i = 0; i < factors.length; i++) {
product *= factors[i];
}
return product;
}
}
Here's my solution to the problem : (Idea : It is optimal to break integer into multiple of 3)
public int integerBreak(int n) {
// base case :
if (n == 2 || n == 3){
return (n-1);
}
int maxProduct = 1;
while (n > 4){
n -= 3;
maxProduct *= 3; // Keep multiplying 3.
}
return (n * maxProduct); // multiply with left over n.
}
This is simple O(N) solution. Hope this helps someone !
The idea is to break the number into multiples of 2 or 3. If you write the breaking results for couple of numbers like 7 to 10 you should get the idea. Assuming the max number is 60, there is a simple dynamic solution:
int dp[60];
public:
int integerBreak(int n)
{
dp[1]=1,dp[2]=1,dp[3]=2,dp[4]=4,dp[5]=6,dp[6]=9;
for(int i=7;i<=n;i++)
dp[i]=max(dp[i-3]*3,dp[i-2]*2);
return dp[n];
}
};
As I wrote in the comment above, we have to break the number into 3s. If we derive the maxima, we get the e (base of the logarithm) to be 2 < e < 3. But the thing is 6= 33 and 6=22*2 so every triplet of 2 can be replaced with a tuple of 3 for the maximum product.
So here is the code I wrote. It is in Python so I hope you don't mind -
def maximize_product(num):
product = 1
if num == 2 or num == 3:
return num - 1
else:
while num > 4:
product = product * 3
num -= 3
return num * product
If you make a loop trying to find the number then is going to get complicated and not as efficient (the greater the number, the longest will take you to find it, you need to consider indexes, etc etc)
The best and fastest algorithm is the middle point algorithm, i.e divide the given number by 2, calculate deviation if number is odd, finally calculate the product
Example:
static int func(int number) {
int result = 0;
if (number < 0) {
System.err.println("no negative allowed");
System.exit(0);
}
int a = 0;
int b = 0;
a = number / 2;
b = number / 2;
a += number - (a + b);
result = a * b;
System.out.println(" this is a " + a);
System.out.println(" this is b " + b);
return result;
}
if you execute it like
public static void main(String[] args) {
int number = 9;
int result = func(number);
System.out.println(result);
}
will get the results correctly...
Note: This has been solved. I have posted the working code below in a later post.
First off, I know there is a similar question here: Pick four cards and compute their sum JAVA
However, the outcome of their script is different than what mine needs to be, they are just calculating 4 random cards. I need to find EVERY combination of 4 cards that exists.
I am currently in my first Java programming class. We have covered up to methods and arrays, but nothing about classes and objects yet. So please keep that in mind if you choose to answer.
My homework this week is to write a program that finds every possible combination of 4 cards in a deck of 52 that add up to 24. (with Ace being 1, Jack 11, Queen 12, and King 13) I have posted my code below which I know has some mistakes, it doesn't work right for how I want it to. I am posting here to see if I'm on the right track. My instructor says the correct answer is 12,517, and it's up to us to come up with that answer. Any hints would be greatly appreciated.
Specific Question as requested - "How can I change my below code that will produce the output of 12,517"
Things I know:
I know some numbers are missing in the iterations, the 4th stack resets back to 4 instead of going to 1. I haven't yet figured out how to correct this.
I know my deepest For loop will loop the same combination 4 times before continuing... I have NO idea why (or how) it's doing this.
NOTE!: I have output messages in the "calculate" method for debugging. If you want to use them, start then stop the script immediately, that will give you an idea. If you want the program to run till completion, then comment out the 3 output messages in the nested 4 loop.
public static void main(String[] args) {
int[] deck = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
int total;
total = calculate(deck);
output(total);
}
public static int calculate(int[] deck){
int total = 0;
int stack1, stack2, stack3, stack4, accumulate;
for (stack1 = 0; stack1 < 52; stack1++){
for (stack2 = 1; stack2 < 52; stack2++){
for (stack3 = 2; stack3 < 52; stack3++){
for (stack4 = 3; stack4 < 52; stack4++){
accumulate = (deck[stack1] + deck[stack2] + deck[stack3] + deck[stack4]);
System.out.println(deck[stack1] + " + " + deck[stack2] + " + " + deck[stack3] + " + " + deck[stack4]);
if (accumulate == 24){
System.out.println(deck[stack1] + " + " + deck[stack2] + " + " + deck[stack3] + " + " + deck[stack4]);
total++;
System.out.println("Accumulate is at " + accumulate);
System.out.println("Currently at " + total);
}
}
}
}
}
return total;
}
public static void output(int total){
System.out.println ("The total number of card combinations of 4 that \n"
+ "equal 24 is: " + total);
}
}
I would do it as such:
public static void main(String[] args) {
int counter = 0; //can also just say int counter; ==> auto intialize to 0
int d, c, h, s; //diamond, club, heart, spade
for(d = 1; d < 14; d++) //each suit starts at Ace, or the value of 1
for(c = 1; c < 14; c++) //each suit ends at 13, or King
for(h = 1; h < 14; h++)
for(s = 1; s < 14; s++)
if( d + c + h + s == 24 )
counter++;
System.out.println(counter); //Your total should be your instructor's 12,517
}
If I may clarify your question: You do NOT mean to ask for every single "combination" of cards (so printing out all 12,517 possibilities).
Rather, you mean to get the total number of combinations represented by counter.
What my four for loops are doing is very simple: it goes through all the possibilities using Ace as 1 and King as 13. If the sum of the four cards equals ( == ) 24, then add one to the counter.
This will work due to the nature of nested for loops, going through all four sets of 13C1 combinatorics.
I hope this helped!
NOTE: In case you weren't aware: in languages with brackets (Java, C), if you're using a conditional statement or a loop (if/else, while, for) with only one following statement, like in my code, you can omit the brackets.
Here is working code that produces the correct result. The key was to parent the child stack to the parent stack + 1:
public static void main(String[] args) {
int[] deck = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
int total;
total = calculate(deck);
output(total);
}
public static int calculate(int[] deck){
int total = 0;
int stack1, stack2, stack3, stack4, accumulate;
for (stack1 = 0; stack1 < 52; stack1++){
for (stack2 = (stack1 + 1); stack2 < 52; stack2++){
for (stack3 = (stack2 + 1); stack3 < 52; stack3++){
for (stack4 = (stack3 + 1); stack4 < 52; stack4++){
accumulate = (deck[stack1] + deck[stack2] + deck[stack3] + deck[stack4]);
if (accumulate == 24)
total++;
}
}
}
}
return total;
}
public static void output(int total){
System.out.println ("The total number of card combinations of 4 that \n"
+ "equal 24 is: " + total);
}
}