DEV Community

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

Posted on

AdventJS 2023: Reto del Día 11

Solución al reto #11 del AdventJS 2023

Solución del reto anterior

Solución del siguiente reto

Descripción del Reto

En el taller de Santa, los elfos aman los acertijos 🧠. Este año, han creado uno especial: un desafío para formar un palíndromo navideño.

Un palíndromo es una palabra que se lee igual hacia adelante y hacia atrás. Los elfos quieren saber si es posible formar un palíndromo haciendo, como mucho, un intercambio de letras.

Crea una función getIndexsForPalindrome que reciba una cadena de caracteres y devolverá:

  • Si ya es un palíndromo, un array vacío.
  • Si no es posible, null.
  • Si se puede formar un palíndromo con un cambio, un array con las dos posiciones (índices) que se deben intercambiar para poder crearlo. Por ejemplo:
getIndexsForPalindrome('anna') // []
getIndexsForPalindrome('abab') // [0, 1]
getIndexsForPalindrome('abac') // null
getIndexsForPalindrome('aaaaaaaa') // []
getIndexsForPalindrome('aaababa') // [1, 3]
getIndexsForPalindrome('caababa') // null
Enter fullscreen mode Exit fullscreen mode


javascript
Si se puede formar el palíndromo con diferentes intercambios, siempre se debe devolver el primero que se encuentre.

Análisis

En este reto nuestro objetivo es encontrar un palindromo intercambiando de lugar dos elementos del string y retornar el índice de esos dos elementos, de no encontrar un palindromo se retorna un array vacío.

Entrada

  1. Word(word): Un string con la palabra a evaluar.

Salida

  • Un array de dos elementos con los índices a cambiar para encontrar el palindromo
  • Si ya es un palindromo se retorna un array vacío
  • Si no se cumplen ninguna de las dos anteriores se retorna null

Consideraciones

  • Si se pueden formar varios palindromos siempre debemos devolver el primero en ser encontrado.

Solución

Se puede solucionar recorriendo cada elemento del string, y dentro de esa iteración volverlo a recorrer e ir intercambiando elementos para comparar.

Código

/**
 * Devuelve los índices de los caracteres que deben invertirse para hacer que una palabra sea un palíndromo.
 *
 * @param {string} word - La palabra para verificar sus propiedades palindrómicas.
 * @return {number[] | null} - Un array de dos índices que representan los caracteres a invertir, o null si no existen dichos índices.
 */
function getIndexsForPalindrome(word) {
  // Verifica si la palabra dada ya es un palíndromo
  const isPalindrome = (s) => s === s.split("").reverse().join("");

  // Si la palabra ya es un palíndromo, devuelve un array vacío
  if (isPalindrome(word)) {
    return [];
  }

  // Itera a través de todas las posibles combinaciones de índices
  for (let i = 0; i < word.length; i += 1) {
    for (let j = i + 1; j < word.length; j += 1) {
      // Crea una nueva palabra intercambiando los caracteres en los índices i y j
      const newWord =
        word.substring(0, i) +
        word[j] +
        word.substring(i + 1, j) +
        word[i] +
        word.substring(j + 1);

      // Si la nueva palabra es un palíndromo, devuelve los índices i y j
      if (isPalindrome(newWord)) {
        return [i, j];
      }
    }
  }

  // Si no existen dichos índices, devuelve null
  return null;
}
Enter fullscreen mode Exit fullscreen mode

Soluciones de la comunidad

Solución por iswilljr:

function getIndexsForPalindrome(word: string) {
  const _letters = [...word]
  const palindrome = word === [..._letters].reverse().join('')

  let initial: number[] | null = [null, []][+palindrome]
  let index = 0
  let aux = 1

  const letters = [_letters, []][+palindrome]
  let auxLetters = letters.slice(1)

  for (const letter of letters) {
    for (const auxLetter of auxLetters) {
      const w = [...letters]
      w[index] = auxLetter
      w[aux] = letter

      const isPalindrome = +(w.join('') === w.reverse().join(''))
      const isInitialNull = +(initial == null)
      const isDifferentIndex = +(index !== aux)

      const values = [initial, initial, initial, [index, aux]]

      initial = values[isInitialNull + isDifferentIndex + isPalindrome]
      aux++
    }

    index++
    aux = 1
    auxLetters = [[], auxLetters][+(initial == null)]
  }

  return initial
}
Enter fullscreen mode Exit fullscreen mode

Solución por Achalogy:

function getIndexsForPalindrome(word) {
  let res: any = null
  for (const a of Array.from({ length: word.length }).keys()) {
    for (const b of Array.from({ length: word.length }).keys()) {
      let swapped = [...word]
      let aux = word[a]
      swapped[a] = word[b]
      swapped[b] = aux

      let left = swapped.slice(0, Math.floor(word.length / 2)).join("")
      let right = swapped.slice(Math.ceil(word.length / 2)).reverse().join("")

      res = [
        [
          null
          , [
            []
            , [a, b]
          ][+((a + b) > 0)]
        ][+(left == right)]
        , res
      ][+!!res]
    }
  }
  return res
}
Enter fullscreen mode Exit fullscreen mode

Y ese fue el reto para el 11 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!

Top comments (0)