2016-12-10 3 views
2

기능을 일반적인 방법으로 생성 Collatz 시퀀스를 작성 후 :스키마/라켓에서 펼치기를 사용하여 Collatz 시퀀스를 작성하는 방법은 무엇입니까?

(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

두 솔루션에서 시퀀스의 시작 요소를 제외하고 unfold 기반 솔루션의 경우 생성 된 시퀀스가 ​​어느 정도 위치가 뒤떨어져 있으므로 next-colatz-step을 두 번 통과해야합니다.

n 숫자부터 시작하면 unfold의 두 번째 인수는 identity 절차 일 뿐이므로보다 자연 스럽습니다. 그러나 이것은 우리에게 마지막 값 (항상 1이어야하며, Collatz 추측이 사실이라고 가정 할 때)이 없어지는 문제점을 안겨줍니다. 그래서 이제 목록 꼬리 생성을위한 추가 절차를 제공해야합니다. 이 시도 :

(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

왜 않습니다 가'((하나 N) (목록 1) 정의)' 이 PARAM로 N이조차 힘든 그것을 사용하지 않는거야? – X10D

+0

@ X10D는 'unfold'가 마지막 인수로 one-arg 프로 시저를 기대하기 때문에 발생하지만, 마지막 값은 '1'이어야한다는 것을 이미 알고 있습니다. 그러나 재귀 함수'n' _is_'1'의 그 시점에서 매개 변수를 사용하도록 업데이트했습니다. –

관련 문제