Coding Problem 9
Después de un tiempo volvemos con nuestros famosos Coding Problems.
Este problema fue preguntado por Google.
Implementa una clase PrefixMapSum con los siguientes métodos:
insert(key: str, value: int): establece el valor de una clave determinada en el mapa. Si la clave ya existe, sobrescriba el valor.
sum(prefix: str): devuelve la suma de todos los valores de las claves que comienzan con un prefijo determinado.
Por ejemplo, debería poder ejecutar el siguiente código:
mapsum.insert("columnar", 3)
assert mapsum.sum("col") == 3
mapsum.insert("column", 2)
assert mapsum.sum("col") == 5
Solución:
Bien, comencemos con los tests, lo que nos dice el enunciado es que tenemos que encontrar todas las claves que comiencen con el prefijo que pasamos por parámetro y sumar todos los valores. Para ello primero debemos crear un método que nos permita insertar estos valores y sobrescribirlos si ya existen, no añadirlos.
Tests:
public class PrefixMapSumTest {
private PrefixMapSum prefixMapSum;
@Before
public void setup() {
prefixMapSum = new PrefixMapSum(new HashMap<>());
}
@Test
public void shouldAddValueToMap() {
prefixMapSum.insert("columnar", 3);
assertTrue(prefixMapSum.getMap().containsKey("columnar"));
assertEquals(prefixMapSum.getMap().size(), 1);
}
@Test
public void shouldOverrideValueIfAlreadyExists() {
prefixMapSum.insert("columnar", 3);
prefixMapSum.insert("columnar", 3);
prefixMapSum.insert("columnar", 3);
assertTrue(prefixMapSum.getMap().containsKey("columnar"));
assertEquals(prefixMapSum.getMap().size(), 1);
}
@Test
public void shouldWriteAllValuesIfNotExists() {
prefixMapSum.insert("columnar", 3);
prefixMapSum.insert("columna", 2);
prefixMapSum.insert("pepito", 5);
assertTrue(prefixMapSum.getMap().containsKey("columnar"));
assertEquals(prefixMapSum.getMap().size(), 3);
}
@Test
public void shouldReturnTheExpectedSumOfValues() {
prefixMapSum.insert("columnar", 3);
prefixMapSum.insert("column", 2);
assertEquals(prefixMapSum.sum("col"), 5);
assertEquals(prefixMapSum.getMap().size(), 2);
}
}
Ahora implementamos el mínimo código posible:
public class PrefixMapSum {
private Map<String, Integer> map;
public PrefixMapSum(Map<String, Integer> map) {
this.map = map;
}
public void insert(String key, int value) {
map.put(key, value);
}
public Map<String, Integer> getMap() {
return map;
}
public int sum(String prefix) {
int sum = 0;
for (String key : map.keySet()) {
if(key.startsWith(prefix)) sum += map.get(key);
}
return sum;
}
}
Pero claro, esto es refactorizable, al menos el método sum, vamos a ello:
public int sum(String prefix) {
return map.entrySet().stream()
.filter(value -> value.getKey().startsWith(prefix))
.map(Map.Entry::getValue)
.reduce(Integer::sum)
.orElse(0);
}
Espero que te haya gustado este nuevo Coding Problem con su solución, espero que te sirva para practicar, nos vemos en la próxima :)