3
\$\begingroup\$

I have solved this exercise, but it looks really redundant. Is there a built-in function in Java or a cleaner way to caluclate mod of a value + deviation without multiple OR statements? If I had to calculate this for a deviation of 5, this would then require a lot of repetition.

Given a non-negative number "num", return true if num is within 2 of a multiple of 10. Note: (a % b) is the remainder of dividing a by b, so (7 % 5) is 2.


    public boolean nearTen(int num) {
        return isMod10(num) || isMod10(num - 1) || isMod10(num + 1) || isMod10(num - 2) || isMod10(num + 2);
    }

    private boolean isMod10(int num) {
        return num % 10 == 0;
    }

\$\endgroup\$
5
\$\begingroup\$

You should read about congruent integers and modular arithmic. The distance of a number to a base is the minimum distance of its congruent value and its inverted congruent value.

 public boolean nearBase(int num, int base, int deviation) {

        // ..TODO check guards, normalize input or throw exceptions 
        // - base and deviation are expected strict positive integers
        // - deviation is expected smaller than base
        // - num is expected a positive integer

        var congruent = num % base;
        var inverted = base - congruent;
        var distance = Math.min(congruent, inverted);
        return distance <= deviation;
    }

 // your method rewritten ->
 public boolean nearTen(int num) {
        return nearBase(num, 10, 2);
    }
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Okay, thanks! I had this topic in introductory algebra but did not think about it at all. \$\endgroup\$ – whatamidoingwithmylife Jun 1 '19 at 15:54
3
\$\begingroup\$

Let's consider the results of numbers around 10 as an example :

7 % 10 = 7
8 % 10 = 8
9 % 10 = 9
10 % 10 = 0
11 % 10 = 1
12 % 10 = 2
13 % 10 = 3

We know that 8 to 12 should be included.

For 10 to 12 it's easy, we just need to check if their modulo is smaller than 2.

public boolean nearTen(int num) {
    int modulo = num % 10;
    return modulo <= 2;
}

For 8 and 9, if we look at the above results, we can see that the difference between their modulo and the original number will give us a number under 2. So we'll add that to the algorithm:

public boolean nearTen(int num) {
    int modulo = num % 10;
    return modulo <= 2 || num - modulo <= 2;
}

With that, we covered all cases. When facing a problem like this one, don't be afraid to write down the results and try to find a match.

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Instead of your individual checks of the deviations in the range -2 .. 2, you could check the range as such. With a lower bound check and an upper bound check. Although -2 .. 2 doesn't play well because % 10 splits it into 8 .. 9 and 0 .. 2. Shifting by 2 gives you the simpler range 0 .. 4, which % 10 leaves intact, and where we get the lower bound for free and only have to check the upper bound:

    public boolean nearTen(int num) {
        return (num + 2) % 10 <= 4;
    }

Btw, about yours you say "If I had to calculate this for a deviation of 5, this would then require a lot of repetition", which isn't true. Every integer is within 5 of a multiple of 10, so you wouldn't need any checks for that. Anyway, for a generalization, you could do this:

    public boolean nearTen(int num, maxDeviation) {
        return (num + maxDeviation) % 10 <= 2 * maxDeviation;
    }
| improve this answer | |
\$\endgroup\$
-1
\$\begingroup\$

Thanks to @RoastedPotatoe's answer above; I now understand that we want to consider only those numbers which are in the range \$((10-2)\%10)\$ to \$((10+2)\%10)\$. For example \$(8\%10)\$ to \$(12\%10)\$.

This means our use cases to be passed are:

  • \$(8\%10=8)\$,
  • \$(9\%10=9)\$,
  • \$(10\%10=0)\$,
  • \$(11\%10=1)\$, and
  • \$(12\%10=2)\$.

From here I know I can just say:

  • if the remainder comes out to be 8 or 9 return true. Otherwise,
  • if the remainder to be between 0 and 2 return true. Otherwise,
  • return false.
public boolean nearTen(int num){
    if((num%10==8 || num%10==9) || (num%10 >= 0  && num%10 <= 2)) return true;
    else return false;
}
| improve this answer | |
New contributor
ldev is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.