bowling scoreler

計算部分だけ。golferではないのでそんなに短くない。
haskellなどにあるasパターンを使う方法はないのかな?
せっかく、matchを使っているのにも関わらずcdrとかcddrとやっているのは不思議な感じがする。
xs@(y . z .rest)とするとsymbolの解析もしなければいけなくなってしまうのか。
asパターンのようなものが使えないのはしかたがないことなのかもしれない。

(use srfi-1)
(use util.match)

(define (scorer seqs)
  (define (update x scores) (cons (+ x (car scores)) scores))
  (define (end scores) (cdr (reverse scores)))
  (let loop ((scores '(0)) (i 0) (seqs seqs))
    (cond ((>= i 10) (end scores))
	  (else (match seqs
		  [(x) (end (update x scores))]
		  [(x y) (end (update (+ x y) scores))]
		  [(10 x y . rest) (loop (update (+ 10 x y) scores) (+ i 1) (cdr seqs))]
		  [(x y z . rest)
		   (let1 v (if (= 10 (+ x y)) (+ x y z) (+ x y))
		     (loop (update v scores) (+ i 1) (cddr seqs)))])))))

(let1 l '(10 10 10 10 10 10 10 10 10 10 10 10)
  (scorer l)) ; => (30 60 90 120 150 180 210 240 270 300)
(let1 l '(10 9 1 8 1 7 3 5 2 8 1 4 6 8 2 10 9 1 3)
  (scorer l)) ; => (20 38 47 62 69 78 96 116 136 149)
(let1 l '(10 10 10 0 8 10 10 0 0 7 0 6 2 9 0)
  (scorer l)) ; => (30 50 68 76 96 106 106 113 121 130)

追記

コメントでandを使えばasパターンと同じことができると教えてもらいました。
それを使うと以下のように書けます。

	  (else (match seqs
		  [(10 . (and (x y . _) next-seqs)) 
		   (loop (update (+ 10 x y) scores) (+ i 1) next-seqs)]
		  [(x y . (and (z . _) next-seqs))
		   (let1 v (if (= 10 (+ x y)) (+ x y z) (+ x y))
		     (loop (update v scores) (+ i 1) next-seqs))])))))
...

今までmatchを使ったときに感じていたフラストレーションが解消されました。

dancing kid

(use util.match)
(use text.tree)

(match-define (h b t) '("('-')" "|_|" " | |"))
(write-tree
 ((match-lambda
  ["left" `(,h "/\n/" ,b "\n" ,t "")]
  ["right" `("\\" ,h "\n " ,b "\\\n" ,t)]
  ["right&left" `("\\" ,h "/\n " ,b "\n" ,t)])
  (read-line)))

e

実数で100桁まで出す方法わからない。

(use gauche.collection)
(use srfi-42)
(define (f len)
  (+ 1 (sum-ec (: n (map-accum (lambda (i p) (let1 i* (* i p) (values i* i*))) 1 (iota len 1)))
	       (/ 1 n))))
(f 100) ; => 4299778907798767752801199122242037634663518280784714275131782813346597523870956720660008227544949996496057758175050906671347686438130409774741771022426508339/1581800261761765299689817607733333906622304546853925787603270574495213559207286705236295999595873191292435557980122436580528562896896000000000000000000000000