• No results found

TDA144 Exempellösningar för hemtenta Dokumentet innehåller exempellösningar samt korta beskrivningar av vanliga korrekta lösningar och

N/A
N/A
Protected

Academic year: 2022

Share "TDA144 Exempellösningar för hemtenta Dokumentet innehåller exempellösningar samt korta beskrivningar av vanliga korrekta lösningar och"

Copied!
7
0
0

Loading.... (view fulltext now)

Full text

(1)

TDA144 Exempellösningar för hemtenta 2020-03-17

Dokumentet innehåller exempellösningar samt korta beskrivningar av vanliga korrekta lösningar och vanliga misstag

(2)

Exempellösning:

public static int height(Robot r){

int h = 1;

// Den här loopen körs för varje rad i tomrummet while(true) {

// Flytta till västra ändan av raden while (tryMoving(r, Robot.WEST)) ;

// Flytta steg för steg österut while (true)

if (tryMoving(r, Robot.SOUTH)){

h++;

break; // Om vi kan gå söderut startar den yttre loopen om } else if (!tryMoving(r, Robot.EAST))

return h; // Om vi inte kan gå söder eller öster är vi klara }

}

// Försök gå ett steg i angiven riktning.

// Returnerar svaret på om förflyttning gick att genomföra public static boolean tryMoving(Robot r, int dir){

while (r.getDirection() != dir) r.turnLeft();

if (r.canMove()){

r.move();

return true;

} else

return false;

}

De vanligaste lösningarna använder en av två beskrivningar av ungefär samma algoritm:

• För varje rad "scannar" roboten från ena till andra sidan efter en möjlighet att gå söderut.

Hittar den ingen är den klar.

• Roboten följer en vägg tills den bara kan gå norrut.

Båda är lika acceptabla men mitt allmäna intryck är att lösningar av den första typen är tydligare i beskrivningen av algoritmen, kanske för att den är lättare att dela upp i tydliga steg.

Vanliga fel:

• Loopar som tydligt inte fungerar.

• Missar att gå tillbaka till början av varje ny rad.

• Kod som verkar utgå från att roboten inte kan röra sig höger eller vänster på nedersta raden.

• Missförstånd om hur hålrummet ser ut (att man aldrig behöver gå norr) Vanliga småfel:

• Att inte räkna raden roboten börjar på.

(3)

Uppgift 2:

Exempellösning:

import java.util.*;

public class Parameters {

// Övre och undre gräns för tillåtna värden i den här samlingen private double upperLimit;

private double lowerLimit;

// Nycklar är parameternamn, värden parametervärden

private Map<String, Double> values = new TreeMap<String, Double>();

// Default-värde för den här samlingen private double defaultValue = 0;

public Parameters(double upperLimit, double lowerLimit) { this.upperLimit = upperLimit;

this.lowerLimit = lowerLimit;

}

public void setValue(String parameter, double value) { if (value >= lowerLimit && value <= upperLimit)

// Skriver automatiskt över tidigare värde om det finns något values.put(parameter, value);

else

throw new RuntimeException("Value out of bounds: "+value);

}

public double getValue(String parameter) { // En vanlig lösning:

// Double v = values.get(parameter) // Viktigt att använda Double // if (v != null)

// return v;

// return defaultValue;

// Finns en metod i Map som gör exakt det vi vill här // metoden ger aldrig null

values.getOrDefault(parameter, defaultValue) }

public void setDefaultValue(double defaultValue) { this.defaultValue = defaultValue;

}

// Testkod

public static void main(String[] args) {

Parameters par = new Parameters(100.0, -100.0);

System.out.println(par.getValue("x"));

par.setValue("x", 10.0);

System.out.println(par.getValue("x"));

par.setDefaultValue(5.0);

System.out.println(par.getValue("y"));

try {

par.setValue("z", -101);

} catch (RuntimeException e) {

System.out.println(e.getMessage());

} } }

(4)

• Tre doubles för övre gräns, nedre gräns och default-värde

• En datastruktur för själva samlingen

Korrekt lösning för metodsignaturer:

• Konstruktor som tar övre och undre gräns för värden:

public Parameters(double upperLimit, double lowerLimit)

• Andra konstruerare förekommer, till exempel en som tar även någon datastruktur

• public void setValue(String key, double value)

• public double getValue(String key)

• public void setDefaultValue(double defaultValue)

• Det här är I princip det korrekta sättet att göra metodsignaturerna, för att kunna skriva testprogrammet så som det anges

Vanliga korrekta lösningar för datastrukturen:

• Använda en Map<String, Double> och delegera nästan alla metoder till den. Det här är den enklaste korrekta lösningen.

• Använda två listor (en med parameternamn och en med värden på samma positioner).

Fungerar också, men blir lite mer invecklad med större risk för misstag.

• En lista med objekt av en ytterligare klass Parameter som är en enkel lagringsklass för par av namn och värden.

Vanliga misstag:

• Att enbart göra en klass som bara kan representera en parameter (ingen datastruktur).

• Att ha instansvariabler för namn och värde direkt i Parameters.

• Att göra någon instansvariabel statisk.

• Att spara värden men inga namn

• Att kräva att alla parametrar läggs till innan de får ett värde

• Att hårdkoda in gränserna så de är samma för alla parametersamlingar.

• Missa try-catch

• Helt missa test-koden

(5)

Uppgift 3:

Knight:

import java.util.*;

