コラッツ予想がとけたらいいな2

自分の考察を書いていきます。

Egisonの練習その2

パターンマッチを使う関数を3つほど。

データコンストラクタを外す関数。

(define $mcer
  (algebraic-data-matcher
    {<a integer> <b integer>}))
(define $cut
  (lambda $xs
    (match xs mcer
      {[<a $x> x]
       [<b $x> x]})))

> (cut <A 6>)
6
> (cut <B 7>)
7
> (cut <C 7>)
Error: failed pattern match
>

1個以上の連続したデータにマッチする関数。

(define $any-series
  (lambda [$x $xs]
    (if (eq? x (car xs))
      (match xs (list something)
        {[(loop $i [1 $n] <cons ,x ...> (| <cons ^,x _> <nil>))
          (take n (repeat1 x)) ] })
      (if (empty? (cdr xs)) {} (any-series x (cdr xs))))))

> (any-series 3 {1 2 3 3 3 4})
{3 3 3}
> (any-series 5 {1 2 3 3 3 4})
{}
>

Haskellでいうgroupみたいなもの。

(define $group
  (lambda $xs
    (delete {}
      (match-all (append {{}} xs) (list something)
        [<join <snoc $x0 _>
               (loop $i [1 $n] <cons (& $x_i (& ^,x0 ,x_1)) ...>
                               (| <cons ^,x_1 _> <nil>)) >
         (take n (repeat1 x_1)) ] ))))

> (group {1 1 2 2 2 3 3})
{{1 1} {3 3} {2 2 2}}
> (group {1 1 2 2 2 3 3 4 5 5 5 5 5 5 5})
{{4} {1 1} {3 3} {2 2 2} {5 5 5 5 5 5 5}}
>

順番が変わってしまうのはご愛嬌。