import java.util.Calendar; import java.util.Random; import java.util.Scanner; import java.util.concurrent.ThreadLocalRandom; class runLabs { public static void main(String[] args) { // new Lab4(); // new Lab5(); new Lab6(); // new Lab7(); } } class Exercise { private int _exerciseNumber; public Exercise(int s) { this._exerciseNumber = s; this.printExercise(); } public void printExercise() { String title = String.format("Starting exercise %s", this._exerciseNumber); System.out.println("-".repeat(title.length())); System.out.println(String.format("%s", title)); System.out.println("-".repeat(title.length())); } public int get_exerciseNumber() { return _exerciseNumber; } public void set_exerciseNumber(int _exerciseNumber) { this._exerciseNumber = _exerciseNumber; } } class Lab { private int _labNumber; public Exercise currentExercise; public Lab(int lN) { String title = String.format("|Starting Lab %s|", lN); this._labNumber = lN; System.out.println("*".repeat(title.length())); System.out.println(title); System.out.println("*".repeat(title.length())); } public Exercise getCurrentExercise() { return currentExercise; } public void setCurrentExercise(Exercise currentSection) { this.currentExercise = currentSection; } public static void printSection(String section) { String title = String.format("Starting exercise %s", section); System.out.println("-".repeat(title.length())); System.out.println(String.format("%s", title)); System.out.println("-".repeat(title.length())); } public int getLabNumber() { return this._labNumber; } } class Lab4 extends Lab { public Lab4() { super(4); // ex44(); ex46(); } // public static void main(String[] args) { // } public static void ex41() { String labSection = "4.1"; // System.out.println(String.format("Starting section %s", labSection)); printSection(labSection); int testYear1 = 1996; // true int testYear2 = 1997; // false int testYear3 = 2000; // true int testYear4 = 9332; // true int testYear5 = 1900; // false int randomYear = ThreadLocalRandom.current().nextInt(1, 9999 + 1); System.out.println(String.format("Testing %s", testYear1)); System.out.println(String.format("%s", isLeap(testYear1))); System.out.println(String.format("Testing %s", testYear2)); System.out.println(String.format("%s", isLeap(testYear2))); System.out.println(String.format("Testing %s", testYear3)); System.out.println(String.format("%s", isLeap(testYear3))); System.out.println(String.format("Testing %s", testYear4)); System.out.println(String.format("%s", isLeap(testYear4))); System.out.println(String.format("Testing %s", randomYear)); System.out.println(String.format("%s", isLeap(randomYear))); System.out.println(String.format("Testing %s", testYear5)); } public static void ex44() { String labSection = "4.4"; printSection(labSection); // System.out.println("------------------------"); // System.out.println("Starting lab section " + labSection); // System.out.println("------------------------"); String month1 = "oct"; int year1 = 2000; System.out.println(String.format("Month: %s\tYear: %d\tDays in month: %d", month1, year1, monthLen(month1, year1))); String month2 = "feb"; int year2 = 2000; System.out.println(String.format("Month: %s\tYear: %d\tDays in month: %d", month2, year2, monthLen(month2, year2))); String month3 = "feb"; int year3 = 1997; System.out.println(String.format("Month: %s\tYear: %d\tDays in month: %d", month3, year3, monthLen(month3, year3))); String month4 = "apr"; int year4 = 2001; System.out.println(String.format("Month: %s\tYear: %d\tDays in month: %d", month4, year4, monthLen(month4, year4))); } /** * Lab section 4.5 * * Write a program that can calculate how many whole years old someone is from * today’s date and their date of birth. You could store each date as three * integers (day, month, year) */ public static void ex46() { String labSection = "4.6"; printSection(labSection); // calculate whole years' old to date Calendar today = Calendar.getInstance(); System.out.println("Today:\t" + today.getTime()); Calendar dob1 = Calendar.getInstance(); dob1.set(1990, 1, 1); System.out.println(String.format( "DOB 1:\t%s (difference:\t%d years)", dob1.getTime(), yearsOld(today, dob1))); Calendar dob2 = Calendar.getInstance(); dob2.set(1994, 11, 22); System.out.println(String.format( "DOB 2:\t%s (difference:\t%d years)", dob2.getTime(), yearsOld(today, dob2))); Calendar dob3 = Calendar.getInstance(); dob3.set(2000, 8, 19); // 23 years old System.out.println(String.format( "DOB 3:\t%s (difference:\t%d years)", dob3.getTime(), yearsOld(today, dob3))); Calendar dob4 = Calendar.getInstance(); dob4.set(2000, 8, 20); // 23 years old System.out.println(String.format( "DOB 4:\t%s (difference:\t%d years)", dob4.getTime(), yearsOld(today, dob4))); Calendar dob5 = Calendar.getInstance(); dob5.set(2000, 8, 21); // 22 years old System.out.println(String.format( "DOB 5:\t%s (difference:\t%d years)", dob5.getTime(), yearsOld(today, dob5))); } public static boolean isLeap(int year) { if (year % 4 != 0) { return false; } else { if (year % 100 == 0) { if (year % 400 == 0) { return true; } else { return false; } } return true; } } public static int monthLen(String month, int year) { if (month == "feb") { if (isLeap(year)) { return 29; } else { return 28; } } else if ( (month == "apr") || (month == "jun") || (month == "sep") || (month == "nov")) { return 30; } else { return 31; } } public static int yearsOld(Calendar laterDate, Calendar earlierDate) { int birthdayModifier = 0; // we assume they've had their birthday // we could probably do this with one if, checking DAY_OF_YEARs, // but since problem spec mentioned months and days we should really // pay attention to those if (earlierDate.get(Calendar.MONTH) > laterDate.get(Calendar.MONTH)) { // ie 8 (August) < 9 (September) birthdayModifier = -1; // not had their birthday yet so take 1 year off difference } else if (earlierDate.get(Calendar.MONTH) == laterDate.get(Calendar.MONTH)) { if (earlierDate.get(Calendar.DAY_OF_MONTH) > laterDate.get(Calendar.DAY_OF_MONTH)) { birthdayModifier = -1; } } return (int) Math.abs(laterDate.get(Calendar.YEAR) - earlierDate.get(Calendar.YEAR) + birthdayModifier ); } } /** * Keyboard input */ class Lab5 extends Lab { public Lab5() { super(5); // new five1(); // new five5(); // new five6(); new five7(); } class five1 extends Exercise { /** * We will now look at how we can get user input from the keyboard. We will * gloss over some * of the details here, but give you just the information you need to start * getting input and * processing it. */ public five1() { super(1); Scanner keyboard = new Scanner(System.in); System.out.println("Please enter your name, followed by the return key?"); String userEntry = keyboard.nextLine(); System.out.println("Hello " + userEntry); System.out.println(String.format("%s", keyboard)); System.out.println("Please enter your age"); int userAge = keyboard.nextInt(); // keyboard.nextLine(); System.out.println("You are " + userAge + " years old"); System.out.println("What is your favourite colour?"); String col = keyboard.nextLine(); } } /** * Prompt for input and summarise a circle * */ class five5 extends Exercise { public five5() { super(5); userCircles(); } public void userCircles() { Scanner kbIn = new Scanner(System.in); System.out.println(String.format("Please supply a radius, that I might describe you a circle")); double radius = kbIn.nextDouble(); kbIn.nextLine(); summariseCircle(radius); kbIn.close(); } public void summariseCircle(double radius) { System.out.println(String.format("A circle with radius %.2f has circumference %.2f and radius %.2f", radius, compCircumference(radius), compArea(radius))); } public double compCircumference(double radius) { return (2 * Math.PI * radius); } public double compArea(double radius) { return (Math.PI * Math.pow(radius, 2)); } } /** * {@link Scanner} understanding - actually process input * */ class five6 extends Exercise { public five6() { super(6); getNameAndAge(); } public void getNameAndAge() { String userName; int userAge; Scanner kbIn = new Scanner(System.in); System.out.println(String.format("Please enter your name and age separated by a space")); String userInput = kbIn.nextLine(); Scanner inputOps = new Scanner(userInput); userName = inputOps.next(); // TOASK -- is this what 'add an extra line that fixes this problem' was going for? while (!inputOps.hasNextInt()) { userName += " " + inputOps.next(); } if (inputOps.hasNextInt()) { userAge = inputOps.nextInt(); } else { userAge = 0; } System.out.println(String.format("Your name is %s and your age is %d", userName, userAge)); kbIn.close(); inputOps.close(); } } /** * Get DOB from user input and calculate age using {@link Lab4.ex46()} * */ class five7 extends Exercise { public five7() { super(7); showUserAge(); } public void showUserAge() { Scanner userInput = new Scanner(System.in); System.out.println(String.format("Please input your DOB")); System.out.println(String.format("input format is YYYY M D")); String inputString = userInput.nextLine(); Scanner processInput = new Scanner(inputString); int dobYear = processInput.nextInt(); int dobMonth = processInput.nextInt(); int dobDay = processInput.nextInt(); // input sanitisation could be nice... Calendar userDOB = Calendar.getInstance(); // recall months are zero-indexed! userDOB.set(dobYear, dobMonth-1, dobDay); Calendar today = Calendar.getInstance(); System.out.println(String.format("Today:\t%s", today.getTime())); System.out.println(String.format( "DOB :\t%s (difference: %d years)", userDOB.getTime(), Lab4.yearsOld(today, userDOB))); userInput.close(); processInput.close(); } } } /** * Loops */ class Lab6 extends Lab { public Lab6() { super(6); new six1(); System.out.println(String.format("%n")); new six3(); new six6(); new six7(); new six8(); new six9(); // new six5(); } /** * Times tables */ class six1 extends Exercise { public six1() { super(1); int testNum = 6; System.out.println(String.format("Times table for %d:", testNum)); writeTimesTable(7); } } class six3 extends Exercise { public six3() { super(3); int testNum = 13; // statistically the most prime of all numbers System.out.println(String.format("Testing primes...")); System.out.println(String.format("%d prime? %s", testNum, isPrime(testNum))); System.out.println(String.format("%d prime? %s", 23, isPrime(23))); System.out.println(String.format("%d prime? %s", 27, isPrime(27))); System.out.println(String.format("%d prime? %s", 28, isPrime(28))); System.out.println(String.format("%d prime? %s", 299, isPrime(299))); System.out.println(String.format("Generating primes...")); generatePrimes(1024); System.out.println(String.format("Done!%n")); } } /** * Number guessing game * Random number between 0 and 99, user guesses and is told higher / lower / correct */ class six5 extends Exercise { private Random random = new Random(); public six5() { super(5); numberGuessingGame(); } public void numberGuessingGame() { final boolean SUPER_ADVANCED_AI = false; // true - simulated guesses, false - stdin final Scanner userInput = new Scanner(System.in); final int HIGHEST = 99; final int MAX_GUESSES = 10; int guess; int chosenNumber = random.nextInt(HIGHEST + 1); // super advanced AI section int maxPossible = HIGHEST + 1; int minPossible = 0; String guesses = "guess"; // for correct plurals if (SUPER_ADVANCED_AI) { guess = random.nextInt(HIGHEST+1); } else { guess = getUserGuess(userInput); } System.out.printf("Guessing...\t"); for (int i = 0; i < MAX_GUESSES; i++ ) { System.out.printf("%d", guess); if (guess == chosenNumber) { System.out.println(String.format("\nYou guessed right after %d %s! It was indeed %d", i+1, guesses, chosenNumber)); userInput.close(); return; } guesses = "guesses"; // didn't get it on the first try if (guess < chosenNumber) { System.out.printf("↑\t"); if (guess > minPossible) { minPossible = guess; } } else { System.out.printf("↓\t"); if (guess < maxPossible) { maxPossible = guess; } } // The better approach is to guess halfway between minPossible and maxPossible // but that's kinda boring and robotic if (SUPER_ADVANCED_AI) { guess = randomBetween(minPossible, maxPossible); } else { guess = getUserGuess(userInput); } // TODO change the behaviour so it doesn't guess the same number in a row } System.out.println(String.format("\nThe answer was: %d. Better luck next time!", chosenNumber)); userInput.close(); } public int randomBetween(int min, int max) { if (min < 0) { min = 0; } if (max == 0) { return 0; } // System.out.printf(" random.nextInt(%d - %d) + %d ", max, min, min); return (random.nextInt(max - min) + min); } public int getUserGuess(Scanner userInput) { System.out.println(String.format("Please enter an integer between 0 and 99 to guess")); int guess = userInput.nextInt(); userInput.nextLine(); return guess; } } /** * Produce a number triangle * * eg: * 1 * 2 2 * 3 3 3 * 4 4 4 4 */ class six6 extends Exercise { public six6() { super(6); numberTriangle(1); numberTriangle(4); numberTriangle(8); numberTriangle(29); } } class six7 extends Exercise { public six7() { super(7); describeDD(4.2, 1.6); describeDD(47.42, 7.9); } /** Simple exposition of double division * @param num1 Dividend * @param num2 Divisor */ public void describeDD(double num1, double num2) { System.out.println(String.format("Double division of %.2f by %.2f:\t", num1, num2)); DoubleDivisionResult result = doubleDivision(num1, num2); System.out.println(String.format("Quotient: %d (ie %.2f ✕ %d = %.2f)\tRemainder: %.2f", result.getQuotient(), num2, result.getQuotient(), (num2 * result.getQuotient()), result.getRemainder())); } } /** * Exercise 8 - String pad with specified character */ class six8 extends Exercise { public six8() { super(8); describeStringPadding("NoNeed", 4, '!'); describeStringPadding("Simon", 10, '@'); describeStringPadding("Zaphod Beeblebrox", 42, '?'); // describeStringPadding("Unicode", 10, '🤯'); aww } /** * Print for display what we're padding and the result * * @param toPad The string to pad eg "Simon" * @param length Desired length * @param padChar Character to pad with */ public void describeStringPadding(String toPad, int paddedLength, char padChar) { System.out.println(String.format("Padding '%s' to length %d using padding character: %s", toPad, paddedLength, padChar)); System.out.println(stringLPad(toPad, paddedLength, padChar)); } /** * (Left-)pad a string with the specific character * * @param toPad The string to pad eg "Simon" * @param length Desired length * @param padChar Character to pad with * @return The padded result */ public static String stringLPad(String toPad, int paddedLength, char padChar) { // early out - return unmodified if (toPad.length() >= paddedLength) { return toPad; } // note that we could do this with String.repeat(), but since this is in the 'Loops' // part of the lab, we should probably do this with a loop // String paddedString = String.valueOf(padChar) + toPad; String paddedString = toPad; while (paddedString.length() < paddedLength) { paddedString = String.valueOf(padChar) + paddedString; } return paddedString; } } class six9 extends Exercise { private Random random = new Random(); // initialise once // see https://stackoverflow.com/a/35277291, to pick a random member of an enum, first convert it to an array private Throw[] throwsArray = Throw.values(); // can't call it 'throws' for obvious reasons final Throw randomThrow() { return throwsArray[random.nextInt(throwsArray.length)]; } public six9() { super(9); Throw player1 = Throw.ROCK; // "Good ol' rock, nothing beats that" Throw player2 = randomThrow(); System.out.println(String.format("Playing three games to warm up:")); playRockPaperScissors(player1, player2); player2 = randomThrow(); playRockPaperScissors(player1, player2); player2 = randomThrow(); playRockPaperScissors(player1, player2); System.out.println(String.format("Grand. Now it's your turn!")); player1 = getUserThrow(); playRockPaperScissors(player1, player2); } } public Throw getUserThrow() { Scanner userInput = new Scanner(System.in); // Throw userThrow = null; while (true) { System.out.println(String.format("Please enter your throw:")); System.out.println(String.format("\t0 (rock), 1 (paper), 2 (scissors)")); System.out.println(String.format("\tor the word corresponding to the throw you'd like")); System.out.println(String.format("\t[q / quit] quits")); // check for number if (userInput.hasNextInt()) { int choiceNumber = userInput.nextInt(); if ((choiceNumber < 0) || (choiceNumber > 2)) { continue; } else { userInput.close(); Throw[] throwsArray = Throw.values(); return throwsArray[choiceNumber]; } } else if (userInput.hasNext()) { String choiceString = userInput.nextLine(); switch (choiceString.toLowerCase()) { case "rock": case "stone": userInput.close(); return Throw.ROCK; case "paper": userInput.close(); return Throw.PAPER; case "scissors": userInput.close(); return Throw.SCISSORS; case "q": case "quit": userInput.close(); System.exit(0); default: continue; } } } } public void playRockPaperScissors (Throw player1, Throw player2) { // slight semantic overload with throwing an error but I think that's the term // for plays in RPS String result; // early out - TOASK why this doesn't work when it works in a REPL!! // answered - umm, I forgot the else >_< if (player1 == player2) { result = "a draw"; } else { switch (player1) { case ROCK: if (player2 == Throw.SCISSORS) { result = "R>S Player 1 wins"; } else { result = "R
MAXNUM)) { System.err.println(String.format("Please specify a number between %.2f and %.2f (supplied: %.2f)", MINNUM, MAXNUM, num)); return; } if ((limit < MINLIMIT) || (limit > MAXLIMIT)) { System.err.println(String.format("Please specify a limit between %d and %d (supplied: %d)", MINLIMIT, MAXLIMIT, limit)); return; } for (int i = 0; i < (limit + 1); i++) { // output specification: // ~~.~~~ x ~~ = ~~~~~.~~~ System.out.printf("%2.3f x %02d = %5.3f%n", num, i, (num*i)); } } }