--------------080605000108030807000709 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit So, according to my calculations, 48+ hours have elapsed. Thus, here's my solution to Regexp.build(). I assumed the following: 1) leading zeros are accepted (ie, "0004" Regexp.build(4) matches) 2) nothing is captured (besides the match itself) 3) "2004" !~ Regexp.build(4) - Jamis Ruby Quiz wrote: > The three rules of Ruby Quiz: > > 1. Please do not post any solutions or spoiler discussion for this quiz until > 48 hours have passed from the time on this message. > > 2. Support Ruby Quiz by submitting ideas as often as you can: > > http://www.grayproductions.net/ruby_quiz/ > > 3. Enjoy! > > - - - - - - - - - - - - - - - - - - - - > > There's been some discussion on Ruby Talk lately about Range.member? which tests > if a given element (often a number) is a member of the set the Range object > iterates over. Obviously, this kind of test is useful in many aspects of > programming, but let's approach this problem from a different angle. > > This week's quiz is to build a library that adds a class method called build() > to Regexp. build() should accept a variable number of arguments which can > include integers and ranges of integers. Have build() return a Regexp object > that will match only integers in the set of passed arguments. > > Here are some examples of possible usage: > > lucky egexp.build( 3, 7 ) > "7" lucky # true > "13" lucky # false > "3" lucky # true > > month egexp.build( 1..12 ) > "0" month # false > "1" month # true > "12" month # true > day egexp.build( 1..31 ) > "6" day # true > "16" day # true > "Tues" day # false > year egexp.build( 98, 99, 2000..2005 ) > "04" year # false > "2004" year # true > "99" year # true > > num egexp.build( 0..1_000_000 ) > "-1" num # false > > Some issues you may want to consider while building you're library: > > * How should leading zeros be handled? > > Match the hour from a clock formatted in military time (0 to 23). Hours 0 > through 9 may or may not have a single leading zero. > > * Should anything be captured by the returned Regexp? > > * How should anchoring work? > > "2004" Regexp.build( 4 ) # ??? > > . > -- Jamis Buck jgb3 / email.byu.edu http://www.jamisbuck.org/jamis --------------080605000108030807000709 Content-Type: text/plain; name egexp.rb" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename egexp.rb" class Regexp class NumericRegexpBuilder def initialize @patterns ] end def add_pattern( pattern ) @patterns << pattern end alias :<< :add_pattern def to_regexp Regexp.new( "(?:^|[^-])\\b0*(?:" + @patterns.map{|p| "(?:#{p})"}.join( "|" ) + ")\\b" ) end end def self.build( *parms ) raise ArgumentError, "expected at least one parameter" if parms.empty? builder umericRegexpBuilder.new parms.each do |parm| case parm when Numeric builder << parm when Range parm.each { |i| builder << i } else raise ArgumentError, "unsupported parm type #{parm.class} (#{parm.inspect})" end end return builder.to_regexp end end if $0 __FILE__ require 'test/unit' class TC_Regexp < Test::Unit::TestCase def test_build_none assert_raise( ArgumentError ) do Regexp.build end end def test_build_one_integer re egexp.build( 5 ) assert_match re, "5" assert_match re, "!5!" assert_match re, "!00005," assert_no_match re, "15" assert_no_match re, "52" end def test_build_multiple_integers re egexp.build( 5, 7, 15 ) assert_match re, "5" assert_match re, "!5!" assert_match re, "!00005," assert_match re, "015" assert_match re, "007" assert_no_match re, "52" assert_no_match re, "57" assert_no_match re, "070" end def test_build_one_range re egexp.build( 0..100 ) assert_match re, "000" assert_match re, "052" assert_match re, "15,32" assert_match re, "100" assert_no_match re, "777" assert_no_match re, "101" end def test_build_multiple_ranges re egexp.build( 0..10, 20...35, 71..77 ) assert_match re, "000" assert_match re, "34" assert_match re, "000072" assert_no_match re, "11" assert_no_match re, "35" end def test_mix_and_match re egexp.build( 0, 5, 10..15, 17, 21, 31...35, 70...100 ) assert_match re, "0" assert_match re, "005" assert_match re, "012" assert_no_match re, "22" assert_no_match re, "35" assert_no_match re, "100" end def test_negative re egexp.build( 0..5 ) assert_no_match re, "-1" re egexp.build( -5..5 ) assert_no_match re, "-1" end end end --------------080605000108030807000709--