Kurzusok
/
Factor
Factor
/
Feladatok
/
A könyvtáros főkönyve
A könyvtáros főkönyve

A könyvtáros főkönyve

Tanulófeladat

Bevezetés

Néha egy sorozatot egyetlen értékké szeretnél összevonni, néha viszont minden köztes értéket látni szeretnél, amelyet az összevonás közben előállít. A Factor ezeket két eszközre bontja: az egyetlen értékre hajtogatáshoz a reduce-t (a sequences szótárban), a futó változathoz pedig a math.statistics kumulatív családját.

reduce - az általános hajtogatás

reduce ( seq init quot: ( prev elt -- next ) -- result )

A reduce egyesével halad végig a sorozaton, magával hordozva egy futó eredményt (az akkumulátort), és azt egy kétargumentumú quotationnek adja át. A quotation megkapja a futó akkumulátort és a következő elemet; ami a vermen marad, az lesz az új akkumulátor.

USING: math sequences ;

{ 1 2 3 4 } 0 [ + ] reduce .         ! => 10
{ 1 2 3 4 } 1 [ * ] reduce .         ! => 24

A nem nulla kezdőérték és a saját kombináló függvény azok a részei a reduce-nak, amelyeket a sum és a product nem tud elérni. Például egy sorozat legnagyobb értéke, egy alapértelmezett értékkel arra az esetre, ha semmi sem múlja felül:

USING: math.order ;

{ 3 1 -4 5 -2 } 0 [ max ] reduce .   ! => 5
{ -3 -1 -4 }    0 [ max ] reduce .   ! => 0

A 0 kezdőérték részt vesz az összehasonlításban: akkor lesz belőle az eredmény, amikor minden elem veszít, így a csupa negatív értékből álló sorozat is 0-t ad eredményül, nem pedig egy tetszőleges legkisebb értéket.

Kumulatív redukciók

Néha minden köztes eredményre szükséged van, nem csak a végsőre. A math.statistics kumulatív családja egy ugyanolyan hosszú sorozatot ad vissza, mint a bemenet, ahol minden pozíció az adott pozícióig tartó előtagra végzett redukció:

cum-sum     ( seq -- newseq )    ! running total
cum-product ( seq -- newseq )    ! running product
cum-min     ( seq -- newseq )    ! running minimum
cum-max     ( seq -- newseq )    ! running maximum
USING: math.statistics ;

{ 3 1 4 1 5 9 2 6 } cum-sum .        ! => { 3 4 8 9 14 23 25 31 }
{ 1 2 3 4 } cum-product .            ! => { 1 2 6 24 }
{ 3 1 4 1 5 9 2 6 } cum-min .        ! => { 3 1 1 1 1 1 1 1 }
{ 3 1 4 1 5 9 2 6 } cum-max .        ! => { 3 3 4 4 5 9 9 9 }

Hasznos minta a láncolt kumulatív redukció: az egyik kimenete maga is sorozat, amely készen áll arra, hogy egy másikba kerüljön. Így a „futó összegzés futó összegzése” két szóval kifejezhető. A kombinációk rugalmasak, párosítsd őket aszerint, hogy az egyes lépések mit összegeznek.

produce - a kihajtogatás

A reduce egy sorozatot fogyaszt el egyetlen értékké. A produce (a sequences szótárban) az ellenkező irányba megy: előállít egy sorozatot egy kezdőértékből, ismételt vizsgálattal és léptetéssel:

produce ( pred quot -- seq )

Minden iteráció először lefuttatja a pred-et az aktuális állapoton; ha igaz értéket ad vissza, meghívódik a quot, hogy előállítsa a következő elemet és frissítse az állapotot. Amikor a pred f-et ad vissza, az iteráció leáll, és a begyűjtött elemek visszaadásra kerülnek.

Klasszikus példa a Fibonacci-sorozat (minden szám az előző kettő összege). A futó állapot az (a, b) pár. Minden lépés kiadja a b-t, majd a párt (b, a + b)-re cseréli:

USING: kernel math sequences ;

! Fibonacci numbers strictly below 100:
0 1 [ dup 100 < ] [ tuck + over ] produce 2nip .
! => { 1 1 2 3 5 8 13 21 34 55 89 }

