2008 Winter Scripting Games Event 4
If you aren't already in the know, these ten problems are from the 2008 Winter Scripting games.
For each problem, I'm going to quickly sum up the interesting (interesting TO ME) bits of each problem, then I'm going to post the full source.
Event 4: Image is Everything
In this challenge, we are asked to pretty-print a calendar from text.
My solution is ugly. I don't make excuses, it's ugly. I don't know if I could have cleaned it up any without adding a lot of complexity/structure, so, this is honestly as pretty as I could make it in PowerShell.
Source
#PROBLEM #4
function Parse-Input ($monthYear)
{
$split = $monthYear.Split("/");
$month = [int][string]$split[0]
$year = [int][string]$split[1]
[datetime]"$year-$month-1"
}
$weekdayLabels = @("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")
$weekdayToIndexMap = @{}
foreach ($index in 0..6) { $weekdayToIndexMap[$weekdayLabels[$index]] = $index }
function PrettyPrint-Calendar ($date)
{
$output = @()
$output += ""
$output += $date.ToString("MMMM yyyy")
$output += ""
$output += [string]::Join("`t", $weekdayLabels)
$output += PrettyPrint-DaysGrid -month $date
Write-Host ($output | Out-String)
}
function Pad-Cell ($cell)
{
$cell = $cell.ToString()
if ($cell.length -eq 1)
{
" $cell"
} elseif ($cell.length -eq 2) {
" $cell"
} else {
"$cell"
}
}
#POSTSCRIPT - I think everyone's solution for this was ugly, or maybe
#I'm just projecting. Projecting my opinion that "this code sucks and is ugly"
#out to everyone else's solution. Clearly it's not "elegant".
function PrettyPrint-DaysGrid ($month)
{
#gets first day through last day of this month
$days = 1..($month.AddMonths(1).AddDays(-1).Day)
$daysOutput = @()
$firstWeekdayIndex = $weekdayToIndexMap[$month.DayOfWeek.ToString().Substring(0,3)]
$weekdayOffset = ($firstWeekdayIndex + 7 - 1) % 7
foreach ($emptyDay in 0..($firstWeekdayIndex - 1))
{
$daysOutput += "`t"
}
foreach ($day in $days)
{
$weekday = ($day + $weekdayOffset) % 7
if ($weekday -le 5)
{
$daysOutput += "$(Pad-Cell $day)`t"
}
else
{
$daysOutput += "$(Pad-Cell $day)`n"
}
}
[string]::Join("", $daysOutput)
}
function Solve-Problem4
{
#POSTSCRIPT-OOPS - Apparently I forgot that Read-Host takes in a "prompt" argument,
#so I "innovated" and found an unnecessary workaround using Write-Host below! Go me!
Write-Host -noNewLine "Please enter a date in M/YYYY format: "
PrettyPrint-Calendar -date ( Parse-Input -monthYear (Read-Host) )
}
Solve-Problem4
function Parse-Input ($monthYear)
{
$split = $monthYear.Split("/");
$month = [int][string]$split[0]
$year = [int][string]$split[1]
[datetime]"$year-$month-1"
}
$weekdayLabels = @("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")
$weekdayToIndexMap = @{}
foreach ($index in 0..6) { $weekdayToIndexMap[$weekdayLabels[$index]] = $index }
function PrettyPrint-Calendar ($date)
{
$output = @()
$output += ""
$output += $date.ToString("MMMM yyyy")
$output += ""
$output += [string]::Join("`t", $weekdayLabels)
$output += PrettyPrint-DaysGrid -month $date
Write-Host ($output | Out-String)
}
function Pad-Cell ($cell)
{
$cell = $cell.ToString()
if ($cell.length -eq 1)
{
" $cell"
} elseif ($cell.length -eq 2) {
" $cell"
} else {
"$cell"
}
}
#POSTSCRIPT - I think everyone's solution for this was ugly, or maybe
#I'm just projecting. Projecting my opinion that "this code sucks and is ugly"
#out to everyone else's solution. Clearly it's not "elegant".
function PrettyPrint-DaysGrid ($month)
{
#gets first day through last day of this month
$days = 1..($month.AddMonths(1).AddDays(-1).Day)
$daysOutput = @()
$firstWeekdayIndex = $weekdayToIndexMap[$month.DayOfWeek.ToString().Substring(0,3)]
$weekdayOffset = ($firstWeekdayIndex + 7 - 1) % 7
foreach ($emptyDay in 0..($firstWeekdayIndex - 1))
{
$daysOutput += "`t"
}
foreach ($day in $days)
{
$weekday = ($day + $weekdayOffset) % 7
if ($weekday -le 5)
{
$daysOutput += "$(Pad-Cell $day)`t"
}
else
{
$daysOutput += "$(Pad-Cell $day)`n"
}
}
[string]::Join("", $daysOutput)
}
function Solve-Problem4
{
#POSTSCRIPT-OOPS - Apparently I forgot that Read-Host takes in a "prompt" argument,
#so I "innovated" and found an unnecessary workaround using Write-Host below! Go me!
Write-Host -noNewLine "Please enter a date in M/YYYY format: "
PrettyPrint-Calendar -date ( Parse-Input -monthYear (Read-Host) )
}
Solve-Problem4
2008 Winter Scripting Game Events: Index
- Introduction: TOTAL DOMINATION!
- Event 1: Could I Get Your Phone Number?
- Event 2: Skating on Thin Ice
- Event 3: Instant (Runoff) Winner
- Event 4: Image is Everything
- Event 5: You Call That a Password?
- Event 6: Prime Time
- Event 7: Play Ball!
- Event 8: Making Beautiful Music
- Event 9: You're Twisting My Words
- Event 10: Blackjack!
- Recap