commit 953a897f01db0cb615ced2f2ebbbef49d83b93ad Author: Daniel Bulant Date: Mon Sep 22 15:51:40 2025 +0200 first commit diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..ebe51d3 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = false +insert_final_newline = false \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6f66c74 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.zip \ No newline at end of file diff --git a/build.nu b/build.nu new file mode 100644 index 0000000..d83268d --- /dev/null +++ b/build.nu @@ -0,0 +1,13 @@ +ls | where type == "dir" | sort-by name -n | get name | where $it != "common" | +each { |folder| + cd $folder + if not ("common" | path exists) { + ln -s ../common ./common + } + if ("doc.typ" | path exists) { + typst compile doc.typ + } + let zip = ("../" + $folder + ".zip") + rm -f $zip + 7z a $zip * +} \ No newline at end of file diff --git a/common/common.typ b/common/common.typ new file mode 100644 index 0000000..85f02a7 --- /dev/null +++ b/common/common.typ @@ -0,0 +1,13 @@ + +#let template(doc) = [ + #set page(height: auto) + #show link: underline + #set quote(block: true) + #doc +] + +#let embedClass(name: str) = { + show figure: set align(left) + show figure.caption: set align(center) + figure(caption: name, raw(read("../" + name + ".java"), lang:"java", block: true)) +} \ No newline at end of file diff --git a/week1/UseArgument.java b/week1/UseArgument.java new file mode 100644 index 0000000..0ee4271 --- /dev/null +++ b/week1/UseArgument.java @@ -0,0 +1,7 @@ +public class UseArgument { + public static void main(String[] args) { + System.out.print("Hi, "); + System.out.print(args[0]); + System.out.println(". How are you?"); + } +} \ No newline at end of file diff --git a/week1/UseThree.java b/week1/UseThree.java new file mode 100644 index 0000000..d93edd3 --- /dev/null +++ b/week1/UseThree.java @@ -0,0 +1,10 @@ + +public class UseThree { + public static void main(String[] args) { + if (args.length != 3) { + System.out.println("Error: Program expects exactly three arguments"); + return; + } + System.out.printf("Hi %s, %s and %s. How are you?%n", args[2], args[1], args[0]); + } +} \ No newline at end of file diff --git a/week1/common b/week1/common new file mode 120000 index 0000000..60d3b0a --- /dev/null +++ b/week1/common @@ -0,0 +1 @@ +../common \ No newline at end of file diff --git a/week1/doc.pdf b/week1/doc.pdf new file mode 100644 index 0000000..0e61803 Binary files /dev/null and b/week1/doc.pdf differ diff --git a/week1/doc.typ b/week1/doc.typ new file mode 100644 index 0000000..ae60b40 --- /dev/null +++ b/week1/doc.typ @@ -0,0 +1,47 @@ +#import "./common/common.typ" : * + +#show: template + += Week 1 + +== Exercise 1.1.5 + +#embedClass(name: "UseArgument") + +Describe what happens if you try to execute `UseArgument` with each of the +following command lines: + +#set enum(numbering: "a.") + ++ `java UseArgument java` + + Prints `java` as the name: `Hi, java. How are you?` + ++ `java UseArgument @!&^%` + + This will return different results depending on the shell you're using. + If you pass those arguments directly as-is, it will just print `Hi, @!&^%. How are you?`. + + If your shell uses any of these characters, not all arguments may be passed to the java program, you may get an error, or get no output. + For example, in a POSIX-compatible shell like bash, `&` is used as a delimiter to run programs asynchronously (return user control before the program finishes running), and otherwise acts as `;`. An error may be thrown due to `^%` not being a known command. + ++ `java UseArgument 1234` + + Prints `Hi, 1234. How are you?` + ++ `java UseArgument.java Bob` + + Newer Java versions run `javac` if a `.java` file is provided as the class name to run, and then run the compiled bytecode. + ++ `java UseArgument Alice Bob` + + Arguments are whitespace delimited (in most shells), and only the first one is read in the program: + `Hi, Alice. How are you?` + +== Exercise 1.1.6 + +Modify `UseArgument.java` to make a program `UseThree.java` that takes +three names as command-line arguments and prints a proper sentence with the +names in the rev + +#embedClass(name: "UseThree") \ No newline at end of file diff --git a/week2/RandomValues.java b/week2/RandomValues.java new file mode 100644 index 0000000..94f2da9 --- /dev/null +++ b/week2/RandomValues.java @@ -0,0 +1,25 @@ +import java.util.ArrayList; + +class RandomValues { + public static void main(String[] args) { + var numbers = new ArrayList(5); + for (var i = 0; i < 5; i++) + numbers.add(Math.random()); + var min = 1.; + var max = 0.; + var sum = 0.; + for (var num : numbers) { + min = Math.min(num, min); + max = Math.max(num, max); + sum += num; + } + + var avg = sum / numbers.size(); + + for (var num : numbers) { + System.out.printf("%f ", num); + } + System.out.println(); + System.out.printf("Average: %f, Minimum: %f, Maximum: %f%n", avg, min, max); + } +} \ No newline at end of file diff --git a/week2/WindChill.java b/week2/WindChill.java new file mode 100644 index 0000000..0e8b7a2 --- /dev/null +++ b/week2/WindChill.java @@ -0,0 +1,21 @@ + +class WindChill { + public static void main(String[] args) { + if (args.length < 2) { + System.err.println("Usage: [temperature] [velocity]"); + return; + } + var temperature = Double.parseDouble(args[0]); + var velocity = Double.parseDouble(args[1]); + if (Math.abs(temperature) > 50. || velocity > 120. || velocity < 3.) { + System.err.println("Values outside of allowed range."); + return; + } + var wind_chill = WindChill.calculateWindChill(temperature, velocity); + System.out.printf("The effective temperature is %fF.%n", wind_chill); + } + + public static double calculateWindChill(double T, double v) { + return 35.74 + (0.6215 * T) + (0.4275 * T - 35.75) * Math.pow(v, 0.16); + } +} \ No newline at end of file diff --git a/week2/common b/week2/common new file mode 120000 index 0000000..60d3b0a --- /dev/null +++ b/week2/common @@ -0,0 +1 @@ +../common \ No newline at end of file diff --git a/week2/doc.pdf b/week2/doc.pdf new file mode 100644 index 0000000..1a13b54 Binary files /dev/null and b/week2/doc.pdf differ diff --git a/week2/doc.typ b/week2/doc.typ new file mode 100644 index 0000000..2aab333 --- /dev/null +++ b/week2/doc.typ @@ -0,0 +1,31 @@ +#import "./common/common.typ" : * + +#show: template + += Week 2 + +== Exercise 1.2.25 + +_Wind chill_. Given the temperature $T$ (in degrees Fahrenheit) +and the wind speed v (in miles per hour), the National Weather Service +defines the effective temperature (the wind chill) as follows: + +$w = 35.74 + 0.6215 T + (0.4275 T - 35.75) v^0.16$ + +Write a program that takes two double command-line arguments temperature +and velocity and prints the wind chill. Use ```java Math.pow(a, b)``` to +compute $a^b$. Note: +The formula is not valid if $T$ is larger than $50$ in absolute value or +if v is larger than $120$ or less than $3$ (you may assume that the values +you get are in that range). + +#embedClass(name: "WindChill") + +== Exercise 1.2.30 + +_Uniform random numbers_. Write a program that prints five uniform random +numbers between $0$ and $1$, their average value, and their minimum and +maximum values. Use ```java Math.random()```, ```java Math.min()```, and +```java Math.max()```. + +#embedClass(name: "RandomValues") \ No newline at end of file diff --git a/week3/Gambler.java b/week3/Gambler.java new file mode 100644 index 0000000..7825c33 --- /dev/null +++ b/week3/Gambler.java @@ -0,0 +1,29 @@ +public class Gambler { + public static void main(String[] args) { + // Run trials experiments that start with + // $stake and terminate on $0 or $goal. + int stake = Integer.parseInt(args[0]); + int goal = Integer.parseInt(args[1]); + int trials = Integer.parseInt(args[2]); + double probability = Double.parseDouble(args[3]); + int bets = 0; + int wins = 0; + for (int t = 0; t < trials; t++) { + // Run one experiment. + int cash = stake; + while (cash > 0 && cash < goal) { + // Simulate one bet. + bets++; + if (Math.random() < probability) + cash++; + else + cash--; + } + // Cash is either 0 (ruin) or $goal (win). + if (cash == goal) + wins++; + } + System.out.println(100 * wins / trials + "% wins"); + System.out.println("Avg # bets: " + bets / trials); + } +} \ No newline at end of file diff --git a/week3/GamblerPlot.java b/week3/GamblerPlot.java new file mode 100644 index 0000000..aba343a --- /dev/null +++ b/week3/GamblerPlot.java @@ -0,0 +1,36 @@ +public class GamblerPlot { + public static void main(String[] args) { + // Run trials experiments that start with + // $stake and terminate on $0 or $goal. + int stake = Integer.parseInt(args[0]); + int goal = Integer.parseInt(args[1]); + double probability = 0.5; + int bets = 0; + + // Run one experiment. + int cash = stake; + while (cash > 0 && cash < goal) { + // Simulate one bet. + bets++; + if (Math.random() < probability) + cash++; + else + cash--; + + GamblerPlot.printCash(cash); + } + + boolean won = cash == goal; + String wonText = won ? "Won" : "Lost"; + + System.out.println(); + System.out.printf("%s after %s bets", wonText, bets); + } + + public static void printCash(int cash) { + for(int i = 0; i < cash; i++) { + System.out.print("*"); + } + System.out.println(); + } +} \ No newline at end of file diff --git a/week3/RollLoadedDie.java b/week3/RollLoadedDie.java new file mode 100644 index 0000000..5e2d290 --- /dev/null +++ b/week3/RollLoadedDie.java @@ -0,0 +1,10 @@ +public class RollLoadedDie { + public static void main(String[] args) { + double rand8 = Math.random() * 8.; + // floor returns double. Round gives long for double input, so conversion needed + int random = (int)(Math.round(Math.floor(rand8)) + 1); + // 1 - 8 to 1 - 6, with 6 receiving the probabilities of 7 - 8 + random = Math.min(random, 6); + System.out.println(random); + } +} diff --git a/week3/common b/week3/common new file mode 120000 index 0000000..60d3b0a --- /dev/null +++ b/week3/common @@ -0,0 +1 @@ +../common \ No newline at end of file diff --git a/week3/doc.pdf b/week3/doc.pdf new file mode 100644 index 0000000..dfdde9f Binary files /dev/null and b/week3/doc.pdf differ diff --git a/week3/doc.typ b/week3/doc.typ new file mode 100644 index 0000000..7eb2a05 --- /dev/null +++ b/week3/doc.typ @@ -0,0 +1,30 @@ +#import "./common/common.typ" : * + +#show: template + += Week 3 + +== Exercise 1.3.5 + +Write a program `RollLoadedDie` that prints the result of rolling +a loaded die such that the probability of getting a $1$, $2$, $3$, $4$, +or $5$ is $1/8$ and the probability of getting a $6$ is $3/8$. + +#embedClass(name: "RollLoadedDie") + +== Exercise 1.3.24 + +Write a program `GamblerPlot` that traces a gambler's ruin simulation +by printing a line after each bet in which one asterisk corresponds +to each dollar held by the gambler. + +#embedClass(name: "GamblerPlot") + +== Exercise 1.3.25 + +Modify `Gambler` to take an extra command-line argument that specifies +the (fixed) probability that the gambler wins each bet. Use your program +to try to learn how this probability affects the chance of winning and the +expected number of bets. Try a value of $p$ close to $0.5$ (say, $0.48$). + +#embedClass(name: "Gambler") \ No newline at end of file diff --git a/week4/Card.java b/week4/Card.java new file mode 100644 index 0000000..898ca5d --- /dev/null +++ b/week4/Card.java @@ -0,0 +1,120 @@ +public class Card { + public static final String CLUBS = "♣"; + public static final String DIAMONDS = "♦"; + public static final String HEARTS = "♥"; + public static final String SPADES = "♠"; + + public enum Suit { + Clubs, + Diamonds, + Hearts, + Spades; + + public String sprint() { + switch(this) { + case Clubs: return Card.CLUBS; + case Diamonds: return Card.DIAMONDS; + case Hearts: return Card.HEARTS; + case Spades: return Card.SPADES; + } + throw new NullPointerException(); + } + } + + public Suit suit; + public int value; + + public Card(Suit suit, int value) { + this.suit = suit; + this.value = value; + } + + public static Card fromNumbers(int suit, int value) { + return new Card(Suit.values()[suit], value); + } + + public String sprintValue() { + if(this.value == 1) { + return "A"; + } else if(this.value == 11) { + return "J"; + } else if(this.value == 12) { + return "Q"; + } else if(this.value == 13) { + return "K"; + } else if(this.value == 10) { + return "⒑"; + } + return Integer.toString(this.value); + } + + public String sprintCard() { + var output = ""; + var value = this.sprintValue(); + var suit = this.suit.sprint(); + + output += value; + + if(this.value > 10) { + output += " "; + } else { + output += this.value >= 4 ? suit : " "; + output += this.value < 4 && this.value > 1 ? suit : " "; + output += this.value >= 4 ? suit : " "; + } + output += value; + output += "\n"; + + if(this.value > 10) { + output += suit + " " + suit + "\n"; + output += suit + " " + suit + "\n"; + } else { + output += " "; + output += this.value >= 6 ? suit : " "; + output += this.value % 2 == 1 || this.value >= 8 ? suit : " "; + output += this.value >= 6 ? suit : " "; + output += " "; + output += "\n"; + + + output += " "; + output += this.value >= 9 ? suit : " "; + output += this.value == 8 || this.value == 10 ? suit : " "; + output += this.value >= 9 ? suit : " "; + output += " "; + output += "\n"; + } + + + output += value; + + if(this.value > 10) { + output += " "; + } else { + output += this.value >= 4 ? suit : " "; + output += this.value < 4 && this.value > 1 ? suit : " "; + output += this.value >= 4 ? suit : " "; + } + output += value; + output += "\n"; + + return output; + } + + public static String sprintCards(Card[] cards) { + String[] output = { "", "", "", "" }; + + for(var i = 0; i < cards.length; i++) { + var cardstr = cards[i].sprintCard().split("\n"); + for(var x = 0; x < cardstr.length; x++) { + output[x] += cardstr[x] + " "; + } + } + + var outputstr = ""; + for(var i = 0; i < output.length; i++) { + outputstr += output[i] + "\n"; + } + return outputstr; + } +} diff --git a/week4/Deal.java b/week4/Deal.java new file mode 100644 index 0000000..5a52e0e --- /dev/null +++ b/week4/Deal.java @@ -0,0 +1,31 @@ +import java.util.Random; + +public class Deal { + public static void main(String[] args) { + int handCount = Integer.parseInt(args[0]); + if(handCount > 10) { + System.err.println("Too many hands! Maximum is 10.\njava Deal [hands]"); + } + + Card[] deck = new Card[52]; + for(var i = 0; i < 52; i++) { + var value = (i % 13) + 1; + var suit = i / 13; + deck[i] = Card.fromNumbers(suit, value); + } + + Random random = new Random(); + for(var i = 0; i < deck.length; i++) { + var second = random.nextInt(deck.length); + var a = deck[i]; + deck[i] = deck[second]; + deck[second] = a; + } + + for(var handNumber = 0; handNumber < handCount; handNumber++) { + var offset = handNumber * 5; + Card[] hand = { deck[offset], deck[offset+1], deck[offset+2], deck[offset+3], deck[offset+4] }; + System.out.println(Card.sprintCards(hand)); + } + } +} diff --git a/week4/common b/week4/common new file mode 120000 index 0000000..60d3b0a --- /dev/null +++ b/week4/common @@ -0,0 +1 @@ +../common \ No newline at end of file diff --git a/week4/doc.pdf b/week4/doc.pdf new file mode 100644 index 0000000..2c21800 Binary files /dev/null and b/week4/doc.pdf differ diff --git a/week4/doc.typ b/week4/doc.typ new file mode 100644 index 0000000..5ec005a --- /dev/null +++ b/week4/doc.typ @@ -0,0 +1,25 @@ +#import "./common/common.typ" : * + +#show: template + += Week 4 + +== Exercise 1.4.10 + +Write a program `Deal` that takes an integer command-line argument `n` and +prints `n` poker hands (five cards each) from a shuffled deck, separated by blank lines. + +#embedClass(name: "Deal") + +#embedClass(name: "Card") + +== Exercise 1.4.14 + +Write a code fragment to print the transposition (rows and columns exchanged) of a square two-dimensional array. +For the example spreadsheet array in the text, you code would print the following: + +``` +99 98 92 94 99 90 76 92 97 89 +85 57 77 32 34 46 59 66 71 29 +98 78 76 11 22 54 88 89 24 38 +```