Five weekends: Difference between revisions

Added Easylang
No edit summary
(Added Easylang)
 
(13 intermediate revisions by 7 users not shown)
Line 532:
 
=={{header|Amazing Hopper}}==
<p>VERSION 1</p>
<syntaxhighlight lang="txt">
#include <jambo.h>
Line 632 ⟶ 633:
2100 : Octubre |
Total de años con weekend de 5 días = 201
</pre>
<p>VERSION 2</p>
<p>Esta versión genera el mismo resultado, sin hacer uso de la macro "calendar", con la diferencia que ahora le añadí el conteo de los días que no tienen el famoso "five weekend":</p>
<syntaxhighlight lang="txt">
#include <jambo.h>
 
#define __PRNNL__ {"\n"}print
#synon __PRNNL__ *Print it
#synon Set *Set
 
Main
Set stack 15
 
Init zero (candidato, total, sin weekend largo, sw, columna, fecha)
/* Configura meses */
mes largo = {}
Let list ( mes largo := 1, 3, 5, 7, 8, 10, 12 )
/* Busca los meses con weekend larguísimo */
Loop for (año = 1900, #( año <= 2100), ++año)
Loop for( i=1, #(i<=7), ++i)
 
Let ( candidato := [i] Of 'mes largo' )
Let ( fecha := Multicat ("1/",Str(candidato),"/",Str(año)) )
 
When ( Strday 'fecha' Is equal to '"Viernes"', \
And ( Days of month 'fecha' Compared to '31', Are equals? )) {
++total, sw=1
Print (año," : ", Just left (13, Month name 'candidato')," | ")
When ( columna++ Is equal to '3' ) { Prnl, columna=0 }
}
Back
When ( Not( sw ) ) { ++ sin weekend largo }, sw=0
Back
now Set ( Utf8("\nTotal de años con weekend de 5 días = "), total )
and Set ( Utf8("\nAños sin weekend de 5 días: "), sin weekend largo) then Print it
End
</syntaxhighlight>
{{out}}
<pre>
1901 : Marzo | 1902 : Agosto | 1903 : Mayo | 1904 : Enero |
1904 : Julio | 1905 : Diciembre | 1907 : Marzo | 1908 : Mayo |
...
2093 : Mayo | 2094 : Enero | 2094 : Octubre | 2095 : Julio |
2097 : Marzo | 2098 : Agosto | 2099 : Mayo | 2100 : Enero |
2100 : Octubre |
Total de años con weekend de 5 días = 201
Años sin weekend de 5 días: 29
 
</pre>
 
Line 879 ⟶ 931:
1984, 1990, 2001, 2007, 2012, 2018, 2029, 2035, 2040, 2046, 2057, 2063, 2068, 2074,
2085, 2091, 2096}}}</syntaxhighlight>
 
