|
|
|
#1 |
|
Messages: n/a
Hébergeur: |
Here's my solution. It converts a time window into an array of arrays of ra=
nges. Each range matches an interval of time (e.g.: 500..1700); each subarr= ay contains all the ranges for a given day. I then wrote the simple Array#s= ome method that returns true if the given predicate returns true for at lea= st one of its elements, which I used to write TimeWindow#incude?.=0A=0A$day= s =3D {"Sun"=3D>0,=0A "Mon"=3D>1,=0A "Tue"=3D>2,= =0A "Wed"=3D>3,=0A "Thu"=3D>4,=0A "F= ri"=3D>5,=0A "Sat"=3D>6}=0A=0Aclass Array=0A def some=0A e= ach {|el| return true if yield el}=0A false=0A end=0Aend=0A=0Aclass Tim= eWindow=0A def initialize(win_str)=0A @times =3D ([nil]*7).map{[]}=0A = win_str << " " #In case of empty=0A win_str.split(/;/).each do |win|= =0A days_str =3D win.match(/(((#{$days.keys.join('|')}|)( |-)?)*)/)[0]= ..strip=0A days =3D []=0A days_str.scan(/#{$days.keys.join('|')}/)= do |day|=0A days << $days[day]=0A end=0A days_str.scan(/(= #{$days.keys.join('|')})-(#{$days.keys.join('|')})/) do=0A a =3D $da= ys[$1]=0A b =3D $days[$2]=0A days +=3D (a..(b > a ? b : b+7))= ..to_a.map{|d|d%7}=0A end=0A days =3D (0..6).to_a if days.empty?= =0A =0A times =3D []=0A win.scan(/(\d{4})-(\d{4})/) do=0A = times << (($1.to_i)...($2.to_i))=0A end=0A times =3D [0..240= 0] if times.empty?=0A =0A days.each do |d|=0A times.each d= o |t|=0A @times[d] << t=0A end=0A end=0A end=0A = =0A def include?(time)=0A @times[time.wday].some{|trange| trange = =3D=3D=3D (time.hour*100+time.min)}=0A end=0A end=0Aend=0A=0A----- Orig= inal Message ----=0AFrom: Ruby Quiz <james@grayproductions.net>=0ATo: ruby-= talk ML <ruby-talk@ruby-lang.org>=0ASent: Friday, October 19, 2007 7:14:00 = AM=0ASubject: [QUIZ] Time Window (#144)=0A=0A=0AThe three rules of Ruby Qui= z:=0A=0A1. Please do not post any solutions or spoiler discussion for this= =0A quiz until=0A48 hours have passed from the time on this message.=0A=0A2= .. Support Ruby Quiz by submitting ideas as often as you can:=0A=0Ahttp://w= ww.rubyquiz.com/=0A=0A3. Enjoy!=0A=0ASuggestion: A [QUIZ] in the subject = of emails about the problem s=0A everyone=0Aon Ruby Talk follow the dis= cussion. Please reply to the original quiz=0A message,=0Aif you can.=0A=0A= -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-= =3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D= -=3D-=3D-=3D=0A=0Aby Brian Candler=0A=0AWrite a Ruby class which can tell y= ou whether the current time (or any=0A given=0Atime) is within a particular= "time window". Time windows are defined by=0A strings=0Ain the following f= ormat:=0A=0A # 0700-0900 # every day between thes= e times=0A # Sat Sun # all day Sat and Sun, no = other=0A times=0A # Sat Sun 0700-0900 # 0700-0900 on Sat = and Sun only=0A # Mon-Fri 0700-0900 # 0700-0900 on Monday= to Friday=0A only=0A # Mon-Fri 0700-0900; Sat Sun # ditto plus al= l day Sat and Sun=0A # Fri-Mon 0700-0900 # 0700-0900 on F= ri Sat Sun Mon=0A # Sat 0700-0800; Sun 0800-0900 # 0700-0800 on Sat,= plus=0A 0800-0900 on Sun=0A=0ATime ranges should exclude the upper bound, = i.e. 0700-0900 is 07:00:00=0A to=0A08:59:59. An empty time window means "al= l times everyday". Here are=0A some test=0Acases to make it clearer:=0A=0A = class TestTimeWindow < Test::Unit::TestCase=0A def test_window_1=0A= w =3D TimeWindow.new("Sat-Sun; Mon Wed 0700-0900; Thu 0700-0900=0A = 1000-1200")=0A =0A assert ! w.include?(Time.mktime(2007,9,25,= 8,0,0)) # Tue=0A assert w.include?(Time.mktime(2007,9,26,8,0,0))= # Wed=0A assert ! w.include?(Time.mktime(2007,9,26,11,0,0))=0A = assert ! w.include?(Time.mktime(2007,9,27,6,59,59)) # Thu=0A as= sert w.include?(Time.mktime(2007,9,27,7,0,0))=0A assert w.includ= e?(Time.mktime(2007,9,27,8,59,59))=0A assert ! w.include?(Time.mktim= e(2007,9,27,9,0,0))=0A assert w.include?(Time.mktime(2007,9,27,11,= 0,0))=0A assert w.include?(Time.mktime(2007,9,29,11,0,0)) # Sat= =0A assert w.include?(Time.mktime(2007,9,29,0,0,0))=0A asse= rt w.include?(Time.mktime(2007,9,29,23,59,59))=0A end=0A =0A = def test_window_2=0A w =3D TimeWindow.new("Fri-Mon")=0A as= sert ! w.include?(Time.mktime(2007,9,27)) # Thu=0A assert w.includ= e?(Time.mktime(2007,9,28))=0A assert w.include?(Time.mktime(2007,9= ,29))=0A assert w.include?(Time.mktime(2007,9,30))=0A asser= t w.include?(Time.mktime(2007,10,1))=0A assert ! w.include?(Time.m= ktime(2007,10,2)) # Tue=0A end=0A =0A def test_window_nil=0A= w =3D RDS::TimeWindow.new("")=0A assert w.include?(Time.mkti= me(2007,9,25,1,2,3)) # all times=0A end=0A end=0A=0A=0A=0A=0A= =0A_______________________________________________ ___=0ADo You Yahoo!?=0ATi= red of spam? Yahoo! Mail has the best spam protection around =0Ahttp://mai= l.yahoo.com |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
On 10/24/07, James Koppel <jamesbkoppel@yahoo.com> wrote:
> I then wrote the simple Array#some method that returns true if the given > predicate returns true for at least one of its elements, which I used to write > TimeWindow#incude?. > class Array > def some > each {|el| return true if yield el} > false > end > end Isn't this the same as Enumerable#any? Jesus. |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
That's the same thought that I had. Assuming that any? didn't exist, =20=
I am still fearful of adding methods to core classes. I think core =20 classes should only be modified in special cases, like building a =20 framework. How do the rest of us feel about this? - Philip On Oct 24, 2007, at 12:16 AM, Jes=FAs Gabriel y Gal=E1n wrote: > On 10/24/07, James Koppel <jamesbkoppel@yahoo.com> wrote: >> I then wrote the simple Array#some method that returns true if =20 >> the given >> predicate returns true for at least one of its elements, which I =20 >> used to write >> TimeWindow#incude?. > >> class Array >> def some >> each {|el| return true if yield el} >> false >> end >> end > > Isn't this the same as Enumerable#any? > > Jesus. > |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
On 10/24/07, Philip Gatt <gattster@gmail.com> wrote:
> That's the same thought that I had. Assuming that any? didn't exist, > I am still fearful of adding methods to core classes. I think core > classes should only be modified in special cases, like building a > framework. > > How do the rest of us feel about this? Well, first of all it depends if you are building a library that someone will use, or just a program that will run independently. If it's the former, even then I would think that just adding methods is OK, as long as the method makes sense. What should be done with really great care (or not at all) is modifying existing methods. But I'm fairly new to Ruby so take my opinion with a grain of salt. Jesus. |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
On Oct 24, 2007, at 2:16 AM, Jes=FAs Gabriel y Gal=E1n wrote:
> On 10/24/07, James Koppel <jamesbkoppel@yahoo.com> wrote: >> I then wrote the simple Array#some method that returns true if =20 >> the given >> predicate returns true for at least one of its elements, which I =20 >> used to write >> TimeWindow#incude?. > >> class Array >> def some >> each {|el| return true if yield el} >> false >> end >> end > > Isn't this the same as Enumerable#any? It sure is. James Edward Gray II= |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
On Oct 24, 2007, at 3:04 AM, Philip Gatt wrote:
> That's the same thought that I had. Assuming that any? didn't > exist, I am still fearful of adding methods to core classes. I > think core classes should only be modified in special cases, like > building a framework. > > How do the rest of us feel about this? Like most things, it's just another tool in your belt. You'll need to consider when to use it and when not to. On the plus side, slowly transforming Ruby into the language of a problem is a powerful way to work. The minus is that you can make it hard to use your code with other Ruby solutions in the process. You will need to decide when that's a good trade-off and when it's not. Ruby trusts you to make the choice. James Edward Gray II |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
On Wed, 24 Oct 2007 10:04:56 +0900, James Koppel wrote:
> Here's my solution. It converts a time window into an array of arrays of > ranges. Each range matches an interval of time (e.g.: 500..1700); each > subarray contains all the ranges for a given day. I then wrote the > simple Array#some method that returns true if the given predicate > returns true for at least one of its elements, which I used to write > TimeWindow#incude?. > > $days = {"Sun"=>0, > "Mon"=>1, > "Tue"=>2, > "Wed"=>3, > "Thu"=>4, > "Fri"=>5, > "Sat"=>6} I suggest using a constant rather than a global variable for this. You can put the constant in the TimeWindow class. > class Array > def some > each {|el| return true if yield el} > false > end > end This has already been discussed as being equal to Enumerable#any? > class TimeWindow > def initialize(win_str) > @times = ([nil]*7).map{[]} This is the same as Array.new(7){[]}, which is a more usual way to express this. > win_str << " " #In case of empty > win_str.split(/;/).each do |win| > days_str = win.match(/(((#{$days.keys.join('|')}|)( > |-)?)*)/)[0].strip days = [] > days_str.scan(/#{$days.keys.join('|')}/) do |day| > days << $days[day] > end > days_str.scan(/(#{$days.keys.join('|')})-(#{$days.keys.join ('|')})/) > do > a = $days[$1] > b = $days[$2] > days += (a..(b > a ? b : b+7)).to_a.map{|d|d%7} > end > days = (0..6).to_a if days.empty? > > times = [] > win.scan(/(\d{4})-(\d{4})/) do > times << (($1.to_i)...($2.to_i)) > end > times = [0..2400] if times.empty? > > days.each do |d| > times.each do |t| > @times[d] << t > end > end > end > > def include?(time) > @times[time.wday].some{|trange| trange === > (time.hour*100+time.min)} > end > end > end Looks generally like my solution. --Ken -- Ken Bloom. PhD candidate. Linguistic Cognition Laboratory. Department of Computer Science. Illinois Institute of Technology. http://www.iit.edu/~kbloom1/ |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
On Oct 24, 2007, at 9:10 AM, Ken Bloom wrote:
> On Wed, 24 Oct 2007 10:04:56 +0900, James Koppel wrote: > >> Here's my solution. It converts a time window into an array of >> arrays of >> ranges. Each range matches an interval of time (e.g.: 500..1700); >> each >> subarray contains all the ranges for a given day. I then wrote the >> simple Array#some method that returns true if the given predicate >> returns true for at least one of its elements, which I used to write >> TimeWindow#incude?. >> >> $days = {"Sun"=>0, >> "Mon"=>1, >> "Tue"=>2, >> "Wed"=>3, >> "Thu"=>4, >> "Fri"=>5, >> "Sat"=>6} > > I suggest using a constant rather than a global variable for this. You > can put the constant in the TimeWindow class. This is also just an Array disguised as a Hash. James Edward Gray II |
|
|
|
#9 |
|
Messages: n/a
Hébergeur: |
On Oct 24, 9:16 am, James Edward Gray II <ja...@grayproductions.net> wrote: > On Oct 24, 2007, at 9:10 AM, Ken Bloom wrote: > > > > > On Wed, 24 Oct 2007 10:04:56 +0900, James Koppel wrote: > > >> Here's my solution. It converts atimewindowinto an array of > >> arrays of > >> ranges. Each range matches an interval oftime(e.g.: 500..1700); > >> each > >> subarray contains all the ranges for a given day. I then wrote the > >> simple Array#some method that returns true if the given predicate > >> returns true for at least one of its elements, which I used to write > >> TimeWindow#incude?. > > >> $days = {"Sun"=>0, > >> "Mon"=>1, > >> "Tue"=>2, > >> "Wed"=>3, > >> "Thu"=>4, > >> "Fri"=>5, > >> "Sat"=>6} > > > I suggest using a constant rather than a global variable for this. You > > can put the constant in the TimeWindow class. > > This is also just an Array disguised as a Hash. > > James Edward Gray II It could be a lot worse. Which of us hasn't run across something like this? days = { 0 => 'Sun', 1 => 'Mon', 2 => 'Tue', 3 => 'Wed', 4 => 'Thu', 5 => 'Fri', 6 => 'Sat', } -- -yossef |
|
![]() |
| Outils de la discussion | |
|
|