列を1つ1つの要素としてではなく、かたまりの並びとして見たいことがあります。grouping、splitting、splitting.monotonicというボキャブラリーを使うと、そのための4つの方法が手に入ります。
group(サイズnの重なりのないかたまり)group ( seq n -- groups )
USING: grouping ;
{ 1 2 3 4 5 6 7 } 3 group .
! => { { 1 2 3 } { 4 5 6 } { 7 } }
列の長さがnの倍数でない場合、最後のかたまりはnより短くなります。
clump(サイズnの重なり合うスライド窓)clump ( seq n -- clumps )
USING: grouping ;
{ 1 2 3 4 5 } 2 clump .
! => { { 1 2 } { 2 3 } { 3 4 } { 4 5 } }
列がnより短い場合、結果は空になります。
split-when(述語が該当したところで区切る)split-when ( seq quot: ( elt -- ? ) -- pieces )
USING: splitting ;
{ 1 2 0 3 4 0 5 } [ zero? ] split-when .
! => { { 1 2 } { 3 4 } { 5 } }
各要素に対してそれぞれ述語が呼び出されます。真となる要素が区切り位置であり、結果には含まれません。
monotonic-split(隣り合うペアのチェックが失敗したところで連続を区切る)monotonic-split ( seq quot: ( a b -- ? ) -- pieces )
USING: splitting.monotonic ;
{ 1 1 2 2 2 3 } [ = ] monotonic-split .
! => { { 1 1 } { 2 2 2 } { 3 } }
述語は隣り合うペアに対して実行されます。真を返している間は同じ連続が続き、fを返すと新しいかたまりが始まります。[ = ]なら等しい要素の連続、[ <= ]なら減少しない連続、といった具合です。
group/clump:欲しいサイズがわかっているとき。split-when:区切りになる要素がどんなものかわかっているとき。monotonic-split:隣り合う2つの要素がまだ同じかたまりに属するのはどんな条件かわかっているとき。アントワープ操車場では、また忙しい夜が始まりました。今晩の当直は操車係です。入ってくる貨車を行き先ごとの列車に組み直し、連結器を点検し、分岐点でルートを分け、同じ貨物は請求のためにひとまとめにしなければなりません。
それぞれの貨車は、積んでいるものを表す文字列です。たとえば"coal"、"timber"、"crates"などです。
coupleを定義して、貨車の配列と長さnを受け取り、それぞれn両の貨車からなる、重なりのない列車を返すようにしましょう。貨車の数が割り切れない場合、最後の列車は短くなってもかまいません。
{ "coal" "coal" "coke" "ore" "ore" "timber" "timber" } 3 couple .
! => { { "coal" "coal" "coke" } { "ore" "ore" "timber" } { "timber" } }
peek-couplingsを定義して、貨車の配列を受け取り、隣り合う貨車のペアをすべて返すようにしましょう。そうすれば、点検員がそれぞれの連結器を調べられます。
{ "coal" "ore" "timber" "crates" } peek-couplings .
! => { { "coal" "ore" } { "ore" "timber" } { "timber" "crates" } }
split-at-junctionsを定義して、貨車の配列と、junctions(切れ目を表す貨車)の配列を受け取り、分岐点の貨車の間にある区間を返すようにしましょう。分岐点の貨車自体は残しません。
{ "coal" "coal" "switch" "ore" "switch" "timber" }
{ "switch" } split-at-junctions .
! => { { "coal" "coal" } { "ore" } { "timber" } }
coalesce-cargoを定義して、貨車の配列を受け取り、同じ貨物を積んだ連続する貨車をまとまりにグループ化するようにしましょう。
{ "coal" "coal" "ore" "ore" "ore" "timber" "coal" } coalesce-cargo .
! => { { "coal" "coal" } { "ore" "ore" "ore" } { "timber" } { "coal" } }