はわわーっ

はわわわわっ

scheme で再帰とか

なんとなく scheme し始めたので勉強ついでにブログに書いていく。
再帰とか関数の定義とかそのへん。

(define (factorial n)
  (if (= n 0) 1
    (* n (factorial (- n 1)))))

(print (factorial 4))
;24

(define (double-factorial n)
  (cond
    ((= n 0) 1)
    ((= n 1) 1)
    (else (* n (double-factorial (- n 2))))))

(print (double-factorial 8))
;384
(print (double-factorial 7))
;105

(define (log2 n)
  (let loop ((m n) (c 0))
    (let ((q (quotient m 2)))
      (if (= q 0) c
        (loop q (+ c 1))))))

(print (log2 16))
;4
(print (log2 11))
;3
(print (log2 1))
;0

(define (my-length ls)
  (let loop ((ms ls) (c 0))
    (if (null? ms) c
      (loop (cdr ms) (+ c 1)))))

(print (my-length '(1 2 3 4)))
;4
(print (my-length '()))
;0

(define (my-reverse ls)
  (let loop ((ms ls) (ns ()))
    (if (null? ms) ns
      (loop (cdr ms) (cons (car ms) ns)))))

(print (my-reverse '(1 2 3 4 5)))
;(5 4 3 2 1)
(print (my-reverse '()))
;()

(define (my-sum ls)
  (let loop ((ms ls) (sum 0))
    (if (null? ms) sum
      (loop (cdr ms) (+ sum (car ms))))))

(print (my-sum '(1 2 3 4 5 6)))
;21
(print (my-sum '()))
;0

(define (my-replicate n a)
  (let loop ((m n) (ls ()))
    (if (= m 0) ls
      (loop (- m 1) (cons a ls)))))

(print (my-replicate 3 5))
;(5 5 5)
(print (my-replicate 5 #\a))
;(a a a a a)
(print (my-replicate 0 2))
;()

(define (my-range n)
  (let loop ((m n) (ls ()))
    (if (< m 0) ls
      (loop (- m 1) (cons m ls)))))

(print (my-range 9))
;(0 1 2 3 4 5 6 7 8 9)
(print (my-range 0))
;(0)
(print (my-range -2))
;()

(define (my-zip ls ms)
  (let loop ((xs ls) (ys ms))
    (if (or (null? xs) (null? ys)) ()
      (cons (list (car xs) (car ys)) (loop (cdr xs) (cdr ys))))))

(print (my-zip '(1 2 3) '(4 5 6)))
;((1 4) (2 5) (3 6))
(print (my-zip '(1 2 3) '(4)))
;((1 4))
(print (my-zip '() '(4 5 6)))
;()