Comment detail

逆順になるあみだくじ (Nested Flatten)
再帰つらい…orz
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
(define (bars n)
  (define (limit i j) (<= (+ i j) (* 2 (- n 1))))
  (define (oddp n) (= (remainder n 2) 1))
  (define (append0 i j result)
    (if (limit i j)
      (cons (cons i j) result)
      result))
        
  (define (rec i j result)
    (cond ((<= i (* 2 (- n 1)))
           (if (<= j i)
             (rec i (+ j 2) (append0 i j result))
             (rec (+ i 1) (if (oddp (+ i 1)) 1 2) result)))
          (else
           result)))
  (rec 1 1 ()))

(define (draw n bars)
  (define (empty i)
    (cond ((<= i n)
           (display "| ")
           (empty (+ i 1)))
          (else
           (display "\n"))))
  (define (rec i j)
    (cond ((<= j n)
           (cond ((<= i (* 2 (- n 1)))
                  (display "|")
                  (display (if (member (cons i j) bars) "-" " "))
                  (rec i (+ j 1)))
                 (else
                  'ok)))
          (else
           (display "\n")
           (rec (+ i 1) 1))))
  (empty 1)
  (rec 1 1))

(define (amida n) (draw n (bars n)))
同じアルゴリズムをモダンなSchemeっぽく書き直してみました。数値でループを回すならsrfi-42のcomprehensionが圧倒的に楽です。また、Schemeといえば再帰、ですが、実際のコードではmapやfoldなどの高階関数とかnamed letなどを使うことが圧倒的に多く、明示的な再帰はそんなに頻繁に出てきません(複雑な相互再帰とか、データ構造もツリーのように再帰的になっている場合など)。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
(use srfi-42)

(define (bars n)
  (define lim (- (* 2 n) 1))
  (append-ec (: i 1 lim)
             (: j (if (odd? i) 1 2) (+ i 1) 2)
             (if (<= (+ i j) lim) `((,i . ,j)) '())))

(define (draw n bars)
  (do-ec (: i (- (* 2 n) 1))
         (: j 1 (+ n 1))
         (format #t "|~a"
                 (cond [(= j n) "\n"]
                       [(member (cons i j) bars) "-"]
                       [else " "])))
  )

(define (amida n) (draw n (bars n)))

Index

Feed

Other

Link

Pathtraq

loading...