# Find the product of digits at odd/even places

The 'score' of a race is given.

We have to calculate the 'bonus points' to be given to the participant.

The 'bonus points' are dependent on the relation between product of digits at even places and product of digits at odd places.

So essentially I have to find the product of digits at even and odd places.

I first counted the number of digits in 'score' and then went on storing the product of digits in odd/even places in separate integers reducing one digit at a time

Code in Java

import java.util.Scanner;

class BonusPoints {
public static int countDigits(int dist) {
int counter=0;
while (dist>0) {
dist /= 10;
counter++;
}
return counter;
}

public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int dist = sc.nextInt();
int bonus=0;
int prodOdd = 1;
int prodEven = 1;
int currDigit = 0;

if (dist < 0) {
System.out.printf("Invalid Input ");
System.exit(0);
}

int counter = countDigits(dist);
int lol = counter;
//System.out.println("Number of Digits are " + counter);

for (int i = 0; i < lol; i++) {

//System.out.println("Current Dist " + dist);

currDigit = dist % 10;
//System.out.println("Current Digit " + currDigit);

if (counter % 2 == 0){
prodEven *= currDigit;
//System.out.println("Current ProdEven "+prodEven);
}
else {
prodOdd *= currDigit;
//System.out.println("Current ProdOdd " +prodEven);
}

dist /= 10;
counter--;
}

if (prodOdd == prodEven)
bonus = 2 * prodOdd;
else
bonus = prodOdd > prodEven ? prodOdd : prodEven;

System.out.println("The bonus is "+bonus);
}
}


Those comments were used for debugging process while writing the code

Is there a better method to do this and what are changes that one can make to this code to optimize it?

• The 'bonus points' are dependent on the relation between product of digits at even places and product of digits at odd places. — please be more specific, so that we can evaluate your code properly? – 200_success Aug 10 '19 at 5:10
• @200_success That is not important. Whichever product is greater is used as bonus. If both products are same them twice of the product is bonus. – KshitijV97 Aug 10 '19 at 9:11

### Program structure

Separate I/O from the calculation and keep the main function short:

public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int dist = sc.nextInt();
if (dist < 0) {

}

int bonus = calculateBonus(dist);
System.out.println("The bonus is " + bonus);
}


That makes the program structure clearer, makes the functions reusable, and allows to add test cases easily.

### Handle invalid input

By convention, error messages are written to the standard error output, and a nonzero exit code indicates an abnormal program termination. Instead of "Invalid Input" I suggest to print a message indicating the correct usage:

if (dist < 0) {
System.err.printf("Input must be a non-negative integer.");
System.exit(1);
}


### Miscellaneous

Inconsistent white space here:

int bonus=0;
int prodOdd = 1;


It can be difficult to choose a good variable name, but I am sure that you'll find something better here:

int lol = counter;


Declare variables at the nearest scope where they are used. As an example, currDigit is only used inside the for-loop:

for (int i = 0; i < lol; i++) {
int currDigit = dist % 10;
// ...
}


### Simplifiying the program

The calculation of

    if (prodOdd == prodEven)
bonus = 2 * prodOdd;
else
bonus = prodOdd > prodEven ? prodOdd : prodEven;


does not change if we exchange the even and the odd product. Therefore it does not matter if we count even and odd position from the most significant (decimal) digit or from the least significant digit.

As a consequence, we can process the digits starting with the least significant one, and it is not necessary to calculate the number of digits beforehand.

Instead of the counter, a boolean variable is sufficient to keep track of even and odd positions.

So the countDigits() function is obsolete, and calculateBonus() could be implemented like this:

public static int calculateBonus(int dist) {
int prodOdd = 1;
int prodEven = 1;
boolean evenPosition = true;

while (dist > 0) {
int currDigit = dist % 10;
if (evenPosition) {
prodEven *= currDigit;
} else {
prodOdd *= currDigit;
}

dist /= 10;
evenPosition = !evenPosition;
}

return prodOdd == prodEven ?
2 * prodOdd :
prodOdd > prodEven ? prodOdd : prodEven;
}

• Regarding 'Declare variables at the nearest scope where they are used. As an example, currDigit is only used inside the for-loop', Wont that lead to recreation of the variable for every iteration of the for loop and wont that affect the time comlexity adversely? – KshitijV97 Aug 10 '19 at 18:18
• @KshitijV97: You can dump the byte code with javap -c BonusPoints to verify that it makes no difference in the compiled program. – Martin R Aug 10 '19 at 18:30
• @MartinR - The efficiency could be improved by simply calculating 2 digits for each iteration of the loop. The first is even and the second odd. – tinstaafl Aug 12 '19 at 12:56
• @tinstaafl: Yes, that would make the boolean variable obsolete. On the other hand, you have to check if the value still has a digit at the second (odd) position, to avoid multiplication with zero. – It probably does not make a big difference for the 32 bits of a Java integer. – Martin R Aug 12 '19 at 13:17
• Since this is most likely for a programming challenge and their test cases tend to be extreme, minor optimizations would increase the overall score by quite a bit. – tinstaafl Aug 12 '19 at 16:20