Hi all, I'm new to Ruby and this is the first quiz I'm doing. Not sure if I'm missing something, but this seems pretty easy to me. Here's what I have: class FuzzyTime # if 24 then show in 24 hour format, else 12 hour format attr_accessor :mode def initialize(startAt = Time.now, variance = 5*60) @time = Time.at(startAt) @offset = Time.now - @time @variance = variance @mintime = Time.at(@time.to_i - @variance).to_i @mode = 24 end def to_s t = @time.to_i - @variance + rand(@variance * 2) @mintime = @mintime > t ? @mintime : t now = Time.at(@mintime) sprintf('%02d:%d~ %s', @mode == 24 ? now.hour : now.hour % 12, now.min / 10, @mode != 24 ? now.hour / 12 == 1 ? 'pm' : 'am' : '' ) end def update @time = Time.now + @offset end def actual @time end # def advance(amt) def +(amt) @time = @time + amt self end def -(amt) @time = @time + (-amt) # reset the minimum displayed time @mintime = Time.at(@time.to_i - @variance).to_i self end end if __FILE__ == $0 then t = FuzzyTime.new t.mode = 24 30.times { t += 60 puts "#{t.to_s} (#{t.actual.strftime('%H:%M')})" } end Any comments are welcome. Cheers, Thomas 2006/10/30, Caleb Powell <caleb.powell / gmail.com>: > Hi, > > attached is my FuzzyTime.rb solution and a corresponding Unit Test > file. Thanks for the quiz, I look forward to any feedback. I didn't > have time to do the extra credit tasks :-( > > On 10/27/06, Ruby Quiz <james / grayproductions.net> 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.rubyquiz.com/ > > > > 3. Enjoy! > > > > Suggestion: A [QUIZ] in the subject of emails about the problem helps everyone > > on Ruby Talk follow the discussion. Please reply to the original quiz message, > > if you can. > > > > -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= > > > > by Gavin Kistner > > > > The Background > > --------------------------------------------------------------------- > > > > Last night I was having trouble falling asleep, and was staring at my digital > > alarm clock (as I do so often under that circumstance). Something on the bedside > > table was occluding the minutes digit, however, so all I could tell is that it > > was "10 4". (Oddly, my alarm clock has no ":" between the hours and minutes.) > > > > "How nice!" I thought. "An imposed vagueness to keep me from obsessing on > > exactly what time it is! Should I really be worried about the exact time? > > Shouldn't I be more relaxed? Shouldn't a 10-minute precision in life be enough > > to keep me roughly on time, without obsessing on exacting promptitude?" > > > > I realized that if I kept staring at the clock (as I did), and I were to observe > > it changing from "10 4" to "10 5", that I would, at that moment, know exactly > > what time it is. > > > > "Bah" I thought, "so much for that idea." > > > > And then I thought some more. I thought of bad ideas: analog watches where the > > hand erratically swings forward and backward, digital clocks that showed random > > times near the correct time. And then I dreamed of the watch I wanted to own... > > > > The Challenge > > --------------------------------------------------------------------- > > > > Requirement #1: Write a Ruby program that shows the current time, but only the > > 'tens' part of the minutes. For example, if the time is 10:37, then the program > > might output "10:3~" > > > > Requirement #2: The time shown by the clock must randomly vary +/- 5 minutes > > from reality. For example, if the time is actually 10:37, the program might > > output "10:3~" or "10:4~" (but not "10:2~" or "10:5~"). > > > > Requirement #3: The time on the clock should continuously increase. If the time > > shows "10:4~" it must continue to show "10:4~" until it shows "10:5~". (It can't > > show "10:4~", then "10:3~" for a bit and then come back to "10:4~".) > > > > Putting the three requirements together, the left column below shows the actual > > time and the next three columns show the possible outputs from three different > > runs of the same program: > > > > 10:35 10:3~ 10:4~ 10:3~ > > 10:36 10:3~ 10:4~ 10:3~ > > 10:37 10:3~ 10:4~ 10:3~ > > 10:38 10:3~ 10:4~ 10:3~ > > 10:39 10:4~ 10:4~ 10:3~ > > 10:40 10:4~ 10:4~ 10:3~ > > 10:41 10:4~ 10:4~ 10:3~ > > 10:42 10:4~ 10:4~ 10:3~ > > 10:43 10:4~ 10:4~ 10:3~ > > 10:44 10:4~ 10:4~ 10:3~ > > 10:45 10:4~ 10:4~ 10:4~ > > 10:46 10:4~ 10:4~ 10:5~ > > 10:47 10:4~ 10:4~ 10:5~ > > 10:48 10:4~ 10:4~ 10:5~ > > 10:49 10:4~ 10:4~ 10:5~ > > 10:50 10:4~ 10:4~ 10:5~ > > 10:51 10:4~ 10:4~ 10:5~ > > 10:52 10:5~ 10:4~ 10:5~ > > 10:53 10:5~ 10:4~ 10:5~ > > 10:54 10:5~ 10:4~ 10:5~ > > 10:55 10:5~ 10:5~ 10:5~ > > 10:56 10:5~ 10:5~ 11:0~ > > 10:57 10:5~ 10:5~ 11:0~ > > 10:58 10:5~ 10:5~ 11:0~ > > 10:59 10:5~ 10:5~ 11:0~ > > 11:00 10:5~ 10:5~ 11:0~ > > 11:01 10:5~ 10:5~ 11:0~ > > > > Testing your Output > > --------------------------------------------------------------------- > > > > You should supply a FuzzyTime class that supports the following: > > > > ft = FuzzyTime.new # Start at the current time > > ft = FuzzyTime.new(Time.at(1161104503)) # Start at a specific time > > > > p ft.to_s # to_s format > > #=> "10:5~" > > > > p ft.actual, ft.actual.class # Reports real time as Time > > #=> Tue Oct 17 11:01:36 -0600 2006 > > #=> Time > > > > ft.advance( 60 * 10 ) # Manually advance time > > puts ft # by a specified number of > > #=> 11:0~ # seconds. > > > > sleep( 60 * 10 ) > > > > ft.update # Automatically update the time based on the > > puts ft # time that has passed since the last call > > #=> 11:1~ # to #initialize, #advance or #update > > > > Your class and output will be tested with code like the following: > > > > def test_output > > # Initialize with a well-known time > > ft = FuzzyTime.new( Time.at( ... ) ) > > > > 60.times do > > @legal = ... # Find the array of legal output strings > > @output = ft.to_s > > > > assert_block "#@output not one of #@legal.inspect" do > > @legal.include?( @output ) > > end > > > > sleep( rand( 30 ) ) > > ft.update > > end > > > > 60.times do > > @legal = ... # Find the array of legal output strings > > @output = ft.to_s > > > > assert_block "#@output not one of #@legal.inspect" do > > @legal.include?( @output ) > > end > > > > ft.advance( rand( 30 ) ) > > end > > end > > > > Extra Credit > > --------------------------------------------------------------------- > > > > * Provide a self-running application that shows the time somehow. > > (ASCII in the terminal, some GUI window, etc.) > > > > * Allow your class to be customized to display 12- or 24-hour time. > > > > * Allow your class to be customized to change how close to reality > > it must display. (+/- 3 minutes, +/- 12 minutes, etc.) > > > > * Allow your class to be customized to change how roughly it displays > > the time (e.g. 1 minute, 10 minute, 1 hour intervals). > > > > * Ensure that the transition from one digit to the next occurs > > randomly across the range of -5 to +5. (So, while the digit might > > change 5 minutes before or 5 minutes after the real transition, on > > average the change should occur around the transition itself.) > > You might need to assume that your update/advance method will be > > called with a certain regularity (e.g. once per second, once every > > 7 seconds, once every 30 seconds, etc.) > > > > * Come up with your own technique of displaying time that > > (a) is always 'close' to right, but (b) never allows a > > watchful person to ever know exactly what time it is. > > > > Things to Keep in Mind > > --------------------------------------------------------------------- > > > > * You need to be able to handle the transition across hour/day > > boundaries. (10:5~ might change to 11:0~ when the real time is still > > 10:58, or might continue to display 10:5~ when the real time is > > 11:04. On a 24-hour click, you also need to be able to wrap from > > 23:5~ to 00:0~) > > > > * For testing purposes of the real-time #update advancing, you might > > find it easier to work with minutes and seconds instead of hours and > > minutes. > > > > * Requirement #3 is, well, a requirement. Repeated #update/#to_s > > calls to a FuzzyTime instance should never show an earlier time > > (unless 24 hours occurred between #update calls ;). > > > > > > > -- > Caleb > > "There is no theory of evolution, just a list of creatures Chuck > Norris allows to live." > > >