Solución al reto #9 del AdventJS 2023
Descripción del Reto
Están encendiendo las luces de Navidad 🎄 en la ciudad y, como cada año, ¡hay que arreglarlas!
Las luces son de dos colores: 🔴 y 🟢 . Para que el efecto sea el adecuado, siempre deben estar alternadas. Es decir, si la primera luz es roja, la segunda debe ser verde, la tercera roja, la cuarta verde, etc.
Nos han pedido que escribamos una función adjustLights que, dado un array de strings con el color de cada luz (representados con los emojis 🔴 para el rojo y 🟢 para el verde), devuelva el número mínimo de luces que hay que cambiar para que estén los colores alternos.
adjustLights(['🟢', '🔴', '🟢', '🟢', '🟢'])
// -> 1 (cambias la cuarta luz a 🔴)
adjustLights(['🔴', '🔴', '🟢', '🟢', '🔴'])
// -> 2 (cambias la segunda luz a 🟢 y la tercera a 🔴)
adjustLights(['🟢', '🔴', '🟢', '🔴', '🟢'])
// -> 0 (ya están alternadas)
adjustLights(['🔴', '🔴', '🔴'])
// -> 1 (cambias la segunda luz a 🟢)
Análisis
Para este ejercicio el objetivo es encontrar la menor cantidad de cambios necesarios para que las luces queden alternadas. La complejidad no reside tanto en dejarlas alternadas, sino de encontrar la menor cantidad de cambios para llegar a ese punto.
Entrada
- Lights(
lights
): Un arreglo de strings en el que irá cada color de luz.
Salida
- El número mínimo de movimientos necesarios para que las luces queden alternadas.
Consideraciones
- Hay que tomar en cuenta que no solo es de que los colores queden alternados, debe buscarse la manera de hacerlo con la menor cantidad de movimientos, como en este caso:
["🟢", "🔴", "🔴", "🟢", "🔴", "🟢", "🔴", "🟢", "🔴"]
Donde empezamos con un verde, luego un rojo y posteriormente un rojo otra vez, si cambiamos ese rojo a verde nos daremos cuenta que el siguiente también es verde y también debemos cambiarlo, en este caso por un rojo, pero seguidamente iría otro rojo... y así sucesivamente, dando como respuesta un7
. El punto es que si simplemente cambiamos el primer verde por un rojo y el primer rojo por un verde tendríamos todo resuelto con solo2
cambios.
Solución
Teniendo en cuenta que los colores deben ir alternados, podemos razonar que si arreglamos el array de dicha manera, éste va a empezar por el color rojo o por el verde e ir alternando a partir de allí, por lo tanto podemos evaluar ambos escenarios y contar cuantos cambios se necesitarían, así se mitiga el problema que se comentaba en las consideraciones.
Código
/**
* Ordenar alternadamente las luces en base un arreglo desordenado.
*
* @param {string[]} lights - El arreglo de luces.
* @return {number} Número de cambios necesarios para ordenar las luces.
*/
function adjustLights(lights) {
// Inicializar las variables que contarán los cambios necesarios
// tanto si se empieza por rojo o por verde
let redCount = 0;
let greenCount = 0;
// Iterar sobre cada color de luz en el arreglo
lights.forEach((light, index) => {
// Chequeamos si el índice es par o impar
// esto con la finalidad de que contemos los cambios
// para ambos casos, rojo pares y verde impares
// o para verde pares y rojo impares
if (index % 2) {
// Evaluaremos los casos donde sea par
// Si es verde, se suma +1 a verde
if (light === "🟢") greenCount++;
// Si es roja, se suma +1 a rojo
if (light === "🔴") redCount++;
} else {
// Caso contrario para los impares
// Si la luz es roja, haremos lo contrario y +1 para verde
if (light === "🔴") greenCount++;
// Si la luz es verde, +1 al rojo
if (light === "🟢") redCount++;
}
});
// Retornamos el mínimo entre rojo y verde
return Math.min(redCount, greenCount);
}
Soluciones de la comunidad
Solución por Jioh19:
function adjustLights(lights) {
const color = ['🟢', '🔴'];
let res = 0;
for (const [i, light] of lights.entries()) {
res += +(light == color[i % 2]);
}
return Math.min(res, lights.length - res);
}
Solución por Yasai:
function adjustLights(lights) {
const init = lights[0];
let rev = false;
let count1 = 0;
let count2 = 0;
for (const light of lights) {
count1 += rev == (light == init);
rev = !rev;
}
rev = true;
for (const light of lights) {
count2 += rev == (light == init);
rev = !rev;
}
count1 = Math.min(count1, count2);
// Code here
return count1;
}
Y ese fue el reto para el 9 de diciembre y sus soluciones. Dale like si te ha gustado el reto o la solución!
¿Tienes otra solución alternativa? ¡Déjala en los comentarios!
Top comments (0)