Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions src/main/java/problems/impl/RunLengthConverter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package problems.impl;

/**
* Run-length encoding is a fast and simple method of encoding strings.
* The basic idea is to represent repeated successive characters as a single count and character.
* For example, the string "AAAABBBCCDAA" would be encoded as "4A3B2C1D2A".
* Implement run-length encoding and decoding.
* You can assume the string to be encoded have no digits and consists solely of alphabetic characters.
* You can assume the string to be decoded is valid.
*/

public class RunLengthConverter {
public static String encode(String value) {
if (value.isEmpty()) {
return "";
}

char[] chars = value.toCharArray();

StringBuilder encodedValue = new StringBuilder();

char currentChar = chars[0];
int charCount = 1;

for (int i = 0; i < chars.length - 1; i++) {
char nextChar = chars[i + 1];

if (nextChar == currentChar) {
charCount++;
} else {
encodedValue.append(charCount).append(currentChar);
charCount = 1;
}

currentChar = nextChar;
}

encodedValue.append(charCount).append(currentChar);

return encodedValue.toString();
}

public static String decode(String value) {
char[] chars = value.toCharArray();
StringBuilder decodedValue = new StringBuilder();

for (int i = 0; i < chars.length - 1; i += 2) {
int count = Character.getNumericValue(chars[i]);
char c = chars[i + 1];
for (int j = 0; j < count; j++) {
decodedValue.append(c);
}
}
return decodedValue.toString();
}
}
69 changes: 69 additions & 0 deletions src/test/java/problems/impl/RunLengthConverterTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package problems.impl;

import org.junit.Test;

import static org.junit.Assert.*;

public class RunLengthConverterTest {

@Test
public void itShouldReturnEmptyStringWhenEncodingEmptyString() {
assertEquals(RunLengthConverter.encode(""), "");
}

@Test
public void itShouldEncodeForSingleCharacter() {
assertEquals(RunLengthConverter.encode("a"), "1a");
}

@Test
public void itShouldEncodeForTwoSingleCharacters() {
assertEquals(RunLengthConverter.encode("ab"), "1a1b");
}

@Test
public void itShouldEncodeRepeatingCharacter() {
assertEquals(RunLengthConverter.encode("aaaaaa"), "6a");
}

@Test
public void itShouldEncodeRepeatingCharactersThatEndsWithADifferentCharacter() {
assertEquals(RunLengthConverter.encode("aaaaab"), "5a1b");
}

@Test
public void itShouldEncodeRepeatingCharactersThatEndsWithMultipleDifferentCharacters() {
assertEquals(RunLengthConverter.encode("aaaaabb"), "5a2b");
}

@Test
public void itShouldDecodeEmptyString() {
assertEquals(RunLengthConverter.decode(""), "");
}

@Test
public void itShouldDecodeSingleCharacter() {
assertEquals(RunLengthConverter.decode("1a"), "a");
}

@Test
public void itShouldDecodeTwoSingleCharacters() {
assertEquals(RunLengthConverter.decode("1a1b"), "ab");
}

@Test
public void itShouldDecodeRepeatingCharacters() {
assertEquals(RunLengthConverter.decode("5a"), "aaaaa");
}

@Test
public void itShouldDecodeRepeatingCharactersThatEndsWithADifferentCharacter() {
assertEquals(RunLengthConverter.decode("5a1b"), "aaaaab");
}

@Test
public void itShouldDecodeRepeatingCharactersThatEndWithMultipleDifferentCharacters() {
assertEquals(RunLengthConverter.decode("5a2b"), "aaaaabb");
}

}