new tasks
This commit is contained in:
parent
2a4d27cea0
commit
80737d5a6a
1194 changed files with 15353 additions and 1 deletions
15
Task/Calendar/0DESCRIPTION
Normal file
15
Task/Calendar/0DESCRIPTION
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
Create a routine that will generate a text calendar for any year. Test the calendar by generating a calendar for the year 1969, on a device of the time. Choose one of the following devices:
|
||||
|
||||
* A line printer with a width of 132 characters.
|
||||
* An [[wp:IBM_3270#Displays|IBM 3278 model 4 terminal]] (80Ã43 display with accented characters). Target formatting the months of the year to fit nicely across the 80 character width screen. Restrict number of lines in test output to 43.
|
||||
|
||||
(Ideally, the program will generate well-formatted calendars for any page width from 20 characters up.)
|
||||
|
||||
Kudos (κῦδοÏ) for routines that also correctly transition from Julian to Gregorian calendar in September 1752.
|
||||
|
||||
This task is inspired by [http://www.ee.ryerson.ca/~elf/hack/realmen.html Real Programmers Don't Use PASCAL] by Ed Post, Datamation, volume 29 number 7, July 1983.
|
||||
THE REAL PROGRAMMER'S NATURAL HABITAT
|
||||
"Taped to the wall is a line-printer Snoopy calender for the year 1969."
|
||||
For further Kudos see task [[Calendar - for "real" programmers|CALENDAR]], where all code is to be in UPPERCASE.
|
||||
|
||||
For economy of size, do not actually include Snoopy generation in either the code or the output, instead just output a place-holder.
|
||||
2
Task/Calendar/1META.yaml
Normal file
2
Task/Calendar/1META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
note: Date and time
|
||||
125
Task/Calendar/C/calendar.c
Normal file
125
Task/Calendar/C/calendar.c
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int width = 80, year = 1969;
|
||||
int cols, lead, gap;
|
||||
|
||||
const char *wdays[] = { "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" };
|
||||
struct months {
|
||||
const char *name;
|
||||
int days, start_wday, at;
|
||||
} months[12] = {
|
||||
{ "January", 31, 0, 0 },
|
||||
{ "Februray", 28, 0, 0 },
|
||||
{ "March", 31, 0, 0 },
|
||||
{ "April", 30, 0, 0 },
|
||||
{ "May", 31, 0, 0 },
|
||||
{ "June", 30, 0, 0 },
|
||||
{ "July", 31, 0, 0 },
|
||||
{ "August", 31, 0, 0 },
|
||||
{ "September", 30, 0, 0 },
|
||||
{ "October", 31, 0, 0 },
|
||||
{ "November", 30, 0, 0 },
|
||||
{ "December", 31, 0, 0 }
|
||||
};
|
||||
|
||||
void space(int n) { while (n-- > 0) putchar(' '); }
|
||||
|
||||
void init_months()
|
||||
{
|
||||
int i;
|
||||
|
||||
if ((!(year % 4) && (year % 100)) || !(year % 400))
|
||||
months[1].days = 29;
|
||||
|
||||
year--;
|
||||
months[0].start_wday
|
||||
= (year * 365 + year/4 - year/100 + year/400 + 1) % 7;
|
||||
|
||||
for (i = 1; i < 12; i++)
|
||||
months[i].start_wday =
|
||||
(months[i-1].start_wday + months[i-1].days) % 7;
|
||||
|
||||
cols = (width + 2) / 22;
|
||||
while (12 % cols) cols--;
|
||||
gap = cols - 1 ? (width - 20 * cols) / (cols - 1) : 0;
|
||||
if (gap > 4) gap = 4;
|
||||
lead = (width - (20 + gap) * cols + gap + 1) / 2;
|
||||
year++;
|
||||
}
|
||||
|
||||
void print_row(int row)
|
||||
{
|
||||
int c, i, from = row * cols, to = from + cols;
|
||||
space(lead);
|
||||
for (c = from; c < to; c++) {
|
||||
i = strlen(months[c].name);
|
||||
space((20 - i)/2);
|
||||
printf("%s", months[c].name);
|
||||
space(20 - i - (20 - i)/2 + ((c == to - 1) ? 0 : gap));
|
||||
}
|
||||
putchar('\n');
|
||||
|
||||
space(lead);
|
||||
for (c = from; c < to; c++) {
|
||||
for (i = 0; i < 7; i++)
|
||||
printf("%s%s", wdays[i], i == 6 ? "" : " ");
|
||||
if (c < to - 1) space(gap);
|
||||
else putchar('\n');
|
||||
}
|
||||
|
||||
while (1) {
|
||||
for (c = from; c < to; c++)
|
||||
if (months[c].at < months[c].days) break;
|
||||
if (c == to) break;
|
||||
|
||||
space(lead);
|
||||
for (c = from; c < to; c++) {
|
||||
for (i = 0; i < months[c].start_wday; i++) space(3);
|
||||
while(i++ < 7 && months[c].at < months[c].days) {
|
||||
printf("%2d", ++months[c].at);
|
||||
if (i < 7 || c < to - 1) putchar(' ');
|
||||
}
|
||||
while (i++ <= 7 && c < to - 1) space(3);
|
||||
if (c < to - 1) space(gap - 1);
|
||||
months[c].start_wday = 0;
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
void print_year()
|
||||
{
|
||||
int row;
|
||||
char buf[32];
|
||||
sprintf(buf, "%d", year);
|
||||
space((width - strlen(buf)) / 2);
|
||||
printf("%s\n\n", buf);
|
||||
for (row = 0; row * cols < 12; row++)
|
||||
print_row(row);
|
||||
}
|
||||
|
||||
int main(int c, char **v)
|
||||
{
|
||||
int i, year_set = 0;
|
||||
for (i = 1; i < c; i++) {
|
||||
if (!strcmp(v[i], "-w")) {
|
||||
if (++i == c || (width = atoi(v[i])) < 20)
|
||||
goto bail;
|
||||
} else if (!year_set) {
|
||||
if (!sscanf(v[i], "%d", &year) || year <= 0)
|
||||
year = 1969;
|
||||
year_set = 1;
|
||||
} else
|
||||
goto bail;
|
||||
}
|
||||
|
||||
init_months();
|
||||
print_year();
|
||||
return 0;
|
||||
|
||||
bail: fprintf(stderr, "bad args\nUsage: %s year [-w width (>= 20)]\n", v[0]);
|
||||
exit(1);
|
||||
}
|
||||
1
Task/Calendar/Perl/calendar.pl
Normal file
1
Task/Calendar/Perl/calendar.pl
Normal file
|
|
@ -0,0 +1 @@
|
|||
$_=$ARGV[0]//1969;`cal $_ >&2`
|
||||
13
Task/Calendar/PicoLisp/calendar.l
Normal file
13
Task/Calendar/PicoLisp/calendar.l
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
(de cal (Year)
|
||||
(prinl "====== " Year " ======")
|
||||
(for Dat (range (date Year 1 1) (date Year 12 31))
|
||||
(let D (date Dat)
|
||||
(tab (3 3 4 8)
|
||||
(when (= 1 (caddr D))
|
||||
(get *Mon (cadr D)) )
|
||||
(caddr D)
|
||||
(day Dat *Day)
|
||||
(when (=0 (% (inc Dat) 7))
|
||||
(pack "Week " (week Dat)) ) ) ) ) )
|
||||
|
||||
(cal 1969)
|
||||
47
Task/Calendar/Python/calendar.py
Normal file
47
Task/Calendar/Python/calendar.py
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
>>> import calendar
|
||||
>>> help(calendar.prcal)
|
||||
Help on method pryear in module calendar:
|
||||
|
||||
pryear(self, theyear, w=0, l=0, c=6, m=3) method of calendar.TextCalendar instance
|
||||
Print a years calendar.
|
||||
|
||||
>>> calendar.prcal(1969)
|
||||
1969
|
||||
|
||||
January February March
|
||||
Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
|
||||
1 2 3 4 5 1 2 1 2
|
||||
6 7 8 9 10 11 12 3 4 5 6 7 8 9 3 4 5 6 7 8 9
|
||||
13 14 15 16 17 18 19 10 11 12 13 14 15 16 10 11 12 13 14 15 16
|
||||
20 21 22 23 24 25 26 17 18 19 20 21 22 23 17 18 19 20 21 22 23
|
||||
27 28 29 30 31 24 25 26 27 28 24 25 26 27 28 29 30
|
||||
31
|
||||
|
||||
April May June
|
||||
Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
|
||||
1 2 3 4 5 6 1 2 3 4 1
|
||||
7 8 9 10 11 12 13 5 6 7 8 9 10 11 2 3 4 5 6 7 8
|
||||
14 15 16 17 18 19 20 12 13 14 15 16 17 18 9 10 11 12 13 14 15
|
||||
21 22 23 24 25 26 27 19 20 21 22 23 24 25 16 17 18 19 20 21 22
|
||||
28 29 30 26 27 28 29 30 31 23 24 25 26 27 28 29
|
||||
30
|
||||
|
||||
July August September
|
||||
Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
|
||||
1 2 3 4 5 6 1 2 3 1 2 3 4 5 6 7
|
||||
7 8 9 10 11 12 13 4 5 6 7 8 9 10 8 9 10 11 12 13 14
|
||||
14 15 16 17 18 19 20 11 12 13 14 15 16 17 15 16 17 18 19 20 21
|
||||
21 22 23 24 25 26 27 18 19 20 21 22 23 24 22 23 24 25 26 27 28
|
||||
28 29 30 31 25 26 27 28 29 30 31 29 30
|
||||
|
||||
October November December
|
||||
Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
|
||||
1 2 3 4 5 1 2 1 2 3 4 5 6 7
|
||||
6 7 8 9 10 11 12 3 4 5 6 7 8 9 8 9 10 11 12 13 14
|
||||
13 14 15 16 17 18 19 10 11 12 13 14 15 16 15 16 17 18 19 20 21
|
||||
20 21 22 23 24 25 26 17 18 19 20 21 22 23 22 23 24 25 26 27 28
|
||||
27 28 29 30 31 24 25 26 27 28 29 30 29 30 31
|
||||
|
||||
>>> print('1234567890'*8)
|
||||
12345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
>>>
|
||||
145
Task/Calendar/REXX/calendar.rexx
Normal file
145
Task/Calendar/REXX/calendar.rexx
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
/*REXX program to show any year's (monthly) calendar (with/without grid)*/
|
||||
|
||||
@abc='abcdefghijklmnopqrstuvwxyz'; @abcU=@abc; upper @abcU
|
||||
calfill=' '; mc=12; _='1 3 1234567890' "fb"x
|
||||
parse var _ grid calspaces # chk . cv_ days.1 days.2 days.3 daysn sd sw
|
||||
_=0; parse var _ cols 1 jd 1 lowerCase 1 maxKalPuts 1 narrow 1,
|
||||
narrower 1 narrowest 1 short 1 shorter 1 shortest 1,
|
||||
small 1 smaller 1 smallest 1 upperCase
|
||||
parse arg mm '/' dd "/" yyyy _ '(' ops; uops=ops
|
||||
if _\=='' | \is#(mm) | \is#(dd) | \is#(yyyy) then call erx 86
|
||||
|
||||
do while ops\==''; ops=strip(ops,'L'); parse var ops _1 2 1 _ . 1 _o ops
|
||||
upper _
|
||||
select
|
||||
when abb('CALSPaces') then calspaces=nai()
|
||||
when abb('DEPth') then sd=nai()
|
||||
when abbn('GRIDs') then grid=no()
|
||||
when abbn('LOWercase') then lowerCase=no()
|
||||
when abb('CALMONths') then mc=nai()
|
||||
when abbn('NARrow') then narrow=no()
|
||||
when abbn('NARROWER') then narrower=no()
|
||||
when abbn('NARROWESt') then narrowest=no()
|
||||
when abbn('SHORt') then short=no()
|
||||
when abbn('SHORTER') then shorter=no()
|
||||
when abbn('SHORTESt') then shortest=no()
|
||||
when abbn('SMALl') then small=no()
|
||||
when abbn('SMALLER') then smaller=no()
|
||||
when abbn('SMALLESt') then smallest=no()
|
||||
when abbn('UPPercase') then upperCase=no()
|
||||
when abb('WIDth') then sw=nai()
|
||||
otherwise nop
|
||||
end /*select*/
|
||||
end /*do while opts\== ...*/
|
||||
|
||||
mc=int(mc,'monthscalender'); if mc>0 then cal=1
|
||||
days='Sunday Monday Tuesday Wednesday Thursday Friday Saturday'
|
||||
months='January February March April May June July August September October November December'
|
||||
days=' 'days; months=' 'months
|
||||
cyyyy=right(date(),4); hyy=left(cyyyy,2); lyy=right(cyyyy,2)
|
||||
dy.=31; _=30; parse var _ dy.4 1 dy.6 1 dy.9 1 dy.11; dy.2=28+ly(yyyy)
|
||||
yy=right(yyyy,2); sd=p(sd 43); sw=p(sw 80); cw=10; cindent=1; calwidth=76
|
||||
if small then do; narrow=1 ; short=1 ; end
|
||||
if smaller then do; narrower=1 ; shorter=1 ; end
|
||||
if smallest then do; narrowest=1; shortest=1; end
|
||||
if shortest then shorter=1
|
||||
if shorter then short =1
|
||||
if narrow then do; cw=9; cindent=3; calwidth=69; end
|
||||
if narrower then do; cw=4; cindent=1; calwidth=34; end
|
||||
if narrowest then do; cw=2; cindent=1; calwidth=20; end
|
||||
cv_=calwidth+calspaces+2
|
||||
calfill=left(copies(calfill,cw),cw)
|
||||
do j=1 for 7; _=word(days,j)
|
||||
do jw=1 for 3; _d=strip(substr(_,cw*jw-cw+1,cw))
|
||||
if jw=1 then _d=centre(_d,cw+1)
|
||||
else _d=left(_d,cw+1)
|
||||
days.jw=days.jw||_d
|
||||
end /*jw*/
|
||||
__=daysn
|
||||
if narrower then daysn=__||centre(left(_,3),5)
|
||||
if narrowest then daysn=__||center(left(_,2),3)
|
||||
end /*j*/
|
||||
_yyyy=yyyy; calPuts=0; cv=1; _mm=mm+0; month=word(months,mm)
|
||||
dy.2=28+ly(_yyyy); dim=dy._mm; _dd=01; dow=dow(_mm,_dd,_yyyy); $dd=dd+0
|
||||
|
||||
/*ââââââââââââââââââââââââââââânow: the business of the building the cal*/
|
||||
call calGen
|
||||
do _j=2 to mc
|
||||
if cv_\=='' then do
|
||||
cv=cv+cv_
|
||||
if cv+cv_>=sw then do; cv=1; call calPut
|
||||
call fcalPuts;call calPb
|
||||
end
|
||||
else calPuts=0
|
||||
end
|
||||
else do;call calPb;call calPut;call fcalPuts;end
|
||||
_mm=_mm+1; if _mm==13 then do; _mm=1; _yyyy=_yyyy+1; end
|
||||
month=word(months,_mm); dy.2=28+ly(_yyyy); dim=dy._mm
|
||||
dow=dow(_mm,_dd,_yyyy); $dd=0; call calGen
|
||||
end /*_j*/
|
||||
call fcalPuts
|
||||
return _
|
||||
|
||||
/*âââââââââââââââââââââââââââââcalGen subroutineââââââââââââââââââââââââ*/
|
||||
calGen: cellX=;cellJ=;cellM=;calCells=0;calline=0
|
||||
call calPut
|
||||
call calPutl copies('â',calwidth),"ââ"; call calHd
|
||||
call calPutl month ' ' _yyyy ; call calHd
|
||||
if narrowest | narrower then call calPutl daysn
|
||||
else do jw=1 for 3
|
||||
if space(days.jw)\=='' then call calPutl days.jw
|
||||
end
|
||||
calft=1; calfb=0
|
||||
do jf=1 for dow-1; call cellDraw calFill,calFill; end
|
||||
do jy=1 for dim; call cellDraw jy; end
|
||||
calfb=1
|
||||
do 7; call cellDraw calFill,calFill; end
|
||||
if sd>32 & \shorter then call calPut
|
||||
return
|
||||
|
||||
/*âââââââââââââââââââââââââââââcellDraw subroutineââââââââââââââââââââââ*/
|
||||
cellDraw: parse arg zz,cdDOY;zz=right(zz,2);calCells=calCells+1
|
||||
if calCells>7 then do
|
||||
calLine=calLine+1
|
||||
cellX=substr(cellX,2)
|
||||
cellJ=substr(cellJ,2)
|
||||
cellM=substr(cellM,2)
|
||||
cellB=translate(cellX,,")(â-"#)
|
||||
if calLine==1 then call cx
|
||||
call calCsm; call calPutl cellX; call calCsj; call cx
|
||||
cellX=; cellJ=; cellM=; calCells=1
|
||||
end
|
||||
cdDOY=right(cdDOY,cw); cellM=cellM'â'center('',cw)
|
||||
cellX=cellX'â'centre(zz,cw); cellJ=cellJ'â'center('',cw)
|
||||
return
|
||||
|
||||
/*âââââââââââââââââââââââââââââgeneral 1-line subsââââââââââââââââââââââ*/
|
||||
abb: arg abbu; parse arg abb; return abbrev(abbu,_,abbl(abb))
|
||||
abbl: return verify(arg(1)'a',@abc,'M')-1
|
||||
abbn: parse arg abbn; return abb(abbn) | abb('NO'abbn)
|
||||
calCsj: if sd>49 & \shorter then call calPutl cellB; if sd>24 & \short then call calPutl cellJ; return
|
||||
calCsm: if sd>24 & \short then call calPutl cellM; if sd>49 & \shorter then call calPutl cellB; return
|
||||
calHd: if sd>24 & \shorter then call calPutl ; if sd>32 & \shortest then call calPutl ; return
|
||||
calPb: calPuts=calPuts+1; maxKalPuts=max(maxKalPuts,calPuts); if symbol('CT.'calPuts)\=='VAR' then ct.calPuts=; ct.calPuts=overlay(arg(1),ct.calPuts,cv); return
|
||||
calPutl: call calPut copies(' ',cindent)left(arg(2)"â",1)center(arg(1),calwidth)||right('â'arg(2),1);return
|
||||
cx:cx_='ââ¤';cx=copies(copies('â',cw)'â¼',7);if calft then do;cx=translate(cx,'â¬',"â¼");calft=0;end;if calfb then do;cx=translate(cx,'â´',"â¼");cx_='ââ';calfb=0;end;call calPutl cx,cx_;return
|
||||
dow: procedure; arg m,d,y; if m<3 then do; m=m+12; y=y-1; end; yl=left(y,2); yr=right(y,2); w=(d+(m+1)*26%10+yr+yr%4+yl%4+5*yl)//7; if w==0 then w=7; return w
|
||||
er :parse arg _1,_2; call '$ERR' "14"p(_1) p(word(_1,2) !fid(1)) _2;if _1<0 then return _1; exit result
|
||||
err: call er '-'arg(1),arg(2); return ''
|
||||
erx: call er '-'arg(1),arg(2); exit ''
|
||||
fcalPuts: do j=1 for maxKalPuts; call put ct.j; end; ct.=; maxKalPuts=0; calPuts=0; return
|
||||
int: int=numx(arg(1),arg(2));if \isint(int) then call erx 92,arg(1) arg(2); return int/1
|
||||
is#: return verify(arg(1),#)==0
|
||||
isint: return datatype(arg(1),'W')
|
||||
lower:return translate(arg(1),@abc,@abcU)
|
||||
ly: if arg(1)\=='' then call erx 01,arg(2);parse var ops na ops;if na=='' then call erx 35,_o;return na
|
||||
nai: return int(na(),_o)
|
||||
nan: return numx(na(),_o)
|
||||
no: if arg(1)\=='' then call erx 01,arg(2); return left(_,2)\=='NO'
|
||||
num: procedure;parse arg x .,f,q;if x=='' then return x;if datatype(x,'N') then return x/1;x=space(translate(x,,','),0);if datatype(x,'N') then return x/1;return numnot()
|
||||
numnot: if q==1 then return x;if q=='' then call er 53,x f;call erx 53,x f
|
||||
numx: return num(arg(1),arg(2),1)
|
||||
p: return word(arg(1),1)
|
||||
put: _=arg(1);_=translate(_,,'_'chk);if \grid then _=ungrid(_);if lowerCase then _=lower(_);if upperCase then upper _;if shortest&_=' ' then return;call tell _;return
|
||||
tell: say arg(1);return
|
||||
ungrid: return translate(arg(1),,"âââââ¤âââ´â¬ââ¼ââââââââ¢ââ¡â«âªâ¤â§â¥â¨â â£")
|
||||
70
Task/Calendar/Ruby/calendar.rb
Normal file
70
Task/Calendar/Ruby/calendar.rb
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
require 'date'
|
||||
|
||||
# Creates a calendar of _year_. Returns this calendar as a multi-line
|
||||
# string fit to _columns_.
|
||||
def cal(year, columns)
|
||||
|
||||
# Start at January 1.
|
||||
#
|
||||
# Date::ENGLAND marks the switch from Julian calendar to Gregorian
|
||||
# calendar at 1752 September 14. This removes September 3 to 13 from
|
||||
# year 1752. (By fortune, it keeps January 1.)
|
||||
#
|
||||
date = Date.new(year, 1, 1, Date::ENGLAND)
|
||||
|
||||
# Collect calendars of all 12 months.
|
||||
months = (1..12).collect do |month|
|
||||
rows = [Date::MONTHNAMES[month].center(20), "Su Mo Tu We Th Fr Sa"]
|
||||
|
||||
# Make array of 42 days, starting with Sunday.
|
||||
days = []
|
||||
date.wday.times { days.push " " }
|
||||
while date.month == month
|
||||
days.push("%2d" % date.mday)
|
||||
date += 1
|
||||
end
|
||||
(42 - days.length).times { days.push " " }
|
||||
|
||||
days.each_slice(7) { |week| rows.push(week.join " ") }
|
||||
next rows
|
||||
end
|
||||
|
||||
# Calculate months per row (mpr).
|
||||
# 1. Divide columns by 22 columns per month, rounded down. (Pretend
|
||||
# to have 2 extra columns; last month uses only 20 columns.)
|
||||
# 2. Decrease mpr if 12 months would fit in the same months per
|
||||
# column (mpc). For example, if we can fit 5 mpr and 3 mpc, then
|
||||
# we use 4 mpr and 3 mpc.
|
||||
mpr = (columns + 2).div 22
|
||||
mpr = 12.div((12 + mpr - 1).div mpr)
|
||||
|
||||
# Use 20 columns per month + 2 spaces between months.
|
||||
width = mpr * 22 - 2
|
||||
|
||||
# Join months into calendar.
|
||||
rows = ["[Snoopy]".center(width), "#{year}".center(width)]
|
||||
months.each_slice(mpr) do |slice|
|
||||
slice[0].each_index do |i|
|
||||
rows.push(slice.map {|a| a[i]}.join " ")
|
||||
end
|
||||
end
|
||||
return rows.join("\n")
|
||||
end
|
||||
|
||||
|
||||
ARGV.length == 1 or abort "usage: #{$0} year"
|
||||
|
||||
# Guess width of terminal.
|
||||
# 1. Obey environment variable COLUMNS.
|
||||
# 2. Try to require 'io/console' from Ruby 1.9.3.
|
||||
# 3. Try to run `tput co`.
|
||||
# 4. Assume 80 columns.
|
||||
columns = begin Integer(ENV["COLUMNS"] || "")
|
||||
rescue
|
||||
begin require 'io/console'; IO.console.winsize[1]
|
||||
rescue LoadError
|
||||
begin Integer(`tput co`)
|
||||
rescue
|
||||
80; end; end; end
|
||||
|
||||
puts cal(Integer(ARGV[0]), columns)
|
||||
203
Task/Calendar/Scala/calendar.scala
Normal file
203
Task/Calendar/Scala/calendar.scala
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
import java.util.TimeZone
|
||||
import java.util.Locale
|
||||
import java.util.Calendar
|
||||
import java.util.GregorianCalendar
|
||||
|
||||
object Helper {
|
||||
def monthsMax(locale: Locale = Locale.getDefault): Int = {
|
||||
val cal = Calendar.getInstance(locale)
|
||||
cal.getMaximum(Calendar.MONTH)
|
||||
}
|
||||
|
||||
def numberOfMonths(locale: Locale = Locale.getDefault): Int = monthsMax(locale)+1
|
||||
|
||||
def namesOfMonths(year: Int, locale: Locale = Locale.getDefault): List[String] = {
|
||||
val cal = Calendar.getInstance(locale)
|
||||
val f1: Int => String = i => {
|
||||
cal.set(year,i,1)
|
||||
cal.getDisplayName(Calendar.MONTH, Calendar.LONG, locale)
|
||||
}
|
||||
(0 to monthsMax(locale)) map f1 toList
|
||||
}
|
||||
|
||||
def jgt(cal: GregorianCalendar): Int = {cal.setTime(cal.getGregorianChange); cal.get(Calendar.YEAR)}
|
||||
|
||||
def isJGT(year: Int, cal: GregorianCalendar) = year==jgt(cal)
|
||||
|
||||
def offsets(year: Int, locale: Locale = Locale.getDefault): List[Int] = {
|
||||
val cal = Calendar.getInstance(locale)
|
||||
val months = cal.getMaximum(Calendar.MONTH)
|
||||
val f1: Int => Int = i => {
|
||||
cal.set(year,i,1)
|
||||
cal.get(Calendar.DAY_OF_WEEK)
|
||||
}
|
||||
((0 to months) map f1 toList) map {i=>if((i-2)<0) i+5 else i-2}
|
||||
}
|
||||
|
||||
def headerNameOfDays(locale: Locale = Locale.getDefault) = {
|
||||
val cal = Calendar.getInstance(locale)
|
||||
val mdow = cal.getDisplayNames(Calendar.DAY_OF_WEEK, Calendar.SHORT, locale) // map days of week
|
||||
val it = mdow.keySet.iterator
|
||||
import scala.collection.mutable.ListBuffer
|
||||
val lb = new ListBuffer[String]
|
||||
while (it.hasNext) lb+=it.next
|
||||
val lpdow = lb.toList.map{k=>(mdow.get(k),k.substring(0,2))} // list pair days of week
|
||||
(lpdow map {p=>if((p._1-2)<0) (p._1+5, p._2) else (p._1-2, p._2)} sortWith(_._1<_._1) map (_._2)).foldRight("")(_+" "+_)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
object CalendarPrint extends App {
|
||||
import Helper._
|
||||
|
||||
val tzd = TimeZone.getDefault
|
||||
val locd = Locale.getDefault
|
||||
|
||||
def printCalendar(year: Int, printerWidth: Int, loc: Locale, tz: TimeZone) = {
|
||||
|
||||
def getCal: List[Triple[Int, Int, String]] = {
|
||||
val cal = new GregorianCalendar(tz, loc)
|
||||
|
||||
def getGregCal: List[Triple[Int, Int, String]] = {
|
||||
val month = 0
|
||||
val day = 1
|
||||
cal.set(year,month,day)
|
||||
val f1: Int => Triple[Int, Int, Int] = i => {
|
||||
val cal = Calendar.getInstance(tz, loc)
|
||||
cal.set(year,i,1)
|
||||
val minday = cal.getActualMinimum(Calendar.DAY_OF_MONTH)
|
||||
val maxday = cal.getActualMaximum(Calendar.DAY_OF_MONTH)
|
||||
(i, minday, maxday)
|
||||
}
|
||||
val limits = (0 to monthsMax(loc)) map f1
|
||||
val f2: (Int, Int, Int) => String = (year, month, day) => {
|
||||
val cal = Calendar.getInstance(tz, loc)
|
||||
cal.set(year,month,day)
|
||||
cal.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.SHORT, loc)
|
||||
}
|
||||
val calend = for {
|
||||
i <- 0 to monthsMax(loc)
|
||||
j <- limits(i)._2 to limits(i)._3
|
||||
val dow = f2(year, i, j)
|
||||
} yield (i, j, dow)
|
||||
if (isJGT(year, new GregorianCalendar(tz, loc))) calend.filter{_._1!=9}.toList else calend.toList
|
||||
}
|
||||
|
||||
def getJGT: List[Triple[Int, Int, String]] = {
|
||||
if (!isJGT(year, new GregorianCalendar(tz, loc))) return Nil
|
||||
|
||||
val cal = new GregorianCalendar(tz, loc)
|
||||
cal.set(year,9,1)
|
||||
var ldom = 0
|
||||
def it = new Iterator[Tuple3[Int,Int, String]]{
|
||||
def next={
|
||||
val res = (cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), cal.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.SHORT, Locale.GERMAN))
|
||||
ldom = res._2
|
||||
cal.roll(Calendar.DAY_OF_MONTH, true)
|
||||
res
|
||||
}
|
||||
def hasNext = (cal.get(Calendar.DAY_OF_MONTH)>ldom)
|
||||
}
|
||||
it.toList
|
||||
}
|
||||
(getGregCal++getJGT).sortWith((s,t)=>s._1*100+s._2<t._1*100+t._2)
|
||||
}
|
||||
|
||||
def printCal(calList: List[Triple[Int, Int, String]]) = {
|
||||
val pwmax = 300 // printer width maximum
|
||||
val mw = 20 // month width
|
||||
val gwf = 2 // gap width fixed
|
||||
val gwm = 2 // gap width minimum
|
||||
val fgw = true
|
||||
|
||||
val arr = Array.ofDim[String](6,7)
|
||||
def clear = for (i <- 0 until 6) for (j <- 0 until 7) arr(i)(j) = " "
|
||||
|
||||
def limits(printerWidth: Int): Tuple5[Int, Int, Int, Int, Int] = {
|
||||
val pw = if (printerWidth<20) 20 else if (printerWidth>300) 300 else printerWidth
|
||||
|
||||
def getFGW(msbs: Int,gsm: Int) = {val r=(pw-msbs*mw-gsm)/2; (r,gwf,r)} // fixed gap width
|
||||
def getVGW(msbs: Int,gsm: Int) = pw-msbs*mw-gsm match { // variable gap width
|
||||
case a if (a<2*gwm) => (a/2,gwm,a/2)
|
||||
case b => {val x = (b+gsm)/(msbs+1); (x,x,x)}
|
||||
}
|
||||
|
||||
// months side by side, gaps sum minimum
|
||||
val (msbs, gsm) = {
|
||||
val (x, y) = {val c = if (pw/mw>12) 12 else pw/mw; if (c*mw+(c-1)*gwm<=pw) (c, c*gwm) else (c-1, (c-1)*gwm)}
|
||||
val x1 = x match {
|
||||
case 5 => 4
|
||||
case a if (a>6 && a<12) => 6
|
||||
case other => other
|
||||
}
|
||||
(x1, (x1-1)*gwm)
|
||||
}
|
||||
|
||||
// left margin, gap width, right margin
|
||||
val (lm,gw,rm) = if (fgw) getFGW(msbs,gsm) else getVGW(msbs,gsm)
|
||||
(pw,msbs,lm,gw,rm)
|
||||
}
|
||||
|
||||
val (pw,msbs,lm,gw,rm) = limits(printerWidth)
|
||||
val monthsList = (0 to monthsMax(loc)).map{m=>calList.filter{_._1==m}}.toList
|
||||
val nom = namesOfMonths(year,loc)
|
||||
val offsetList = offsets(year,loc)
|
||||
val hnod = headerNameOfDays(loc)
|
||||
|
||||
val fsplit: List[(Int, Int, String)] => List[String] = list => {
|
||||
val fap: Int => (Int, Int) = p => (p/7,p%7)
|
||||
clear
|
||||
for (i <- 0 until list.size) arr(fap(i+offsetList(list(i)._1))._1)(fap(i+offsetList(list(i)._1))._2)="%2d".format(list(i)._2)
|
||||
//arr.toList.map(_.toList).map(_.foldLeft("")(_+" "+_))
|
||||
arr.toList.map(_.toList).map(_.foldRight("")(_+" "+_))
|
||||
}
|
||||
val monthsRows = monthsList.map(fsplit)
|
||||
|
||||
val center: (String, Int) => String = (s,l) => {
|
||||
if (s.size>=l) s.substring(0,l) else
|
||||
(" "*((l-s.size)/2)+s+" "*((l-s.size)/2)+" ").substring(0,l)
|
||||
}
|
||||
|
||||
println(center("[Snoopy Picture]",pw))
|
||||
println
|
||||
println(center(""+year,pw))
|
||||
println
|
||||
|
||||
val ul = numberOfMonths(loc)
|
||||
val rowblocks = (1 to ul/msbs).map{i=>
|
||||
(0 to 5).map{j=>
|
||||
val lb = new scala.collection.mutable.ListBuffer[String]
|
||||
val k = (i-1)*msbs
|
||||
(k to k+msbs-1).map{l=>
|
||||
lb+=monthsRows(l)(j)
|
||||
}
|
||||
lb.toList
|
||||
}.toList
|
||||
}.toList
|
||||
|
||||
val mheaders = (1 to ul/msbs).map{i=>(0 to msbs-1).map{j=>center(nom(j+(i-1)*msbs),20)}.toList}.toList
|
||||
val dowheaders = (1 to ul/msbs).map{i=>(0 to msbs-1).map{j=>center(hnod,20)}.toList}.toList
|
||||
|
||||
(1 to 12/msbs).foreach{i=>
|
||||
println(" "*lm+mheaders(i-1).foldRight("")(_+" "*gw+_))
|
||||
println(" "*lm+dowheaders(i-1).foldRight("")(_+" "*gw+_))
|
||||
rowblocks(i-1).foreach{xs=>println(" "*lm+xs.foldRight("")(_+" "*(gw-1)+_))}
|
||||
println
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
val calList = getCal
|
||||
printCal(calList)
|
||||
|
||||
}
|
||||
|
||||
def printGregCal(year: Int = 1969, pw: Int = 80, JGT: Boolean = false, loc: Locale = Locale.getDefault, tz: TimeZone = TimeZone.getDefault) {
|
||||
val _year = if (JGT==false) year else jgt(new GregorianCalendar(tz, loc))
|
||||
printCalendar(_year, pw, loc, tz)
|
||||
}
|
||||
|
||||
printGregCal()
|
||||
printGregCal(JGT=true, loc=Locale.UK, pw=132, tz=TimeZone.getTimeZone("UK/London"))
|
||||
|
||||
}
|
||||
2
Task/Calendar/Tcl/calendar-2.tcl
Normal file
2
Task/Calendar/Tcl/calendar-2.tcl
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
snoopy
|
||||
cal 1969
|
||||
2
Task/Calendar/Tcl/calendar-3.tcl
Normal file
2
Task/Calendar/Tcl/calendar-3.tcl
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
snoopy
|
||||
cal 1582 :Europe/Madrid es_ES
|
||||
75
Task/Calendar/Tcl/calendar.tcl
Normal file
75
Task/Calendar/Tcl/calendar.tcl
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
package require Tcl 8.5
|
||||
|
||||
# Produce information about the days in a month, without any assumptions about
|
||||
# what those days actually are.
|
||||
proc calMonthDays {timezone locale year month} {
|
||||
set days {}
|
||||
set moment [clock scan [format "%04d-%02d-00 12:00" $year $month] \
|
||||
-timezone $timezone -locale $locale -format "%Y-%m-%d %H:%M"]
|
||||
while 1 {
|
||||
set moment [clock add $moment 1 day]
|
||||
lassign [clock format $moment -timezone $timezone -locale $locale \
|
||||
-format "%m %d %u"] m d dow
|
||||
if {[scan $m %d] != $month} {
|
||||
return $days
|
||||
}
|
||||
lappend days $moment [scan $d %d] $dow
|
||||
}
|
||||
}
|
||||
|
||||
proc calMonth {year month timezone locale} {
|
||||
set dow 0
|
||||
set line ""
|
||||
set lines {}
|
||||
foreach {t day dayofweek} [calMonthDays $timezone $locale $year $month] {
|
||||
if {![llength $lines]} {lappend lines $t}
|
||||
if {$dow > $dayofweek} {
|
||||
lappend lines [string trimright $line]
|
||||
set line ""
|
||||
set dow 0
|
||||
}
|
||||
while {$dow < $dayofweek-1} {
|
||||
append line " "
|
||||
incr dow
|
||||
}
|
||||
append line [format "%2d " $day]
|
||||
set dow $dayofweek
|
||||
}
|
||||
lappend lines [string trimright $line]
|
||||
}
|
||||
|
||||
proc cal3Month {year month timezone locale} {
|
||||
# Extract the month data
|
||||
set d1 [lassign [calMonth $year $month $timezone $locale] t1]; incr month
|
||||
set d2 [lassign [calMonth $year $month $timezone $locale] t2]; incr month
|
||||
set d3 [lassign [calMonth $year $month $timezone $locale] t3]
|
||||
# Print the header line of month names
|
||||
foreach t [list $t1 $t2 $t3] {
|
||||
set m [clock format $t -timezone $timezone -locale $locale -format "%B"]
|
||||
set l [expr {10 + [string length $m]/2}]
|
||||
puts -nonewline [format "%-25s" [format "%*s" $l $m]]
|
||||
}
|
||||
puts ""
|
||||
# Print the month days
|
||||
foreach l1 $d1 l2 $d2 l3 $d3 {
|
||||
puts [format "%-25s%-25s%s" $l1 $l2 $l3]
|
||||
}
|
||||
}
|
||||
|
||||
proc cal {{year ""} {timezone :localtime} {locale en}} {
|
||||
if {$year eq ""} {
|
||||
set year [clock format [clock seconds] -format %Y]
|
||||
}
|
||||
puts [format "%40s" "-- $year --"]
|
||||
foreach m {1 4 7 10} {
|
||||
puts ""
|
||||
cal3Month $year $m $timezone $locale
|
||||
}
|
||||
}
|
||||
|
||||
proc snoopy {} {
|
||||
puts [format "%43s\n" {[Snoopy Picture]}]
|
||||
}
|
||||
|
||||
snoopy
|
||||
cal
|
||||
Loading…
Add table
Add a link
Reference in a new issue