Треки
/
Factor
Factor
/
Вправи
/
Підрахунок птахів на подвірʼї
Підрахунок птахів на подвірʼї

Підрахунок птахів на подвірʼї

Навчальна вправа

Вступ

Здебільшого Factor виконує ітерацію через комбінатори, як-от each, map і count. Іноді, втім, найчистіший спосіб записати обчислення - це рекурсія, тобто слово, яке викликає саме себе.

Визначення рекурсивного слова

Визначення : може викликати саме себе безпосередньо:

: count-down ( n -- )
    dup 0 = [ drop ] [ dup . 1 - count-down ] if ;

5 count-down
! prints 5 4 3 2 1

Розгалуження: порожня послідовність чи ні

if-empty (з sequences) - це природний базовий випадок рекурсії:

if-empty ( seq emptyquot nonemptyquot -- )
{ 4 0 9 } [ "empty" ] [ "got data" ] if-empty .
! => "got data"

emptyquot виконується, коли (порожню) послідовність уже знято зі стека; nonemptyquot виконується, коли послідовність ще лежить на стеку.

cond - ланцюжок гілок із перевірками

Коли в нашій рекурсії більше ніж два випадки, cond (з combinators) допомагає зберегти код читабельним:

: classify ( n -- label )
    {
        { [ dup 0 < ] [ drop "negative" ] }
        { [ dup 0 = ] [ drop "zero"     ] }
        [ drop "positive" ]
    } cond ;

Посилання вперед за допомогою DEFER:

Визначення : може викликати саме себе безпосередньо, але коли два слова викликають одне одного, парсер бачить перше з них раніше, ніж існує друге. DEFER: резервує імʼя, щоб перше визначення могло скомпілюватися:

DEFER: even?

: odd? ( n -- ? ) dup 0 = [ drop f ] [ 1 - even? ] if ;
: even? ( n -- ? ) dup 0 = [ drop t ] [ 1 - odd? ] if ;

DEFER: також стає в пригоді, коли допоміжне слово природніше читати після слова, яке його використовує.

Вказівки

Ми ведемо щоденний облік того, скільки птахів відвідує наш сад. Дані зберігаються як масив цілих чисел, де сьогоднішня кількість стоїть першою.

1. Сьогоднішня кількість

Визначте today, щоб вона брала масив щоденних кількостей зі стека й повертала сьогоднішню кількість, або f, якщо масив порожній.

{ 2 5 1 } today .
! => 2

{ } today .
! => f

2. Інкремент сьогоднішньої кількості

Визначте increment-day-count, щоб вона повертала новий масив, у якому сьогоднішню кількість збільшено на одиницю. Якщо вхідні дані порожні, поверніть { 1 }.

{ 4 0 2 } increment-day-count .
! => { 5 0 2 }

{ } increment-day-count .
! => { 1 }

3. Чи був день без птахів?

Визначте has-day-without-birds?, щоб вона повертала t, якщо хоч один день мав нуль птахів, інакше f.

Використайте рекурсію, а не any? чи інші слова вищого порядку для послідовностей.

{ 2 0 4 } has-day-without-birds? .   ! => t
{ 3 8 1 5 } has-day-without-birds? . ! => f

4. Загальна кількість птахів від початку

Визначте total, щоб вона повертала суму всіх кількостей.

Використайте рекурсію, а не sum.

{ 4 0 9 0 5 } total .
! => 18

5. Зайняті дні

Зайнятим днем вважається день, коли птахів пʼять або більше. Визначте busy-days, щоб вона повертала кількість зайнятих днів.

Використайте рекурсію, а не count.

{ 4 5 0 0 6 } busy-days .
! => 2
Редагувати через GitHub Посилання відкривається в новому вікні або вкладці
Factor Exercism

Час розпочати Підрахунок птахів на подвірʼї?

Зареєструйтеся на Exercism, щоб вивчати й опановувати Factor, а також 47 концепцій163 вправи та справжнє наставництво від людей, і все це безкоштовно.