Іноді потрібно розглядати послідовність як низку частин,
а не елемент за елементом. Бібліотеки grouping,
splitting та
splitting.monotonic дають нам чотири
способи це зробити.
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: ми знаємо, завдяки чому два сусідні
елементи все ще належать до однієї серії.У нас знову насичена ніч на сортувальній станції в Антверпені. Сьогодні роль чергового диспетчера виконуємо ми: вантажні вагони, що прибувають, потрібно перегрупувати у поїзди на вихід, оглянути зчіпки, розділити маршрути на вузлах, а однакові вантажі обʼєднати для виставлення рахунків.
Кожен вагон - це рядок тексту (англ. string), що називає його вантаж: "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" } }
Зареєструйтеся на Exercism, щоб вивчати й опановувати Factor, а також 47 концепцій163 вправи та справжнє наставництво від людей, і все це безкоштовно.