The challenge
Your task is to add up letters to one letter.
The function will be given an array of single-character Strings, each one being a letter to add.
Notes:
- Letters will always be lowercase.
- Letters can overflow (see second to last example of the description)
- If no letters are given, the function should return
'z'
Examples:
addLetters("a", "b", "c") = "f"
addLetters("a", "b") = "c"
addLetters("z") = "z"
addLetters("z", "a") = "a"
addLetters("y", "c", "b") = "d" // notice the letters overflowing
addLetters() = "z"
The solution in Java code
Option 1:
public class Solution {
public static String addLetters(String... letters) {
String abc = "zabcdefghijklmnopqrstuvwxyz";
int sum = 0;
for (int i = 0; i < letters.length; i++) {
sum += abc.indexOf(letters[i]);
}
return String.valueOf(abc.charAt(sum % 26));
}
}
Option 2:
import static java.util.stream.Stream.of;
class Solution {
static String addLetters(String... letters) {
int sum = of(letters).mapToInt(l -> l.charAt(0) - 96).sum() % 26 + 96;
return "" + (char) (sum != 96 ? sum : 122);
}
}
Option 3:
import java.util.Arrays;
public class Solution {
public static String addLetters(String... letters) {
int sum = Arrays.stream(letters)
.flatMapToInt(String::chars)
.map(letter -> letter == 'z' ? 0 : letter - 'a' + 1)
.sum();
int overflow = sum % 26;
return overflow == 0 ? "z" : Character.valueOf((char)(overflow + 'a' - 1)).toString();
}
}
Test cases to validate our solution
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.junit.runners.JUnit4;
import java.util.Arrays;
import java.util.Random;
public class SolutionTest {
@Test
public void fixedTests() {
assertEquals("f", Solution.addLetters("a", "b", "c"));
assertEquals("z", Solution.addLetters("z"));
assertEquals("c", Solution.addLetters("a", "b"));
assertEquals("c", Solution.addLetters("c"));
assertEquals("a", Solution.addLetters("z", "a"));
assertEquals("d", Solution.addLetters("y", "c", "b"));
assertEquals("z", Solution.addLetters());
}
private String solution(String... letters) {
int sum = Arrays.stream(letters).mapToInt(s->s.charAt(0)-96).sum() % 26;
return sum == 0 ? "z" : String.valueOf((char)(sum+96));
}
@Test
public void randomTests() {
Random rnd = new Random();
for (int i = 0; i < 100; ++i) {
String[] letters = rnd.ints(97, 123)
.limit(rnd.nextInt(10) + 1)
.mapToObj(c -> String.valueOf((char) c))
.toArray(String[]::new);
assertEquals(solution(letters), Solution.addLetters(letters));
}
}
}