LULEÅ TEKNISKA UNIVERSITET Tentamen i Funktionell programmering Totala antalet uppgifter: 6 (5 för vissa) Lärare: Håkan Jonsson, Thomas Björklund, 1700, 3001 Tentan beräknas vara färdigrättad senast 2004-11-12. Tillåtna hjälpmedel: Inga. Kurskod SMD108 (001/090/131) Datum 2004-10-28 Skrivtid 4 tim Bilaga: Fördefinierade funktioner. Du som omtenterar en 4p-variant av kursen: 1. Välj själv ut 5 (fem) uppgifter och lämna endast in lösningar på dem. Om du lämnar in svar på alla 6 uppgifter bortses från den mest poänggivande lösningen vid rättningen, så gör inte det. 2. Du betygsätts som tidigare år, dvs 25p = alla rätt och du behöver ungefär hälften av maxpoängen för godkänt. 3. Skriv “OMTENTA” och din gamla kurskod (t ex SMD001) mitt på det oranga tentaomslaget. 1. Tvillingar (5p) Skriv en funktion twins :: Eq t => [t] -> Int som beräknar antalet förekomster av två på varandra följande och identiska element i en lista. Exempel: twins [], twins [100] och twins [3.0,4.0] ska alla bli 0. twins [’R’,’R’] ska bli 1, twins [2,2,2] ska bli 2 och twins "abbcdeeeab" ska bli 3. 2. Nollvision a) Definiera en algebraisk typ SKOGSDJUR för att representera älgar, rävar och harar. En älg har en viss vikt i kilo (ett heltal) och en räv kan vara [listig] (ett boolskt värde). Harar har ingen egenskap som skall representeras i datatypen. (2p) b) En väg anses vara farlig om det finns minst en älg eller en räv som inte är [listig] längs den. Att krocka med en älg är förstås direkt farligt och en o[listig] räv är inte smart nog att undvika bilar så den utgör också en trafikfara. Skriv en funktion dangerous :: [SKOGSDJUR] -> Bool som givet en lista med djur som förekommer längs en väg avgör om vägen är farlig eller ej. (2p) c) Deklarera typen SKOGSDJUR som en instans i klassen Ord så att djur ordnas efter vikt. Rävar väger ungefär 7 kilo och harar 3 kilo [källa: Jägarnas Riksförbund]. Som bilaga hittar du klassen Ord. Observera att i det i klassens definition redan finns implementationer av alla funktioner och operatorer, förutom operatorn <= som dessa beror av. Det räcker därför att implementera operatorn <= för att uppfylla signaturen. (1p) 3. Listor av listor (5p) Skriv en funktion dislike :: Eq a => a -> [[a]] -> [[a]] som givet ett värde och en lista av listor tar bort alla förekomster av detta värde i de inre listorna. Exempel: dislike 1 [[3,1,4],[1,5,9],[2]] skall returnera [[3,4],[5,9],[2]]. dislike ’e’ ["eCesu","eckes"] skall returnera ["Csu","cks"]. 4. Primtal (5p) Ett primtal är ett heltal > 1 som inte är jämnt delbart med andra tal än 1 och talet självt. Ex: 2, 3, 5, 7 och 11. Skriv en funktion som tar ett heltal som argument och returnerar True om heltalet är ett primtal, annars False. Exempel: isPrime 2 skall returnera True. isPrime 42 skall returnera False. 5. Upprepad förekomst (5p) Skriv en funktion pos :: Eq t => Int -> t -> [t] -> Int som givet ett positivt heltal i, ett värde v och en lista l ger tillbaka positionen för den i:e förekomsten av v i l. Huvudet i en lista förekommer på position 1, nästa element på position 2 etc. Om det inte finns någon i:e förekomst av v i listan ska pos avbrytas med hjälp av error och lämpligt felmeddelande. Exempel: pos 1 0 [2,4,0,4,0] ska bli 3. pos 2 0 [2,4,0,4,0] ska bli 5. pos 3 0 [2,4,0,4,0] ska resultera i avbruten programkörning. pos 2 ’c’ "That’s completely clear!" ska bli 19. 6. Träd på djupet a) Definiera en rekursiv algebraisk datatyp för ett binärt träd som innehåller noder och löv utan innehåll. (2p) b) Djupet hos ett löv i ett binärt träd är definierat som antalet noder som vägen upp från lövet till trädets rot innehåller. Det enda lövet i ett träd som bara består av ett löv har djupet 0. Skriv en funktion som givet ett binärt träd, representerat med hjälp av datatypen i a), beräknar djupet för varje löv och returnerar (alla) djupen i en lista. Du får själv välja den ordning i vilken djupen förekommer i resultatlistan. (3p) Exempel: Om funktionen appliceras på trädet i Figur 1 kan en korrekt lösning returnera [3,4,4,2,3,4,4,3,3] Figur 1: Ett binärt träd där noderna representeras av cirklar och löven av kvadrater. Bilaga: Klassen Ord class (Eq a) => Ord a where compare :: a -> a -> Ordering (<), (<=), (>=), (>) :: a -> a -> Bool max, min :: a -> a -> a -- Minimal complete definition: (<=) or compare -- using compare can be more efficient for complex types compare x y | x == y = EQ | x <= y = LT | otherwise = GT x x x x <= < >= > y y y y max x | | min x | | = = = = y x >= y otherwise y x <= y otherwise compare compare compare compare = x = y = x = y x x x x y y y y /= == /= == GT LT LT GT