Coding Problem #1

Este problema fue recientemente pregunta por Google.


Enunciado: Dada una lista de números y un número 'k', devuelve dos números cualquiera de la lista que sumen 'k'. Por ejemplo, dado [10, 15, 3, 7] y 'k' es 17, devuelve verdadero porque 10 + 7 es 17.


Bonus: ¿Puedes hacer esto de una pasada?


ATENCIÓN: A continuación voy a presentar mi solución a dicho problema, te recomiendo que hagas como yo y primero intentes resolverlo, seguramente mi solución no sea la mejor, pero yo también estoy aprendiendo y practicando para mejorar :)

Una primera aproximación, hecha en 5 minutos con podría ser algo como esto, algo bastante feo, vamos a refactorizar un poco e intentar conseguir el bonus:



public class Problem {
  public static boolean resolveProblem(int sum, int[] numbers) {
    if(numbers.length == 1 && numbers[0] == sum) return true;
    for(int i = 0; i < numbers.length - 1; i++){
      for(int j = 0; j < numbers.length; j++){
        if(numbers[i] + numbers[j] == sum) return true;
      }
    }
   return false;
  }
}

Después de la refactorización y de la búsqueda de un solución mas elegante nos quedamos así:


import java.util.stream.IntStream;

public class Problem {
 public static boolean resolveProblem(int sum, int[] numbers) {
   if(numbers[0] == sum) return true;
 
   for(Integer number : numbers) {
     int numberToSearch = sum - number;
 
     boolean arrayContainsNumbersWithSum =    IntStream.of(numbers).anyMatch(value -> value == numberToSearch);
 if(arrayContainsNumbersWithSum) return true;
   }
 
   return false;
  }
 }

Lo que he hecho ha sido restar al total el número actual del array, y si el resultado se encontraba en el array era porque existen 2 números cuya suma es el total, quizás se podría haber hecho de otra forma pero ha sido la solución que he encontrado, ¿tú que propones? Por supuesto hemos hecho una batería de test para probar esto:



public class ProblemTest {
 int sum = 17;

 @Test
 public void givenAnArrayWithTwoElementsWithCorrectSumShouldReturnTrue() {
 int [] numbers = new int[]{1, 15, 16, 7, 18, 6, 20};
 assertTrue(Problem.resolveProblem(sum, numbers));
    }

 @Test
 public void givenAnArrayWithoutElementsWithCorrectSumShouldReturnFalse() {
 int [] numbers = new int[]{10, 15, 3, 6};
 assertFalse(Problem.resolveProblem(sum, numbers));
    }

 @Test
 public void givenAnArrayWithouOnlyOneElementWithSumShouldReturnFalse() {
 int [] numbers = new int[]{10, 15, 3, 17};
 assertFalse(Problem.resolveProblem(sum, numbers));
    }

 @Test
 public void givenAnArrayWithOnePositionWithSumShouldReturnTrue() {
 int [] numbers = new int[]{17};
 assertTrue(Problem.resolveProblem(sum, numbers));
    }

 @Test
 public void givenAnArrayWithOnePositionWithoutSumShouldReturnFalse() {
 int [] numbers = new int[]{10};
 assertFalse(Problem.resolveProblem(sum, numbers));
    }
}

Habrá algún caso que nos hayamos dejado, como que ocurre si el array se encuentra vacío o viene de forma incorrecta, o está nulo, o hay varios números que cumplen la condición, o si pueden venir números negativos, pero para simplificar el ejercicio hemos supuesto que siempre viene de forma correcta. Todos estos casos que menciono aquí se me han ocurrido por haber hecho TDD, que es una herramienta que más que ayudar a que nuestro código esté bien, nos ayuda a diseñar nuestro código. Espero que te haya gustado este primer post, y nos vemos en el siguiente :)




111 vistas

©2020 por Juanma Perez.