Home > Blockchain >  Solution codewars to car Mileage problem, running out of ideas?
Solution codewars to car Mileage problem, running out of ideas?

Time:12-09

I am trying to work out a solution to the CodeWars challenge Catching Car Mileage Numbers:

Write the function that parses the mileage number input, and returns a 2 if the number is "interesting" (see below), a 1 if an interesting number occurs within the next two miles, or a 0 if the number is not interesting.

Interesting numbers are 3-or-more digit numbers that meet one or more of the following criteria:

  • Any digit followed by all zeros: 100, 90000
  • Every digit is the same number: 1111
  • The digits are sequential, incementing: 1234
  • The digits are sequential, decrementing: 4321
  • The digits are a palindrome: 1221 or 73837
  • The digits match one of the values in the awesomePhrases array

For incrementing sequences, 0 should come after 9, and not before 1, as in 7890.
For decrementing sequences, 0 should come after 1, and not before 9, as in 3210.

I can pass all tests in the first batch, but fail to pass the second batch.

Any feedback would be very much appreciated, not only on a possible solution but also to the way I'm thinking about the exercise.

public static int isInteresting(int number, int[] awesomePhrases) {
    for (int offSet = 0; offSet <= 2; offSet  ) {
        int testNumber = number;
        testNumber  = offSet;
        boolean isYellow = testNumber != number;
        int yellowOffset = 0;
        if (isYellow) {
            yellowOffset = 1;
        }
        //check three or more digit number
        boolean greaterThan99 = testNumber > 99;
        int[] numbers = Integer.toString(testNumber).chars().map(c -> c - '0').toArray();
        int zeroCounter = 0;
        int identicalCounter = 0;
        int incrementingCounter = 0;
        int decrementingCounter = 0;
        int palindromeCounter = 0;
        boolean endsInZero = numbers[numbers.length - 1] == 0;
        for (int i = 0; i < numbers.length; i  ) {
            //check digit followed by zeros
            if (numbers[i] == 0) {
                zeroCounter  ;
            }
            if (i   1 < numbers.length) {
                //check every digit is the same
                if (numbers[i] == numbers[i   1]) identicalCounter  ;
                //check ascending order
                if (numbers[i   1] - numbers[i] == 1) incrementingCounter  ;
                //check descending order
                if (numbers[i] - numbers[i   1] == 1) decrementingCounter  ;
            }
        }        
        if (greaterThan99) {
            //check awesomePhrases
            for (int phrase : awesomePhrases) {
                if (phrase == testNumber) return 2 - yellowOffset;
            }
            //check palindrome
            int reversedIndex = numbers.length - 1;
            for (int i = 0; i < numbers.length; i  ) {
                if (numbers[reversedIndex] == numbers[i]) {
                    palindromeCounter  ;
                }
                reversedIndex--;
            }            
            if (zeroCounter == numbers.length - 1) return 2 - yellowOffset;
            if (identicalCounter == numbers.length - 1) return 2 - yellowOffset;
            if (incrementingCounter == numbers.length - 1) return 2 - yellowOffset;
            if (incrementingCounter == numbers.length - 2 && endsInZero) return 2 - yellowOffset;
            if (decrementingCounter == numbers.length - 1) return 2 - yellowOffset;
            if (decrementingCounter == numbers.length - 2 && endsInZero) return 2 - yellowOffset;
            if (palindromeCounter == numbers.length) return 2 - yellowOffset;
        }
    }
    return 0;
}

I've tried pretty much all I know but to no result, all the tests I try pass, would love to know what I'm doing wrong.

1

CodePudding user response:

The problem is in how your code tests for increasing sequences that end in a zero. It is not enough to test that the sequence has n-2 increments and the last digit is a zero, because that will give a false positive on numbers like 6780. It is required that the one-but-last digit is a 9.

A similar issue exist for the decreasing sequence logic, however, there you would not need a special test for an ending zero at all. This condition is covered by counting n-1 decrements, where the ending could be a 1 followed by a zero. There is no special case to be handled here.

To fix the first problem, I would suggest you not only check whether the last digit is a zero, but whether the last two digits are 9 and 0, or in other words, that the number modulo 100 is equal to 90.

You could replace this:

boolean endsInZero = numbers[numbers.length - 1] == 0;

by this:

boolean endsInNinety = testNumber % 100 == 90;

and then replace:

if (incrementingCounter == numbers.length - 2 && endsInZero) return 2 - yellowOffset;

by:

if (incrementingCounter == numbers.length - 2 && endsInNinety) return 2 - yellowOffset;

and finally remove this test:

if (decrementingCounter == numbers.length - 2 && endsInZero) return 2 - yellowOffset;

This will fix it.

Note that it can be helpful to have your function print the input it gets, so that when a test fails, at least you can know for which input there was a problem:

System.out.println("input "   number);
  • Related