Exercises from labs 2023-2024
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

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