Reputation: 379
I would like to write a program in Java which, given an array, finds the sum of all the numbers in the array - with an exception! Since the number 13 is very unlucky, I propose that we shall completely exclude the number 13, and the number directly after 13, if it exists, from the total sum.
The program, which I shall call sum13
, should produce the following results from the following inputs (these are just a few examples):
sum13([1,2,2,1]) = 6
This one is normal; no 13's here.
sum13([5, 13, 2]) = 5
The 13 and the number directly after the 13 are excluded.
sum13([13, 13]) = 0
The array contains only 13's, so neither of them are included.
sum13([1, 2, 13, 2, 1, 13]) = 4
A slightly longer example of the expected output.
Here is the code which I came up with for sum13
:
public int sum13(int[] nums) {
int sum = 0;
for (int i = 0; i < nums.length; i++) {
// we start by adding all the non-13s to the sum
if (nums[i] != 13) sum += nums[i];
}
// now we go back and remove all the non-13s directly after a 13
for (int j = 0; j < nums.length; j++) {
// the outermost loop checks if the numbers are a 13
if (nums[j] == 13 && j < nums.length - 1) {
for (int k = j + 1; k < nums.length; k++) {
// this loop checks that the number after the 13 is not a 13
if (nums[k] != 13) {
sum -= nums[k];
break;
}
}
}
}
return sum;
}
The program above works, although it does look quite messy!
Is there a better way of writing such a program that doesn't include multiple loops and nested if
s?
Upvotes: 6
Views: 1271
Reputation: 1075029
Kepotx shows how to do it with a traditional for
loop. You can also do it with a flag in an enhanced for
loop:
public int sum13(int[] nums) {
int sum = 0;
boolean skipNext = false;
for (int num : nums) {
if (num == 13) {
skipNext = true;
} else {
if (!skipNext) {
sum += num;
}
skipNext = false;
}
}
return sum;
}
Live Example with the provided inputs and expected outputs.
Hopefully someone savvy with streams shows us the clever streams approach... :-) ...and Malte Hartwig did (although as he says, there's a not-best-practice in there).
Upvotes: 5
Reputation: 4555
Using an AtomicBoolean
can shorten to loop considerably, and it gets even shorter when you use IntStream
to sum:
public static int sum13(int[] numbers)
{
AtomicBoolean was13 = new AtomicBoolean(false);
return IntStream.of(numbers)
.filter(i -> !was13.getAndSet(i == 13) && i != 13)
.sum();
}
The big advantage is that AtomicBoolean.getAndSet(boolean)
allows us to check whether the previous number was 13 and store whether the current number is 13 the same time.
Warning: As Hulk pointed out in the comment, is not the best practice to change the state of objects "outside" the stream. This can come back to haunt you if you try to use the stream in parallel, for example. It is possible to avoid using outside state here using a custom Collector
, but this would make the code way too complicated for this particular problem.
Upvotes: 3
Reputation: 43
Why not using ArrayList class? It has iterator() method implemented and the code could look like this:
int sum13 (ArrayList<Integer> a) {
Iterator<Integer> iter = a.iterator();
int n;
int sum=0;
while (iter.hasNext() ) {
n = iter.next();
if (n !=13)
sum = sum + n; /* n!=13 it will be added*/
else if (iter.hasNext() )
iter.next() /* n==13 not summing and skipping next */
}
return sum;
}
Upvotes: 0
Reputation: 2266
As soon as number 13 arrives you need to skip the 13 and next char in the loop
public class HelloWorld{
public static void main(String []args){
int arr[] = {1, 2, 4, 2, 1, 13,10};
System.out.println(sum13(arr));
}
public static int sum13(int[] nums) {
int sum = 0;
int n = nums.length;
for (int i = 0; i < n; i++) {
if (nums[i] == 13){
i=i+2;
}
if(i<n){
sum += nums[i];
}
}
return sum;
}
}
Upvotes: 0
Reputation: 1082
Well, you use i as iterator. just make i++
when the current number is 13. This way, not only you don't add 13 to the sum but you also skip the next value.
public int sum13(int[] nums) {
int sum = 0;
for (int i = 0; i < nums.length; i++) {
// we start by adding all the non-13s to the sum
if (nums[i] != 13){
sum += nums[i];
}
else {
i++;
}
}
return sum;
}
Upvotes: 9