add week 6

This commit is contained in:
Daniel Bulant 2025-10-11 18:38:36 +02:00
parent ee42aa5d4f
commit 631623009b
No known key found for this signature in database
10 changed files with 1023 additions and 1 deletions

534
common/StdStats.java Normal file
View file

@ -0,0 +1,534 @@
package common;
/******************************************************************************
* Compilation: javac StdStats.java
* Execution: java StdStats < input.txt
* Dependencies: StdOut.java
*
* Library of statistical functions.
*
* The test client reads an array of real numbers from standard
* input, and computes the minimum, mean, maximum, and
* standard deviation.
*
* The functions all throw a java.lang.IllegalArgumentException
* if the array passed in as an argument is null.
*
* The floating-point functions all return NaN if any input is NaN.
*
* Unlike Math.min() and Math.max(), the min() and max() functions
* do not differentiate between -0.0 and 0.0.
*
* % more tiny.txt
* 5
* 3.0 1.0 2.0 5.0 4.0
*
* % java StdStats < tiny.txt
* min 1.000
* mean 3.000
* max 5.000
* std dev 1.581
*
* Should these functions use varargs instead of array arguments?
*
******************************************************************************/
/**
* The {@code StdStats} class provides static methods for computing
* statistics such as min, max, mean, sample standard deviation, and
* sample variance.
* <p>
* For additional documentation, see
* <a href="https://introcs.cs.princeton.edu/22library">Section 2.2</a> of
* <i>Computer Science: An Interdisciplinary Approach</i>
* by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public final class StdStats {
private StdStats() { }
/**
* Returns the maximum value in the specified array.
*
* @param a the array
* @return the maximum value in the array {@code a[]};
* {@code Double.NEGATIVE_INFINITY} if no such value
*/
public static double max(double[] a) {
validateNotNull(a);
double max = Double.NEGATIVE_INFINITY;
for (int i = 0; i < a.length; i++) {
if (Double.isNaN(a[i])) return Double.NaN;
if (a[i] > max) max = a[i];
}
return max;
}
/**
* Returns the maximum value in the specified subarray.
*
* @param a the array
* @param lo the left endpoint of the subarray (inclusive)
* @param hi the right endpoint of the subarray (exclusive)
* @return the maximum value in the subarray {@code a[lo..hi)};
* {@code Double.NEGATIVE_INFINITY} if no such value
* @throws IllegalArgumentException if {@code a} is {@code null}
* @throws IllegalArgumentException unless {@code (0 <= lo) && (lo < hi) && (hi <= a.length)}
*/
public static double max(double[] a, int lo, int hi) {
validateNotNull(a);
validateSubarrayIndices(lo, hi, a.length);
double max = Double.NEGATIVE_INFINITY;
for (int i = lo; i < hi; i++) {
if (Double.isNaN(a[i])) return Double.NaN;
if (a[i] > max) max = a[i];
}
return max;
}
/**
* Returns the maximum value in the specified array.
*
* @param a the array
* @return the maximum value in the array {@code a[]};
* {@code Integer.MIN_VALUE} if no such value
*/
public static int max(int[] a) {
validateNotNull(a);
int max = Integer.MIN_VALUE;
for (int i = 0; i < a.length; i++) {
if (a[i] > max) max = a[i];
}
return max;
}
/**
* Returns the minimum value in the specified array.
*
* @param a the array
* @return the minimum value in the array {@code a[]};
* {@code Double.POSITIVE_INFINITY} if no such value
*/
public static double min(double[] a) {
validateNotNull(a);
double min = Double.POSITIVE_INFINITY;
for (int i = 0; i < a.length; i++) {
if (Double.isNaN(a[i])) return Double.NaN;
if (a[i] < min) min = a[i];
}
return min;
}
/**
* Returns the minimum value in the specified subarray.
*
* @param a the array
* @param lo the left endpoint of the subarray (inclusive)
* @param hi the right endpoint of the subarray (exclusive)
* @return the maximum value in the subarray {@code a[lo..hi)};
* {@code Double.POSITIVE_INFINITY} if no such value
* @throws IllegalArgumentException if {@code a} is {@code null}
* @throws IllegalArgumentException unless {@code (0 <= lo) && (lo < hi) && (hi <= a.length)}
*/
public static double min(double[] a, int lo, int hi) {
validateNotNull(a);
validateSubarrayIndices(lo, hi, a.length);
double min = Double.POSITIVE_INFINITY;
for (int i = lo; i < hi; i++) {
if (Double.isNaN(a[i])) return Double.NaN;
if (a[i] < min) min = a[i];
}
return min;
}
/**
* Returns the minimum value in the specified array.
*
* @param a the array
* @return the minimum value in the array {@code a[]};
* {@code Integer.MAX_VALUE} if no such value
*/
public static int min(int[] a) {
validateNotNull(a);
int min = Integer.MAX_VALUE;
for (int i = 0; i < a.length; i++) {
if (a[i] < min) min = a[i];
}
return min;
}
/**
* Returns the average value in the specified array.
*
* @param a the array
* @return the average value in the array {@code a[]};
* {@code Double.NaN} if no such value
*/
public static double mean(double[] a) {
validateNotNull(a);
if (a.length == 0) return Double.NaN;
double sum = sum(a);
return sum / a.length;
}
/**
* Returns the average value in the specified subarray.
*
* @param a the array
* @param lo the left endpoint of the subarray (inclusive)
* @param hi the right endpoint of the subarray (exclusive)
* @return the average value in the subarray {@code a[lo..hi)};
* {@code Double.NaN} if no such value
* @throws IllegalArgumentException if {@code a} is {@code null}
* @throws IllegalArgumentException unless {@code (0 <= lo) && (lo < hi) && (hi <= a.length)}
*/
public static double mean(double[] a, int lo, int hi) {
validateNotNull(a);
validateSubarrayIndices(lo, hi, a.length);
int length = hi - lo;
if (length == 0) return Double.NaN;
double sum = sum(a, lo, hi);
return sum / length;
}
/**
* Returns the average value in the specified array.
*
* @param a the array
* @return the average value in the array {@code a[]};
* {@code Double.NaN} if no such value
*/
public static double mean(int[] a) {
validateNotNull(a);
if (a.length == 0) return Double.NaN;
int sum = sum(a);
return 1.0 * sum / a.length;
}
/**
* Returns the sample variance in the specified array.
*
* @param a the array
* @return the sample variance in the array {@code a[]};
* {@code Double.NaN} if no such value
*/
public static double var(double[] a) {
validateNotNull(a);
if (a.length == 0) return Double.NaN;
double avg = mean(a);
double sum = 0.0;
for (int i = 0; i < a.length; i++) {
sum += (a[i] - avg) * (a[i] - avg);
}
return sum / (a.length - 1);
}
/**
* Returns the sample variance in the specified subarray.
*
* @param a the array
* @param lo the left endpoint of the subarray (inclusive)
* @param hi the right endpoint of the subarray (exclusive)
* @return the sample variance in the subarray {@code a[lo..hi)};
* {@code Double.NaN} if no such value
* @throws IllegalArgumentException if {@code a} is {@code null}
* @throws IllegalArgumentException unless {@code (0 <= lo) && (lo < hi) && (hi <= a.length)}
*/
public static double var(double[] a, int lo, int hi) {
validateNotNull(a);
validateSubarrayIndices(lo, hi, a.length);
int length = hi - lo;
if (length == 0) return Double.NaN;
double avg = mean(a, lo, hi);
double sum = 0.0;
for (int i = lo; i < hi; i++) {
sum += (a[i] - avg) * (a[i] - avg);
}
return sum / (length - 1);
}
/**
* Returns the sample variance in the specified array.
*
* @param a the array
* @return the sample variance in the array {@code a[]};
* {@code Double.NaN} if no such value
*/
public static double var(int[] a) {
validateNotNull(a);
if (a.length == 0) return Double.NaN;
double avg = mean(a);
double sum = 0.0;
for (int i = 0; i < a.length; i++) {
sum += (a[i] - avg) * (a[i] - avg);
}
return sum / (a.length - 1);
}
/**
* Returns the population variance in the specified array.
*
* @param a the array
* @return the population variance in the array {@code a[]};
* {@code Double.NaN} if no such value
*/
public static double varp(double[] a) {
validateNotNull(a);
if (a.length == 0) return Double.NaN;
double avg = mean(a);
double sum = 0.0;
for (int i = 0; i < a.length; i++) {
sum += (a[i] - avg) * (a[i] - avg);
}
return sum / a.length;
}
/**
* Returns the population variance in the specified subarray.
*
* @param a the array
* @param lo the left endpoint of the subarray (inclusive)
* @param hi the right endpoint of the subarray (exclusive)
* @return the population variance in the subarray {@code a[lo..hi)};
* {@code Double.NaN} if no such value
* @throws IllegalArgumentException if {@code a} is {@code null}
* @throws IllegalArgumentException unless {@code (0 <= lo) && (lo < hi) && (hi <= a.length)}
*/
public static double varp(double[] a, int lo, int hi) {
validateNotNull(a);
validateSubarrayIndices(lo, hi, a.length);
int length = hi - lo;
if (length == 0) return Double.NaN;
double avg = mean(a, lo, hi);
double sum = 0.0;
for (int i = lo; i < hi; i++) {
sum += (a[i] - avg) * (a[i] - avg);
}
return sum / length;
}
/**
* Returns the sample standard deviation in the specified array.
*
* @param a the array
* @return the sample standard deviation in the array {@code a[]};
* {@code Double.NaN} if no such value
*/
public static double stddev(double[] a) {
validateNotNull(a);
return Math.sqrt(var(a));
}
/**
* Returns the sample standard deviation in the specified array.
*
* @param a the array
* @return the sample standard deviation in the array {@code a[]};
* {@code Double.NaN} if no such value
*/
public static double stddev(int[] a) {
validateNotNull(a);
return Math.sqrt(var(a));
}
/**
* Returns the sample standard deviation in the specified subarray.
*
* @param a the array
* @param lo the left endpoint of the subarray (inclusive)
* @param hi the right endpoint of the subarray (exclusive)
* @return the sample standard deviation in the subarray {@code a[lo..hi)};
* {@code Double.NaN} if no such value
* @throws IllegalArgumentException if {@code a} is {@code null}
* @throws IllegalArgumentException unless {@code (0 <= lo) && (lo < hi) && (hi <= a.length)}
*/
public static double stddev(double[] a, int lo, int hi) {
validateNotNull(a);
validateSubarrayIndices(lo, hi, a.length);
return Math.sqrt(var(a, lo, hi));
}
/**
* Returns the population standard deviation in the specified array.
*
* @param a the array
* @return the population standard deviation in the array;
* {@code Double.NaN} if no such value
*/
public static double stddevp(double[] a) {
validateNotNull(a);
return Math.sqrt(varp(a));
}
/**
* Returns the population standard deviation in the specified subarray.
*
* @param a the array
* @param lo the left endpoint of the subarray (inclusive)
* @param hi the right endpoint of the subarray (exclusive)
* @return the population standard deviation in the subarray {@code a[lo..hi)};
* {@code Double.NaN} if no such value
* @throws IllegalArgumentException if {@code a} is {@code null}
* @throws IllegalArgumentException unless {@code (0 <= lo) && (lo < hi) && (hi <= a.length)}
*/
public static double stddevp(double[] a, int lo, int hi) {
validateNotNull(a);
validateSubarrayIndices(lo, hi, a.length);
return Math.sqrt(varp(a, lo, hi));
}
/**
* Returns the sum of all values in the specified array.
*
* @param a the array
* @return the sum of all values in the array {@code a[]};
* {@code 0.0} if no such value
*/
private static double sum(double[] a) {
validateNotNull(a);
double sum = 0.0;
for (int i = 0; i < a.length; i++) {
sum += a[i];
}
return sum;
}
/**
* Returns the sum of all values in the specified subarray.
*
* @param a the array
* @param lo the left endpoint of the subarray (inclusive)
* @param hi the right endpoint of the subarray (exclusive)
* @return the sum of all values in the subarray {@code a[lo..hi)};
* {@code 0.0} if no such value
* @throws IllegalArgumentException if {@code a} is {@code null}
* @throws IllegalArgumentException unless {@code (0 <= lo) && (lo < hi) && (hi <= a.length)}
*/
private static double sum(double[] a, int lo, int hi) {
validateNotNull(a);
validateSubarrayIndices(lo, hi, a.length);
double sum = 0.0;
for (int i = lo; i < hi; i++) {
sum += a[i];
}
return sum;
}
/**
* Returns the sum of all values in the specified array.
*
* @param a the array
* @return the sum of all values in the array {@code a[]};
* {@code 0.0} if no such value
*/
private static int sum(int[] a) {
validateNotNull(a);
int sum = 0;
for (int i = 0; i < a.length; i++) {
sum += a[i];
}
return sum;
}
/**
* Plots the points (0, <em>a</em><sub>0</sub>), (1, <em>a</em><sub>1</sub>), ...,
* (<em>n</em>-1, <em>a</em><sub><em>n</em>-1</sub>) to standard draw.
*
* @param a the array of values
*/
public static void plotPoints(double[] a) {
validateNotNull(a);
int n = a.length;
StdDraw.setXscale(-1, n);
StdDraw.setPenRadius(1.0 / (3.0 * n));
for (int i = 0; i < n; i++) {
StdDraw.point(i, a[i]);
}
}
/**
* Plots the line segments connecting
* (<em>i</em>, <em>a</em><sub><em>i</em></sub>) to
* (<em>i</em>+1, <em>a</em><sub><em>i</em>+1</sub>) for
* each <em>i</em> to standard draw.
*
* @param a the array of values
*/
public static void plotLines(double[] a) {
validateNotNull(a);
int n = a.length;
StdDraw.setXscale(-1, n);
StdDraw.setPenRadius();
for (int i = 1; i < n; i++) {
StdDraw.line(i-1, a[i-1], i, a[i]);
}
}
/**
* Plots bars from (0, <em>a</em><sub><em>i</em></sub>) to
* (<em>a</em><sub><em>i</em></sub>) for each <em>i</em>
* to standard draw.
*
* @param a the array of values
*/
public static void plotBars(double[] a) {
validateNotNull(a);
int n = a.length;
StdDraw.setXscale(-1, n);
for (int i = 0; i < n; i++) {
StdDraw.filledRectangle(i, a[i]/2, 0.25, a[i]/2);
}
}
// throw an IllegalArgumentException if x is null
// (x is either of type double[] or int[])
private static void validateNotNull(Object x) {
if (x == null)
throw new IllegalArgumentException("argument is null");
}
// throw an exception unless 0 <= lo <= hi <= length
private static void validateSubarrayIndices(int lo, int hi, int length) {
if (lo < 0 || hi > length || lo > hi)
throw new IllegalArgumentException("subarray indices out of bounds: [" + lo + ", " + hi + ")");
}
/**
* Unit tests {@code StdStats}.
* Convert command-line arguments to array of doubles and call various methods.
*
* @param args the command-line arguments
*/
public static void main(String[] args) {
double[] a = StdArrayIO.readDouble1D();
StdOut.printf(" min %10.3f\n", min(a));
StdOut.printf(" mean %10.3f\n", mean(a));
StdOut.printf(" max %10.3f\n", max(a));
StdOut.printf(" stddev %10.3f\n", stddev(a));
StdOut.printf(" var %10.3f\n", var(a));
StdOut.printf(" stddevp %10.3f\n", stddevp(a));
StdOut.printf(" varp %10.3f\n", varp(a));
}
}

