Kurzusok
/
Factor
Factor
/
Feladatok
/
Autók, összeállni!
Autók, összeállni!

Autók, összeállni!

Tanulófeladat

Bevezetés

Ez a feladat az elágazásokat mutatja be: hogyan válasszunk kettő vagy több cselekvési irány közül egy érték alapján. Arra a Boolean-okra épül, amelyekkel az Annalyn's Infiltration feladatban találkoztál, és a Currency Conversion egész számokkal végzett aritmetikájára.

Összehasonlító szavak

Ezek mind a math-ban találhatók (a = pedig a kernel-ben):

=  ( x y -- ? )    ! equal
<  ( x y -- ? )    ! less than
<= ( x y -- ? )    ! less than or equal
>  ( x y -- ? )    ! greater than
>= ( x y -- ? )    ! greater than or equal
3 3 = .     ! => t
2 3 < .     ! => t
3 3 <= .    ! => t
3 4 = not . ! => t    (inequality: combine = with not)

A zero? (a math-ban) a gyakori 0 = vizsgálat rövidítése: elfogyasztja a számot, és a veremre teszi, hogy nulla volt-e:

zero? ( n -- ? )    ! t when n is 0

Tartományvizsgálatok

A between? (a math.order-ben) azt vizsgálja, hogy egy érték egy zárt intervallumba esik-e. Akkor jön jól, amikor egy művelet attól függ, melyik sávba esik egy szám:

between? ( x lo hi -- ? )    ! lo <= x <= hi (inclusive)
5 1 10 between? .    ! => t
0 1 10 between? .    ! => f
10 1 10 between? .   ! => t   (inclusive at both ends)

Gyakran fogod látni cond predikátumként, például dup 1 4 between?, hogy egy ágat értéktartomány, ne pedig egyetlen érték alapján válassz ki.

Quotationok

A fenti összehasonlító szavak Boolean-okat adnak vissza; hogy egy Boolean alapján cselekedj, adj át az elágazásnak egy vagy több quotationt. A quotation egy szögletes zárójelbe zárt kódrészlet: [ ... ]. Ha leírod, a kód értékként kerül a veremre ahelyett, hogy lefutna. Egy if-hez hasonló szó aztán eldönti, melyik quotation fusson le.

[ neg ]   ! a quotation that negates the top of the stack
[ ]       ! the empty quotation — does nothing

Egy későbbi feladat részletesen foglalkozik a quotationokkal; most egyelőre olvasd úgy a [ ... ]-t, mint „az ebben az ágban lefutó kód”.

if, when, unless

Az if (a kernel-ben) egy Boolean-t és két quotationt vár. Az első quotationt akkor futtatja le, amikor a Boolean igaz értékű, a másodikat pedig akkor, amikor hamis értékű:

if ( ? then-quot else-quot -- )
: abs ( x -- y ) dup 0 < [ neg ] [ ] if ;

A when csak akkor futtatja le a quotationt, amikor a Boolean igaz értékű; az unless pedig csak akkor, amikor hamis értékű:

when   ( ? quot -- )
unless ( ? quot -- )

if*, when* és unless*

A kernel három változata úgy kezeli a Boolean-t, mint egy értéket, amelyet érdemes megtartani, amikor igaz értékű. Ez akkor hasznos, amikor egy szó „a dolgot vagy f-et” ad vissza:

if*     ( ? true false -- )    ! truthy: true is called WITH ? on stack
when*   ( ? true       -- )    ! truthy: true is called WITH ? on stack
unless* ( ? false      -- )    ! falsy: false runs and pushes a default

Az if* a kétágú forma. Az igaz ág úgy hívódik meg, hogy az érték még a vermen van; a hamis ág pedig anélkül hívódik meg:

42 [ ] [ "nothing" ] if* .   ! prints 42
f  [ ] [ "nothing" ] if* .   ! prints "nothing"

Az unless* a klasszikus „érték vagy alapérték” idióma. Ha az érték igaz értékű, érintetlenül marad; ha f, az érték lekerül a veremről, és a quotation fut le, hogy egy helyettesítő értéket tegyen a helyére:

