Voici un problème de programmation simple de SPOJ: http://www.spoj.com/problems/PROBTRES/ .
Fondamentalement, vous êtes invité à sortir le plus grand cycle de Collatz pour les nombres entre i et j. (Le cycle de Collatz d'un nombre $ n $ est le nombre d'étapes pour éventuellement passer de $ n $ à 1.)
Je cherchais un moyen Haskell pour résoudre le problème avec des performances comparatives à celles de Java ou C ++ (afin de s'adapter à la limite d'exécution autorisée). Bien qu'une solution Java simple qui mémorise la durée des cycles déjà calculés fonctionnera, je n'ai pas réussi à appliquer l'idée d'obtenir une solution Haskell.
J'ai essayé le Data.Function.Memoize, ainsi que la technique de mémorisation du temps de connexion brassée à la maison en utilisant l'idée de ce post: /programming/3208258/memoization-in-haskell . Malheureusement, la mémorisation rend en fait le calcul du cycle (n) encore plus lent. Je crois que le ralentissement vient des frais généraux de la voie Haskell. (J'ai essayé de courir avec le code binaire compilé, au lieu d'interpréter.)
Je soupçonne également que la simple itération des nombres de i à j peut être coûteuse ($ i, j \ le10 ^ 6 $). J'ai donc même essayé de tout précalculer pour la requête de plage, en utilisant l'idée de http://blog.openendings.net/2013/10/range-trees-and-profiling-in-haskell.html . Cependant, cela donne toujours l'erreur "Time Limit Exceeding".
Pouvez-vous aider à informer un programme Haskell compétitif soigné pour cela?