Exercises from labs 2023-2024
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

574 line
18 KiB

  1. import java.util.Calendar;
  2. import java.util.Scanner;
  3. import java.util.concurrent.ThreadLocalRandom;
  4. class runLabs {
  5. public static void main(String[] args) {
  6. new Lab4();
  7. new Lab5();
  8. new Lab6();
  9. new Lab7();
  10. }
  11. }
  12. class Exercise {
  13. private int _exerciseNumber;
  14. public Exercise(int s) {
  15. this._exerciseNumber = s;
  16. this.printExercise();
  17. }
  18. public void printExercise() {
  19. String title = String.format("Starting exercise %s", this._exerciseNumber);
  20. System.out.println("-".repeat(title.length()));
  21. System.out.println(String.format("%s", title));
  22. System.out.println("-".repeat(title.length()));
  23. }
  24. public int get_exerciseNumber() {
  25. return _exerciseNumber;
  26. }
  27. public void set_exerciseNumber(int _exerciseNumber) {
  28. this._exerciseNumber = _exerciseNumber;
  29. }
  30. }
  31. class Lab {
  32. private int _labNumber;
  33. public Exercise currentExercise;
  34. public Lab(int lN) {
  35. String title = String.format("|Starting Lab %s|", lN);
  36. this._labNumber = lN;
  37. System.out.println("*".repeat(title.length()));
  38. System.out.println(title);
  39. System.out.println("*".repeat(title.length()));
  40. }
  41. public Exercise getCurrentExercise() {
  42. return currentExercise;
  43. }
  44. public void setCurrentExercise(Exercise currentSection) {
  45. this.currentExercise = currentSection;
  46. }
  47. public static void printSection(String section) {
  48. String title = String.format("Starting exercise %s", section);
  49. System.out.println("-".repeat(title.length()));
  50. System.out.println(String.format("%s", title));
  51. System.out.println("-".repeat(title.length()));
  52. }
  53. public int getLabNumber() {
  54. return this._labNumber;
  55. }
  56. }
  57. class Lab4 extends Lab {
  58. public Lab4() {
  59. super(4);
  60. ex44();
  61. ex46();
  62. }
  63. // public static void main(String[] args) {
  64. // }
  65. public static void ex41() {
  66. String labSection = "4.1";
  67. // System.out.println(String.format("Starting section %s", labSection));
  68. printSection(labSection);
  69. int testYear1 = 1996; // true
  70. int testYear2 = 1997; // false
  71. int testYear3 = 2000; // true
  72. int testYear4 = 9332; // true
  73. int testYear5 = 1900; // false
  74. int randomYear = ThreadLocalRandom.current().nextInt(1, 9999 + 1);
  75. System.out.println(String.format("Testing %s", testYear1));
  76. System.out.println(String.format("%s", isLeap(testYear1)));
  77. System.out.println(String.format("Testing %s", testYear2));
  78. System.out.println(String.format("%s", isLeap(testYear2)));
  79. System.out.println(String.format("Testing %s", testYear3));
  80. System.out.println(String.format("%s", isLeap(testYear3)));
  81. System.out.println(String.format("Testing %s", testYear4));
  82. System.out.println(String.format("%s", isLeap(testYear4)));
  83. System.out.println(String.format("Testing %s", randomYear));
  84. System.out.println(String.format("%s", isLeap(randomYear)));
  85. System.out.println(String.format("Testing %s", testYear5));
  86. }
  87. public static void ex44() {
  88. String labSection = "4.4";
  89. printSection(labSection);
  90. // System.out.println("------------------------");
  91. // System.out.println("Starting lab section " + labSection);
  92. // System.out.println("------------------------");
  93. String month1 = "oct";
  94. int year1 = 2000;
  95. System.out.println(String.format("Month: %s\tYear: %d\tDays in month: %d",
  96. month1, year1, monthLen(month1, year1)));
  97. String month2 = "feb";
  98. int year2 = 2000;
  99. System.out.println(String.format("Month: %s\tYear: %d\tDays in month: %d",
  100. month2, year2, monthLen(month2, year2)));
  101. String month3 = "feb";
  102. int year3 = 1997;
  103. System.out.println(String.format("Month: %s\tYear: %d\tDays in month: %d",
  104. month3, year3, monthLen(month3, year3)));
  105. String month4 = "apr";
  106. int year4 = 2001;
  107. System.out.println(String.format("Month: %s\tYear: %d\tDays in month: %d",
  108. month4, year4, monthLen(month4, year4)));
  109. }
  110. /**
  111. * Lab section 4.5
  112. *
  113. * Write a program that can calculate how many whole years old someone is from
  114. * today’s date and their date of birth. You could store each date as three
  115. * integers (day,
  116. * month, year)
  117. */
  118. public static void ex46() {
  119. String labSection = "4.6";
  120. printSection(labSection);
  121. // calculate whole years' old to date
  122. Calendar today = Calendar.getInstance();
  123. System.out.println("Today:\t" + today.getTime());
  124. Calendar dob1 = Calendar.getInstance();
  125. dob1.set(1990, 1, 1);
  126. System.out.println(String.format(
  127. "DOB 1:\t%s (difference:\t%d years)",
  128. dob1.getTime(),
  129. yearDifference(today, dob1)));
  130. Calendar dob2 = Calendar.getInstance();
  131. dob2.set(1994, 12, 22);
  132. System.out.println(String.format(
  133. "DOB 2:\t%s (difference:\t%d years)",
  134. dob2.getTime(),
  135. yearDifference(today, dob2)));
  136. }
  137. public static boolean isLeap(int year) {
  138. if (year % 4 != 0) {
  139. return false;
  140. } else {
  141. if (year % 100 == 0) {
  142. if (year % 400 == 0) {
  143. return true;
  144. } else {
  145. return false;
  146. }
  147. }
  148. return true;
  149. }
  150. }
  151. public static int monthLen(String month, int year) {
  152. if (month == "feb") {
  153. if (isLeap(year)) {
  154. return 29;
  155. } else {
  156. return 28;
  157. }
  158. } else if (
  159. (month == "apr") ||
  160. (month == "jun") ||
  161. (month == "sep") ||
  162. (month == "nov")) {
  163. return 30;
  164. } else {
  165. return 31;
  166. }
  167. }
  168. public static int yearDifference(Calendar date1, Calendar date2)
  169. {
  170. return (int) Math.abs(date1.get(Calendar.YEAR) -
  171. date2.get(Calendar.YEAR)
  172. );
  173. }
  174. }
  175. /**
  176. * Keyboard input
  177. */
  178. class Lab5 extends Lab {
  179. public Lab5() {
  180. super(5);
  181. new five1();
  182. }
  183. class five1 extends Exercise {
  184. /**
  185. * We will now look at how we can get user input from the keyboard. We will
  186. * gloss over some
  187. * of the details here, but give you just the information you need to start
  188. * getting input and
  189. * processing it.
  190. */
  191. public five1() {
  192. super(1);
  193. System.out.println(String.format("TBC"));
  194. // Scanner keyboard = new Scanner(System.in);
  195. // System.out.println("Please enter your name, followed by the return key?");
  196. // String userEntry = keyboard.nextLine();
  197. // System.out.println("Hello " + userEntry);
  198. // System.out.println(String.format("%s", keyboard));
  199. }
  200. }
  201. }
  202. /**
  203. * Loops
  204. */
  205. class Lab6 extends Lab {
  206. public Lab6() {
  207. super(6);
  208. new six1();
  209. System.out.println(String.format("%n"));
  210. new six3();
  211. new six5();
  212. new six6();
  213. new six7();
  214. new six8();
  215. new six9();
  216. }
  217. /**
  218. * Times tables
  219. */
  220. class six1 extends Exercise {
  221. public six1() {
  222. super(1);
  223. int testNum = 6;
  224. System.out.println(String.format("Times table for %d:", testNum));
  225. writeTimesTable(7);
  226. }
  227. }
  228. class six3 extends Exercise {
  229. public six3() {
  230. super(3);
  231. int testNum = 13; // statistically the most prime of all numbers
  232. System.out.println(String.format("Testing primes..."));
  233. System.out.println(String.format("%d prime? %s", testNum, isPrime(testNum)));
  234. System.out.println(String.format("%d prime? %s", 23, isPrime(23)));
  235. System.out.println(String.format("%d prime? %s", 27, isPrime(27)));
  236. System.out.println(String.format("%d prime? %s", 28, isPrime(28)));
  237. System.out.println(String.format("%d prime? %s", 299, isPrime(299)));
  238. System.out.println(String.format("Generating primes..."));
  239. generatePrimes(1024);
  240. System.out.println(String.format("Done!%n"));
  241. }
  242. }
  243. class six5 extends Exercise {
  244. public six5() {
  245. super(5);
  246. System.out.println(String.format("TODO / NOT IMPLEMENTED until we get stdin working"));
  247. }
  248. }
  249. /**
  250. * Produce a number triangle
  251. *
  252. * eg:
  253. * 1
  254. * 2 2
  255. * 3 3 3
  256. * 4 4 4 4
  257. */
  258. class six6 extends Exercise {
  259. public six6() {
  260. super(6);
  261. numberTriangle(1);
  262. numberTriangle(4);
  263. numberTriangle(8);
  264. numberTriangle(29);
  265. }
  266. }
  267. class six7 extends Exercise {
  268. public six7() {
  269. super(7);
  270. describeDD(4.2, 1.6);
  271. describeDD(47.42, 7.9);
  272. }
  273. /** Simple exposition of double division
  274. * @param num1 Dividend
  275. * @param num2 Divisor
  276. */
  277. public void describeDD(double num1, double num2) {
  278. System.out.println(String.format("Double division of %.2f by %.2f:\t", num1, num2));
  279. DoubleDivisionResult result = doubleDivision(num1, num2);
  280. System.out.println(String.format("Quotient: %d (ie %.2f ✕ %d = %.2f)\tRemainder: %.2f",
  281. result.getQuotient(),
  282. num2,
  283. result.getQuotient(),
  284. (num2 * result.getQuotient()),
  285. result.getRemainder()));
  286. }
  287. }
  288. /**
  289. * Exercise 8 - String pad with specified character
  290. */
  291. class six8 extends Exercise {
  292. public six8() {
  293. super(8);
  294. describeStringPadding("NoNeed", 4, '!');
  295. describeStringPadding("Simon", 10, '@');
  296. describeStringPadding("Zaphod Beeblebrox", 42, '?');
  297. // describeStringPadding("Unicode", 10, '🤯'); aww
  298. }
  299. /**
  300. * Print for display what we're padding and the result
  301. *
  302. * @param toPad The string to pad eg "Simon"
  303. * @param length Desired length
  304. * @param padChar Character to pad with
  305. */
  306. public void describeStringPadding(String toPad, int paddedLength, char padChar) {
  307. System.out.println(String.format("Padding '%s' to length %d using padding character: %s",
  308. toPad, paddedLength, padChar));
  309. System.out.println(stringLPad(toPad, paddedLength, padChar));
  310. }
  311. /**
  312. * (Left-)pad a string with the specific character
  313. *
  314. * @param toPad The string to pad eg "Simon"
  315. * @param length Desired length
  316. * @param padChar Character to pad with
  317. * @return The padded result
  318. */
  319. public String stringLPad(String toPad, int paddedLength, char padChar) {
  320. // early out - return unmodified
  321. if (toPad.length() >= paddedLength) {
  322. return toPad;
  323. }
  324. // note that we could do this with String.repeat(), but since this is in the 'Loops'
  325. // part of the lab, we should probably do this with a loop
  326. // String paddedString = String.valueOf(padChar) + toPad;
  327. String paddedString = toPad;
  328. while (paddedString.length() < paddedLength) {
  329. paddedString = String.valueOf(padChar) + paddedString;
  330. }
  331. return paddedString;
  332. }
  333. }
  334. class six9 extends Exercise {
  335. public six9() {
  336. super(9);
  337. System.out.println(String.format("TODO: ro sham bo once we have stdin working"));
  338. }
  339. }
  340. /* TOASK - is there a better way of returning multiple values in Java?
  341. à la python, ie: return (quotient, remainder)
  342. */
  343. /**
  344. * Wrapper class for returning results from double division
  345. */
  346. final class DoubleDivisionResult {
  347. private int quotient; // that's the number of times something goes into something else
  348. private double remainder; // that's the bit left over
  349. public DoubleDivisionResult(int quotient, double remainder) {
  350. this.quotient = quotient;
  351. this.remainder = remainder;
  352. }
  353. public int getQuotient() {
  354. return quotient;
  355. }
  356. public double getRemainder() {
  357. return remainder;
  358. }
  359. }
  360. /**
  361. * Perform 'double division'
  362. *
  363. * @param dividend Number to be divided
  364. * @param divisor Number to divide by
  365. * @return a {@link DoubleDivisionResult} with the (int) quotient and (double) remainder
  366. */
  367. public DoubleDivisionResult doubleDivision(double dividend, double divisor) {
  368. // example used is 4.2 and 1.6
  369. // should return 2 and 1.0
  370. final boolean DEBUG = false;
  371. double dQuotient = dividend / divisor;
  372. int iQuotient = (int)dQuotient;
  373. double remainder = dividend - (iQuotient * divisor);
  374. if (DEBUG) {
  375. System.out.println(String.format("float quotient: %.2f", dQuotient));
  376. System.out.println(String.format("int quotient: %d", iQuotient));
  377. // TOASK: is there a neater way to do this casting?
  378. }
  379. return new DoubleDivisionResult(iQuotient, remainder);
  380. }
  381. /**
  382. * @param num Size of triangle
  383. */
  384. public void numberTriangle(int num) {
  385. /* Observations:
  386. - for even-sized triangles, preceding number of spaces starts at n=rows and decrements
  387. - for even-sized triangles even numbers have odd spaces and vice versa
  388. TODO: handle multi-digit numbers
  389. */
  390. System.out.println(String.format(""));
  391. int spaces = num;
  392. for (int i = 1; i <= num; i++) {
  393. System.out.println(" ".repeat(spaces)
  394. + String.format("%s ", i).repeat(i)
  395. + " ".repeat(spaces-1)
  396. );
  397. spaces--;
  398. }
  399. System.out.println(String.format(""));
  400. }
  401. /**
  402. * @param num The number to write the times table for
  403. * @param limit How many multiples to show
  404. */
  405. public void writeTimesTable(int num, int limit) {
  406. for (int i = 0; i < (limit + 1); i++) {
  407. System.out.printf("%d\t", num * i);
  408. }
  409. }
  410. /* TOASK - overload example.
  411. Question: is there a better way of doing optional function parameters in java?
  412. */
  413. /**
  414. * Write times table for num (10 entries)
  415. * @param num Number to show times table for
  416. */
  417. public void writeTimesTable(int num) {
  418. int DEFAULT_LIMIT = 10;
  419. writeTimesTable(num, DEFAULT_LIMIT);
  420. }
  421. public void generatePrimes(int upperLimit) {
  422. // handle 2 as a special case
  423. System.out.println(String.format("2"));
  424. // for (int i = 3; i <= upperLimit; i += 2) {
  425. for (int i = 2; i <= upperLimit; i++) {
  426. // TODO: figure out smarter way of doing this, I'm sure primes must be at least 6 apart...
  427. // Something about 2n ± 1 ?
  428. // seive of Erasthotenes ..?
  429. if (isPrime(i)) {
  430. System.out.printf("%d\t", i);
  431. }
  432. }
  433. }
  434. /**
  435. * But is it prime?
  436. * @param num Integer to test for primality
  437. * @return if it's prime
  438. */
  439. public boolean isPrime(int num) {
  440. boolean DEBUG = false;
  441. if ((num == 2) || (num == 1)) {
  442. return true;
  443. }
  444. if (num % 2 == 0){
  445. return false;
  446. } else {
  447. int divisor = 3;
  448. double numSquareRoot = Math.sqrt((double)num);
  449. while (divisor <= numSquareRoot) {
  450. if (num % divisor == 0) {
  451. return false;
  452. }
  453. divisor += 2;
  454. if (DEBUG) {
  455. System.out.printf("%d\t", divisor);
  456. }
  457. }
  458. return true;
  459. }
  460. }
  461. }
  462. /**
  463. * String formatting
  464. *
  465. */
  466. class Lab7 extends Lab {
  467. public Lab7() {
  468. super(7);
  469. writeTimesTable(8.24579, 10);
  470. writeTimesTable(93.12279, 22);
  471. writeTimesTable(193.12279, 22);
  472. writeTimesTable(13.9, 122);
  473. }
  474. /**
  475. * @param num The number to write the times table for (0 <= num <= 99)
  476. * @param limit How many multiples to show (0 <= limit <= 99)
  477. */
  478. public void writeTimesTable(double num, int limit) {
  479. final double MINNUM = 0;
  480. final double MAXNUM = 99;
  481. final int MINLIMIT = 0;
  482. final int MAXLIMIT = 99;
  483. if ((num < MINNUM) || (num > MAXNUM)) {
  484. System.err.println(String.format("Please specify a number between %.2f and %.2f (supplied: %.2f)",
  485. MINNUM, MAXNUM, num));
  486. return;
  487. }
  488. if ((limit < MINLIMIT) || (limit > MAXLIMIT)) {
  489. System.err.println(String.format("Please specify a limit between %d and %d (supplied: %d)",
  490. MINLIMIT, MAXLIMIT, limit));
  491. return;
  492. }
  493. for (int i = 0; i < (limit + 1); i++) {
  494. // output specification:
  495. // ~~.~~~ x ~~ = ~~~~~.~~~
  496. System.out.printf("%2.3f x %02d = %5.3f%n", num, i, (num*i));
  497. }
  498. }
  499. }