-
-
Save denlab/1231894 to your computer and use it in GitHub Desktop.
(defn primes [n] nil | |
(reverse | |
(loop [candidate 2 current n acc []] | |
(if (zero? current) | |
acc | |
(if (every? #(not= 0 (rem candidate %)) acc) | |
(recur (inc candidate) (dec current) (cons candidate acc)) | |
(recur (inc candidate) current acc)))))) | |
(fact | |
(primes 1) => [2] | |
(primes 2) => [2 3] | |
(primes 3) => [2 3 5]) |
Je me suis amusé à faire une version lazy, sans chercher à modifier l'algorithme initial (donc c'est du lazy qui retient la head, pire, qui double la taille de la liste en memoire. Mais c'est du lazy :-) ) : https://gist.github.com/1233437
Ah oui, en haut de votre fonction, il y a un nil qui traîne
avec iterate, je ne vois pas comment faire pour passer l'accumulateur. A moins que le iterate itere autour du couple (candidate / accumulateur ), et que l'iterate soit "coiffé" par un map qui retourne à chaque niveau le (first) de l'accumulateur :
(map (comp first second) (iterate (fn [[candidate acc]] ....) [2 []])
mais ca commence p-e alors à faire beaucoup de créations d'objets intermédiaires (enfin tant qu'on n'a pas mesuré, bien sûr ...)
Menfin le décompte des objets intermédiaires quand on utilise un algo naïf c'est pas important. Là on est dans une approche parnassienne du code. https://gist.github.com/1236838#comments
"Le code pour le code."
L6 je tends à choisir les formulations qui ont le moins de négations. Ensuite je préfère favoriser les fonctions qui renvoient une valeur par rapport aux prédicats purs qui renvoient des booléens. Ca se marie très bien avec un if-let.
Une solution lazy est toujours possible mais pas forcément plus simple. J'en vois deux, une "matheuse" et une "hackeuse". Bonne nuit.