From: "Simon Kröger" Date: 2006-08-27T22:48:15+09:00 Subject: [SOLUTION][QUIZ] DayRange (#92) This is one of the problems that looks easier than it is (at least to me). My solution handles input in form of day abbreviations, full day names and integers as described in the quiz. It raises an ArgumentError for all other inputs. Further more my solution wraps around: puts DayRange.new('Monday', 'Sun', 5, 2, 6) results in "Fri-Tue" instead of "Mon, Tue, Fri-Sun" (this can be easily switched of by deleting the last two lines of the initialize method). I also included Enumerable and provided an each method, but i'm not sure if this is really helpful because each iterates over each day not each range (would that be more helpful?). Well, here it is: -------------------------------------------------------------- require 'date' class DayRange include Enumerable def initialize *days @days = [] days.map do |d| day = Date::DAYNAMES.index(d) || Date::ABBR_DAYNAMES.index(d) raise ArgumentError, d.to_s unless day || (1..7).include?(d.to_i) day ? day.nonzero? || 7 : d.to_i end.uniq.sort.each do |d| next @days << [d] if @days.empty? || d != @days.last.last + 1 @days.last << d end p @days return unless @days.first.first == 1 && @days.last.last == 7 @days.last.concat(@days.shift) if @days.size > 1 end def each @days.flatten.each{|d| yield d} end def to_s @days.map do |r| first = Date::ABBR_DAYNAMES[r.first % 7] last = Date::ABBR_DAYNAMES[r.last % 7] next "#{first}, #{last}" if r.size == 2 r.size > 2 ? "#{first}-#{last}" : first end * ', ' end end puts DayRange.new(1, 2, 3, 4, 5, 6, 7) #=> Mon-Sun puts DayRange.new('Monday', 'Sun', 5, 2, 6) #=> Fri-Tue puts DayRange.new(2, 6, 'Friday', 'Sun') #=> Tue, Fri-Sun dr = DayRange.new(2, 6, 'Friday', 'Sun') puts dr.map{|d| Date::DAYNAMES[d % 7]} * ', ' #=> Tuesday, Friday, Saturday, Sunday ----------------------------------------------------------------- cheers Simon