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."
>
>
>