public class Knight extends ChessPiece {

public Knight(Position pos, boolean isWhite) { super(pos, isWhite);

}

public List<Position> possibleMoves(ChessBoard board) { List<Position> res = new ArrayList<>();

// Pjäsens nuvarande rad och kolumn int row = getPosition().getRow();

int col = getPosition().getCol();

// En array med de åtta tänkbara positionerna (kan vara ogiltiga) // Man kan generera de här positionerna programmatiskt med loopar, // men fördelen är diskutabel.

Position[] basic = {

new Position(row+2,col+1), new Position(row+2,col-1), new Position(row-2,col+1), new Position(row-2,col-1), new Position(row+1,col+2), new Position(row+1,col-2), new Position(row-1,col+2), new Position(row-1,col-2) };

// Lägg till de tänkbara positioner som är giltiga och inte har en // allierad pjäs på sig

for(Position p : basic) {

if (ChessBoard.isValid(p)) {

// Kunde vara utanför if-satsen också ChessPiece piece = board.getPiece(p);

if(piece == null || piece.isWhite() != isWhite()) res.add(p);

} }

return res;

} }

Vanliga korrekta lösningar:

• Generera först alla åtta tänkbara positioner (endera med loopar eller genom åtta satser), loopa sedan igenom dem och lägg de tillåtna dragen i en lista (visad här).

• Lägg alla tänkbara drag direkt i en lista, filtrera sedan bort de ogiltiga dragen.

(6)

import java.util.*;

public class Bishop extends ChessPiece {

public Bishop(Position pos, boolean isWhite) { super(pos, isWhite);

}

public List<Position> possibleMoves(ChessBoard b){

List<Position> res = new ArrayList<>();

// Lägg till alla drag för de fyra tillåtna riktningarna addMoves(res, b, 1, 1 );

addMoves(res, b, 1, -1);

addMoves(res, b, -1, 1 );

addMoves(res, b, -1, -1);

return res;

}

// Lägg till i alla drag i en riktning till listan

// Riktningen anges genom förändring i kolumn/rad för varje steg // Till exempel (1,0) för att gå rakt neråt eller (-1,-1) upp vänster // Slutar när den når en pjäs eller en ogiltig position

private void addMoves(List<Position> res, ChessBoard b, int deltaRow, int deltaCol) {

// Offset är antalet steg den tar i den givna riktningen for(int offset = 1; true; offset++) {

// Positionen pjäsen skulle hamna på Position p = new Position(

getPosition().getRow()+offset*deltaRow, getPosition().getCol()+offset*deltaCol );

// Pjäsen på p (eller null om p är tom) ChessPiece other = b.getPiece(p);

if (!ChessBoard.isValid(p))

return; // Avbryt metoden om p är ogiltig else if (other!=null) {

// p innehåller en pjäs, metoden avbryts

// Är pjäsen en motståndarpjäs läggs p till listan if (other.isWhite() != this.isWhite())

res.add(p);

return;

}

// p är giltig och tom, lägg till i listan res.add(p);

} } }

Vanliga korrekta lösningar:

* Fyra loopar för de fyra riktningarna, som avbryts vid en pjäs eller ogiltig ruta.

(7)

Vanliga misstag:

• Inte kontrollera om resultatet av getPiece() är null innan det används.

• Att använda instansvariabler för att lagra listor med drag (oftast utan att återskapa dem vid varje anrop)

• Att inte få den grundläggande infrastrukturen rätt (skapa, fylla och returnera en lista) till exempel att skapa positioner men aldrig lägga till dem i listor.

• Att låta löparen hoppa över pjäser. Ofta genom att använda en loop för alla diagonaler och alltså inte kunna avbryta den när en pjäs påträffas.

• Att göra något helt annat än possibleMoves, till exempel en move-metod eller en metod som avgör om ett specifikt drag är giltigt.

Vanliga småfel:

• Inkorrekta eller väldigt invecklade sätt att avgöra om en pjäs är en motståndarpjäs.

• Att försöka tilldela metodanrop, typ p.getRow()++

Överbetygsuppgift:

• Flera metoder skulle behövas, till exempel ett sätt att avgöra vilken pjäs som är kung för varje spelare.

• Några har identifierat att det vore praktiskt om man kunde simulera drag utan att uföra dem. Då kunde man avgöra matt genom att simulera varje möjligt drag och se om schackläget består för varje möjligt drag för alla pjäser.

• Att ha någon slags samlad datastruktur för nåbara rutor på brädet för varje spelare är troligtvis en bra tanke.

• Många identifierade korrekt olika problem som kunde uppstå, till exempel att det inte räcker med att se om någon pjäs kan ställa sig mellan en hotad kung och den hotande pjäsen eftersom att varje förflyttning kan leda till att kungen hotas på något annat sätt.

• Många identifierade korrekt att det kan bli ganska beräkningsintensivt att beräkna matt.

References

Related documents

Den undre laktattröskeln är inte en viktig parameter för uthållighetsidrottare eftersom man oftast ligger i ett högre tempo under tävling där kroppen hämtar energi

Faktorerna som påverkar hur lätt vagnen är att manövrera är vikten, val av hjul och storleken på vagnen. Val av material påverkar vikten i stor utsträckning och då vagnen ska

När två enheter kommunicerar kan en angripare utnyttja pauser i kommunikationen och skicka sitt eget meddelande, som då tolkas som ett svar istället för det

a) Visa på nedan angivna balans- och resultaträkningskonton hur Fredrikssons AB bokför de två kundfordringarna, dels löpande under året och dels i bokslutet för 2004. Bortse

Redovisa fullständiga, korrekta lösningar av följande uppgifter för be- tyget

Redovisa fullständiga, korrekta lösningar av följande

Subject D, for example, spends most of the time (54%) reading with both index fingers in parallel, 24% reading with the left index finger only, and 11% with the right

The more detailed steps of this eHealth scenario are as follows (see also Figure 1): In a hospital system, a medical doctor (Doctor A) is upon discharge of the patient from a