View file

@ -15,7 +15,7 @@ Collection of solutions to programming exercises as part of Introduction to Prog
)
#{
let count = 5;
let count = 6;
for week in range(1, count + 1) {
let a = "./week" + str(week) + "/doc.typ"
include a

88
week6/Calendar.java Normal file
View file

@ -0,0 +1,88 @@
package week6;
public class Calendar {
static final String[] months = {
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
};
public static void main(String[] args) {
int month = Integer.parseInt(args[0]);
int year = Integer.parseInt(args[1]);
System.out.printf("%s %d\n", months[month - 1], year);
System.out.println(" S M Tu W Th F S");
int daysToSkip = dayOfWeek(year, month, 1);
int monthLength = monthLength(year, month);
for(var i = 1; i < monthLength + daysToSkip + 1; i++) {
if(i < daysToSkip && i % 7 == 0) {
System.out.println();
continue;
}
if(i <= daysToSkip) {
System.out.print(" ");
continue;
}
System.out.printf("%2d ", i - daysToSkip);
if(i % 7 == 0) {
System.out.println();
}
}
}
static final int[] monthLengths = {
31,
28,
31,
30,
31,
30,
31,
31,
30,
31,
30,
31,
};
/**
* Length of a given month
* @param year
* @param month 1=January
* @return length of the month in days, leap year adjusted
*/
static int monthLength(int year, int month) {
return monthLengths[month - 1] + (month == 2 ? (isLeapYear(year) ? 1 : 0) : 0);
}
static boolean isLeapYear(int year) {
boolean isLeapYear;
isLeapYear = (year % 4 == 0);
isLeapYear = isLeapYear && (year % 100 != 0);
isLeapYear = isLeapYear || (year % 400 == 0);
return isLeapYear;
}
/**
* @param year
* @param month 1=January
* @param day
* @return day of week, 0=Sunday,6=Saturday
*/
static int dayOfWeek(int year, int month, int day) {
int y0 = year - (14 - month) / 12;
int leapAdjustedYear = y0 + y0 / 4 - y0 / 100 + y0 / 400;
int m0 = month + 12 * ((14 - month) / 12) - 2;
return (day + leapAdjustedYear + (31 * m0) / 12) % 7;
}
}

141
week6/Card.java Normal file
View file

@ -0,0 +1,141 @@
package week6;
public class Card {
public enum Suit {
Clubs,
Diamonds,
Hearts,
Spades;
public static final String CLUBS = "";
public static final String DIAMONDS = "";
public static final String HEARTS = "";
public static final String SPADES = "";
public String sprint() {
switch(this) {
case Clubs: return CLUBS;
case Diamonds: return DIAMONDS;
case Hearts: return HEARTS;
case Spades: return SPADES;
}
throw new NullPointerException();
}
}
public Suit suit;
public int value;
public Card(Suit suit, int value) {
this.suit = suit;
this.value = value;
}
// Print a single character for the value
// Only a single character is returned so that we can format
// the card output correctly and easily
public char sprintValue() {
assert this.value > 0 && this.value < 14;
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) {
// UTF-8 character that looks like a 10
// but uses only one character width
return '⒑';
}
// asserted 0 < x < 14, we handled 1, 10-13
// the only valid values here are 2-9
return Integer.toString(this.value).charAt(0);
}
// Print the card to a string to be later processed (or printed).
// Approximates 'normal' card deck look
// Numbered cards have their suit symbol repeated based on their value.
// Face cards are empty.
public String sprintCard() {
var output = "";
var value = this.sprintValue();
var suit = this.suit.sprint();
// Generate the top (and bottom) of a card
// this will show the value of the card on each edge
var top = "";
top += value;
if(this.value > 10) {
// face cards are empty
top += " ";
} else {
// and for numbered cards, show the suit characters
top += this.value >= 4 ? suit : " ";
top += this.value < 4 && this.value > 1 ? suit : " ";
top += this.value >= 4 ? suit : " ";
}
top += value;
top += "\n";
output += top;
if(this.value > 10) {
// face cards get suits on the side, right above and under their values
// numbered cards are empty on their sides
output += suit + " " + suit + "\n";
output += suit + " " + suit + "\n";
} else {
// normal cards have either 3 or 4 rows of suits in 1-3 columns,
// with the middle one sometimes floating.
// we have to have a set size and can't have floating characters,
// so this is a best effort approximation
// instead of using 3 rows we have a gap in the 3rd row
output += " ";
output += this.value >= 6 ? suit : " ";
// odd or 10 have a symbol in the middle
output += this.value % 2 == 1 || this.value == 10 ? suit : " ";
output += this.value >= 6 ? suit : " ";
output += " ";
output += "\n";
output += " ";
output += this.value >= 8 ? suit : " ";
output += this.value == 10 ? suit : " ";
output += this.value >= 8 ? suit : " ";
output += " ";
output += "\n";
}
output += top;
return output;
}
// Shows cards next to each other (left to right)
// for visuals, assumes that sprintCard returns the same width for each card (and each row of a card)
// for correctness, assumes that sprintCard always returns 4 rows (is asserted)
public static String sprintCards(Card[] cards) {
String[] output = { "", "", "", "" };
// split each card into it's 4 rows
// save the row into relevant output
for(var i = 0; i < cards.length; i++) {
var cardstr = cards[i].sprintCard().split("\n");
assert output.length == cardstr.length;
for(var x = 0; x < cardstr.length; x++) {
output[x] += cardstr[x] + " ";
}
}
// and join the rows together with a newline
var outputstr = "";
for(var i = 0; i < output.length; i++) {
outputstr += output[i] + "\n";
}
return outputstr;
}
}

