50 lines
1.5 KiB
Scala
50 lines
1.5 KiB
Scala
/**
|
|
* Loosely based on the Ruby implementation.
|
|
*
|
|
* Focuses on immutability and Scala idioms,
|
|
* while trying to remain readable and clean.
|
|
*/
|
|
object YearCalendarApp extends App with Extras {
|
|
|
|
val defaultYear = 1752
|
|
val columns = 86
|
|
|
|
val year = args.headOption.map(_.toInt).getOrElse(defaultYear)
|
|
|
|
yearCalendarLines(year, columns).foreach(println)
|
|
|
|
def yearCalendarLines(year: Int, columns: Int): Seq[String] = {
|
|
// At least one. Divide rest columns by width + 2 spaces (separator)
|
|
val calendarsPerRow = 1 + (columns - 20) / (20 + 2)
|
|
|
|
// Use 20 columns per month + 2 spaces between months
|
|
val width = calendarsPerRow * 22 - 2
|
|
|
|
List(
|
|
"[Snoopy]".center(width),
|
|
s"${year}".center(width)) ++
|
|
// Get, group, transpose and join calendar lines
|
|
allMonthCalendarLines(year).grouped(calendarsPerRow).flatMap { calGroup =>
|
|
calGroup.transpose.map(stringsInRow => stringsInRow.mkString(" "))
|
|
}
|
|
}
|
|
|
|
def allMonthCalendarLines(year: Int): Seq[Seq[String]] = {
|
|
(1 to 12).map { monthNr =>
|
|
val date = MonthCalendar(monthInYear = monthNr, year)
|
|
|
|
// Make array of 42 days (7 * 6 weeks max.) starting with Sunday (which is 0)
|
|
val daySlotsInMonth = {
|
|
(Seq().padTo(date.dayOfWeek, " ") ++
|
|
date.daysInMonth.map { dayNr => "%2d".format(dayNr) }).
|
|
padTo(42, " ")
|
|
}
|
|
|
|
List(
|
|
date.monthName.center(20),
|
|
"Su Mo Tu We Th Fr Sa") ++
|
|
daySlotsInMonth.grouped(7).map { weekSlots => weekSlots.mkString(" ") }
|
|
}
|
|
}
|
|
|
|
}
|