R
Ruby Quiz
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 .
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 .