95
week6/Hand.java Normal file
View file

@ -0,0 +1,95 @@
package week6;
import java.util.Arrays;
public class Hand {
enum Type {
StraightFlush,
FourOfAKind,
FullHouse,
Flush,
Straight,
ThreeOfAKind,
TwoPair,
Pair,
HighCard;
}
Card[] cards;
public Hand(Card[] cards) {
assert cards != null;
assert cards.length == 5;
this.cards = cards;
}
public Type type() {
var doubleHistogram = doubleHistogram();
var hasFlush = hasFlush();
var hasStraight = hasStraight();
if(hasFlush && hasStraight) return Type.StraightFlush;
if(hasFlush) return Type.Flush;
if(hasStraight) return Type.Straight;
if(doubleHistogram[4] == 1) return Type.FourOfAKind;
if(doubleHistogram[3] == 1 && doubleHistogram[2] == 1) return Type.FullHouse;
if(doubleHistogram[3] == 1) return Type.ThreeOfAKind;
if(doubleHistogram[2] == 2) return Type.TwoPair;
if(doubleHistogram[2] == 1) return Type.Pair;
return Type.HighCard;
}
int[] values() {
var values = new int[cards.length];
for(var i = 0; i < cards.length; i++) {
values[i] = cards[i].value;
}
return values;
}
/**
* Generates a histogram of card values.
* Each element in an array contains the number of cards with that value.
*/
int[] histogram() {
return Histogram.histogram(values(), 14);
}
/**
* Generates a histogram of the histogram of card values.
* This shows how many times did any repetitions repeat.
* For example (1,1,2,2,2,3,3) first histogram results in (0,2,3,2)
* Second histogram (what this function returns) results in (1,0,2,1).
* This tells us that there are two pairs and one three of a kind.
*/
int[] doubleHistogram() {
// if cards are dealt properly, the max is 5 (cards.length),
// as a card can't appear more than 4 times
var histogram = histogram();
// System.out.println(Arrays.toString(histogram));
return Histogram.histogram(histogram, cards.length + 1);
}
boolean hasFlush() {
var suit = cards[0].suit;
for(var i = 1; i < cards.length; i++) {
if(cards[i].suit != suit) return false;
}
return true;
}
boolean hasStraight() {
var values = values();
Arrays.sort(values);
var isStraight = true;
for(var i = 1; i < values.length; i++) {
if(values[i] != values[i-1] + 1) {
isStraight = false;
break;
}
}
if(isStraight) return true;
return isStraight || Arrays.equals(values, new int[]{
// A 10 J Q K is valid as well
1, 10, 11, 12, 13
});
}
}

