DEV Community

Cover image for AdventJS 2023: Reto del Día 4
Fenriuz
Fenriuz

Posted on • Updated on

AdventJS 2023: Reto del Día 4

Solución al reto #4 del AdventJS 2023

Solución del reto anterior

Solución del siguiente reto

Descripción del Reto

En el taller de Santa 🎅, algunos mensajes navideños han sido escritos de manera peculiar: las letras dentro de los paréntesis deben ser leídas al revés

Santa necesita que estos mensajes estén correctamente formateados. Tu tarea es escribir una función que tome una cadena de texto y revierta los caracteres dentro de cada par de paréntesis, eliminando los paréntesis en el mensaje final.

Eso sí, ten en cuenta que pueden existir paréntesis anidados, por lo que debes invertir los caracteres en el orden correcto.

const a = decode('hola (odnum)')
console.log(a)// hola mundo
const b = decode('(olleh) (dlrow)!')
console.log(b)// hello world!
const c = decode('sa(u(cla)atn)s')
console.log(c)// santaclaus
// Paso a paso:
// 1. Invertimos el anidado -> sa(ualcatn)s
// 2. Invertimos el que queda -> santaclaus

Enter fullscreen mode Exit fullscreen mode

Notas:

  • Las cadenas de entrada siempre estarán bien formadas con paréntesis que coinciden correctamente, no necesitas validarlos.
  • En el mensaje final no deben quedar paréntesis.
  • El nivel máximo de anidamiento es 2.

Análisis

En este ejercicio el objetivo es ordenar al revés aquellas letras que estén dentro de paréntesis. Si hay paréntesis anidados habrá que reordenar varias veces, según la cantidad de niveles anidados que haya.

Entrada

  1. Message(message): Un string con el mensaje en el cuál debemos buscar y reordenar las letras que estén dentro de paréntesis.

Salida

  • El string correctamente ordenado

Consideraciones

  • No se necesita validar que los paréntesis coincidan y estén bien cerrados
  • Se deben eliminar todos los paréntesis del texto

Solución

Para cubrir todos los casos y consideraciones, se debe empezar a buscar el último paréntesis de apertura ( y luego hacerlo coincidir con el primer paréntesis de cierre ) que esté después del de apertura. Extraer las letras que estén dentro y reordenarlas al revés.

Posteriormente se debe repetir el proceso con el string resultante, así que podemos usar un ciclo while para logralo

Código

/**
 * Decodifica un mensaje invirtiendo los caracteres entre cada par de paréntesis.
 *
 * @param {string} message - El mensaje a decodificar.
 * @return {string} - El mensaje decodificado.
 */
function decode(message) {
  // Inicializa variables para almacenar los índices de los paréntesis de apertura y cierre
  let init, end;

  // Bucle hasta que no haya más paréntesis de apertura y cierre
  while (init !== -1 || end !== -1) {
    // Encuentra el índice del último paréntesis de apertura
    init = message.lastIndexOf("(");

    // Encuentra el índice del paréntesis de cierre después del último paréntesis de apertura
    end = message.indexOf(")", init);

    // Extrae la cadena codificada entre los paréntesis de apertura y cierre
    const encoded = message.substring(init, end + 1);

    // Invierte los caracteres en la cadena codificada, excluyendo los paréntesis de apertura y cierre
    const decoded = encoded.split("").slice(1, -1).reverse().join("");

    // Reemplaza la cadena codificada con la cadena decodificada en el mensaje original
    message = message.replace(encoded, decoded);
  }

  // Devuelve el mensaje decodificado
  return message;
}
Enter fullscreen mode Exit fullscreen mode

Soluciones de la comunidad

Solución por cristianstu:

function decode(message) {
  const msg = message.replace(/\(([^()]*)\)/g, (_, match) => 
    match.split('').reverse().join('')
  );

  return msg.includes('(') ? decode(msg) : msg
}
Enter fullscreen mode Exit fullscreen mode

Solución por TimmyElTaco:

function decode(message) {
  let matches = [];

  while (matches = message.match(/\(([^()]*)\)/)) {
    matches = matches.map((word) => {
      return word.split('').reverse().join('')
    })
    let string = matches[0].replace(/[()]/g, '');
    message = message.replace(/\(([^()]*)\)/, string);
  }

  return message;
}
Enter fullscreen mode Exit fullscreen mode

Y ese fue el reto para el 4 de diciembre y sus soluciones. ¿Tienes otra solución alternativa? ¡Déjala en los comentarios!

Top comments (2)

Collapse
 
ignaciovigo profile image
ignaciovigo

utilizando una pila (stack)

function decode(message) {
const stack = ['']
for(let char of message){
  if(char === '('){
    stack.push('')
  }else if (char === ')'){
    let last = stack.pop()
    stack[stack.length - 1] += last.split('').reverse().join('')
  } else{
    stack[stack.length - 1] += char
  }
}
return stack[0]
}

Enter fullscreen mode Exit fullscreen mode
Collapse
 
fenriuz profile image
Fenriuz

Interesante solución, Ignacio. No había pensado en un enfoque utilizando una pila
Gracias por compartirla!