A futó állapot két értéket fog át, ezért a törzs a tuck-kal (a kernel szótárban; ez a háromelemű keverés, amely a legfelsőt a második alá másolja) lépteti a párt, a végén pedig a 2nip (szintén a kernel szótárban, a nip kételemű megfelelője) tesz rendet. A hívást balról jobbra olvasva:

  • A [ dup 100 < ] predikátum a pár tetejére pillant (a következő kiadandó számra), és addig folytatja, amíg az még a korlát alatt van.
  • A [ tuck + over ] törzs (b, a + b)-re lépteti az állapotot, és kiadja a b-t, így három érték marad a vermen: alul az új pár, felül a kiadott szám.
  • Miután a produce leáll, a két záró értéket (a végső párt) a 2nip eldobja, és csak az előállított sorozat marad.

A produce a reduce pontos duálisa: ahol a reduce egy sorozatot hajtogat le egyetlen értékig, ott a produce egy értéket hajtogat ki sorozattá.

Utasítások

Te vagy a könyvtáros, aki az olvasói számlák főkönyvét vezeti. Hetente kétféle munka kerül az asztalodra:

  • Kérések sora: olyan jóváírások, amelyeket az olvasó kér, hogy alkalmazzunk (könyvvisszaadás, befizetett bírság), valamint a rendszer által naplózott új terhelések (újonnan felhalmozódott késedelmi bírságok). Az olvasó számlája jóváírással védett: egy akkora jóváírás, amely mínuszba vinné az olvasót, csak a tartozás mértékéig kerül alkalmazásra, így a folyó egyenleg soha nem csökken nulla alá.
  • Tranzakciók listája: a számlán már rögzített tételek. A pozitív összegek terhelések (új bírságok), a negatív összegek jóváírások (befizetések).

Minden héten összesíted a könyveket: egy záró egyenleget, miután a kéréseket teljesítetted, a tranzakciókból számított napi folyó egyenleget, valamint egy folyó mélypontot, amely megjelöli azokat az időszakokat, amikor megugrottak a bírságok.

1. Teljesítsd a kérések sorát

Definiáld a protected-balance függvényt úgy, hogy egy opening egyenleget és requests (előjeles összegek) tömbjét kapja, és adja vissza a záró egyenleget, miután minden kérést sorban teljesítettél. Egy olyan kérés, amely nulla alá csökkentené az egyenleget, csak a rendelkezésre álló összegig teljesül, így a folyó egyenleg nullánál áll meg.

100 { 50 -200 30 } protected-balance .
! => 30

500 { 100 -300 -250 } protected-balance .
! => 50

0 { -10 50 } protected-balance .
! => 50

2. Folyó egyenleg

Definiáld a running-balance függvényt úgy, hogy transactions tömbjét kapja, és egy ugyanilyen hosszú sorozatot adjon vissza, amelynek i-edik eleme az első i+1 tranzakció utáni egyenleg (nulla kezdőegyenleghez viszonyítva).

{ 50 -30 -20 100 } running-balance .
! => { 50 20 0 100 }

3. Eddigi legkisebb egyenleg

Definiáld a least-balance-so-far függvényt úgy, hogy transactions tömbjét kapja, és egy ugyanilyen hosszú sorozatot adjon vissza, amelynek i-edik eleme az i pozícióig (beleértve) látott legalacsonyabb folyó egyenleg. Ez a folyó mélypont, ami hasznos, hogy kiszúrjuk azokat a napokat, amikor kockázatosnak tűnt a számla.

{ 50 -30 -20 100 } least-balance-so-far .
! => { 50 20 0 0 }

{ 200 -50 -100 -200 } least-balance-so-far .
! => { 200 150 50 -150 }

4. Felezz a célértékig

A könyvtár bírságamnesztia-programot indít: az olvasó fennálló tartozása minden fizetési időszakban feleződik, amíg el nem éri vagy alá nem esik egy elengedési küszöbnek. Definiáld a halve-until függvényt úgy, hogy egy principal és egy target értéket kapjon, és adja vissza a felezett értékek sorozatát (egész osztást használva), az első felezéstől kezdve, addig folytatva, amíg a folyó érték szigorúan target fölött van. Az utolsó kiadott érték lesz az első, amely eléri vagy aláesik a target-nek.

100 5 halve-until .
! => { 50 25 12 6 3 }

64 1 halve-until .
! => { 32 16 8 4 2 1 }

3 5 halve-until .
! => { }
Szerkesztés GitHubon A hivatkozás új ablakban vagy lapon nyílik meg
Factor Exercism

Készen állsz elkezdeni a(z) A könyvtáros főkönyve 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.