11
week6/Histogram.java Normal file
View file

@ -0,0 +1,11 @@
package week6;
public class Histogram {
public static int[] histogram(int[] a, int max) {
int[] output = new int[max];
for(var x = 0; x < a.length; x++) {
output[a[x]]++;
}
return output;
}
}

16
week6/HistogramTests.java Normal file
View file

@ -0,0 +1,16 @@
package week6;
import java.util.Arrays;
public class HistogramTests {
public static void main(String[] args) {
assert Arrays.equals(
new int[]{ 0,1,1,1 },
Histogram.histogram(new int[]{ 1,2,3 }, 4)
);
assert Arrays.equals(
new int[]{ 0,3,0,0 },
Histogram.histogram(new int[]{ 1,1,1 }, 4)
);
}
}

81
week6/PokerAnalysis.java Normal file
View file

@ -0,0 +1,81 @@
package week6;
import common.StdDraw;
import common.StdRandom;
import common.StdStats;
public class PokerAnalysis {
/**
* Example program using PokerAnalysis
*
* Renders a plot of each type of hand
* The bars represent types in Hand.Type, in the same order
*/
public static void main(String[] args) {
var decks = 1000;
// var hands = decks * 10;
var types = analyzeShuffledDecks(decks);
var typeFloats = new double[types.length];
var max = StdStats.max(types);
for(var i = 0; i < types.length; i++) {
// max or hands can be used here
typeFloats[i] = (double)types[i] / max;
}
StdDraw.setPenColor();
StdStats.plotBars(typeFloats);
}
/**
* Gets nth (5-card) hand of a given deck.
* Up to 10 hands can be dealt from a given deck
*/
public static Hand getHand(Card[] deck, int handOffset) {
var offset = handOffset * 5;
return new Hand(new Card[]{
deck[offset],
deck[offset+1],
deck[offset+2],
deck[offset+3],
deck[offset+4]
});
}
/**
* Gets the first hand of a given deck.
*/
public static Hand getHand(Card[] deck) {
return getHand(deck, 0);
}
public static Card[] getRandomDeck() {
Card[] deck = new Card[52];
for(var i = 0; i < 52; i++) {
var value = (i % 13) + 1;
var suit = i / 13;
deck[i] = new Card(Card.Suit.values()[suit], value);
}
StdRandom.shuffle(deck);
return deck;
}
/**
* Shuffles n decks, draws 10 hands from each, and saves the number of hands of each type
* Returns an array mapping type (using their ordinals) to number of hands found
*/
public static int[] analyzeShuffledDecks(int decks) {
var types = new int[Hand.Type.values().length];
for(var i = 0; i < decks; i++) {
var deck = getRandomDeck();
for(var offset = 0; offset < 10; offset++) {
var hand = getHand(deck, offset);
types[hand.type().ordinal()]++;
}
}
return types;
}
public static int numberOfHandsOfType(int[] analyzedShuffledDecks, Hand.Type type) {
return analyzedShuffledDecks[type.ordinal()];
}
}

