Skip to content

Instantly share code, notes, and snippets.

@denlab
Created September 21, 2011 12:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save denlab/1231894 to your computer and use it in GitHub Desktop.
Save denlab/1231894 to your computer and use it in GitHub Desktop.
coding-dojo-20110921
(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])
@cgrand
Copy link

cgrand commented Sep 21, 2011

L3 bon choix le vecteur vide.
L7 mauvais choix le cons, ici on travaille avec une collection concrète, conj est mieux
L3 du coup la form loop évalue à un vecteur
L2 et on peut appeler rseq sur le vecteur pour le retourner... sauf que comme un vecteur a été utilisé, même pas besoin.

L6 alternativemen (some #(zero? (rem candidate %)) acc)

@denlab
Copy link
Author

denlab commented Sep 21, 2011

cool le conseil d'un maitre!

L7 oui c'est en CLisp qu'on fait ca et oblige de renverser la liste, mais en clojure pas besoin
L6 oui plus concis avec some?

mais on ne pourrait pas utiliser une lazy seq plutot ? avec iterate ?

@cgrand
Copy link

cgrand commented Sep 21, 2011

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.

@laurentpetit
Copy link

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

@laurentpetit
Copy link

Ah oui, en haut de votre fonction, il y a un nil qui traîne

@denlab
Copy link
Author

denlab commented Sep 22, 2011 via email

@denlab
Copy link
Author

denlab commented Sep 22, 2011 via email

@laurentpetit
Copy link

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 ...)

@cgrand
Copy link

cgrand commented Sep 23, 2011

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."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment