Five weekends: Difference between revisions

From Rosetta Code
Content added Content deleted
(Added suggestions for how to do the task)
(Added extra credit requirement and added it to Java. Also scrolling the output.)
Line 4: Line 4:
'''The task'''
'''The task'''
# Write a program to show all months that have this same characteristic of five full weekends from the year 1900 through 2100 (Gregorian calendar).
# Write a program to show all months that have this same characteristic of five full weekends from the year 1900 through 2100 (Gregorian calendar).
# Show the ''number'' of months with this property.
# Show the ''number'' of months with this property (there should be 201).
# Show at least the first and last five dates, in order.
# Show at least the first and last five dates, in order.


Line 11: Line 11:
*Find all of the 31-day months that begin on Friday.
*Find all of the 31-day months that begin on Friday.


'''Extra credit'''
Show all of the years which do not have at least one five-weekend month (there should be 29).
=={{header|D}}==
=={{header|D}}==
<lang d>import std.stdio ;
<lang d>import std.stdio ;
Line 69: Line 71:
import java.util.GregorianCalendar;
import java.util.GregorianCalendar;


public class FiveFSS{
public class FiveFSS {
private static boolean[] years = new boolean[201];
//dreizig tage habt september...
//dreizig tage habt september...
private static int[] month31 = {Calendar.JANUARY, Calendar.MARCH, Calendar.MAY,
private static int[] month31 = {Calendar.JANUARY, Calendar.MARCH, Calendar.MAY,
Line 77: Line 80:
StringBuilder months = new StringBuilder();
StringBuilder months = new StringBuilder();
int numMonths = 0;
int numMonths = 0;
for(int year = 1900; year <= 2100; year++){
for (int year = 1900; year <= 2100; year++) {
for(int month : month31){
for (int month : month31) {
Calendar date = new GregorianCalendar(year, month, 1);
Calendar date = new GregorianCalendar(year, month, 1);
if(date.get(Calendar.DAY_OF_WEEK) == Calendar.FRIDAY){
if (date.get(Calendar.DAY_OF_WEEK) == Calendar.FRIDAY) {
years[year - 1900] = true;
numMonths++;
numMonths++;
//months are 0-indexed in Calendar
//months are 0-indexed in Calendar
months.append((date.get(Calendar.MONTH) + 1) + "-" + year + "\n");
months.append((date.get(Calendar.MONTH) + 1) + "-" + year +"\n");
}
}
}
}
}
}
System.out.println("There are " + numMonths + " with five weekends from 1900 through 2100:");
System.out.println("There are "+numMonths+" with five weekends from 1900 through 2100:");
System.out.println(months);
System.out.println(months);
System.out.println("Years with no five-weekend months:");
for (int year = 1900; year <= 2100; year++) {
if(!years[year - 1900]){
System.out.println(year);
}
}
}
}
}</lang>
}</lang>
Output (middle results cut out):
Output (middle results cut out):
<pre>There are 201 with five weekends from 1900 through 2100:
<pre style="height:30ex;overflow:scroll"> There are 201 with five weekends from 1900 through 2100:
3-1901
3-1901
8-1902
8-1902
Line 115: Line 125:
5-2099
5-2099
1-2100
1-2100
10-2100</pre>
10-2100

Years with no five-weekend months:
1900
1906
1917
1923
1928
1934
1945
1951
1956
1962
1973
1979
1984
1990
2001
2007
2012
2018
2029
2035
2040
2046
2057
2063
2068
2074
2085
2091
2096</pre>


=={{header|Python}}==
=={{header|Python}}==

Revision as of 19:39, 23 October 2010

Task
Five weekends
You are encouraged to solve this task according to the task description, using any language you may know.

The month of October in 2010 has five Fridays, five Saturdays, and five Sundays.

The task

  1. Write a program to show all months that have this same characteristic of five full weekends from the year 1900 through 2100 (Gregorian calendar).
  2. Show the number of months with this property (there should be 201).
  3. Show at least the first and last five dates, in order.

Algorithm suggestions

  • Count the number of Fridays, Saturdays, and Sundays in every month.
  • Find all of the 31-day months that begin on Friday.

Extra credit Show all of the years which do not have at least one five-weekend month (there should be 29).

D

<lang d>import std.stdio ; import std.gregorian ; // this module currently work in progress

Date[] m5w(Date start = Date(1900,1,1), Date end = Date(2100,12,31) ) {

   Date[] res ;    
   for(Date when = Date(start.year, start.month, 1) ; // adjust to 1st day
       when < end ; 
       when = Date(when.year, 1 + when.month, 1)) {
               
       if(when.endOfMonthDay == 31)   // Such month must has 3 + 4*7 
           if(when.dayOfWeek == 5 )   // days and start at friday
               res ~= when ;          // for 5 FULL weekends.
   }
   return res ;

}

void main() {

   auto m = m5w() ; // use default input       
       
   writefln("There are %d months of which the first and last five are:",
       m.length) ;     
   foreach(d;m[0..5]~m[$-5..$]) 
       writefln("%s", d.toSimpleString[0..$-2]) ;

}</lang>

output match python one.

J

