Scheme どう書く?的お題を Squeak Smalltalk で
Scheme どう書く?的 - higepon blog 発で、整数リストの変形 - プログラミング日記 で提案された拡張版のお題を、ちょっと変わった方向性で。
関連クラスにメソッド「#,,」を定義(「#,」は使えないので、代わりに…)し、これを使ってリテラル風のリスト記述から圧縮済み配列を生成しています。
Object >> ,, other other ifNil: [^{self}]. ^{self to: other by: other - self} SequenceableCollection >> ,, element ^self allButLast, (self last,, element) Interval >> ,, element stop + step = element ifTrue: [stop := element. ^{self}]. self size = 2 ifTrue: [^super,, element]. element ifNil: [^{self}]. ^{self. element}
実行例
1,, 3,, 4,, 5,, 6,, 12,, 13,, 15,, nil "=> {1 . (3 to: 6) . 12 . 13 . 15} "
1,, 4,, 6,, 8,, 9,, 10,, 11,, 12,, 15,, nil "=> {1 . (4 to: 8 by: 2) . (9 to: 12) . 15} "
関連:
拡張前のお題を同じ方針で書いたものも。
Integer >> ,, other ^other - self = 1 ifTrue: [{self to: other}] ifFalse: [{self. other}] SequenceableCollection >> ,, elem ^self allButLast, (self last,, elem) Interval >> ,, elem ^stop + step = elem ifTrue: [stop := elem. {self}] ifFalse: [{self. elem}]
1,, 3,, 4,, 5,, 6,, 12,, 13,, 15 "=> {1 . (3 to: 6) . (12 to: 13) . 15} "
ほぼ似たような動きを Gauche で。
(use srfi-1) (define (compact-number-list lst) (letrec ([compact-cons (lambda (a b) (cond [(number? b) (if (= (- a b) 1) `((,b . ,a)) `(,a ,b))] [(list? b) (append (compact-cons a (car b)) (cdr b))] [(pair? b) (if (= (- a (cdr b)) 1) `((,(car b) . ,a)) `(,a ,b))]))]) (reverse (reduce compact-cons () lst)))) (compact-number-list '(1 3 4 5 6 12 13 15)) ;;=> (1 (3 . 6) (12 . 13) 15)