2016-12-10 6 views
2

機能に通常の方法を生成するこのCollat​​zシーケンスを書いた後:スキル/ラケットでアンフォールドを使用してCollat​​zシーケンスを書き込む方法は?

(define (colatz-seq #;[email protected] n) 
    (cond ((= n 1) '()) 
     ((even? n) (cons (/ n 2) (colatz-seq (/ n 2)))) 
     ((odd? n) (cons (+ (* n 3) 1) (colatz-seq (+ (* n 3) 1)))))) 

は、私が展開使用して、それを書きたい:

(define (next-colatz-step n) 
    (cond ((even? n) (/ n 2)) 
     ((odd? n) (+ (* n 3) 1)))) 

(define (one? n) 
    (= n 1)) 

(define (colatz-seq #;[email protected] n) 
    (unfold one? next-colatz-step next-colatz-step n)) 

をそして、それは予想通りしかし、私はそれをせずに動作させることができなかった作品"next-colatz-step"を2番目と3番目の展開のパラメータとして使用します。どうして? 2つのパラメータに同じ引数を与えるのはちょっと奇妙なようです。

答えて

2

シーケンスの開始要素を除外しており、unfoldベースのソリューションでは、生成されたシーケンスが何らかの形で1つの位置に遅れていることに注意してください。そのため、next-colatz-stepを2回渡す必要があります。

nの番号から始めると、unfoldの2番目の引数はidentityの手順に過ぎず、より自然なようです。しかしそれは、最後の値(Collat​​zの推測が真であると仮定した場合、常に1であるべきである)が失われているという問題を残す。そのため、リストの末尾を生成するための追加手順を提供する必要があります。

(require srfi/1) 

(define (one? n) 
    (= n 1)) 

(define (next-collatz-step n) 
    (cond ((even? n) (/ n 2)) 
     (else (+ (* 3 n) 1)))) 

(define (last-value n) 
    (list n)) 

(define (collatz-seq n) 
    (unfold one? identity next-collatz-step n last-value)) 

(collatz-seq 10) 
=> '(10 5 16 8 4 2 1) 
+0

理由ん::このお試しください '()(1つのnを定義 (リスト1))を' がPARAM nとして、それを使用していないにも厳しいがありますか? – X10D

+0

@ X10Dこれは、 'unfold'が最後の引数としてone-arg手続きを期待しているからですが、最後の値が' 1'であることが既に分かっています。しかし、再帰関数 'n' _is_' 1'のその時点でパラメータを使用するように更新しました。 –

関連する問題