LUNDS TEKNISKA HÖGSKOLA 1(4) Institutionen för datavetenskap Tentamen, EDAA20/EDA501 Programmering 2013 08 22, 8.00 13.00 Anvisningar: Denna tentamen består av fyra uppgifter. Preliminärt ger uppgifterna 6 + 14 + 14 + 6 = 40 poäng. För godkänt betyg krävs 20 poäng. Tillåtet hjälpmedel: Java-snabbreferens. Lösningsförslag kommer att finnas på kursens hemsida senast dagen efter tentamen. När rättningen är klar meddelas detta på kursens hemsida. Tentamensvillkor för EDA501: 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(4) 1. Ett antal träd ska planteras i en rektangulär park. För att det ska bli snyggt vill man plantera träden på slumpmässiga platser. Man får dock inte plantera träden så att trädkronorna går in i varandra eller kommer utanför parkgränserna. Träden är av olika arter som har olika stora kronor. Det kan se ut så här (sett ovanifrån): höjd bredd Ett träd beskrivs av klassen Tree. Alla koordinater är i meter och mäts relativt parkens origo (övre vänstra hörnet). Trädens storlekar är också i meter. /** Skapar ett träd av arten species */ Tree(String species); /** Placerar trädet med mittpunkten (trädstammen) på koordinaterna x, y */ void placeat(double x, double y); /** Tar reda på arten */ String getspecies(); /** Tar reda på x-koordinaten */ double getx(); /** Tar reda på y-koordinaten */ double gety(); /** Tar reda på trädkronans radie */ double getradius(); /** Returnerar true om detta träds krona går in i trädet t:s krona */ boolean overlaps(tree t); Implementera klassen. Anvisningar: Trädkronornas storlekar definieras av följande klass: TreeSizes /** Tar reda på trädkronans storlek för ett träd av arten species */ static double getradius(string species); För att undersöka om två trädkronor överlappar är det enklast att jämföra avståndet mellan trädstammarna med summan av de båda kronornas radier.
3(4) 2. Parken med träd beskrivs av följande klass: /** Skapar en park med namnet name, bredden width och höjden height */ Park(String name, double width, double height); /** Tar reda på parkens namn */ String getname(); /** Tar reda på bredden */ double getwidth(); /** Tar reda på höjden */ double getheight(); /** Placerar trädet t på en slumpmässig plats i parken så att 1) trädets krona inte går utanför parkens gränser och 2) trädets krona inte överlappar kronan på något annat träd i parken. Du får förutsätta att det är möjligt att placera trädet. */ void placetree(tree t); /** Returnerar en vektor med de utplacerade träden */ Tree[] gettrees(); Implementera klassen. Det är lämpligt att lagra träden i en ArrayList. 3. Klassen ParkPlanner är ansvarig för att placera ut träd i en park. /** Skapar en planerare för en park */ ParkPlanner(Park park); /** Placerar ut träden i listan treelist på slumpmässiga platser i parken. Listan är inte sorterad */ void placetrees(arraylist<tree> treelist); /** Skriver ut en "planteringslista" för de utplacerade träden: en rad för varje träd med art, x-koordinat och y-koordinat */ void print(); /** Ritar ut träden (se bilden i uppgift 1) i ett ritfönster (se nedan) */ void draw(double scale); Implementera klassen. Anvisningar: Träden ska placeras ut i ordning efter avtagande storlek. (Om man placerar ut i annan ordning kan det hända att man i slutet inte får plats med ett stort träd.) Ritfönstret har följande specifikation: Window /** Skapar ett fönster med titeln title, bredden width pixlar och höjden height pixlar */ Window(String title, int width, int height); /** Ritar en cirkel med radien r och medelpunkten i x,y (pixlar) */ void drawcircle(int x, int y, int r); Parametern scale anger hur många pixlar på skärmen som varje meter motsvarar. Om till exempel parken har storleken 100 60 meter och skalan är 5 så ska ritfönstret ha storleken 500 300 pixlar och ett träd med radien 5 meter ritas som en cirkel med radien 25 pixlar.
4(4) 4. Skriv en klass med en main-metod som skapar en park och placerar ut träd i den. Anvisningar: Parkens namn, bredd och höjd ska läsas från tangentbordet. Sedan läses (från tangentbordet på valfritt sätt) alla träd som skall placeras ut. För varje träd läses artens namn. Exempel: Björk Ek Alm Alm Björk Lind Planteringslistan ska skrivas ut och parken ska ritas i ett ritfönster.
LUNDS TEKNISKA HÖGSKOLA 1(4) Institutionen för datavetenskap Lösningsförslag till tentamen i EDAA20/EDA501 2013 08 22 1. public class Tree { private String species; private double radius; private double x; private double y; /** Skapar ett träd av arten species */ public Tree(String species) { this.species = species; radius = TreeSizes.getRadius(species); x = Double.MIN_VALUE; y = Double.MIN_VALUE; /** Placerar trädet med mittpunkten (trädstammen) på koordinaterna x, y */ public void placeat(double x, double y) { this.x = x; this.y = y; /** Tar reda på arten */ public String getspecies() { return species; /** Tar reda på x-koordinaten */ public double getx() { return x; /** Tar reda på y-koordinaten */ public double gety() { return y; /** Tar reda på trädkronans radie */ public double getradius() { return radius; /** Returnerar true om detta träds krona går in i trädet t:s krona */ public boolean overlaps(tree t) { double dist = Math.hypot(x - t.x, y - t.y); return dist < radius + t.radius;
2(4) 2. public class Park { private String name; private double width; private double height; private ArrayList<Tree> trees; private static Random rand = new Random(); /** Skapar en park med namnet name, bredden width och höjden height */ public Park(String name, double width, double height) { this.name = name; this.width = width; this.height = height; trees = new ArrayList<Tree>(); /** Tar reda på parkens namn */ public String getname() { return name; /** Tar reda på bredden */ public double getwidth() { return width; /** Tar reda på höjden */ public double getheight() { return height; /** Placerar trädet t på en slumpmässig plats i parken så att 1) trädets krona inte går utanför parkens gränser och 2) trädets krona inte överlappar kronan på något annat träd i parken. Du får förutsätta att det är möjligt att placera trädet. */ public void placetree(tree t) { boolean placeok = false; do { double rad = t.getradius(); double x = rad + rand.nextdouble() * (width - 2*rad); double y = rad + rand.nextdouble() * (height - 2*rad); t.placeat(x, y); int i = 0; while (i < trees.size() &&!trees.get(i).overlaps(t)) { i++; if (i == trees.size()) { placeok = true; while (!placeok); trees.add(t); /** Returnerar en vektor med de utplacerade träden */ public Tree[] gettrees() { Tree[] tarray = new Tree[trees.size()]; for (int i = 0; i < tarray.length; i++) { tarray[i] = trees.get(i); return tarray;
3(4) 3. public class ParkPlanner { private Park park; /** Skapar en planerare för en park */ public ParkPlanner(Park park) { this.park = park; /** Placerar ut träden i listan treelist på slumpmässiga platser i parken. Listan är inte sorterad */ public void placetrees(arraylist<tree> treelist) { while (!treelist.isempty()) { Tree largest = treelist.get(0); for (int i = 1; i < treelist.size(); i++) { if (treelist.get(i).getradius() > largest.getradius()) { largest = treelist.get(i); treelist.remove(largest); park.placetree(largest); /** Skriver ut en "planteringslista" för de utplacerade träden: en rad för varje träd med art, x-koordinat och y-koordinat */ public void print() { Tree[] trees = park.gettrees(); for (int i = 0; i < trees.length; i++) { Tree t = trees[i]; System.out.println(t.getSpecies() + " " + t.getx() + " " + t.gety()); /** Ritar ut träden (se bilden i uppgift 1) i ett ritfönster */ public void draw(double scale) { int width = (int) (scale * park.getwidth()); int height = (int) (scale * park.getheight()); Window w = new Window(park.getName(), width, height); Tree[] trees = park.gettrees(); for (int i = 0; i < trees.length; i++) { Tree t = trees[i]; int x = (int) (t.getx() * scale); int y = (int) (t.gety() * scale); int radius = (int) (t.getradius() * scale); w.drawcircle(x, y, radius);
4(4) 4. public class ParkMain { public static void main(string[] args) { System.out.println("Skriv parkens namn och storlek"); Scanner scan = new Scanner(System.in); String name = scan.next(); int width = scan.nextint(); int height = scan.nextint(); Park park = new Park(name, width, height); ArrayList<Tree> treelist = new ArrayList<Tree>(); while (scan.hasnext()) { String species = scan.next(); treelist.add(new Tree(species)); ParkPlanner planner = new ParkPlanner(park); planner.placetrees(treelist); planner.print(); planner.draw(5);