1 Tekniska högskolan vid Linköpings universitet Institutionen för datavetenskap Anders Haraldsson TDDC74 Programmering, abstraktion och modellering DUGGA 2 Torsdag 19 feb 2009 8-10 Namn: Personnummer: Skriv även ditt namn på varje uppgiftssida. Uppgifterna löses direkt på denna uppgiftslapp, som lämnas in i sedvanligt tentamensomslag. Skriv tydligt så att inte dina lösningar missförstås. Vi har givit början på definitionen av funktionerna med angivna namn på funktionen och parametrarna. Använd helst denna början, dvs fortsätt och skriv koden. Även om det i uppgiften står att du skall skriva en funktion, så får du gärna skriva ytterligare hjälpfunktioner, som kan vara nödvändiga. På uppgifterna kan halva poäng utdelas. Betygsgradering: Det är tre duggor. Varje dugga ger 12p, dvs totalt 36p. För att passera en dugga krävs minst 3p på duggan. Totalt skall du på de tre duggorna för betyget 3 ha minst 20p. För betyget 4 minst 25p och för betyget 5 minst 30p. Lycka till
2 Uppgift 1 (3 poäng) 1a. (1p) Vad blir värdet i parentesformat av följande uttryck. Rita även upp värdet med den grafiska representationen med cons-celler och pekare (box and pointer notation). (cons (list a b) (cons x (y))) 1b. (1p) Skriv ett Scheme-uttryck som skapar följande struktur: () a b () () c 1 1c. (1p) Vad blir värdet i parentesformat av följande uttryck. Rita även upp värdet med den grafiska representationen med cons-celler och pekare (box and pointer notation). (let ((p (list a b))) (list p p p))
3 Uppgift 2 (4p) I uppgift 2 kan du använda Scheme-funktion max, som tar 2 tal och returnerar det största talet. 2a. (2p) Skriv en rekursiv funktion (max-tal lista), som i en rak lista med tal, returnerar det största talet. Vi kan antaga att listan innehåller åtminstone ett element. Ange även om din lösning gör en rekursiv eller iterativ processlösning. Motivera. (max-tal (3 6 4 5 2)) = 6 (max-tal (-3-4 -2-5)) = -2 (define (max-tal lst)
4 2b. (2p) Vi utvidgar funktionen från uppgift 2a med att finna det största talet i en godtycklig lista, där elementen i sin tur kan vara listor. Vi antager att listan ej kan innehålla punkterade par. Dessutom antager vi att alla talen är större än eller lika med 0, och att listan och dellistorna kan vara tomma. (max-alla-tal (3 (6 (4 1)) 5 () 2)) = 6 (max-alla-tal ()) = 0 ; dvs vi returnerar 0 för en tom lista (define (max-alla-tal lst)
5 Uppgift 3 (2p) Skriv en funktion alla-på-nivå, som tar en en nivå (som heltal) och en godtycklig lista (som ej innehåller punkterade par) och som returnerar en lista med alla elementen (icke-listor) på denna nivå. Toppnivån är 1. (alla-på-nivå 1 (a (b c) d e)) = (a d e) ; dvs a, d och e är på toppnivån. (alla-på-nivå 2 (a (b c) d (e f (g)))) = (b c e f) ; på andra nivån (alla-på-nivå 3 (a (b (c d e) f) ((g h)))) = (c d e g h) ; på tredje nivån (define (alla-på-nivå nivå lst)
6 Uppgift 4 (3p) ADT Abstrakt datatyp för att hantera släktträd med personer och barn Vi vill kunna representera släktträd med person och deras barn och sedan i sin tur barnen med sina barn etc. För detta har vi skapat två abstrakta datatyper, person och barnlista. Ett objekt av typen person består av ett namn och en barnlista (som kan vara tom om personen inte har några barn) och objekt av typen barnlista innehåller inget eller flera objekt av typen person. Vi inför följande primitiver (med förhoppningsvis självförklarande namn) för dessa två abstrakta datatyper: skapa-person : namn x barnlista -> person person-namn : person -> namn person-barnen : person -> barnlista skapa-tom-barnlista : -> barnlista lägg-till-barn : person x barnlista -> barnlista första-barnet : barnlista -> person resten-barnlista : barnlista -> barnlista tom-barnlista? : barnlista -> sanningsvärde ; lägger till ett barn först Med dessa kan vi skapa ett släktträd, där KALLE har barnen LISA och STINA, samt där LISA i sin tur har ett barn PER. STINA har inget barn. Detta släktträd kan definieras: (define kalles-släktträd (skap-person 'kalle (lägg-till-barn (skapa-person 'lisa (lägg-till-barn (skapa-person 'per (skapa-tom-barnlista)) (skapa-tom-barnlista))) (lägg-till-barn (skapa-person 'stina (skapa-tom-barnlista)) (skapa-tom-barnlista))))) Vi väljer följande representation: Ett objekt av typen person representeras som en lista med typmärkning: (person namn barnlista) Ett objekt av typen barnlista representeras som en lista med objekt av typen person, och som börjar med en typmärkning: (barnlista person 1 person 2... person n ) I listrepresentationen blir då kalles-släktträd: (person kalle (barnlista (person lisa (barnlista (person per (barnlista)))) (person stina (barnlista)))) För typningen har vi två funktioner, add-tag som lägger till typmärkningen först och remove-tag som tar bort typmärkningen. (define (add-tag typ object) (cons typ objekt)) (define (remove-tag object) (cdr object))
7 Vi definierar ett antal av de olika primitiverna: (define (skapa-person namn barnen) (add-tag person (list namn barnen))) (define (person-namn person) uppgift 4a ) (define (person-barnen person) uppgift 4a ) (define (tom-barnlista) (add-tag 'barnlista ' ())) (define (lägg-till-barn ett-barn barnen) (add-tag 'barnlista (cons ett-barn (remove-tag barnen)))) (define (första-barnet barnen) (car (remove-tag barnen))) (define (resten-barnlista barnen) uppgift 4a ) (define (tom-barnlista? barnen) (null? (remove-tag barnen))) 4a. (1p) Definiera primitiverna person-namn, person-barnen och resten-barnlista. Du skall följa konventionen hur de andra primitiverna har definierats. (define (person-namn person) (define (peson-barnen person) (define (resten-barn-lista barnen) 4b. (2p) Definiera med hjälp av dessa primitiver en funktion avkomlingar, som tar ett släktträd, dvs objekt av typen person och skapar en vanlig rak lista med alla avkomlingar (inklusive första personen i toppen av släktträdet). Ordnignen på avkomlingarna spelar ingen roll. (avkomlingar kalles-släktträd) = (kalle lisa per stina) (define (avkomlingar person)