mirror of
https://github.com/danbulant/introductionToProgramming
synced 2026-05-19 04:18:32 +00:00
add week 6
This commit is contained in:
parent
ee42aa5d4f
commit
631623009b
10 changed files with 1023 additions and 1 deletions
534
common/StdStats.java
Normal file
534
common/StdStats.java
Normal 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));
|
||||
}
|
||||
}
|
||||
2
main.typ
2
main.typ
|
|
@ -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
88
week6/Calendar.java
Normal 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
141
week6/Card.java
Normal 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
95
week6/Hand.java
Normal 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
11
week6/Histogram.java
Normal 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
16
week6/HistogramTests.java
Normal 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
81
week6/PokerAnalysis.java
Normal 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
1
week6/common
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../common
|
||||
55
week6/doc.typ
Normal file
55
week6/doc.typ
Normal 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._
|
||||
Loading…
Reference in a new issue