Coding Problem 4

Este problema fue preguntado por Facebook


Dada una lista de enteros, devuelve el producto más grande que puedas conseguir multiplicando cualquiera de 3 enteros.


Por ejemplo, si la lista es [-10, -10, 5, 2], devolveremos 500, porque, -10*-10*5 es 500.

Puedes asumir que la lista tiene al menos 3 enteros.o


Bien, vamos a por ello, como siempre, primero los test y primero inténtalo tú para poder practicar y mejorar :)


Solución:


Bueno, primer vamos a colocar nuestros tests, vamos a probar que solo hayan 3 enteros positivos, que solo hayan enteros positivos de cualquier longitud, que solo haya enteros negativos, y por último una mezcla de todo, como el ejercicio nos dice que como mínimo habrán 3 números no haremos comprobación de listas vacias o de menor longitud a 3.



public class ProblemTest {

    @Test
    public void shouldReturnTheProductOfTheArray(){
        List<Integer> numbers = List.of(10, 10, 5);

        assertEquals(500, Problem.productOfNumbers(numbers));
    }

    @Test
    public void shouldReturnTheMaxProductOfThreeIntegersWithPositiveNumbers(){
        List<Integer> numbers = List.of(10, 10, 5, 2, 50, 20);

        assertEquals(10000, Problem.productOfNumbers(numbers));
    }

    @Test
    public void shouldReturnTheMaxProductOfThreeIntegersWithNegativeNumbers(){
        List<Integer> numbers = List.of(-5, -2, -10,-1);

        assertEquals(-100, Problem.productOfNumbers(numbers));
    }

    @Test
    public void shouldReturnTheMaxProductOfThreeIntegersWithPostiveAndNegativeNumbers(){
        List<Integer> numbersWithTwoNegativeNumbers = List.of(-10, -10, 5,2);
        List<Integer> numbersWithOneNegativeNumber = List.of(-10, 10, 5,2);
        List<Integer> numbersWithThreeNegativeNumber = List.of(-10, -10, -5,2);
        List<Integer> numbersComplex= List.of(-10, -10, -5,2, 3, 5, -2, 27);

        assertEquals(500, Problem.productOfNumbers(numbersWithTwoNegativeNumbers));
        assertEquals(-500, Problem.productOfNumbers(numbersWithOneNegativeNumber));
        assertEquals(-500, Problem.productOfNumbers(numbersWithThreeNegativeNumber));
        assertEquals(2700, Problem.productOfNumbers(numbersComplex));
    }

}


Y ahora el código productivo, he usado la función absoluto de java para ayudarme y he divido los diferentes casos posibles:



public class Problem {

    public static int productOfNumbers(List<Integer> numbers) {
        if(allNumbersArePositive(numbers)){
            return numbers.stream()
                    .sorted(Comparator.reverseOrder())
                    .limit(3)
                    .reduce((n1, n2) -> n1 * n2)
                    .get();

        } else if(allNumbersAreNegative(numbers)){
            return numbers.stream()
                    .sorted()
                    .limit(3)
                    .reduce((n1, n2) -> n1 * n2)
                    .get();
        }else{
            int product = numbers.stream()
                    .map(Math::abs)
                    .sorted(Comparator.reverseOrder())
                    .limit(3)
                    .reduce((n1, n2) -> n1 * n2)
                    .get();

            return isNegativeResult(numbers) ? product * -1 : product;
        }
    }

    private static boolean isNegativeResult(List<Integer> numbers) {
        return numbers.stream()
                .filter(number -> number < 0)
                .count() % 2 != 0;
    }

    private static boolean allNumbersAreNegative(List<Integer> numbers) {
        return numbers.stream().filter(number -> number < 0).count() == numbers.size();
    }

    private static boolean allNumbersArePositive(List<Integer> numbers) {
        return numbers.stream().filter(number -> number > 0).count() == numbers.size();
    }
}

¿A ti se te habría ocurrido una solución mejor? Si es así compártela para aprender entre todos :), espero que te haya gustado nos vemos en la próxima.

©2020 por Juanma Perez.