Ez a feladat arra az egészszám-aritmetikára épül, amit a Leah ínycsiklandó lasagnéja feladatban láttál. Itt lebegőpontos számokkal fogsz dolgozni, és kiválasztod a feladathoz illő osztási szót.
A Factor megkülönbözteti az egész számokat (1, 42, 1_000_000) a lebegőpontos számoktól (1.0, 3.14, 6.02e23). Ha egy számításban vegyítesz egy egész és egy lebegőpontos számot, az eredmény lebegőpontos lesz:
2 3 + . ! => 5
2 3.0 + . ! => 5.0
A számjegyek csoportosításához aláhúzásjelet tehetsz a számba, például 1_000_000, és a Factor egyszerűen figyelmen kívül hagyja őket.
A Factornak külön szavai vannak az osztásra. Mind a math szótárban található.
/ ( x y -- x/y ) ! exact: ratio for two integers, float if either is a float
/f ( x y -- f ) ! always a float
/i ( x y -- q ) ! integer division (truncates toward zero)
mod ( x y -- r ) ! remainder
/mod ( x y -- q r ) ! quotient and remainder together
1 2 / . ! => 1/2 (a proper ratio)
16 3 / . ! => 5+1/3 (an improper ratio, printed as a mixed numeral)
16 3 /f . ! => 5.333333333333333
16 3 /i . ! => 5 (truncated)
16 3 mod . ! => 1
16 3 /mod .s ! quotient and remainder in one pass
! => 5
! => 1
16.0 3 / . ! => 5.333333333333333
A / két egész számra ratio-t (a Factor egzakt racionális típusát) ad, vagy float-ot, ha valamelyik bemenet lebegőpontos. A /f akkor is lebegőpontos eredményt kényszerít ki, ha mindkét bemenet egész. A /i mindig a nulla felé csonkít.
Számpredikátumok a math, a math.functions és a math.primes szótárból:
zero? ( x -- ? )
even? ( x -- ? )
odd? ( x -- ? )
prime? ( x -- ? )
divisor? ( m n -- ? ) ! true when n divides m
integer? ( x -- ? ) ! true for ints (fixnum or bignum)
float? ( x -- ? ) ! true for floats
number? ( x -- ? ) ! true for any numeric kind
0 zero? . ! => t
0.0 zero? . ! => t
3 zero? . ! => f
4 even? . ! => t
7 even? . ! => f
7 odd? . ! => t
7 prime? . ! => t
9 prime? . ! => f
15 5 divisor? . ! => t (5 divides 15)
15 4 divisor? . ! => f
A math.functions szótár floor, ceiling és round szava mind lebegőpontos értéket ad vissza (3.0-t, nem 3-at). Hogy valódi egész számot kapj, fűzd mögé a >integer-t:
3.7 floor >integer . ! => 3
3.2 ceiling >integer . ! => 4
A sq, ^ és abs (a math.functions szótárban) négyzetet, tetszőleges hatványt és abszolútértéket számol:
sq ( x -- x*x )
^ ( x y -- x^y )
abs ( x -- |x| )
5 sq . ! => 25
2 10 ^ . ! => 1024
2 0.5 ^ . ! => 1.4142135623730951
-7 abs . ! => 7
3 abs . ! => 3
A min ( x y -- z ) és a max ( x y -- z ) (a math.order szótárban) két szám közül a kisebbet, illetve a nagyobbat adja vissza:
3 7 min . ! => 3
3 7 max . ! => 7
A leggyakoribb felhasználás a leszorítás: egy értéket a max-szal egy alsó korláthoz rögzítesz (például a 0 max nem engedi, hogy egy érték negatív legyen), a min-nel pedig egy felső korláthoz.
A math.order emellett before?, after?, before=? és after=? predikátumokat is kínál olyan összehasonlításokhoz, amelyek bármilyen rendezhető típuson működnek (számokon, stringeken, karaktereken):
before? ( obj1 obj2 -- ? ) ! obj1 < obj2
before=? ( obj1 obj2 -- ? ) ! obj1 <= obj2
after? ( obj1 obj2 -- ? ) ! obj1 > obj2
after=? ( obj1 obj2 -- ? ) ! obj1 >= obj2
Ezeket használd a </<= helyett, amikor az értékek stringek is lehetnek, mert az aritmetikai operátorok nem működnek stringeken.
A barátod, Chandler egzotikus országokat szeretne meglátogatni a világ minden táján. Sajnos Chandler matektudása nem valami jó. Eléggé tart tőle, hogy az útja során átverik a pénzváltók, és szeretné, ha készítenél neki egy valutakalkulátort.
Definiáld az exchange-money szót, amely egy budget és egy
exchange-rate paramétert vár, és visszaadja az átváltott valuta
értékét.
Megjegyzés: ha a valutád USD, és USD-t szeretnél EUR-ra váltani
1.20-as árfolyamon, akkor 1.20 USD == 1 EUR.
127.5 1.2 exchange-money .
! => 106.25
Definiáld a get-change szót, amely egy budget (az átváltás előtti
keret) és az exchanging-value (a keretből átváltásra kivett összeg)
paramétert vár. Add vissza a megmaradó pénz mennyiségét.
127.5 120 get-change .
! => 7.5
Definiáld a value-of-bills szót, amely egy denomination (egyetlen
bankjegy értéke) és egy number-of-bills paramétert vár. Add vissza a
bankjegyek összértékét.
5 128 value-of-bills .
! => 640
Definiáld a number-of-bills szót, amely egy amount és egy
denomination paramétert vár. Add vissza, hogy az adott címletből hány
egész bankjegy fér bele az összegbe. Lefelé kerekíts, mert tört
bankjegy nem létezik.
127.5 5 number-of-bills .
! => 25
Definiáld a leftover-of-bills szót, amely egy amount és egy
denomination paramétert vár. Add vissza a maradék összeget, amit nem
lehet egész bankjegyekkel kifizetni.
127.5 20 leftover-of-bills .
! => 7.5
Definiáld az exchangeable-value szót, amely egy denomination,
budget, spread és exchange-rate paramétert vár.
A spread a váltási díjként levont százalék, egész számként megadva.
Ezt tört alakban hozzá kell adni az árfolyamhoz. Ha
1.00 EUR == 1.20 USD, és a spread értéke 10, akkor a teljes
árfolyam 1.00 EUR == 1.32 USD (az 1,20 tíz százaléka 0,12, ami
hozzáadódik az 1,20-hoz).
Add vissza az új valuta maximális értékét, miután alkalmaztad az
árfolyamot a spreaddel együtt, lefelé kerekítve az adott denomination
egész bankjegyjeire. A visszaadott érték egész szám.
20 127.25 10 1.20 exchangeable-value .
! => 80
5 127.25 10 1.20 exchangeable-value .
! => 95
Ugyanaz, mint a get-change, de ha Chandler véletlenül a kereténél
nagyobb átváltandó összeget írt be, akkor negatív szám helyett 0-t adj
vissza. Definiáld a safe-change szót, amely egy budget és egy
exchanging-value paramétert vár.
127.5 120 safe-change .
! => 7.5
50 100 safe-change .
! => 0
Chandler egy szuvenírért alkudozik. Definiáld a cap-spend szót, amely
egy budget és egy price paramétert vár, és a kettő közül a kisebbet
adja vissza, vagyis a legtöbbet, amit ténylegesen ki tud fizetni.
100 30 cap-spend .
! => 30
20 30 cap-spend .
! => 20
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.