ちょっと面白いものを見つけた。
cf. 「Haskell」で「Look and Say 数列」を生成してみた – Zodiacの黙示録
Look and Say 数列とは次のようなものらしい。
1 11 21 1211 111221 ...
ちょっと規則性が見いだせないが、
- 最初の項は「1」
- 次の項は直前の項を見る(look)。すると「1」個の「1」。
- なので「11」と言う(say)。
- さらに次の項は直前の項を見て、「2」個の「1」。
- なので「21」と言う。
- 以下繰り返し
となっている。
リンク先では Haskell でやっているので、Scheme でやってみた。Haskell と違って無限リストは扱えないので、スクリプトの引数で生成する数列の数を指定するようにした。
(use srfi-1) (use gauche.sequence) (define main (lambda (args) (let ((count (string->number (cadr args)))) (print (look-and-say count))))) (define look-and-say (lambda (count) (unfold (lambda (seed) (zero? (car seed))) (lambda (seed) (cadr seed)) (lambda (seed) (list (- (car seed) 1) (las (cadr seed)))) (list count "1")))) (define las (lambda (s) (let ((ls (group-sequence s))) (apply string-append (append-map (lambda (e) (list (write-to-string (length e)) (string (car e)))) ls)))))
unfold
のために srfi-1
を、group-sequence
のために gauche.sequence
を読み込んでいる。group-sequence
はリストや文字列といった sequence を、同じ値ごとにグループ化する手続き。こんな感じ:
gosh> (group-sequence "aabccdddee") ((#\a #\a) (#\b) (#\c #\c) (#\d #\d #\d) (#\e #\e))
さて、実行してみよう。
takatoh@apostrophe $ gosh look-and-say.scm 8 (1 11 21 1211 111221 312211 13112221 1113213211)
うまくいったようだ。