AdventJS 2023: Day 9 Challenge

AdventJS 2023: Day 9 Challenge

Alternating Christmas Lights!

ยท

4 min read

The solution to the Challenge #9 of AdventJS 2023

The solution to the previous challenge

The solution to the next challenge

Challenge Description

They are turning on the Christmas lights ๐ŸŽ„ in the city and, as every year, they have to be fixed!

The lights are of two colors: ๐Ÿ”ด and ๐ŸŸข . For the effect to be appropriate, they must always alternate. That is, if the first light is red, the second must be green, the third red, the fourth green, etc.

We have been asked to write a function adjustLights that, given an array of strings with the color of each light, return the minimum number of lights that need to be changed for the colors to alternate.

adjustLights(['๐ŸŸข', '๐Ÿ”ด', '๐ŸŸข', '๐ŸŸข', '๐ŸŸข'])
// -> 1 (you change the fourth light to ๐Ÿ”ด)

adjustLights(['๐Ÿ”ด', '๐Ÿ”ด', '๐ŸŸข', '๐ŸŸข', '๐Ÿ”ด'])
// -> 2 (you change the second light to ๐ŸŸข and the third to ๐Ÿ”ด)

adjustLights(['๐ŸŸข', '๐Ÿ”ด', '๐ŸŸข', '๐Ÿ”ด', '๐ŸŸข'])
// -> 0 (they are already alternating)

adjustLights(['๐Ÿ”ด', '๐Ÿ”ด', '๐Ÿ”ด'])
// -> 1 (you change the second light to ๐ŸŸข)

Analysis

For this exercise, the goal is to find the least number of changes necessary for the lights to alternate. The complexity lies not so much in leaving them alternating, but in finding the fewest number of changes to get to that point.

Input

  1. Lights (lights): An array of strings where each color of light goes.

Output

  • The minimum number of movements necessary for the lights to alternate.

Considerations

  • It is important to consider that it's not just about alternating the colors, but also finding a way to do it with the least number of movements, as in this case: ["๐ŸŸข", "๐Ÿ”ด", "๐Ÿ”ด", "๐ŸŸข", "๐Ÿ”ด", "๐ŸŸข", "๐Ÿ”ด", "๐ŸŸข", "๐Ÿ”ด"]. We start with a green, then a red and subsequently another red, if we change that red to green we realize that the next one is also green and we must also change it, in this case to a red, but then another red would follow... and so on, resulting in a 7. The point is that if we simply change the first green to a red and the first red to a green, we would have everything solved with only 2 changes.

Solution

Considering that the colors must alternate, we can reason that if we arrange the array in such a way, it will start with either the red or green color and alternate from there, so we can evaluate both scenarios and count how many changes would be needed, thus mitigating the problem mentioned in the considerations.

Code

/**
 * Organizes alternately the lights in an array.
 *
 * @param {string[]} lights - The array of lights.
 * @return {number} Number of changes needed to organize the lights.
 */
function adjustLights(lights) {
  // Initialize variables to count the necessary changes
  // both if starting by red or green
  let redCount = 0;
  let greenCount = 0;

  // Iterate over each light color in the array
  lights.forEach((light, index) => {
    // Check if the index is even or odd
    // this in order to count the changes
    // for both cases, red even and green odd
    // or green even and red odd
    if (index % 2) {
      // We will evaluate the even cases

      // If it's green, add +1 to green
      if (light === "๐ŸŸข") greenCount++;

      // If it's red, add +1 to red
      if (light === "๐Ÿ”ด") redCount++;
    } else {
      // Otherwise for the odd ones

      // If the light is red, we do the opposite and +1 for green
      if (light === "๐Ÿ”ด") greenCount++;

      // If the light is green, +1 for red
      if (light === "๐ŸŸข") redCount++;
    }
  });

  // Return the minimum between red and green
  return Math.min(redCount, greenCount);
}

Community Solutions

Solution by 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);
}

Solution by 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;
}

And that was the challenge for December 9th and its solutions. Give a like if you liked the challenge or the solution!
Do you have another alternative solution? Leave it in the comments!

ย