new tasks

This commit is contained in:
Ingy döt Net 2013-04-09 00:46:50 -07:00
parent 2a4d27cea0
commit 80737d5a6a
1194 changed files with 15353 additions and 1 deletions

View 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
View file

@ -0,0 +1,2 @@
---
note: Date and time

125
Task/Calendar/C/calendar.c Normal file
View 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);
}

View file

@ -0,0 +1 @@
$_=$ARGV[0]//1969;`cal $_ >&2`

View 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)

View 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
>>>

View 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),,"│║─═┤┐└┴┬├┼┘┌╔╗╚╝╟╢╞╡╫╪╤╧╥╨╠╣")

View 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)

View 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"))
}

View file

@ -0,0 +1,2 @@
snoopy
cal 1969

View file

@ -0,0 +1,2 @@
snoopy
cal 1582 :Europe/Madrid es_ES

View 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