ML-övningar I boken finns ett antal ML-övningar. Det kunde dock gärna ha fått vara fler övningar, och kanske framförallt fler lätta övningar. För att råda bot på detta har jag sammanställt ett antal övningar som passar att lösa under tiden ni lär er ML. De är av skiftande svårighetsgrad, men åtminstone en del av dem är lättare än bokens övningar på motsvarande avsnitt. Jag har inga svarsförslag, utan rekommenderar att ni sätter er vid datorn och testar era program. Det finns inget som går upp mot att testa sina program i verkligheten! Kör ni fast är det naturligtvis tillåtet att fråga handledare eller föreläsare, på övningstimmar (eller andra lämpliga tillfälle, undvik olämpliga tillfällen :-) om dessa uppgifter. Enkla funktioner, typer 1) Vilken typ har följande funktioner? a) fun f s = size s * 10; b) fun g (b1,b2) = not b1 orelse b2; c) fun h (s,n) = size s <= n; d) fun k (x,y) = floor x +y; e) fun m (s,x) = floor s * size x; 2) Deklarera en funktion som konkatenerar en sträng med sig själv. Vilken typ har funktionen? - twice very ; > val it = veryvery :string 3) Deklarera en funktion som beräknar nettolönen, givet lön före skatt och skatteprocenten. Vilken typ har funktionen? Ex -netto (20000, 32); > val it = 13600:int; 4) Deklarera en funktion som tar två strängar, och returnerar ett booleskt värde som talar om ifall den andra strängen kommer före den första i alfabetisk ordning. less ( guava, avocado ); >val it = true:bool 5) Deklarera en funktion som givet ett heltal n returnerar en tuple som består av n, kvadraten på n och kuben på n. Vilken typ har funktionen? powers 3; > val it = (3, 9,27): 6) Deklarera följande funktioner, ange deras typ. a) En funktion som tar en sträng s och ett heltal n och talar om ifall s är längre än n tecken. longer ( hugs,3); > val it = true:bool b) En funktion som talar om ifall en första sträng är kortare än en andra sträng. Använd funktionen från a)! shorter ( yard, meter ); val it = true:bool;
7) Ange typen på följande funktioner: a) fun f1 a = 1 f1 b = 2 f1 c = 0; b) fun f3 1 = ( one, 1.0) f3 2 = ( two, 2.0) f3 n = (???, 0.0); c) fun f5 1 = 1 f5 n = f5 (n-1); d) fun f7 x = if x<1 then small else big ; e) fun f9 (x,y) = if x<y then x else f9 (x-0.1) y; 8) Deklarera följande funktioner. Ange deras typ. a) En rekursiv funktion som konkatenerar en sträng s med sig själv n gånger. (Använd inte villkorsuttryck!) -sjoin (3, very ); > val it = veryveryvery :string b) Använd sjoin för att deklarera en funktion som tar en sträng och konkatenerar ihop lika många kopior av strängen som strängen är lång! - ljoin hugs ; val it = hugshugshugshugs : string c) Skriv en funktion som konkatenerar n kopior av strängen s1 med strängen s2. Använd rekursion. - rjoin (!, Help, 3); > val it = Help!!! 9) Deklarera följande funktioner. Ange deras typ. a) En funktion som finner det största av två heltal. -max (4,5); >val it = 5:int; b) En funktion som finner det största av tre reella tal. -max3 (1.2, 3.4, 2.7); > val it = 3.4:real 10) Deklarera följande funktioner. Ange deras typ. a) En funktion som givet två strängar lägger till blanktecken i slutet av den första tills den är lika lång som den andra. (Rekursion!) -extnd ( cat, tiger ); > val it = cat :string b) En funktion som givet ett tecken och två strängar konkatenerar tecknet i slutet av den första strängen tills den är lika lång som den andra strängen. -ext (#, cat, catapult ); > val it = cat : string
Kapitel 3 (tupler, lokala dekl. mm). 11 a) Definiera följande funktion, använd mönstermatchning: Funktionen tar ett par med två reeella (x,y) som argument. On både x och y skiljer sig från noll ska resultatet vara enligt formeln x/y + y/x. Om både x och y är noll ska resultatet vara två. Annars ska resultatet vara 1E30. b) Samma som a) utom när både x och y är noll, då ska en exception aktiveras. 12) Den matematiska funktionen e tanh (tangens hyperbolicus) definieras som x e x tanh(x) = e x + e x Skriv en ML-funktion som beräknar tanh där de två olika exponentialuttrycken beräknas i lokala deklarationer. 13) Skriv en funktion vol2 (r ), (r = radien) som beräknar volymen av ett klot med två decimalers noggrannhet. Du ska deklarera två lokala funktioner vol(r ) som beräknar volymen av ett klot och round2 (x) som avrundar x till två decimaler. Dessa används sedan i vol2. Du får använda (den fördefinierade) funktionen round som avrundar ett reellt tal till närmaste heltal. Volymen av ett klot (om nån skulle lyckats glömma det) är 4πr 3 /3. 14) I ett mycket enkelt grafiksystem representeras linjer av tupler som innehåller x- och y- koordinaterna för linjens start och slut. t ex representeras linjen från 4,5 till 8,9 av tuplen (4, 5, 8, 9). Horisontala linjer har samma y-koordinat för start och slutpunkten, vertikala linjer har samma x-koordinat, och diagonala linjer, ja det får ni tänka ut själva! Deklarera en ML-funktion som tar en 4-tupel och talar om vilken sorts linje den representerar (antingen "horiz", "vert", "diag" eller "none") - lineclass (7,9,11,13); > val it = "diag" : string 15) Ett parkeringshus sparar info om när bilarna kommer i en trippel, där t ex (12, 35, 16) betyder att bilen anlände 12.35.16 (timmarna räknas från 0 till 23). a) Skriv en funktion som konverterar en tids-trippel till sekunder! (Dvs antal sekunder från 00.00.00) Vilken typ har denna funktion? b) Skriv en funktion som konverterar en tid i sekunder till en tids-trippel! Typ? c) Skriv en funktion som givet en tidstrippel vardera för bilens infart och utfart beräknar hur många sekunder bilen tillbringat i P-huset. Listor 16) Vilken typ har följande funktioner: a) fun f1 [ ] = 0.0 f1 (h::t) = h + f1 t; b) fun f3 [ ] = [ ] f3 (0::t) = 0 :: (f3 t) f3 (_::t) = f3 t; c) fun f5 [ ] = f5 (h::t) = h^h^f5 t; d) fun f7 [ ] = [ ] f7 (h::t) = (h,h) :: f7 t; e) fun f8 [ ] = [ ] f8 (h::t) = [h] :: f8 t;
17) Deklarera en funktion som returnerar en lista av tupler som innehåller de första n heltalen och deras respektive kvadrater i fallande ordning. - flist 5; > val it = [(5,25), (4,16), (3,9), (2,4), (1,1)] : (int*int) list 18) Deklarera en funktion som tar en lista med booleska värden och beräknar logiskt och av dessa värden (dvs a1 a2. an) Ex - andlist [true, false, true, true, false] > val it = false:bool 19) Deklarera en funktion som räknar hur många av talen i en heltalslista som är positiva. - poscount [1, 0, 2, ~3, 4]; > val it = 3:int 20) a) Deklarera en (polymorf) funktion som sätter in värdet v 1efter den första förekomsten av värdet v2 i en lista. - insert ( d, c, [ a, b, c, e ]); > val it = [ a, b, c, d, e ]:string list b) Deklarera en funktion som sätter in v1 efter alla förekomster av v2 i en lista. 21) Deklarera en funktion som tar bort sista elementet i en lista 22) Deklarera en funktion flat som givet en lista av listor slår ihop alla dellistor till en lista (i rätt ordning). flat [[1, 2], [3, 4]] [1, 2, 3, 4] 23) En vektor kan representeras som en lista. Deklarera funktionen scalprod som beräknar skalärprodukten av två vektorer. Skalärprodukten är summan av den parvisa multiplikationen av elementen. Definiera även en exception som tar hand om de fall då vektorerna är av olika längd. scalprod [[1, 9], [4, 5]] 1*4 + 9*5 = 49 24) Deklarera en funktion som duplicerar ett värde ett antal gånger och ger en lista som resultat. duplicate ( la, 3) [ la, la, la ] 25) Deklarera en funktion factors som givet ett heltal n ger en lista med alla tal som delar n. Listor och tupler 26) Vilken typ har följande funktioner: a) fun fa [ ] = [ ] fa ((x, y, z)::t) = x+y/z :: fa t; b) fun ff (((x1,y1)::t1), ((x2,y2)::t2)) = (x1,x2,y1,y2):: ff t1 t2 ff = [ ]; 27) Deklarera en funktion som tar en lista av heltalspar, och skapar en ny lista där varje element är summan av motsvarande par. - addpair [(1,2), (3,4), (5,6)]; > val it = [3,7,11] : int list 28) Ett namn kan representeras av ett par (förnamn, efternamn) a) Deklarera en funktion som sätter in ett namn i en lista av namn; listan saka hålas i alfabetisk ordning, sorterad efter efternamn. Om två personer har samma efternamn används förnamnet för sorteringen (som i exemplet nedan) - nameinsert (( Ziggy, Zebra ), [( Chris, Cat ),( Zoe, Zebra )]; > val it = [( Chris, Cat ),( Ziggy, Zebra ), ( Zoe, Zebra )]; b) Deklarera en funktion som sorterar en lista av namn i alfabetisk ordning.
29) Vid en trafikkontroll noteras alla bilar som passerar. När flera bilar med samma märke passerar i en följd räknas antalet. Dessa data sparas i en lista av par, varje par har utseendet (bilmärke, antal). Ordningen i listan är densamma som den ordning i vilken bilarna passerade. [( Volvo,3),( VW,1), ( Saab,2), ( Volvo,4), ( Ford,1), ] För alla uppgifter som följer gäller att de tar en lista av ovanstående typ som parameter (+ ev. någon ytterligare parameter som framgår av resp. deluppgift) a) Deklarera en funktion som tar ett bilmärke som parameter, och returnerar en lista som innehåller alla par som gäller detta bilmärke. b) Deklarera en funktion som tar ett bilmärke som parameter, och räknar hur många bilar av detta märke som totalt passerat. c) Deklarera en funktion som tar ett bilmärke som parameter, och som tar bort det första paret som innehåller detta bilmärke från listan. d) Deklarera en funktion som returnerar namnet på det bilmärke för vilket flest bilar har passerat i en följd. Partiellt applicerbara funktioner, map 30) Definiera en partiellt applicerbar funktion times som multiplicerar ihop sina två argument. Använd times för att definiera double, som multiplicerar sitt argument med 2. 31) Vilken typ har funktionen fun f(x,y) xs = (x+y) * length xs; 32) Längden av en lista kan beräknas genom att mappa en funktion som transformerar alla listans element till en etta var, och sedan summerar ettorna. Deklarera length på detta vis. Använd funktionen sum från föreläsningen för summeringen. 33) Deklarera en funktion som använder map för att generera en lista med tupler (heltal, kvadraten på talet), givet en lista av heltal som argument. 34) En botaniker experimenterar med en ny sorts konstgödning. Varje vecka mäter han alla sina plantor. För varje planta sparar han mätningarna i en lista, ex [1.2, 1.7, 1.9, 2.3, 2.5, 2.6] a) Deklarera en funktion som givet en sådan mätlista returnerar en "tillväxtlista", som visar hur mycket plantan växt mellan varje mätning. (En mätlista med ett element ska returnera en tom lista.). Mätlistan ovan ska generera tillväxtlistan [0.5, 0.2, 0.4, 0.2, 0.1] b) Deklarera en funktion som beräknar den genomsnittliga veckotillväxten, givet en tillväxtlista. c) Använd map för att deklarera en funktion som givet en lista av tillväxtlistor returnerar en lista med genomsnittliga veckotillväxter. (Använd funktionen från b) ) d) Deklarera en funktion som givet en tillväxtlista returnerar en lista av strängar. Varje sträng ska tala om ifall tillväxten den vecka var "high", "medium", eller "low" jämfört med den genomsnittliga veckotillväxten. "high" betyder större än 2*medel, "low" är mindre än medel/2, och "medium" allt däremellan. Datatyper 35) Deklarera en datatyp LOGIC3 för trevärd logik. Den ska ha typkonstruerarna True, False och Undef. Deklarera också funktionerna not3: LOGIC3 -> LOGIC3 and3 : LOGIC3 * LOGIC3 -> LOGIC3 or3 : LOGIC3 * LOGIC3 -> LOGIC3 Ni får fundera ut vilket svar som är lämpligt om Undef förekommer som argument.
36a) Definiera två olika datatyper för att representera koordinater i planet, dels RECT för rektangulära koordinater, dels POLAR för polära koordinater. Rektangulära koordinater representeras av ett koordinatpar (x,y). Polära koordinater representeras av ett par (r,v) där r är radien och v en vinkel. b) Deklarera en funktion to_rect som omvandlar från polära till rektangulära koordinater. (Koordinaterna x och y ges av x= r * cos v och y = r * sin v). 37a) Ett naturligt tal är antingen noll, eller efterföljare till ett annat naturligt tal (rekursiv definition!) Definiera en rekursiv datatyp NAT med konstruerarna Zero och Succ för att representera naturliga tal på detta sätt. b) Deklarera följande funktioner: to_int : NAT -> int. Konverterar ett tal av typ NAT till ett tal av typ int. to_nat: int -> NAT. inversen till to_int add_nat: NAT * NAT -> NAT. Adderar två tal av typen NAT. Försök definiera funktionen utan att använda vanligt heltals-+! mul_nat: NAT * NAT -> NAT. Multiplicerar två NAT. Använd add_nat! 38) I en restaurang representeras rätterna på menyn av följande datatyp: datatype menuitem = vgn of string*real vgt of string *real omn of string*real; (vgn = vegan, vgt = vegetarisk, omn = kan innehålla kött. Real-komponenten anger priset). En meny är en lista av värden av denna datatyp, t ex [vgn ("tofu", 3.6), vgt ("quiche", 2.7), omn ("steak", 7.5) ] a) Skriv en funktion som plockar fram alla vegan-rätter på listan. b) Skriv en funktion som givet en sträng som är namnet på en rätt letar åt rättens pris. c) En beställning är ett par (namn, antal). Skriv en funktion som givet en beställning och en meny beräknar beställningens pris. d) Skriv en funktion som givet en lista av beställningar och en meny beräknar totalpriset för dessa beställningar. Träd (rekursiva datatyper) I följande övningar, utgå från datatypen datatypen datatype 'a tree = empty node of 'a tree * 'a * 'a tree 39 Definiera funktioner som a) adderar ihop alla värden i ett heltalsträd b) konkatenerar ihop alla strängar i ett sträng-träd 40a) Skriv en funktion som givet ett heltalsträd skapar ett nytt träd där varje nods värde är fördubblat jämfört med det gamla trädet. b) Skriv en funktion som givet ett träd och en funktion f, skapar ett nytt träd genom att applicera f på varje nod i det ursprungliga trädet. c) Definiera funktionen i a) genom att använda funktionen i b)! 41) Skriv en funktion som tar två träd som parametrar och kollar om träd1 finns som ett delträd av träd2 Strängar 42) Deklarera en funktion som tar två strängar och talar om (via ett booleskt värde) om sträng1 påbörjar sträng2. 43) Deklarera en funktion som räknar hur ofta en sträng förekommer i en annan sträng. -scount "the" "the pathetic bathe theory with lather"; > 5:int 44) Deklarera en funktion som tar bort första förekomsten av sträng1 från sträng2. 45) Deklarera en funktion som tar bort alla förekomster av sträng1 från sträng2.