LUNDS TEKNISKA HÖGSKOLA 1(6) Institutionen för datavetenskap Tentamen, EDAA10 Programmering i Java 2017 04 20, 14.00 19.00 Anvisningar: Preliminärt ger uppgifterna 4 + 6 + 13 + 7 + 15 = 45 poäng. För godkänt betyg krävs 22,5 poäng. Tillåtet hjälpmedel: Java-snabbreferens. Lösningsförslag kommer att finnas på kursens hemsida senast dagen efter tentamen. Resultatet läggs in i Ladok när rättningen är klar och anslås inte på anslagstavlan. Tentamensvillkor: Om du tenterar utan att vara tentamensberättigad annulleras din skrivning. För att undvika att någon skrivning annulleras av misstag kommer alla som, enligt institutionens noteringar, tenterat utan att vara tentamensberättigade att kontaktas via epost. Felaktigheter i institutionens noteringar kan därefter påtalas fram till nästa tentamenstillfälle då resterande skrivningar annulleras.
2(6) Priset i ekonomisk vetenskap till Alfred Nobels minne tilldelades år 2012 Alvin E. Roth och Lloyd S. Shapley för forskning om algoritmer som kan användas på en marknad där individer handlar med olika resurser enligt givna regler, så att allokeringen blir stabil, med vilket menas att ingen individ har något att vinna på ytterligare handel. Ett exempel på en situation där pristagarnas resultat kan användas är allokering av elever till skolor. Antag att följande grundförutsättningar gäller: Varje elev har sorterat alla skolor i ordning efter vilka den helst vill gå på. Varje skola har ett begränsat antal lediga platser större än noll. Det totala antalet lediga platser på skolorna motsvarar det totala antalet elever, så att varje elev kan få en plats på någon skola. Närhetsprincipen ska gälla: en elev som bor närmare har förtur. I exemplet nedan finns tre skolor och sex elever. Skolornas position och elevernas bostad, visas i rutnätet till vänster. Elevernas skolval visas i tabellen till höger. Varje skola har 2 lediga platser. I uppgift 1-4 ska du implementera en skolallokeringsalgoritm som baseras på nobelpristagarnas forskningsresultat. De ingående klasserna är: Location som beskriver en kartposition. Student som beskriver en elev och dess önskemål om skolplacering. School som beskriver en skola och dess elevplatser. SchoolAllocation som hanterar alla elever och skolor och själva skolallokeringsalgoritmen. Läs igenom alla uppgifterna 1-4 innan du börjar, speciellt har du säkert nytta av att titta på själva skolallokeringsalgoritmen i uppgift 4 (inkl. fortsättningen på exemplet ovan) innan du löser uppgift 2-3. 1. Klassen Location beskriver en kartposition. Location /** Skapar ett positionsobjekt för koordinaterna (x,y) Location(double x, double y); /** Returnerar x-koordinaten double getx(); /** Returnerar y-koordinaten double gety(); /** Returnerar avståndet till other double distanceto(location other); Implementera klassen Location enligt följande anvisningar: distanceto ska beräknas enligt Pythagoras sats, t ex med hjälp av Math.hypot
3(6) 2. Klassen Student beskriver en elev och dess önskemål om skolplacering. Student /** Skapar ett elevobjekt att användas för skolallokering * name = elevens namn * loc = elevens boendeposition * preferredschools är en vektor med alla skolor i preferensordning Student(String name, Location loc, School[] preferredschools); /** Returnerar elevens namn String getname(); /** Returnerar elevens boendeposition Location getlocation(); /** Returnerar nästa skola enligt preferensordning. Första anropet ger skolan * med högst preferens, andra anropet skolan med näst högst preferens, osv. * Får inte anropas fler gånger än antal skolor. School getnextschool(); Implementera klassen Student enligt följande anvisningar: Du kan förutsätta att nextschool inte kommer att anropas fler gånger än det finns skolor i preferredschools. 3. Klassen School beskriver en skola och dess elevplatser. School /** Skapar ett skolobjekt att användas för skolallokering * name = skolans namn * loc = skolans position * maxstudents = antalet elevplatser på skolan School(String name, Location loc, int maxstudents); /** Returnerar skolans namn String getname(); /** Returnerar skolans position Location getlocation(); /** Returnerar antalet elevplatser på skolan int getmaxstudents(); /** Returnerar en vektor med de elever som är allokerade till denna skola just nu Student[] allocatedstudents(); /** Lägger till eleven student till denna skola. Om det blir för många elever * så knuffas den elev som bor längst bort ut. * Returnerar ev. utknuffad elev alternativt null. Student add(student student); Implementera klassen School enligt följande anvisningar: add ska lägga till en elev och eventuellt knuffa ut den elev som bor längst bort från skolan om inte alla får plats efter tillägg. Eventuellt utknuffad elev ska returneras. Algoritmbeskrivningen i nästa uppgift kan vara till ledning.
4(6) 4. Klassen SchoolAllocation hanterar alla elever och skolor och själva skolallokeringsalgoritmen och ser ut enligt följande: public class SchoolAllocation { private ArrayList<Student> allstudents; private ArrayList<School> allschools; public SchoolAllocation() { // Konstruktor given, läser in och fyller allstudents och allschools /** Genomför skolallokeringen enligt given allokeringsalgoritm public void allocate() {... // Ytterligare metoder, ej i denna tentamen Implementera metoden allocate enligt följande algoritm: studentbuffer = en kopia av allstudents (så man inte förstör listan allstudents) while (finns elever i studentbuffer) { student = ta ut första eleven ur studentbuffer school = skolan som är näst i tur bland de skolor som student önskat bumpedout = school.add(student) // add returnerar ev. utknuffad elev Om bumpedout innehåller en elev, lägg till den sist i studentbuffer Varje skola har alltså en egen, privat samling med preliminärt allokerade elever som inte visas i algoritmen ovan. Metoden add lägger till en elev i skolans samling. Om det blir fullt på skolan blir den elev som är längst bort av med sin plats och denna utknuffade (eng. bumped) elev returneras. Om någon elev blev utknuffad så läggs den sist i studentbuffer och kommer alltså placeras senare. Exempel: Om man kör algoritmen på exemplet på sid 2 sker följande (detta är inte utskrifter från programmet utan bara en beskrivning av vad som sker i programmet): 1 Allokera Maj till Tunaskolan 2 Allokera Gustav till Tunaskolan 3 Allokera Sandra till Järnåkraskolan 4 Allokera Patrik till Järnåkraskolan 5 Allokera Anna till Tunaskolan 6 Maj utknuffad från Tunaskolan 7 Allokera Roy till Tunaskolan 8 Roy utknuffad från Tunaskolan 9 Allokera Maj till Järnåkraskolan 10 Maj utknuffad från Järnåkraskolan 11 Allokera Roy till Fäladsgården 12 Allokera Maj till Fäladsgården Dvs allokeringen blir enligt: Fäladsgården: Roy, Maj Järnåkraskolan: Sandra, Patrik Tunaskolan: Gustav, Anna
5(6) 5. Spelet Fyra-i-rad (eng. Connect 4) se bild nästa sida är ett sällskapsspel för två personer som påminner om luffarschack. Varannan gång lägger deltagarna en bricka (eng. marker) i spelet, som är ett lodrät placerat fackverk enligt bilden på nästa sida. Brickorna fylls på uppifrån i separata kolumner och trillar ned i en stapel. Brickorna får ej flyttas efter placering. Den som först får fyra av sina brickor i rad (vågrätt, lodrätt eller diagonalt) vinner. Spelet slutar oavgjort om det inte längre finns plats för fler brickor. Java-klassen Grid nedan representerar rutnätet i ett Fyra-i-rad-spel. Du ska implementera klart klassen genom att skriva metoderna put, count och full, dvs de tre metoderna med /*??? enligt instruktioner på nästa sida. Spelarnas brickor representeras av olika tecken, t.ex. X och O, medan en ledig ruta representeras av ett blanktecken. public class Grid { public static final int rows = 6; public static final int cols = 7; private char[][] grid = new char[rows][cols]; public Grid() { for (int r = 0; r < rows; r++) { for (int c = 0; c < cols; c++) { grid[r][c] = ; public char get(int row, int col) { if (row >= 0 && row < rows && col >= 0 && col < cols) { return grid[row][col]; else { return ; public int put(int col, char marker) { /*??? private int count(int startrow, int startcol, int deltarow, int deltacol, char ch) { /*??? public boolean iswinnerat(int row, int col, char marker) { if (grid[row][col]!= marker) { return false; else { return count(row, col, 1, 0, marker) >= 3 //up-down count(row, col, 0, 1, marker) >= 3 //right-left count(row, col, 1, 1, marker) >= 3 //diagonal 1 count(row,col, 1, -1, marker) >= 3; //diagonal 2 public boolean isfull() { /*???
6(6) https://en.wikipedia.org/w/index.php?curid=52250308 Krav och tips: Positionen längst ned till vänster ska motsvara index (rad, kolumn) = (0, 0) i matrisen grid. Metoden put ska placera brickan marker på den första lediga raden i kolumn col och returnera index för den rad som brickan hamnade på. Om det ej finns plats för fler brickor i denna kolumn ska -1 returneras. Den privata hjälpmetoden count används av den givna metoden iswinner för att räkna hur många brickor som finns i rad i en viss ledd (upp-ner, vänster-höger, diagonalt på två olika håll) från en viss utgångsposition som ges av parametrarna startrow och startcol. Den ledd som count räknar i ges av parametrarna deltarow respektive deltacol. Brickan på utgångspunkten ska inte räknas (det är därför det räcker att summan är >=3 i koden). Tips: Använd i sekvens två loopar som vardera räknar brickor genom att först addera och sedan subtrahera deltavärdena från utgångspunkten enligt nedan exempel: Antag att spelet ser ut som ovan och att count anropas med ch = X samt startrow = 1 och startcol = 2 motsvarande positionen som är markerad i bilden. Om deltarow = 1 och deltacol = 0 ska count räkna antalet brickor i rad först uppåt och sedan nedåt varpå resultatet ska bli 1 (brickan på startpositionen ska ej räknas). Om deltarow = 1 och deltacol = 1 ska count räkna antalet marker i rad i ena diagonalen både uppåt höger och nedåt vänster och resultatet ska bli 3. Metoden isfull ska ge true om brädet är fullt annars false. Tips: Det räcker att kolla om översta raden är full.