/* * Nathaniel Lim * Williams College CSCI136 * February 8, 2008 * * This class is a Date object, that can determine the day of the week * given the month, day, and year using a simple algorithm. */ import java.util.Random; import java.util.Scanner; import structure5.*; public class Date { /** * The following are the instance variables of a date, month, day number, and year * as well as some constant arrays that will help with the associations for numbers * in the computation, and output. Also included is a constructor for the Date class. */ private int month, dayNum,year; private final int[] adj = {0,1,4,4,0,2,5,0,3,6,1,4,6}; private static final int[] daysPerMonth = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; private final String [] dayNames = {"Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday"}; public Date(int month, int dayNum, int year) { this.month = month; this.dayNum = dayNum; this.year = year; } /** * Implements the algorithm for finding the day of the week for a given date */ public String getDay(){ Assert.pre(dayNames.length == 7, "dayNames Array is bad"); Assert.pre(adj.length == 13, "adjustments Array is bad"); int day = (adj[month] +dayNum +(year-1900) + (year-1900)/4) % 7; //If it is a leap year and the month is either a January(1) or a February(2), subtract 1 if (year % 4 == 0 && (month == 1 || month == 2) ){ day--; } Assert.post( (day <=6) && (day >= 0), "Day out of bounds" ); return dayNames[day]; } public String toString(){ return month + "/" + dayNum + "/" + year; } /** * Generates a random date. * The cases of varying month lengths, with and without * leap years are accounted for. * 1. Finds a random year and month. * 2. Checks for whether the year is a leap year * 3. Sets month length for February (special case) and other months */ public static Date genRandomDate(){ Assert.pre(daysPerMonth.length == 13, "daysPerMonth array is bad"); Random r = new Random(); int randomYear = 1900 + r.nextInt(200); int randomMonth = r.nextInt(12) + 1; int randomDayLimit; if (randomMonth != 2) { //If the random month is not a February randomDayLimit = daysPerMonth[randomMonth]; } else { if (randomYear % 4 == 0) {// If the random year is a leap year randomDayLimit = 29; }else { randomDayLimit = 28; } } int randomDay = r.nextInt(randomDayLimit) + 1; Assert.post( (randomMonth >= 0) && (randomMonth <= 12), "Month out of bounds" ); Assert.post( (randomDay >= 0) && (randomDay <= randomDayLimit), "Day out of bounds" ); Assert.post ((randomYear >= 1900)&&(randomYear <= 2099),"Year out of bounds"); return new Date (randomMonth, randomDay, randomYear); } /** * The main method allows the user to make guesses for the * days of the week for random dates. The method records and * prints out the time (in seconds) for 10 correct guesses */ public static void main (String [] args) { int numCorrect = 0; long start = System.currentTimeMillis(); while ( numCorrect < 10){ //Generating the random date, and printing it Date randomDate = genRandomDate(); System.out.println(randomDate); //Prompting the user to make a guess about what day it is. System.out.println("Prediction?"); Scanner s = new Scanner(System.in); String guess = ""; if (s.hasNext()){ guess = s.next(); } //Figuring out the correct day and //checking whether the guess is right or wrong. String actualDay = randomDate.getDay(); if (actualDay.toUpperCase().equals(guess.toUpperCase())){ numCorrect++; System.out.println("Correct: " + guess); }else { System.out.println("Incorrect, it is: " + actualDay); } } //Printing out the time taken (in seconds) to make 10 correct guesses long end = System.currentTimeMillis(); System.out.println("10 correct took: " + (end-start)/1000 + " seconds"); } }