1
week6/common Symbolic link
View file

@ -0,0 +1 @@
../common

55
week6/doc.typ Normal file
View file

@ -0,0 +1,55 @@
#import "./common/common.typ" : *
#show: template
= Week 6
== Exercise 2.1.19
Write a static method `histogram()` that takes an `int array a[]` and an
integer $m$ as arguments and returns an array of length $m$ whose $i$th element is the
number of times the integer $i$ appeared in `a[]`. Assuming the values in `a[]` are
all between $0$ and $m-1$, the sum of the values in the returned array should equal
`a.length`.
#embedClass(name: "Histogram")
== Exercise 2.1.30
_Calendar_. Write a program `Calendar` that takes two integer commandline
arguments $m$ and $y$ and prints the monthly calendar for month $m$ of year $y$, as
in this example:
```
% java Calendar 2 2009
February 2009
S M Tu W Th F S
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
```
#embedClass(name: "Calendar")
== Exercise 2.2.26
_Poker analysis_. Write a `StdRandom` and `StdStats` client (with appropriate
static methods of its own) to estimate the probabilities of getting one pair, two pair,
three of a kind, a full house, and a flush in a five-card poker hand via simulation.
Divide your program into appropriate static methods and defend your design decisions.
_Extra credit_ : Add straight and straight flush to the list of possibilities.
#embedClass(name: "PokerAnalysis")
#embedClass(name: "Hand")
_Note that this reuses #context {
let label = <card>;
if query(label).len() == 0 {
[ class Card ]
} else {
ref(label)
}
} from week 4._