Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
rhiroe committed Oct 29, 2024
1 parent fe72acf commit 28e4847
Showing 1 changed file with 50 additions and 16 deletions.
66 changes: 50 additions & 16 deletions lib/sg_strange_calendar.rb
Original file line number Diff line number Diff line change
@@ -1,36 +1,70 @@
require 'date'

class SgStrangeCalendar
WDAYS = %w[Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo].freeze
MONTHS = %w[Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec].freeze
BLANK = ' '.freeze

def initialize(year, today = nil)
@year = year
@today = today
end

def generate(vertical: false)
header = (vertical ? MONTHS : WDAYS).dup.unshift("#{@year}")
ths = (vertical ? WDAYS : MONTHS).dup
length = vertical ? 3 : 2
calendar = days(length:).then { vertical ? _1.transpose : _1 }.map do |line|
line.unshift(ths.shift.ljust(4))
line.join(' ').then { _1.gsub(/\s(\[\d{,2}\])(?:\s|\z)/) { "#{$1}" } }.rstrip
end
calendar.unshift(header.join(' ')).join("\n")
builder = vertical ? VerticalBuilder : HorizontalBuilder
builder.new(@year, @today).build
end

private
class Builder
WDAYS = %w[Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo].freeze
MONTHS = %w[Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec].freeze
BLANK = ' '.freeze

private_constant :WDAYS, :MONTHS, :BLANK

def initialize(year, today)
@year = year
@today = today
end

def build
calendar = rows.map do |line|
line.unshift(ths.shift.ljust(4))
line.join(' ').then { _1.gsub(/\s(\[\d{,2}\])(?:\s|\z)/) { "#{$1}" } }.rstrip
end
calendar.unshift(header.join(' ')).join("\n")
end

private

def days(length:)
[*1..12].map do |month|
def days_in(month)
begining_of_month, end_of_month = Date.new(@year, month, 1), Date.new(@year, month, -1)
array = [*begining_of_month..end_of_month].map do |date|
date == @today ? "[#{date.day}]".rjust(length + 2) : date.day.to_s.rjust(length)
end
begining_of_month.wday.times { array.unshift(BLANK.rjust(length)) }
array.fill(BLANK.rjust(length), array.size..WDAYS.size - 1)
array.fill(BLANK.rjust(length), array.size...WDAYS.size)
end

def header = raise NotImplementedError
def ths = raise NotImplementedError
def length = raise NotImplementedError
def rows = raise NotImplementedError
end

class HorizontalBuilder < Builder
private

def header = @header ||= WDAYS.dup.unshift("#{@year}")
def ths = @ths ||= MONTHS.dup
def length = 2
def rows = [*1..12].map(&method(:days_in))
end

class VerticalBuilder < Builder
private

def header = @header ||= MONTHS.dup.unshift("#{@year}")
def ths = @ths ||= WDAYS.dup
def length = 3
def rows = [*1..12].map(&method(:days_in)).transpose
end

private_constant :Builder, :HorizontalBuilder, :VerticalBuilder
end

0 comments on commit 28e4847

Please sign in to comment.