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