From: "Roland Swingler" <roland.swingler@gmail.com>
Date: August 28, 2006 3:07:36 PM CDT
To: submission@rubyquiz.com
Subject: Please Forward: Ruby Quiz SubmissionHi,
Here is my solution. I have added start accessor methods so one can
set the day the week starts - a lot of uses for this might want a more
weekend focused week, i.e. Thu-Mon. I had just been reading the first
couple of pages of "Programming Pearls" by Jon Bentley, and that gave
me the idea of using a "bit array" approach to the problem of sorting
the days. One stylistic approach I wanted to play with was using ||
and && in assignment - they might be used slightly too heavilydayrange.rb:
require 'parsedate'
class DayRange
WEEK = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]def initialize(*days)
@start = 0
@days = Array.new(7, nil)
days.each do |day|
i = int_for day
@days[i] = WEEK[i]
end
enddef to_s
# Convert any middle days to "-"
output = [@days[0]] + (1..6).map do |i|
(@days[i] &&
(WEEK.include?(@days[i-1]) || @days[i-1] == "-") &&
WEEK.include?(@days[i+1]) &&
"-") || @days[i]
end
# remove nils, duplicate dashes and any commas surounding them
output.compact.join(", ").gsub(/(, )?-, /, '-').squeeze
enddef start=(day)
i = int_for(day) - @start
if i != 0
@start += i
# shift days from the front or back of the array to the other
end
# so as to get the start day to index 0
index, shift_len = (i > 0) ? [0, i] : [i, -i]
mv_days = @days.slice!(index, shift_len)
@days = (i > 0) ? @days + mv_days : mv_days + @days
end
enddef start
WEEK[@start]
endprivate
def int_for(day)
# Get the day as an integer regardless of input
i = ((day.is_a?(String) && ParseDate.parsedate(day)[7]) || day) - 1
# ParseDate thinks that Sunday is the 0th day of the week
i = 6 if -1 == i
raise ArgumentError unless (0..6).include?(i)
i
end
endAnd my test case - tc_dayrange.rb:
require 'dayrange'
require 'test/unit'class TestDays < Test::Unit::TestCase
def test_all
d = DayRange.new(1,2,3,4,5,6,7)
assert_equal("Mon-Sun", d.to_s)
enddef test_end
d = DayRange.new(1,2,3,4,5,6)
assert_equal("Mon-Sat", d.to_s)
enddef test_start
d = DayRange.new(2,3,4,5,6,7)
assert_equal("Tue-Sun", d.to_s)
enddef test_alternate
d = DayRange.new(1,3,4,6,7)
assert_equal("Mon, Wed, Thu, Sat, Sun", d.to_s)
enddef test_no_wrap
d = DayRange.new(1,2,3,6,7)
assert_equal("Mon-Wed, Sat, Sun", d.to_s)
enddef test_order_unimportant
d = DayRange.new(4,1,5,6,3)
assert_equal("Mon, Wed-Sat", d.to_s)
enddef test_single
d = DayRange.new(7)
assert_equal("Sun", d.to_s)
enddef test_two
d = DayRange.new(7,1)
assert_equal("Mon, Sun", d.to_s)
enddef test_two_names
d = DayRange.new("Monday", "Sun")
assert_equal("Mon, Sun", d.to_s)
enddef test_error_raised
assert_raise(ArgumentError){
d = DayRange.new(1, 8)
}
enddef test_week_start_friday
d = DayRange.new(5,6,7,1)
d.start = "Fri"
assert_equal("Fri-Mon", d.to_s)
enddef test_week_start_can_be_changed
d = DayRange.new(5,6,7,1)
assert_equal "Mon", d.start
d.start = 5
assert_equal("Fri-Mon", d.to_s)
d.start = "Sat"
assert_equal("Sat-Mon, Fri", d.to_s)
d.start = "Monday"
assert_equal("Mon, Fri-Sun", d.to_s)
end
endend
ยทยทยท
Begin forwarded message: