# AdventJS 2023: Day 5 Challenge

The solution to the [Challenge #5](https://adventjs.dev/es/challenges/2023/5) of [AdventJS 2023](https://adventjs.dev/es)

The solution to the [previous challenge](https://alexvalle.dev/adventjs-2023-day-4-challenge)

The solution to the [next ch](https://alexvalle.dev/)[previous challenge](https://alexvalle.dev/adventjs-2023-day-6-challenge)[allenge](https://alexvalle.dev/)

## **Challenge Description**

Santa 🎅 is testing his new electric sled, the *CyberReindeer*, on a North Pole road. The road is represented by a string of characters, where:

* `.` = Road
    
* `S` = Santa's Sled
    
* `*` = Open barrier
    
* `|` = Closed barrier
    

Example of a road: `S...|....|.....`

For each unit of time, **the sled moves one position to the right**. If it encounters a closed barrier, it stops until the barrier opens. If it is open, it goes through directly.

**All barriers start closed**, but after 5 units of time, they all open **forever**.

**Create a function that simulates the sled's movement** for a given time and **returns an array** of strings representing the state of the road at each unit of time:

```javascript
const road = 'S..|...|..'
const time = 10 // units of time
const result = cyberReindeer(road, time)

/* -> result:
[
  'S..|...|..', // initial state
  '.S.|...|..', // sled advances on the road
  '..S|...|..', // sled advances on the road
  '..S|...|..', // sled stops at the barrier
  '..S|...|..', // sled stops at the barrier
  '...S...*..', // barrier opens, sled advances
  '...*S..*..', // sled advances on the road
  '...*.S.*..', // sled advances on the road
  '...*..S*..', // sled advances on the road
  '...*...S..', // passes through the open barrier
]
*/
```

The result is an **array where each element shows the road at each unit of time**.

Take into account that **if the sled is in the same position as a barrier**, then it takes its place in the array.

## **Analysis**

To solve this challenge, we must move the letter `S` within the string and stop it when it finds a barrier (`|`). The barrier will open (`*`) after 5 units of time. We need to store the journey of the letter `S` in an array until the units of time run out.

### **Inputs**

1. Road (`road`): The original string through which the sled will make its journey.
    
2. Time (`time`): A number with the units of time.
    

### **Output**

* An array of the history of the sled's journey
    

### **Considerations**

* We must stop the sled when it encounters a barrier and store it in history even if it does not move from there.
    
* When the sled passes over an open barrier (`*`), it will replace it in the string and once it has passed, the open barrier (`*`) must be put back.
    

## **Solution**

The initial position of the sled is identified at the beginning. The function iterates for each unit of time, advancing the sled if there is no closed barrier ahead. On the fifth unit of time, all barriers open permanently. The state of the road is updated and saved in an array at each iteration, reflecting the position of the sled and the state of the barriers. The final result is an array showing the state of the road at each moment of the given time.

### **Code**

```javascript
/**
 * Simulates the movement of Santa's sled on a road for a given time.
 * 
 * @param {string} road - Representation of the road with '.', 'S', '|', and '*'.
 * @param {number} time - Number of units of time to simulate.
 * @return {string[]} - Array representing the state of the road at each unit of time.
 */
function cyberReindeer(road, time) {
  // Stores the state of the road at each unit of time
  const roadStates = [road];
  
  // Finds the initial position of the sled
  let sledPosition = road.indexOf("S");
  
  // Character that will be replaced by the sled when it moves
  let replacedChar = ".";

  // Iterates for each unit of time, minus one, since the initial state is already included
  for (let i = 0; i < time - 1; i++) {
    // Gets the current state of the road
    let currentRoadState = roadStates[i];

    // On the fifth iteration (unit of time 5), all barriers open
    if (i === 4) {
      currentRoadState = currentRoadState.replace(/[|]/g, "*");
    }

    // Checks if the next position of the sled is not a closed barrier
    if (currentRoadState[sledPosition + 1] !== "|") {
      // Prepares the new sled position
      // concatenating it to the element that previously was in that position
      const newSledPosition = `${replacedChar}S`;
      
      // Updates the character replaced by the sled before being replaced
      replacedChar = currentRoadState[sledPosition + 1];

      // Builds the new state of the road with the sled moved one position
      const firstPart = currentRoadState.substring(0, sledPosition);
      const lastPart = currentRoadState.substring(sledPosition + 2);
      currentRoadState = firstPart + newSledPosition + lastPart;
      
      // Updates the sled position
      sledPosition += 1;
    }

    // Adds the updated state of the road to the array
    roadStates.push(currentRoadState);
  }

  // Returns the array with the state of the road at each unit of time
  return roadStates;
}
```

### **Community Solutions**

Solution by [SantiMenendez19](https://github.com/SantiMenendez19/adventjs/blob/main/2023/challenge05/solution.js):

```javascript
javascriptCopy codefunction cyberReindeer(road, time) {
    let result = []
    let timePassed = 0
    let pos = 0
    let aux = "."
    while (time > 0) {
        result.push(road)
        time--
        timePassed++
        if (timePassed >= 5) road = road.replace(/\|/gi, "*")
        if (road[pos+1] === '.' || road[pos+1] === '*') {
            road = road.split("")
            road[pos] = aux
            aux = road[pos+1]
            road[pos+1] = "S"
            road = road.join("")
            pos++
        }
    }
    return result
}
```

Solution by [Achalogy](https://github.com/Achalogy/advent-js-2023/blob/main/retos/reto-5/main.ts):

```javascript
javascriptCopy codefunction cyberReindeer(road, time) {
  let moves = [road]
  let a = 0
  let b = "."

  for (let i = 1; i < time; i++) {
    if (i == 5) road = road.replace(/\|/g, "*")
    const newRoad = road.replace(/S[\.\*]/, `${b}S`)
    if (newRoad != road) {
      a++
      b = road[a]
    }
    road = newRoad
    moves.push(road)
  }

  return moves;
}
```

And that was the challenge for December 5th and its solutions. Do you have another alternative solution? Leave it in the comments!
