2016-10-18 1 views
1
#(take % 
    (map first 
    (iterate (fn [[i1 i2]] 
       [i2 (+ i1 i2)]) 
      [1 1]))) 

Ceci est une fonction permettant de générer des séquences de fib en clojure. Je ne comprends pas cette partie:Clojure fibonacci

(fn [[i1 i2]] 
      [i2 (+ i1 i2)]) 
      [1 1]) 

de [i2 i1] à [i2 (+ i2 i1)]. comment fait cette séquence continue de croître? il me semble que c'est toujours 2 éléments. besoin d'aide. Merci!

+0

Je pense que ce n'est pas tout à fait en double parce que c'est plus spécifique. –

+0

Il semble confus en raison de la mauvaise indentation. On dirait que le corps de la fonction interne et le second argument de 'itérer' sont au même niveau. – Svante

+0

Correction de la mise en forme –

Répondre

3

la fonction

(fn [[i1 i2]] 
    [i2 (+ i1 i2)]) 

prend dans une étape de la séquence et produit l'étape suivante du processus. Chaque appel produit donc un pas de plus dans la séquence. C'est une solution intermédiaire où chaque étape comporte deux éléments. Le premier élément est la réponse jusqu'à présent, et le second fournit suffisamment de contexte pour produire l'étape suivante. de sorte que la sortie ressemblerait à ceci:

user> (take 5 
      (iterate (fn [[i1 i2]] 
         [i2 (+ i1 i2)]) 
        [1 1])) 
([1 1] [1 2] [2 3] [3 5] [5 8]) 

Puis un stade ultérieur prend cette séquence entière et supprime les informations supplémentaires ne laissant que les réponses de chaque étape.

user> (map first 
      (take 5 
       (iterate (fn [[i1 i2]] 
          [i2 (+ i1 i2)]) 
          [1 1]))) 
(1 1 2 3 5) 

Ceci est une bonne application pour diviser un problème en parties séparables et ensuite composer ces pièces pour former la réponse finale.

1

La fonction passée à iterate est

(fn [[i1 i2]] 
    [i2 (+ i1 i2)]) 

Toutes les fonctions ne sont générer le terme suivant dans la séquence donnée d'un précédent (à l'aide de correspondance de modèle pour attribuer les noms i1 et i2 pour les membres de la vecteur transmis).

iterate prend deux arguments, la fonction qui génère le terme suivant dans la séquence, et la valeur de départ pour la séquence. La fonction iterate est chargée de générer la séquence paresseuse.

Pour un exemple plus facile (sans le motif de correspondance), on peut générer une séquence paresseux d'entiers positifs avec

(iterate inc 0) 
0

Vous avez raison. La fonction ...

(fn [[i1 i2]] [i2 (+ i1 i2)]) 

... produit une paire de nombres d'un autre. Par exemple,

((fn [[i1 i2]] [i2 (+ i1 i2)]) [6 19]) 

; [19 25] 

Son iterate qui produit la séquence, en appliquant de façon répétée la fonction. On obtient ainsi une séquence de paires:

(iterate (fn [[i1 i2]] [i2 (+' i1 i2)]) [1 1]) 

;([1 1] [1 2] [2 3] [3 5] [5 8] [8 13] [13 21] ...) 

Le premier ou le second éléments de ces paires forment une séquence de Fibonacci, selon l'endroit où vous voulez commencer.Pour obtenir l'ancien, nous venons envelopper ci-dessus dans (map first ...): Bien que cette question est très

(map first (iterate (fn [[i1 i2]] [i2 (+' i1 i2)]) [1 1])) 

;(1 1 2 3 5 8 13 21 ...) 

Si vous êtes familier avec le ->> macro filetage, vous trouverez peut-être plus facile à lire comme

(->> [1 1] 
    (iterate (fn [[i1 i2]] [i2 (+ i1 i2)])) 
    (map first)) 

;(1 1 2 3 5 8 13 21 ...)