// Introdution to programming autumn 2006 // Exercise set 5 example solutions // Huomatus suomenkielisille opiskelijoille: // Tämän kerran mallivastaukset ovat englanniksi lukuunottamatta harjoitusta // 24. Jos englanninkielinen teksti aiheuttaa ongelmia, apuna voi käyttää esim. // netmot-verkkosanakirjaa. Sitä voi käyttää laitoksen koneilta osoitteessa // http://mot.kielikone.fi/mot/helyo/netmot.exe ja muualta siihen pääsee käsiksi // Alman kautta. Jos netmot ei ole valmiiksi Alman etusivulla, se löytyy valitsemalla // sivupalkista > Kirjastopalvelut ja tietotekniikka > Tieto- ja kirjastopalvelut. /** * Exercise 21 * Example solution by Janne Korhonen * Based on another solution by Jaakko Nenonen and Jukka Stenlund * * Contains the minimum and maximum temperature of a series of measurements. * Unlike the MinMax-object in exercise 20, this one has always registered * at least one temperature */ public class MinMax { /** Private variables */ private double minimum; private double maximum; /** * Creates a new MinMax-object. First measurement must be given as parameter. * Given parameter is set both as maximum and minimum, because it is the only * temperature registered*/ public MinMax(double temperature) { this.resetWithTemperature(temperature); } /** * Resets the object. Given parameter is the first registered temperature * after the reset and is set as both maximum and minimum */ public void resetWithTemperature(double temperature){ this.minimum = temperature; this.maximum = temperature; } /** * Registers an temperature. The measured value is set as minimum if * it's smaller than current minimum and as maximum if it's larger than * current maximum. Note that in this version there is no need to check * if the object is in initial state, because it has necessarily registered * at least one temperature already! */ public void registerTemperature(double temperature) { if (temperature < this.minimum) this.minimum = temperature; else if (temperature > this.maximum) this.maximum = temperature; } /** * Returns smallest measured value. */ public double getMinimum() { return this.minimum; } /** * Returns largest measured value. */ public double getMaximum() { return this.maximum; } public String toString() { return "Minimum=" + this.getMinimum() + ", Maximum=" + this.getMaximum(); } /** * Test method for MinMax. Creates a new MinMax object and tests giving * input and resetting */ public static void main(String[] args) { System.out.println("Creating a new MinMax with parameter 1.0"); MinMax meter = new MinMax(1.0); System.out.println(meter); System.out.println("Input: -23.0"); meter.registerTemperature(-23.0); System.out.println(meter); System.out.println("Input: -2.0"); meter.registerTemperature(-2.0); System.out.println(meter); System.out.println("Input: 100.0"); meter.registerTemperature(100.0); System.out.println(meter); System.out.println("Input: 90.0"); meter.registerTemperature(90.0); System.out.println(meter); System.out.println("Resetting the meter with parameter 111.0"); meter.resetWithTemperature(111.0); System.out.println(meter); System.out.println("Input: 200.0"); meter.registerTemperature(200.0); System.out.println(meter); } } /** * Exercise 22 * Example solution by Janne Korhonen (2006) * * A ship has a direction of 0...359 degrees and speed of 0.0...40.0 knots * * In case of invalid parameters */ public class Ship { // Constants private static final double MIN_SPEED = 0.0; private static final double MAX_SPEED = 40.0; // Internal variables private double speed = 0; private int direction = 0; // - Constructors - /** * Creates a ship with direction 0 and speed 0.0. Because variables * are already initialised to 0 nothing needs to be done */ public Ship(){} /** Creates a ship with direction 0 and the given speed */ public Ship(double speed){ this.setSpeed(speed); // setSpeed checks the parameter } /** * Creates a ship with the given direction and speed 0.0 * If given angle is not between 0 and 359, some mathematical * trickery can be used to convert it into an angle between * 0 and 359 */ public Ship(int direction){ if (direction > 0) this.direction = direction % 360; else this.direction = (360 + direction % 360) % 360; } /** Creates a ship with the given direction and the given speed */ public Ship(double speed, int direction){ if (direction > 0) this.direction = direction % 360; else this.direction = (360 + direction % 360) % 360; this.setSpeed(speed); } // - Accessors - /** Returns the direction in degrees */ public int getDirection(){ return this.direction; } /** Returns the speed in knots */ public double getSpeed(){ return this.speed; } /** * Turns the ship right (the starboard of the ship) one degree * (notice that if the direction is 359 and it gets turned right * by one degree, the new direction is 0!) */ public void toStarboard(){ this.direction++; if (this.direction == 360) this.direction = 0; } /** Turns the ship left (port of the ship) one degree */ public void toPort(){ this.direction--; if (this.direction == -1) this.direction = 359; } /** * Sets a new speed according to the parameter. * If given parameter is not between minimum and maximum speeds * then speed is set to minimum or maximum depending on * whether the parameter is greater than maximum or less than * minimum */ public void setSpeed(double speed){ if (speed > MAX_SPEED) this.speed = MAX_SPEED; else if (speed < MIN_SPEED) this.speed = MIN_SPEED; else this.speed = speed; } public String toString(){ return "Direction " + this.direction + ", Speed "+this.speed; } } /** * Exercise 23 * Example solution by Janne Korhonen (2006) * * A program for playing with Ships. Creates a new Ship object * and lets user play with it. */ import java.util.Scanner; public class Shipper { private static Scanner sc = new Scanner(System.in); public static void main(String[] args) { Ship ship = new Ship(); // Creates a Ship System.out.println("Welcome aboard, captain!"); // Prints instructions System.out.println("To steer the ship, use following commands:"); System.out.println("l - turn left"); System.out.println("r - turn right"); System.out.println("s - change speed"); System.out.println("Other inputs quit\n"); boolean cont = true; do{ System.out.println(ship); // Prints ship status System.out.print("Command: "); // Command prompt String command = sc.nextLine(); // Read input if (command.equals("l")){ // turn left System.out.println("Turning to port, aye!"); System.out.print("Amount of degrees: "); int turn = readInt(); for (int i = 0; i < turn; i++) ship.toPort(); } else if (command.equals("r")){ // turn right System.out.println("Turning to starboard, aye!"); System.out.print("Amount of degrees: "); int turn = readInt(); for (int i = 0; i < turn; i++) ship.toStarboard(); } else if (command.equals("s")){ // Change speed System.out.println("Changing speed"); System.out.print("New speed: "); double speed = readDouble(); ship.setSpeed(speed); } else { // Quit cont = false; } } while(cont); System.out.println("Bye bye, captain!"); } /** * Method for reading integers * Keeps asking for an integer until one is given. */ public static int readInt(){ do { if (sc.hasNextInt()){ // Check if proper value is given int value = sc.nextInt(); sc.nextLine(); // Clear scanner's buffer return value; } else { System.out.print("Please given an integer: "); sc.nextLine(); // Clear buffer from bad input } } while (true); } /** * Method for reading doubles * Keeps asking for an double until one is given. */ public static double readDouble(){ do { if (sc.hasNextDouble()){ // Check if proper value is given . double value = sc.nextDouble(); sc.nextLine(); // Clear scanner's buffer return value; } else { System.out.print("Please given a number: "); sc.nextLine(); // Clear buffer from bad input } } while (true); } } /** * Harjoitus 24 * Esimerkkiratkaisun laati Mikko Apiola, bugit korjasi Janne Korhonen * * (Tämä on siis ratkaisu suomenkieliseen versioon harjoitus 24:stä. Ensimmäinen * Viljavarasto käyttää Pikkuvarastoa, toisessa sen sijaan pikkuvarasto on korvattu * tehtävään paremmin soveltuvalla Siilolla, jossa on sisäänrakennettuna vetoisuus * sekä muutenkin Viljavaraston kannalta mukavammin toteutetut aksessorit. * * -Janne Korhonen) * /* HUOM! Viljavarasto vaatii toimiakseen Pikkuvarasto:n.*/ import java.util.Scanner; public class Viljavarasto { private Pikkuvarasto siilo1, siilo2; private double siilo1vetoisuus, siilo2vetoisuus; public Viljavarasto(double ekaSiilo, double tokaSiilo) { siilo1 = new Pikkuvarasto(0, "Vilja"); siilo2 = new Pikkuvarasto(0, "Vilja"); siilo1vetoisuus = ekaSiilo; siilo2vetoisuus = tokaSiilo; } public double ekassaOn() { return siilo1.paljonkoOn(); } public double tokassaOn() { return siilo2.paljonkoOn(); } public boolean siirraViljaa(double määrä, boolean ekasta) { if (määrä < 0) return false; if (ekasta) { // jos siilo1:ssä on tarpeeksi, ja jos siilo2:ssa on tilaa if ( (ekassaOn() >= määrä ) && (siilo2vetoisuus - tokassaOn() >= määrä) ) { siilo1.otaVarastosta(määrä); siilo2.vieVarastoon(määrä); return true; } } else { // jos siilo2:ssa on tarpeeksi, ja jos siilo1:ssä on tilaa if ( (tokassaOn() >= määrä) && (siilo1vetoisuus - ekassaOn() >= määrä) ) { siilo2.otaVarastosta(määrä); siilo1.vieVarastoon(määrä); return true; } } return false; } public boolean lisaaViljaa(double määrä) { if ((määrä > (siilo1vetoisuus - ekassaOn())) || (määrä < 0)) return false; siilo1.vieVarastoon(määrä); return true; } public double otaViljaa(double määrä) { return siilo1.otaVarastosta(määrä); } public void hiirivahinko(double vakavuus) { if (vakavuus < 0) return; siilo1.otaVarastosta( ekassaOn() * vakavuus / 100 ); siilo2.otaVarastosta( tokassaOn() * vakavuus / 100 ); } public String toString() { String s = "\nSiilo1 (vetoisuus " + siilo1vetoisuus + ")\n * Sisältö: "+ siilo1; s += "\nSiilo2 (vetoisuus "+siilo2vetoisuus + ")\n * Sisältö: "+ siilo2; return s; } private static Scanner lukija = new Scanner(System.in); public static void main (String [] args) { Viljavarasto v = new Viljavarasto (1000,100); System.out.println(v); v.lisaaViljaa ( 1500 ); System.out.println(v); v.lisaaViljaa ( 500 ); System.out.println(v); v.siirraViljaa( 300, true ); System.out.println(v); v.siirraViljaa( 80, true ); System.out.println(v); v.otaViljaa(5); System.out.println(v); double hiiriprosentti = 10; v.hiirivahinko( hiiriprosentti ); System.out.println(v); } } /* Paranneltu viljavarasto, joka ei käytä Pikkuvarastoa, vaan Siilo-luokkaa */ import java.util.Scanner; public class Viljavarasto2 { private Siilo siilo1, siilo2; public Viljavarasto2(double ekaSiilo, double tokaSiilo) { siilo1 = new Siilo(ekaSiilo, 0); siilo2 = new Siilo(tokaSiilo, 0); } public double ekassaOn() { return siilo1.annaMäärä(); } public double tokassaOn() { return siilo2.annaMäärä(); } public boolean siirraViljaa(double määrä, boolean ekasta) { return ekasta ? siilo2.siirrä(siilo1,määrä) : siilo1.siirrä(siilo2,määrä); /* if (ekasta) return siilo2.siirrä(siilo1,määrä); else return siilo1.siirrä(siilo2,määrä); */ } public boolean lisaaViljaa(double määrä) { return siilo1.lisää(määrä); } public double otaViljaa(double määrä) { return siilo1.ota(määrä); } public void hiirivahinko(double vakavuus) { if (vakavuus < 0) return; siilo1.ota( ekassaOn() * vakavuus / 100 ); siilo2.ota( tokassaOn() * vakavuus / 100 ); } public String toString() { return "\nSiilo1: "+ siilo1 + "\nSiilo2: "+siilo2; } private static Scanner lukija = new Scanner(System.in); public static void main (String [] args) { Viljavarasto v = new Viljavarasto (1000,100); System.out.println(v); v.lisaaViljaa ( 1500 ); System.out.println(v); v.lisaaViljaa ( 500 ); System.out.println(v); v.siirraViljaa( 300, true ); System.out.println(v); v.siirraViljaa( 80, true ); System.out.println(v); v.otaViljaa(5); System.out.println(v); double hiiriprosentti = 10; v.hiirivahinko( hiiriprosentti ); System.out.println(v); } } /* Viljavarasto2:n käyttämä Siilo-luokka */ public class Siilo { private double määrä; // viljan määrä >= 0 private double vetoisuus; // siilon vetoisuus public Siilo() { this(0.0, 10); } public Siilo(double vetoisuus, double määrä) { if (vetoisuus > 0) this.vetoisuus = vetoisuus; else this.vetoisuus = 0.0; if (määrä > 0) this.määrä = määrä; else this.määrä = 0.0; if (this.määrä > this.vetoisuus) this.määrä = this.vetoisuus; } public double annaMäärä() { return this.määrä; } public double annaVetoisuus() { return this.vetoisuus; } public boolean lisää(double paljonko) { if (paljonko < 0) return false; if (this.määrä + paljonko > this.vetoisuus) return false; else this.määrä += paljonko; return true; } public boolean siirrä(Siilo siilosta, double paljonko) { if (siilosta.annaMäärä() <= paljonko) return false; if (this.vetoisuus - this.määrä <= paljonko) return false; this.määrä += siilosta.ota( paljonko ); return true; } public double ota(double paljonko) { if (paljonko <= 0) return 0; if (paljonko <= this.määrä) { this.määrä -= paljonko; return paljonko; } else { paljonko = this.määrä; this.määrä = 0; return paljonko; } } public String toString() { return "(vetoisuus:"+this.vetoisuus+", määrä:"+this.määrä+")"; } } /** * Exercise 25 * Example solution by Olli Lahti * Translated by Vesa Vainio * Commented and edited by Janne Korhonen */ import java.util.Scanner; public class QuizMaster { private static Scanner reader = new Scanner(System.in); private String questionBeginning, questionEnd; private boolean isCaseSensitive; private int questionCount, correctCount; public QuizMaster(String questionBeginning, String questionEnd) { if (questionBeginning != null) this.questionBeginning = questionBeginning; else // Handle null parameter this.questionBeginning = ""; if (questionEnd != null) this.questionEnd = questionEnd; else // Handle null this.questionEnd = "?"; this.isCaseSensitive = false; this.questionCount = this.correctCount = 0; } /** * The answer will be accepted as correct even if it contains extra spaces * at beginning or at the end. The method returns true if the answer is * right, false otherwise. */ public boolean ask(String asked, String correctAnswer) { System.out.println(this.questionBeginning + asked + " " + this.questionEnd); // Ask the question String guess = reader.nextLine(); // Get the answer if (guess == null) guess = ""; // handle a missing string guess = guess.trim(); // Remove extra spaces this.questionCount++; // Check if the answer is ok if ((!this.isCaseSensitive && guess.equalsIgnoreCase(correctAnswer)) || (this.isCaseSensitive && guess.equals(correctAnswer))) { System.out.println("CORRECT!"); this.correctCount++; return true; } else { System.out.println("WRONG! The correct answer is \"" + correctAnswer + "\"."); return false; } } /** * If the method has most recently been called with the value true, lower * case letters and upper case letters will be consired the same. If most * recent call has been with parameter false, lower case letters and upper * case letters will be treated as different characters. The default is * setCaseOff(false). It is possible to change this value for each question, * if necessary. */ public void setCaseSensitive(boolean isCaseSensitive) { this.isCaseSensitive = isCaseSensitive; } /** * Returns the number of questions asked this far. */ public int getQuestionCount() { return this.questionCount; } /** * Returns the number of correct answers this far. */ public int getCorrectCount() { return this.correctCount; } // ------------------------------------------------------------------------ public static void main(String[] args) { QuizMaster quiz = new QuizMaster("What is the Italian phrase ", "in English?"); quiz.setCaseSensitive(false); boolean correct; correct = quiz.ask("tutti", "all"); if (correct) System.out.println("Great, good start!"); quiz.ask("ferro", "iron"); // You can call the method even // without assigning the return value to anywhere! correct = quiz.ask("matto", "crazy"); if (!correct) System.out.println("Why did you say that?"); quiz.ask("madre", "mother"); quiz.ask("cavallo", "horse"); quiz.ask("birra", "beer"); System.out.println("You got "+quiz.correctCount+" correct answers."); System.out.println("Total number of questions was "+quiz.questionCount+"."); } }