トラック
/
Factor
Factor
/
演習
/
ベルギーの貨車
ベルギーの貨車

ベルギーの貨車

学習演習

はじめに

列を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"などです。

1. 貨車をつないで列車にする

coupleを定義して、貨車の配列と長さnを受け取り、それぞれn両の貨車からなる、重なりのない列車を返すようにしましょう。貨車の数が割り切れない場合、最後の列車は短くなってもかまいません。

{ "coal" "coal" "coke" "ore" "ore" "timber" "timber" } 3 couple .
! => { { "coal" "coal" "coke" } { "ore" "ore" "timber" } { "timber" } }

2. 連結器をのぞく

peek-couplingsを定義して、貨車の配列を受け取り、隣り合う貨車のペアをすべて返すようにしましょう。そうすれば、点検員がそれぞれの連結器を調べられます。

{ "coal" "ore" "timber" "crates" } peek-couplings .
! => { { "coal" "ore" } { "ore" "timber" } { "timber" "crates" } }

3. 分岐点で編成を分ける

split-at-junctionsを定義して、貨車の配列と、junctions(切れ目を表す貨車)の配列を受け取り、分岐点の貨車の間にある区間を返すようにしましょう。分岐点の貨車自体は残しません。

{ "coal" "coal" "switch" "ore" "switch" "timber" }
{ "switch" } split-at-junctions .
! => { { "coal" "coal" } { "ore" } { "timber" } }

4. 同じ貨物をまとめる

coalesce-cargoを定義して、貨車の配列を受け取り、同じ貨物を積んだ連続する貨車をまとまりにグループ化するようにしましょう。

{ "coal" "coal" "ore" "ore" "ore" "timber" "coal" } coalesce-cargo .
! => { { "coal" "coal" } { "ore" "ore" "ore" } { "timber" } { "coal" } }
GitHubで編集する リンクは新しいウィンドウまたはタブで開きます
Factor Exercism

ベルギーの貨車を始める準備はできましたか?

Exercismに登録すれば、47個のコンセプト163個の演習、そして本物の人間によるメンタリングとともに、Factorを学んでマスターできます。すべて無料です。