"hello" [ "anonymous" ] unless* .   ! => "hello"
f       [ "anonymous" ] unless* .   ! => "anonymous"

A when* az if* egyágú formája: csak akkor futtatja le a quotationt (úgy, hogy az érték még a vermen van), amikor az érték igaz értékű, és egyszerűen lekerül a veremről, amikor f. Akkor nyúlj hozzá, amikor egy „a dolog vagy f” típusú eredményt szeretnél az aktuális értékbe beépíteni anélkül, hogy az f esettel külön kellene foglalkoznod:

0 41 [ + ] when* .   ! => 41   (truthy: 41 added to the running total)
0 f  [ + ] when* .   ! => 0    (falsy: f dropped, total left untouched)

cond

Amikor több lehetséges cselekvés közül kell választanod, a cond (a combinators-ban) a kézenfekvő választás. Egy { predicate body } párokból álló tömböt vár, és annak az első predikátumnak a törzsét futtatja le, amely igaz értéket ad:

USING: combinators ;

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

Néhány részlet, amit érdemes megjegyezni:

  • A párok sorrendben kerülnek kipróbálásra. Az első egyezés nyer.
  • Egy predikátum nélküli bejegyzés (egyetlen quotation) a végén alapértelmezettként működik.
  • Minden predikátum megvizsgálja a bemenetet, de úgy kell hagynia az adatvermet, ahogy találta. A szokásos idióma erre a dup ... <test>.
  • A kiválasztott pár törzse ugyanazt a vermet kapja, mint amit a predikátum látott, ezért általában azzal kezdődik, hogy egy drop-pal eltávolítja a bemenetet, és az eredményt a veremre teszi.

Utasítások

Ebben a feladatban olyan kódot írsz, amely egy autógyár szerelősorának termelését elemzi. A szerelősor sebessége 0 (kikapcsolva) és 10 (maximum) között mozoghat.

A legkisebb nullától különböző sebességén (1) óránként 221 autó készül. A termelés lineárisan nő a sebességgel, így 4-es sebességnél a sor óránként 4 * 221 = 884 autót gyárt. A nagyobb sebesség viszont megnöveli annak valószínűségét, hogy hibás autók készülnek, amelyeket aztán ki kell selejtezni.

Négy részfeladatod van. Mindegyik egyetlen egész szám paramétert vesz le a veremből: a szerelősor sebességét.

1. Számolj be róla, hogy fut-e a sor

Definiáld a production-status szót úgy, hogy "stopped" értéket adjon vissza, ha a sebesség 0, és "running" értéket minden más sebesség esetén:

0 production-status .
! => "stopped"
3 production-status .
! => "running"

2. Számítsd ki a sikerességi arányt

Definiáld a success-rate szót úgy, hogy egy elem hibamentes legyártásának valószínűségét adja vissza:

  • 0: 0.0
  • 1 to 4: 1.0
  • 5 to 8: 0.9
  • 9: 0.8
  • 10: 0.77
10 success-rate .
! => 0.77

3. Számítsd ki az óránkénti termelési rátát

Definiáld a production-rate-per-hour szót úgy, hogy a szerelősor óránkénti termelési rátáját adja vissza, figyelembe véve a sikerességi arányt.

Először a base-speed szót kell definiálnod, a 221 konstanst.

6 production-rate-per-hour .
! => 1193.4

A visszaadott érték lebegőpontos szám.

4. Számítsd ki a percenként legyártott működő példányok számát

Definiáld a working-items-per-minute szót úgy, hogy visszaadja, hány működő autó készül percenként. Az eredmény egész szám, a töredék autókat nem számoljuk.

6 working-items-per-minute .
! => 19
Szerkesztés GitHubon A hivatkozás új ablakban vagy lapon nyílik meg
Factor Exercism

Készen állsz elkezdeni a(z) Autók, összeállni! feladatot?

Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) Factor nyelvet 47 fogalom163 feladat segítségével, valódi emberi mentorálással, mindez ingyen.