AdventJS 2023: Reto del Día 9
Tags: spanish, javascript, webdev, programming
Published: 2023-12-10 23:18:39

Solución al [reto #9](https://adventjs.dev/es/challenges/2023/9) del [AdventJS 2023](https://adventjs.dev/es)

[Solución del reto anterior](https://dev.to/fenriuz/adventjs-2023-reto-del-dia-8-i44)

[Solución del siguiente reto](https://dev.to/fenriuz/adventjs-2023-reto-del-dia-10-h5d)

{%- # TOC start (generated with https://github.com/derlin/bitdowntoc) -%}

- [Descripción del Reto](#descripción-del-reto)
- [Análisis](#análisis)
   * [Entrada](#entradas)
   * [Salida](#salida)
   * [Consideraciones](#consideraciones)
- [Solución](#solución)
   * [Código](#código)
   * [Soluciones de la comunidad](#soluciones-de-la-comunidad)

{%- # TOC end -%}


## 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.
```javascript
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

1. 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 un `7`. 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 solo `2` 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

```javascript
/**
 * 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](https://github.com/Jioh19/adventjs-2023/blob/main/09/script.js):

```javascript
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](https://github.com/yasai59/adventjs-solutions/blob/main/day9.js):

```javascript
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!