Menu Close

Espirales

Definir la función

   espiral :: Int -> [[Int]]

tal que (espiral n) es la espiral de orden n (es decir, con n filas y n columnas). Por ejemplo,

   λ> mapM_ print (espiral 5)
   [1,1,1,1,1]
   [0,0,0,0,1]
   [1,1,1,0,1]
   [1,0,0,0,1]
   [1,1,1,1,1]
   λ> mapM_ print (espiral 6)
   [1,1,1,1,1,1]
   [0,0,0,0,0,1]
   [1,1,1,1,0,1]
   [1,0,0,1,0,1]
   [1,0,0,0,0,1]
   [1,1,1,1,1,1]
   λ> mapM_ print (espiral 7)
   [1,1,1,1,1,1,1]
   [0,0,0,0,0,0,1]
   [1,1,1,1,1,0,1]
   [1,0,0,0,1,0,1]
   [1,0,1,1,1,0,1]
   [1,0,0,0,0,0,1]
   [1,1,1,1,1,1,1]
   λ> mapM_ print (espiral 8)
   [1,1,1,1,1,1,1,1]
   [0,0,0,0,0,0,0,1]
   [1,1,1,1,1,1,0,1]
   [1,0,0,0,0,1,0,1]
   [1,0,1,0,0,1,0,1]
   [1,0,1,1,1,1,0,1]
   [1,0,0,0,0,0,0,1]
   [1,1,1,1,1,1,1,1]

Nota: La serpiente (formada por los 1) nunca se puede tocar a ella misma.

Soluciones

import Data.List (transpose)
 
espiral :: Int -> [[Int]]
espiral n = espiralAux n n
 
espiralAux :: Int -> Int -> [[Int]]
espiralAux 0 _ = []
espiralAux 1 1 = [[1]]
espiralAux n m = primeraFila n : segundaFila n : filasDesdeTercera n m
 
-- (primeraFila n) es la primera fila de la espiral de orden n. Por
-- ejemplo,
--    λ> primeraFila 5
--    [1,1,1,1,1]
primeraFila :: Int -> [Int]
primeraFila n = replicate n 1
 
-- (segundaFila n) es la segunda de la espiral de orden n. Por
-- ejemplo,
--    λ> segundaFila 5
--    [0,0,0,0,1]
segundaFila :: Int -> [Int]
segundaFila n = replicate (n-1) 0 ++ [1]
 
-- (filasDesdeTercera n m), cuando n = m, es la lista de las filas de la
-- espiral de orden n a partir de la tercera. Por ejemplo,
--    λ> mapM_ print (filasDesdeTercera 5 5)
--    [1,1,1,0,1]
--    [1,0,0,0,1]
--    [1,1,1,1,1]
filasDesdeTercera :: Int -> Int -> [[Int]]
filasDesdeTercera n m = map reverse (transpose (espiralAux (m-2) n))

Nuevas soluciones

  • En los comentarios se pueden escribir nuevas soluciones.
  • El código se debe escribir entre una línea con <pre lang="haskell"> y otra con </pre>

Una solución de “Espirales

  1. Rubén Muñoz Mkrtchian
    -- Observamos que dentro de toda espiral de orden n está incluida una espiral
    -- de orden (n-2); sin embargo, esta aparece dada una vuelta de 180º. Así pues,
    -- la dificultad reside en definir dos casos base y en cómo añadir la primera y
    -- segunda filas, así como la última y penúltima columnas.
     
    espiral :: Int -> [[Int]]
    espiral 1 = [[1]]
    espiral 2 = [[1,1],[0,1]]
    espiral n = replicate n 1 : (replicate (n-1) 0 ++ [1]) : aux xss (n-2)
      where xss = map reverse (reverse (espiral (n-2)))
     
    -- La función aux completa las filas de la espiral de orden (n-2) para así
    -- conseguir las 2 últimas columnas deseadas de espiral n. Por ejemplo,
    --   λ> mapM_ print (aux [[1,1,1,1],[1,0,0,1],[1,0,0,0],[1,1,1,1]] 4)
    --   [1,1,1,1,0,1]
    --   [1,0,0,1,0,1]
    --   [1,0,0,0,0,1]
    --   [1,1,1,1,1,1]
     
    aux :: [[Int]] -> Int -> [[Int]]
    aux (xs:xss) n
      | n == 1 = [xs ++ [1,1]]
      | otherwise = (xs ++ [0,1]) : aux xss (n-1)
     
    -- ¡Muy original el ejercicio!

Leave a Reply

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.