Aquí hay una manera de resolver el problema 43 de Euler (por favor, avíseme si esto no da la respuesta correcta). ¿Hay una mónada o algún otro azúcar sintáctico que pueda ayudar a hacer un seguimiento de las condiciones de notElem
?Euler 43: ¿hay alguna mónada para ayudar a escribir esta lista de comprensión?
toNum xs = foldl (\s d -> s*10+d) 0 xs
numTest xs m = (toNum xs) `mod` m == 0
pandigitals = [ [d0,d1,d2,d3,d4,d5,d6,d7,d8,d9] |
d7 <- [0..9],
d8 <- [0..9], d8 `notElem` [d7],
d9 <- [0..9], d9 `notElem` [d8,d7],
numTest [d7,d8,d9] 17,
d5 <- [0,5], d5 `notElem` [d9,d8,d7],
d3 <- [0,2,4,6,8], d3 `notElem` [d5,d9,d8,d7],
d6 <- [0..9], d6 `notElem` [d3,d5,d9,d8,d7],
numTest [d6,d7,d8] 13,
numTest [d5,d6,d7] 11,
d4 <- [0..9], d4 `notElem` [d6,d3,d5,d9,d8,d7],
numTest [d4,d5,d6] 7,
d2 <- [0..9], d2 `notElem` [d4,d6,d3,d5,d9,d8,d7],
numTest [d2,d3,d4] 3,
d1 <- [0..9], d1 `notElem` [d2,d4,d6,d3,d5,d9,d8,d7],
d0 <- [1..9], d0 `notElem` [d1,d2,d4,d6,d3,d5,d9,d8,d7]
]
main = do
let nums = map toNum pandigitals
print $ nums
putStrLn ""
print $ sum nums
Por ejemplo, en este caso la asignación a d3
no es óptima - lo que realmente debe ser trasladado a justo antes de la prueba numTest [d2,d3,d4] 3
. Hacer eso, sin embargo, significaría cambiar algunas de las pruebas notElem
para eliminar d3
de la lista que se está verificando. Dado que las sucesivas listas notElem
se obtienen con solo incluir el último valor elegido en la lista anterior, parece que esto debería ser factible, de alguna manera.
ACTUALIZACIÓN: Aquí está el programa anterior re-escrito con Louis' UniqueSel
mónada a continuación:
toNum xs = foldl (\s d -> s*10+d) 0 xs
numTest xs m = (toNum xs) `mod` m == 0
pandigitalUS =
do d7 <- choose
d8 <- choose
d9 <- choose
guard $ numTest [d7,d8,d9] 17
d6 <- choose
guard $ numTest [d6,d7,d8] 13
d5 <- choose
guard $ d5 == 0 || d5 == 5
guard $ numTest [d5,d6,d7] 11
d4 <- choose
guard $ numTest [d4,d5,d6] 7
d3 <- choose
d2 <- choose
guard $ numTest [d2,d3,d4] 3
d1 <- choose
guard $ numTest [d1,d2,d3] 2
d0 <- choose
guard $ d0 /= 0
return [d0,d1,d2,d3,d4,d5,d6,d7,d8,d9]
pandigitals = map snd $ runUS pandigitalUS [0..9]
main = do print $ pandigitals
estoy recibiendo un error de tipo: 'runUS choices' es una función' [Int] - > [([Int], a0)] ', pero el compilador espera simplemente' [([Int], a)] ' – ErikR
El' (opciones de runUS) 'debería haber sido' (runUS m options) ' – pat
Además, es 'guard' de' Control.Monad'? Si es así, ¿qué 'mzero' sería para' UniqueSel'? – ErikR