Datortentamen i TDP007 2009-06-10 kl. 14-18 ------------------------------------------- Tips: Kolla igenom alla uppgifterna snabbt innan du sätter igång. Det är inte säkert att de är sorterade i svårighetsordning. Uppgift 1 (6p) -------------- a) Vad är skillnaden på @var och @@var? (1p) b) Ge exempel på minst tre olika sätt att utöka en array i Ruby! (1p) c) Vad är en iterator? Förklara i ord och ge ett belysande kodexempel! (2p) d) Vad är det för skillnad på SAX- och DOM-parsning av XML-dokument? (2p) Uppgift 2 (4p) -------------- I filen europarl.xml finns Sveriges 19 ledamöter i Europaparlamentet under perioden 2004-2009. Läs in denna lista med hjälp av REXML-paketet, eller liknande paket, sortera listan efter närvaro och skriv ut listan på skärmen. (Det gör inget om svenska tecken skrivs ut oläsligt. Det ingår inte i uppgiften att fixa det.) Uppgift 3 (4p) -------------- I filen constraint_networks.rb finns kod för att bygga restriktionsnät som vi diskuterade i samband med seminarie 4. Vi tänker oss att du har löst seminarieuppgifterna och kan skapa ett nät för att omvandla mellan Celsius och Fahrenheit. Användningen av denna omvandlare kunde se ut ungefär så här: irb(main):176:0> c,f=create_temperature_network [#, #] irb(main):177:0> c.user_assign 0 "ok" irb(main):178:0> f.value 32 Antag att vi vill använda intervall istället för heltal. Vad blir 18-20 grader Celsius i Fahrenheit? Då vill vi kunna göra så här: irb(main):179:0> c.user_assign 18..20 "ok" irb(main):180:0> f.value 64..68 irb(main):181:0> Vad behöver göras för att uppnå detta? Du behöver inte implementera temperaturomvandlingen igen, utan skriv bara kod som gör att de constraints som finns i filen kan hantera även intervall. Tips 1: När vi skriver 18..20 avses en instans av klassen Range. Tips 2: Det är inte säkert att du egentligen behöver ändra i koden som finns i filen constraint_networks.rb. Uppgift 4 (5p) -------------- Kalle är systemadministratör för ett tjänsteföretag som heter Cleveland & Harrison och ansvarar bl.a. för att hålla deras webbsidor i trim. För att underlätta sitt arbete har han skapat ett antal konfigurationsfiler där viktig information om företaget finns lagrad. Följande exempel finns i filen companyinfo.rb: companyName "Cleveland & Harrison" greetingSwe "Välkommen till #{companyName}!" greetingEng "Welcome to #{companyName}!" directorFirstName "Grover" directorLastName "Cleveland" director "Mr. "+directorFirstName+" "+directorLastName signaturePersonal "Best Wishes /#{directorFirstName}" signatureFormal "Regards, #{director}" För att slippa skriva en särskild parser för den här typen av konfigurationsfiler vill Kalle tolka filen som om den vore Ruby-kod (vilket den syntaktiskt kan vara). Din uppgift är att hjälpa Kalle med någon av de tekniker för domänspecifika språk som vi har arbetat med under kursen. Han vill att det t.ex. ska funka så här: >> c=Configuration.load("companyinfo.rb") => ... >> c.signatureFormal => "Regards, Mr. Grover Cleveland" Implementera klassen Configuration. Uppgift 5 (5p) -------------- a) Konstruera ett constraint network som implementerar gravitationsformlen: F = G*m1*m2/(r^2) G är gravitationskonstanten 9,81. m1 och m2 är massan hos två objekt och r är avståndet mellan dem. F är gravitationskraften mellan dem. (3p) b) Förklara vad som händer i ditt constraint network när du i tur och ordning tilldelar m1, m2 och r värden. Utgå från klasserna Constraint och Connector och förklara hur värden propageras genom nätet. (2p) Bakgrund till uppgift 6 och 7 ----------------------------- Schack är ett klassiskt brädspel som spelas av två spelare på ett bräde med 8x8 rutor. Varje spelare har från början 16 pjäser till sitt förfogande: en kung, en dam, två löpare, två springare, två torn och åtta bönder. Den ena spelaren har ljusa pjäser och kallas vit, den andra har mörka pjäser och kallas svart. Vit spelare börjar alltid, och därefter fortgår spelet med vartannat drag tills någondera parten kan ta den andres kung. Schackspelare har utvecklat flera olika sätt att redovisa vilka drag som har gjorts under en match. Ett sådant sätt är s.k. algebraisk notation i vilket inledningen av en match kan skrivas så här: 1. e4 c5 2. Nf3 d6 3. Bb5+ Bd7 4. Bxd7+ Qxd7 5. c4 Nc6 6. Nc3 Nf6 Varje omgång består av ett drag från vit spelare och ett drag från svart spelare (under förutsättning att inte svart redan förlorat). Dessa omgångar är numrerade ovan. Varje drag talar om vilken pjäs som flyttas, samt till vilken ruta. Formatet för varje drag ser ut så här: - Pjäsen anges med en stor bokstav (K=kung, Q=dam, R=torn, B=löpare, N=springare). Om ingen pjäs anges innebär det att det är en bonde som flyttats. - Rutorna anges med två koordinater: en bokstav a-h samt en siffra 1-8. - Om en pjäs tar en annan pjäs skjuter man in ett x innan målrutan. - Om ett drag innebär att motspelarens kung är hotad ("schack") lägger man till ett + efter målrutan. Det finns många fler specialregler, och flera varianter på den algebraiska notationen, men för den här tentan nöjer vi oss med ovanstående. Du ska inte behöva känna till mer om schack än detta för att kunna lösa uppgifterna. Uppgift 6 (3p) -------------- a) Konstruera ett reguljärt uttryck som matchar ett schackdrag så som det skrivs i algebraisk notation. Uttrycket ska matcha alla möjliga drag enligt beskrivningen ovan och inget annat. Skriv därefter en funktion som med hjälp av detta uttryck kan tala om huruvida en sträng innehåller ett schackdrag eller inte. (1p) b) Konstruera till sist ett enhetstest som verifierar att funktionen funkar korrekt. (2p) Följande array kan t.ex. användas som exempeldata som ska betraktas som korrekta: ["e4", "c5", "Nf3", "d6", "Bb5+", "Bd7", "Bxd7+", "Qxd7", "c4", "Nc6"] Uppgift 7 (5p) -------------- Utgå från den parser som finns i rdparse.rb och skriv en parser som kan läsa in och tolka filer som innehåller beskrivningar av schackspel i algebraisk notation. Målet är att parsern ska ge som utdata någon form av datastruktur som innehåller alla gjorda drag i spelet på ett lämpligt format. Du får själv avgöra hur detta interna format ska se ut (t.ex. speciella klasser, arrayer eller Struct). Exempelsträngen ovan är lämplig testdata. Du behöver inte verifiera att dragen överensstämmer med reglerna, eller ta hänsyn till hur partierna slutar. Din enda uppgift är att skriva en parser som kan behandla dylika textsträngar och producera någon form av vettiga datastrukturer.