2

The following question was asked in my last interview (yesterday), and I'm trying to solve it since then (couldn't solve it in the interview).

Sorry for any grammar mistakes or any logical mistakes, I don't have the question, it was written by memory:

You are given a number in a string format, for example: "14438832066". You got to sum up the consecutive equal digits in that number. If no consecutive equal digit was found, just add the digit to the result.

for example: solution(19938832066) => 11831632012

Explanation: first digit is 1. The second and third digits are both 9 which means they will turn into 18 in the result string. So on with the rest of the digits (as you can see, the last 2 digits are both 6 which means they will turn into 12 in the result string).

You are required to do that for the result string as well, if needed, until no equal consecutive digits are found in the number.

Example:: number: 14438832066 solution( "19938832066") ->"11831632012" -> "2831632012" Explanation: first result is 11831632012, but then you can see that there are still equal consecutive digits : the first and the second digits are both 1. So process that number as well.

You are given a string and must return a string.

My solution:

I couldn't write the solution, I don't know why. It's a pretty simple question, I thought going recursive at first but didn't want to complex things.

I wrote 2 helper methods:

  1. one that returns a boolean whether the number consists of equal consecutive digits.
  2. one that actually makes the business logic:
turn the string into a char array
create a counter that will count instances of the same digit - (int counter = 1).
loop on the array from the first to the one before the last element :
inside the loop:
//equal digit was found - increment counter and continue to next digit
if char[i] == char[i+1] then counter++
 //calculation in case we are done counting the same digit
else if counter > 0 then result.append(counter*digit[i])
 // if no consecutive equal digit was found
else result.append(digit[i])
end loop: return result

Problems I had:

  • I created the counter inside the loop, so each iteration it got rested. took me few minutes to realize.
  • I had troubles realizing that 'int(digit[i])' doesn't give me the numeric value of the char, it gives the ASCII value. I had to use "Character.getNumericValue" (don't remember the exact name of the method).

Because of these problems, it took me 45 minutes to write the solution which in the end didn't even work.

I'll be glad to get a working solution, and even better - to get any feedback and tips on my solution and what, in your opinion, were my mistakes.

Thank you.

NoobCoder
  • 513
  • 3
  • 18
  • 1
    What happened to the first "1" in the first example? Shouldn't it be "118..."? – erickson Nov 07 '22 at 18:22
  • @erickson you are right. fixed it, thanks. – NoobCoder Nov 08 '22 at 07:17
  • Your pseudo-code actually sounds pretty good. Why not post your real code though? It sounds like you have already fixed the problems you mentioned, but you don't explain what is still not working. – erickson Nov 08 '22 at 16:29
  • @erickson I don't have my real code. As I said, I don't have not the question nor my solution. I wrote it from what I remembered. I can try to re-create my code and add it to my post to let you help me figure out why it didn't work. – NoobCoder Nov 08 '22 at 17:52

3 Answers3

1

Here's an algorithm that uses recursion and a for-loop to add consecutive equal digits. I think the code is pretty self-explanatory but please ask if you have any queries.

public static String addConsecutiveDigits(String number) {
    char[] arr = number.toCharArray();
    StringBuilder result = new StringBuilder();
    boolean foundConsecutive = false; // boolean flag for checking if the number contained consecutive equal digits
    for (int i = 0; i < arr.length; i++) {
        int digit = arr[i] - '0'; //Subtracting ascii values to get integer values
        int newNumber = digit;
        if (i != arr.length - 1) {
            int nextDigit = arr[i + 1] - '0';

            if (digit == nextDigit) { // check if the digits are consecutive digits
                newNumber = digit + nextDigit;
                i++; // increment i as we have already added the i+1 digit
                foundConsecutive = true;
             }
        }       
        result.append(newNumber);
    }
    if (!foundConsecutive) // if no consecutive equal digits were found then return the result;
        return result.toString();
    else // recurse to check for more consecutive equal digits
        return addConsecutiveDigits(result.toString());
}

1

Your pseudo-code seems alright, as far as it goes. What's missing is that you don't repeatedly check the result string to see if another pass is required. I also show how you don't need to remember the API to convert a character to a digit; if you know the digits are decimal, you can interpret them yourself. As an interviewer, I would accept that there is an API that you can't precisely remember or your home-brew solution as equally valid.

String transform(String number) {
  while (true) {
    String result = collapse(number);
    if (result.equals(number)) return result;
    number = result;
  }
}

private static String collapse(String number) {
  StringBuilder result = new StringBuilder();
  for (idx = 0; idx < number.length(); ) {
    int mark = idx;
    int digit = digitAt(number, idx++);
    while (idx < number.length() && digitAt(number, idx) == digit) ++idx;
    result.append((idx - mark) * digit);
  }
  return result.toString();
}

private static int digitAt(String num, int index) {
  char ch = number.charAt(index);
  if (ch < '0' || ch > '9') throw new IllegalArgumentException();
  return ch - '0';
}

The preceding is a naïve approach that transforms the string until there are no changes. I suspect there might be a more "elegant" approach that works from left to right through the input in a single pass, but it would take some thought, and I probably couldn't come up with that in an interview.

erickson
  • 265,237
  • 58
  • 395
  • 493
-1

I'm not a Java guy, so this code might not be ideal but I would do something like this:

public String solve(String input)
    {
        String result = "";
        int i = 0;
        while (i < input.length())
        {
            var first = input.charAt(i);
            if (i == input.length() - 1){
                result += first;
                break;
            }
            var second = input.charAt(i + 1);
            if (first == second){
                result += (Character.getNumericValue(first) + Character.getNumericValue(second));
                i += 2;
            } else {
                result += first;
                i += 1;
            }
        }
        return result;
    }

For the second part, I would just run the function in a loop until the result matches the input.

Matt Clarke
  • 757
  • 4
  • 15