Advent of Code en Rust y un poco de Probabilidad
El problema Report Repair del primer día del Advent of Code 2020 nos plantea un desafío interesante: encontrar dos números en una lista que sumen exactamente 2020 y luego multiplicarlos. Aunque este problema puede resolverse utilizando algoritmos simples, también ofrece una oportunidad única para explorar las matemáticas detrás de este tipo de problemas, especialmente desde la perspectiva de la probabilidad.
En este artículo, resolveremos el problema utilizando el lenguaje de programación Rust y lo analizaremos desde un enfoque probabilístico.
El Problema
El enunciado del problema es el siguiente:
Se te proporciona una lista de números, y tu tarea es encontrar dos números en la lista cuya suma sea exactamente 2020, y luego multiplicar esos dos números. Además, se te pedirá encontrar tres números que sumen 2020 y multiplicarlos.
Por ejemplo, si la lista contiene los siguientes números:
[1721, 979, 366, 299, 675, 1456]
Los dos números que suman son y y al multiplicarlos obtenemos
Resolución en Rust
use itertools::Itertools;
use crate::utils;
pub fn exercise1() {
// Cargar los valores de entrada como una lista de enteros
let expenses: Vec<i64> = utils::loadints_from_file("input/day1");
// Encontrar las combinaciones de dos números cuya suma sea 2020
let found = expenses.into_iter()
// Generar todas las combinaciones de 2 números
.combinations(2)
// Filtrar aquellas cuya suma es 2020
.filter(|v| v[0] + v[1] == 2020)
// Asegurar que solo hay una combinación que cumple
.exactly_one()
// Desempaquetar el resultado
.unwrap();
// Calcular el producto de los dos números
let product = found[0] * found[1];
// Imprimir el resultado
println!("{} * {} = {}", found[0], found[1], product);
}
En este código, utilizamos la biblioteca itertools
para generar todas las combinaciones posibles de dos números en la lista de gastos y luego filtramos aquellas cuya suma sea exactamente 2020. Finalmente, calculamos el producto de los dos números encontrados y lo imprimimos en la consola.
Análisis Probabilístico
No obstante, podríamos preguntarnos que probabilidad hay de que existan dos números en la lista que sumen exactamente 2020. Para responder a esta pregunta, podemos utilizar un enfoque probabilístico.
Distribución Uniforme Discreta
Supongamos que los números de la lista se generan de manera aleatoria siguiendo una distribución uniforme discreta. En una distribución uniforme, cada número tiene la misma probabilidad de ser seleccionado de un rango determinado. Si el rango de valores es de a , la probabilidad de que un número específico sea igual a es:
Suma de Dos Variables Aleatorias Uniformes
El siguiente paso es calcular la probabilidad de que dos números y de esta lista sumen exactamente . La probabilidad de que es extremadamente baja debido al gran rango de valores posibles ( a ).
Debido a que estamos trabajando con dos distribuciones uniforme discreta, la probabilidad de que sigue una distribución triangular.
Así, ¿qué cantidad de números debemos generar como mínimo para esperar encontrar al menos un par que sume 2020?
Valor Esperado
El valor esperado del número de pares que suman se calcula multiplicando el número de combinaciones posibles por la probabilidad de éxito de cada combinación:
Si queremos encontrar dos números que sumen en una lista de números, el valor esperado de pares que suman debe ser igual a 1
Resolución para
Reorganizando la ecuación para resolver :
Resolviendo la ecuación cuadrática y redondeando, obtenemos . Por lo tanto, si generamos al menos números aleatorios en el rango de a , podemos esperar encontrar al menos un par que sume .