===Using integer math===
An alternative to the date object manipulation methods above.
<syntaxhighlight lang="applescript">on monthsWithFiveWeekends(startYear, endYear)
set Dec1 to (current date)
tell Dec1 to set {its day, its month, its year} to {1, December, startYear - 1}
set daysFromBaseFriday to (Dec1's weekday as integer) - Friday
set longMonths to {"January", "March", "May", "July", "August", "October", "December"}
set daysBetween to {31, 59, 61, 61, 31, 61, 61} -- Days since starts of preceding long months.
set hits to {}
set hitlessYears to {}
repeat with y from startYear to endYear
set noHIts to true
-- Find long months that begin on Fridays.
repeat with i from 1 to 7
set daysFromBaseFriday to daysFromBaseFriday + (daysBetween's item i)
if ((i = 2) and (y mod 4 = 0) and ((y mod 100 > 0) or (y mod 400 = 0))) then ¬
set daysFromBaseFriday to daysFromBaseFriday + 1 -- Leap year.
if (daysFromBaseFriday mod 7 = 0) then
set end of hits to (longMonths's item i) & (space & y)
set noHIts to false
end if
end repeat
if (noHIts) then set end of hitlessYears to y
end repeat
return {hits:hits, hitlessYears:hitlessYears}
end monthsWithFiveWeekends
 
on join(lst, delim)
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to delim
set txt to lst as text
set AppleScript's text item delimiters to astid
return txt
end join
 
on task()
set {startYear, endYear} to {1900, 2100}
set theResults to monthsWithFiveWeekends(startYear, endYear)
set output to {((count theResults's hits) as text) & " of the months from " & startYear & ¬
" to " & endYear & " have five weekends,", ¬
"the first and last five of these months being:"}
set end of output to join(theResults's hits's items 1 thru 5, ", ") & " …"
set end of output to "… " & join(theResults's hits's items -5 thru -1, ", ")
set hitlessCount to (count theResults's hitlessYears)
set end of output to linefeed & hitlessCount & " of the years have no such months:"
set cut to (hitlessCount + 1) div 2
set end of output to join(theResults's hitlessYears's items 1 thru cut, ", ")
set end of output to join(theResults's hitlessYears's items (cut + 1) thru -1, ", ")
return join(output, linefeed)
end task
 
task()</syntaxhighlight>
 
{{output}}
<syntaxhighlight lang="applescript">"201 of the months from 1900 to 2100 have five weekends,
the first and last five of these months being:
March 1901, August 1902, May 1903, January 1904, July 1904 …
… March 2097, August 2098, May 2099, January 2100, October 2100
 
29 of the years have no such 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"</syntaxhighlight>
 
=={{header|Arturo}}==
<syntaxhighlight lang="arturo">longMonths: [1 3 5 7 8 10 12]
dates: []
 
yearsWithout: 0
 
loop 1900..2100 'year [
found?: false
loop longMonths 'month [
dt: to :date .format:"d-M-YYYY" ~"1-|month|-|year|"
if friday? dt [
'dates ++ @[@[dt\Month year]]
found?: true
]
]
if not? found? ->
inc 'yearsWithout
]
 
print.lines map first.n:5 dates 'd -> ~"|to :string d\0|, |to :string d\1|"
print "..."
print.lines map last.n:5 dates 'd -> ~"|to :string d\0|, |to :string d\1|"
 
print ""
print ["Found" size dates "months in total."]
print ["There are" yearsWithout "years without any month that has 5 full weekends."]</syntaxhighlight>
 
{{out}}
 
<pre>March, 1901
August, 1902
May, 1903
January, 1904
July, 1904
...
March, 2097
August, 2098
May, 2099
January, 2100
October, 2100
 
Found 201 months in total.
There are 29 years without any month that has 5 full weekends.</pre>
 
=={{header|AutoHotkey}}==
Line 1,604 ⟶ 1,764:
2091
2096
</pre>
 
===Using C++20===
<syntaxhighlight lang="c++">
 
#include <chrono>
#include <iostream>
#include <vector>
 
int main() {
const std::vector<std::chrono::month> long_months = { std::chrono::January, std::chrono::March,
std::chrono::May, std::chrono::July, std::chrono::August, std::chrono::October, std::chrono::December };
 
int month_count = 0;
int blank_years = 0;
for ( int y = 1900; y <= 2100; ++y ) {
bool blank_year = true;
for ( std::chrono::month m : long_months ) {
std::chrono::year_month_day first_of_month{std::chrono::year{y}, m, std::chrono::day{1}};
if ( std::chrono::weekday{first_of_month} == std::chrono::Friday ) {
std::cout << first_of_month.year() << " " << first_of_month.month() << std::endl;
month_count++;
blank_year = false;
}
}
if ( blank_year ) {
blank_years++;
}
}
std::cout << "Found " << month_count << " months with five Fridays, Saturdays and Sundays." << std::endl;
std::cout << "There were " << blank_years << " years with no such months." << std::endl;
}
</syntaxhighlight>
{{ out }}
<pre>
1901 Mar
1902 Aug
1903 May
1904 Jan
1904 Jul
// elided... //
2097 Mar
2098 Aug
2099 May
2100 Jan
2100 Oct
Found 201 months with five Fridays, Saturdays and Sundays.
There were 29 years with no such months.
</pre>
 
Line 2,092 ⟶ 2,300:
Writeln(Format('Years with no 5 weekend months: %d', [lYearsWithout]));
end.</syntaxhighlight>
 
=={{header|EasyLang}}==
<syntaxhighlight>
func leap year .
return if year mod 4 = 0 and (year mod 100 <> 0 or year mod 400 = 0)
.
func weekday year month day .
normdoom[] = [ 3 7 7 4 2 6 4 1 5 3 7 5 ]
c = year div 100
r = year mod 100
s = r div 12
t = r mod 12
c_anchor = (5 * (c mod 4) + 2) mod 7
doom = (s + t + (t div 4) + c_anchor) mod 7
anchor = normdoom[month]
if leap year = 1 and month <= 2
anchor = (anchor + 1) mod1 7
.
return (doom + day - anchor + 7) mod 7 + 1
.
mdays[] = [ 31 28 31 30 31 30 31 31 30 31 30 31 ]
mon$[] = [ "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec" ]
#
for year = 1900 to 2100
for m to 12
if mdays[m] = 31 and weekday year m 1 = 6
print year & "-" & mon$[m]
sum += 1
.
.
.
print "Total : " & sum
</syntaxhighlight>
{{out}}
<pre>
1901-Mar
1902-Aug
1903-May
1904-Jan
1904-Jul
.
.
2097-Mar
2098-Aug
2099-May
2100-Jan
2100-Oct
Total : 201
</pre>
 
=={{header|Elixir}}==
Line 5,487 ⟶ 5,744:
 
=={{header|Python}}==
<syntaxhighlight lang="python">from datetime import timedelta, (date,
timedelta)
 
DAY = timedelta(days=1)
START, STOP = date(1900, 1, 1), date(2101, 1, 1)
WEEKEND = {6, 5, 4} # Sunday is day 6
FMT = '%Y %m(%B)'
 
def fiveweekendspermonth(start=START, stop=STOP):
'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
 
def five_weekends_per_month(start: date = START,
dates = fiveweekendspermonth()
stop: date = STOP) -> list[date]:
"""Compute months with five weekends between dates"""
current_date = start
last_month = weekend_days = 0
five_weekends = []
while current_date < stop:
if current_date.month != last_month:
if weekend_days >= 15:
five_weekends.append(current_date - DAY)
weekend_days = 0
last_month = current_date.month
if current_date.weekday() in WEEKEND:
weekend_days += 1
current_date += DAY
return five_weekends
 
 
dates = five_weekends_per_month()
indent = ' '
print('f"There are %s{len(dates)} 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:]))
 
years_without_five_weekends_months = (STOP.year - START.year
print('\nThere are %i years in the range that do not have months with five weekends'
% len(set(range(START.year, STOP.year)) - len({d.year for d in dates}))</syntaxhighlight>
print(f"\nThere are {years_without_five_weekends_months} years in the "
f"range that do not have months with five weekends")</syntaxhighlight>
 
'''Alternate Algorithm'''
 
The condition is equivalent to having a thirty-one day month in which the last day of the month is a Sunday.
<syntaxhighlight lang="python">LONGMONTHS = (1, 3, 5, 7, 8, 10, 12) # Jan Mar May Jul Aug Oct Dec
 
def fiveweekendspermonth2(start=START, stop=STOP):
 
return [date(yr, month, 31)
def five_weekends_per_month2(start: date = START,
for yr in range(START.year, STOP.year)
for month in LONGMONTHS stop: date = STOP) -> list[date]:
return [last_day
if date(yr, month, 31).timetuple()[6] == 6 # Sunday
]for year in range(start.year, stop.year)
for month in LONG_MONTHS
if (last_day := date(year, month, 31)).weekday() == 6] # Sunday
 
dates2 = fiveweekendspermonth2five_weekends_per_month2()
assert dates2 == dates</syntaxhighlight>
 
Line 6,209 ⟶ 6,472:
2100-October
Total : 201
</pre>
 
=={{header|RPL}}==
{{works with|Halcyon Calc|4.2.7}}
{| class="wikitable"
! RPL code
! Comment
|-
|
OVER 3 < -
R→B DUP 4 / OVER 100 / - OVER 400 / + + B→R
{ 0 3 2 5 0 3 5 1 4 6 2 4 } ROT GET + + 7 MOD
≫ ''''DAYoW'''' STO
{} (0,0) 1900 2100 FOR y
1 CF 1 12 '''FOR''' m
'''IF''' { 1 3 5 7 8 10 12 } m POS '''THEN'''
'''IF''' 1 m y '''DAYoW''' 5 == '''THEN'''
'''IF''' DUP RE 5 < OVER RE 195 > OR '''THEN'''
y m R→C ROT SWAP + SWAP '''END'''
1 + 1 SF '''END'''
'''END'''
'''NEXT IF''' 1 FC? '''THEN''' (0,1) + '''END'''
'''NEXT'''
≫ ''''MW5WE'''' STO
|
'''DAYoW''' ''( j mm aaaa -- day )''
if ( m < 3 ) { y -= 1; }
return (y + y/4 - y/100 + y/400
+ t[m-1] + d) % 7 ;
'''MW5WE''' ''( -- {(first)..(last)} (months,years) )''
For each year in range
reset flag
scan long months
if month starts on Fridays
if in first 5 or last 5 ones
store as (yyyy,mm)
increase month counter, set flag
if flag not set, count the year
|}
{{out}}
<pre>
2: { (1901,3) (1902,8) (1903,5) (1904,1) (1904,7) (2097,3) (2098,8) (2099,5) (2100,1) (2100,10) }
1: (201,29)
</pre>
 
Line 7,054 ⟶ 7,368:
{{libheader|Wren-date}}
{{libheader|Wren-seq}}
<syntaxhighlight lang="ecmascriptwren">import "./date" for Date
import "./seq" for Lst
 
var dates = []
2,041

edits