type Posicion = [Int]
type Jugada = (Int, Int)

jugar          :: Posicion -> Jugada -> Posicion
jugar p (i, n) = quitar 0 (reemplazarEnésimoElemento i (p !! (i - 1) - n) p)

posiblesJugadas   :: Posicion -> [Jugada]
posiblesJugadas p = auxiliarPosiblesJugadas p (length p)

esPosicionGanadora   :: Posicion -> Bool
esPosicionGanadora p = algunaEsJugadaGanadora p (posiblesJugadas p)

jugadaGanadora   :: Posicion -> Jugada
jugadaGanadora p = cualJugadaEsGanadora p (posiblesJugadas p)

numeroDeJugadasGanadoras   :: Posicion -> Int
numeroDeJugadasGanadoras p = contarJugadasGanadoras p (posiblesJugadas p)

-------------- Funciones Auxiliares --------------

quitar                      :: Int -> [Int] -> [Int]
quitar _   []               = []
quitar n (x:xs) | x == n    = xs
                | otherwise = x:quitar n xs

reemplazarEnésimoElemento                        :: Int -> Int -> [Int] -> [Int]
reemplazarEnésimoElemento _ _   []               = []
reemplazarEnésimoElemento i n (x:xs) | i == 1    = n:xs
                                     | otherwise = x:reemplazarEnésimoElemento (i - 1) n xs

auxiliarPosiblesJugadas      :: Posicion -> Int -> [Jugada]
auxiliarPosiblesJugadas [] _ = []
auxiliarPosiblesJugadas p n = (posiblesJugadasEnUnMontoncito n (last p))
                               ++ 
                              (auxiliarPosiblesJugadas (init p) (n - 1))

posiblesJugadasEnUnMontoncito     :: Int -> Int -> [Jugada]
posiblesJugadasEnUnMontoncito i 1 = [(i, 1)]
posiblesJugadasEnUnMontoncito i n = (i, n):posiblesJugadasEnUnMontoncito i (n - 1)

algunaEsJugadaGanadora          :: Posicion -> [Jugada] -> Bool
algunaEsJugadaGanadora _   []   = False
algunaEsJugadaGanadora p (j:js) = not (esPosicionGanadora (jugar p j)) || algunaEsJugadaGanadora p js

cualJugadaEsGanadora                                                 :: Posicion -> [Jugada] -> Jugada
cualJugadaEsGanadora p (j:js) | not (esPosicionGanadora (jugar p j)) = j
                              | otherwise                            = cualJugadaEsGanadora p js

contarJugadasGanadoras                                                 :: Posicion -> [Jugada] -> Int
contarJugadasGanadoras _   []                                          = 0
contarJugadasGanadoras p (j:js) | not (esPosicionGanadora (jugar p j)) = 1 + contarJugadasGanadoras p js
                                | otherwise                            = contarJugadasGanadoras p js