He estado aprendiendo algo de Haskell, y estoy haciendo proyectos de problemas de Euler a medida que avanzo. Realmente no me molesta la respuesta al problema de Euler (que felizmente puedo usar como fuerza bruta, o hacerlo en otro idioma), sino el método.Memoization & Project Euler Problema 15 en Haskell
Estoy atascado en hacer el problema 15 en un tiempo razonable. Solicita la cantidad de rutas que no retroceden desde la parte superior izquierda hasta la parte inferior derecha de una cuadrícula de 20x20. Link here
Yo diría que es bastante obvio que la idea es memorizar (sp?) La función, pero no estoy seguro de cómo hacerlo. Busqué en Google y encontré this en Haskell Cafe que ingenuamente intentado adaptarse, pero terminó con:
memRoute :: (Int,Int) -> Int
memRoute (x,y) = fromJust $ lookup (x,y) $ map (\t -> (t,route t)) [(x,y) | x <- [0..20], y <- [0..20]]
route (0,0) = 0
route (_,0) = 1
route (0,_) = 1
route (x,y) = memRoute (x-1,y) + memRoute (x,y-1)
¿Qué se ve mal, y realiza horrible (mucho más lento que una versión ingenua). El problema es que realmente no entiendo cómo funciona la memoria de Haskell.
Usando mi código como un ejemplo, alguien le importa explicar a) por qué la mía es tan lento
b) la forma en que debe hacerse (sin utilizar mutables, que era una solución que me encontré)
c) cómo la memorización funciona en este caso?
Aún no he leído su programa, pero quería hacerle saber que existe una solución O (1) inteligente. Ver http://www.haskell.org/haskellwiki/Euler_problems/11_to_20#Problem_15 –
De manera más general, este es un problema de combinatoria enumerativa. La solución prevista no es en realidad el tiempo constante, la aritmética no es gratuita, especialmente cuando se trata de factoriales, pero sin duda es mucho más eficiente que iterar en cada ruta. –
Ese problema es horrible ... Todavía lo recuerdo ... y los intentos de fuerza bruta lo fuerzan. Honestamente, quién puede pensar en el triángulo de Pascal cuando ven ese problema :) – Jerome