in Code

Each week, I offer up a JavaScript code challenge. Want more? You can find others here.

This week’s code challenge comes from Coderbyte. Here are the basic instructions:

Have the function `StringReduction(str)` take the `str` parameter being passed and return the smallest number you can get through the following reduction method. The method is: Only the letters a, b, and c will be given in str and you must take two different adjacent characters and replace it with the third.

For example, if you were provided the string “abc,” you could simplify that to “cc” but no further. On the other hand, “aba” could be simplified to “ca” and then to “b.”¬†For simplification, here are all of the¬†transformations:

ac = b
ca = b
cb = a
bc = a
ab = c
ba = c

Here are some test cases:

StringReduction(“abcabc”) should equal 2.
StringReduction(“cccc”) should equal 4.
StringReduction(“baccabcbc”) should equal 1.

Here’s my solution collapsed:

function StringReduction(str) { 
	// Set initial counter variable to 0
	var i = 0;
	// Split the string into an array of letters
	var letters = str.split('');
	// Start do loop.
	do {
		// If the first and second letter in the array match any of the pairs
		if ((letters[i] == "a" && letters[i+1] == "b") || (letters[i] == "b" && letters[i+1] == "a")) {
			// Remove the second letter
			letters.splice(i+1, 1);	
			// Transform the first letter
			letters[i] = "c";
			// Set the counter back to 0 so we can start at the beginning again
			i = 0;
		} else if ((letters[i] == "b" && letters[i+1] == "c") || (letters[i] == "c" && letters[i+1] == "b")) {
			letters.splice(i+1, 1);	
			letters[i] = "a";
			i = 0;
		} else if ((letters[i] == "c" && letters[i+1] == "a") || (letters[i] == "a" && letters[i+1] == "c")) {
			letters.splice(i+1, 1);	
			letters[i] = "b";
			i = 0;
			// If no conditions are met, incremenet the counter
		} else {
			i++;
		}
	}  while (i < letters.length);
	// Return the length of the transformed string
	return letters.length; 
}

console.log(StringReduction("baccabcbc"));

The first step was to setup an initial counter variable for my do/while loop and break the string into individual letters. Next, I entered the do/while loop with the counter set to 0. There are a total of four comparison statements that check if any of the transformations are met. Each comparison statement checks both the forward (ab) and backward (ba) variations.

If the comparison is a match, the second letter in the group (i+1) is spliced from the array while the first letter (i) is transformed. Finally, the counter variable is set back to 0 so we can start again at the beginning of the array.

If the first three comparisons all fail, the counter is incremented by one. This do loop runs while the counter variable (i) is less than the length of the letters array.

I originally started with a for loop. That worked alright, but it moved continuously down the string rather than starting over on a transformation. For example, it would simplify “aabc” to “acc” but not to “bc” or “a.” The do/while loop allowed me to reset the counter when a transformation occurred.