<lang j>require 'types/datetime' find5wkdMonths=: verb define

 years=. 1900 + i. >: 1900 -~ 2100
 months=. 1 3 5 7 8 10 12
 dates=. 31
 m5w=. (#~ 0 = weekday) >,{years;months;dates  NB. 5 full weekends iff 31st is Sunday(0)
 >'MMM YYYY' fmtDate toDayNo m5w

)</lang> Usage: <lang j> # find5wkdMonths NB. number of months found 201

  (5&{. , '...' , _5&{.) find5wkdMonths   NB. First and last 5 months found

Mar 1901 Aug 1902 May 1903 Jan 1904 Jul 1904 ... Mar 2097 Aug 2098 May 2099 Jan 2100 Oct 2100</lang>

Java

<lang java>import java.util.Calendar; import java.util.GregorianCalendar;

public class FiveFSS {

   private static boolean[] years = new boolean[201];
   //dreizig tage habt september...
   private static int[] month31 = {Calendar.JANUARY, Calendar.MARCH, Calendar.MAY,
       Calendar.JULY, Calendar.AUGUST, Calendar.OCTOBER, Calendar.DECEMBER};
   public static void main(String[] args) {
       StringBuilder months = new StringBuilder();
       int numMonths = 0;
       for (int year = 1900; year <= 2100; year++) {
           for (int month : month31) {
               Calendar date = new GregorianCalendar(year, month, 1);
               if (date.get(Calendar.DAY_OF_WEEK) == Calendar.FRIDAY) {
                   years[year - 1900] = true;
                   numMonths++;
                   //months are 0-indexed in Calendar
                   months.append((date.get(Calendar.MONTH) + 1) + "-" + year +"\n");
               }
           }
       }
       System.out.println("There are "+numMonths+" with five weekends from 1900 through 2100:");
       System.out.println(months);
       System.out.println("Years with no five-weekend months:");
       for (int year = 1900; year <= 2100; year++) {
           if(!years[year - 1900]){
               System.out.println(year);
           }
       }
   }

}</lang> Output (middle results cut out):

 There are 201 with five weekends from 1900 through 2100:
3-1901
8-1902
5-1903
1-1904
7-1904
12-1905
3-1907
5-1908
1-1909
10-1909
7-1910
...
12-2090
8-2092
5-2093
1-2094
10-2094
7-2095
3-2097
8-2098
5-2099
1-2100
10-2100

Years with no five-weekend months:
1900
1906
1917
1923
1928
1934
1945
1951
1956
1962
1973
1979
1984
1990
2001
2007
2012
2018
2029
2035
2040
2046
2057
2063
2068
2074
2085
2091
2096

Python

<lang python>from datetime import timedelta, date

DAY = timedelta(days=1) WEEKEND = {6, 5, 4} # Sunday is day 6 FMT = '%Y %m(%B)'

def fiveweekendspermonth(start=date(1900, 1, 1), stop=date(2101, 1, 1)):

   'Compute months with five weekends between dates'
   
   when = start
   lastmonth = weekenddays = 0
   fiveweekends = []
   while when < stop:
       year, mon, _mday, _h, _m, _s, wday, _yday, _isdst = when.timetuple()
       if mon != lastmonth:
           if weekenddays >= 15:
               fiveweekends.append(when - DAY)
           weekenddays = 0
           lastmonth = mon
       if wday in WEEKEND:
           weekenddays += 1
       when += DAY
   return fiveweekends

dates = fiveweekendspermonth() indent = ' ' print('There are %s months of which the first and last five are:' % len(dates)) print(indent +('\n'+indent).join(d.strftime(FMT) for d in dates[:5])) print(indent +'...') print(indent +('\n'+indent).join(d.strftime(FMT) for d in dates[-5:]))</lang>

Sample Output

There are 201 months of which the first and last five are:
  1901 03(March)
  1902 08(August)
  1903 05(May)
  1904 01(January)
  1904 07(July)
  ...
  2097 03(March)
  2098 08(August)
  2099 05(May)
  2100 01(January)
  2100 10(October)

Ruby

<lang ruby># if the last day of the month falls on a Sunday and the month has 31 days,

  1. this is the only case where the month has 5 weekends.

start = Date.parse("1900-01-01") stop = Date.parse("2100-12-31") dates = (start..stop).find_all do |day|

 day.mday == 31 and day.wday == 0

end

puts "There are #{dates.size} months with 5 weekends from 1900 to 2100:" puts dates[0, 5].map { |d| d.strftime("%b %Y") }.join("\n") puts "..." puts dates[-5, 5].map { |d| d.strftime("%b %Y") }.join("\n")</lang>

Output

There are 201 months with 5 weekends from 1900 to 2100:
Mar 1901
Aug 1902
May 1903
Jan 1904
Jul 1904
...
Mar 2097
Aug 2098
May 2099
Jan 2100
Oct 2100

Tcl

<lang tcl>package require Tcl 8.5

for {set year 1900} {$year <= 2100} {incr year} {

   foreach month {Jan Mar May Jul Aug Oct Dec} {

set date [clock scan "$month/01/$year" -format "%b/%d/%Y" -locale en_US] if {[clock format $date -format %u] == 5} { # Month with 31 days that starts on a Friday => has 5 weekends lappend months "$month $year" }

   }

} puts "There are [llength $months] with five weekends" puts [join [list {*}[lrange $months 0 4] ... {*}[lrange $months end-4 end]] \n]</lang> Output:

There are 201 with five weekends
Mar 1901
Aug 1902
May 1903
Jan 1904
Jul 1904
...
Mar 2097
Aug 2098
May 2099
Jan 2100
Oct 2100