The solution to the Challenge #5 of AdventJS 2023
The solution to the previous challenge
The solution to the next challenge
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...|....|.....
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:
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
Road (
road
): The original string through which the sled will make its journey.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
/**
* 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:
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:
function 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!
Top comments (0)