I hope it's not too late for a new submission!
So, when I first read this quiz, it didn't seem like enough of a
challenge. Immediately, I wondered if someone would come up with a
threaded answer, but then everyone started playing golf, and I got a bit
caught up in that...
Well, since no one did go for the threaded solution (and since I needed
to brush up on my threading skills anyway), I give you THE THREADED
FIZZBUZZER!!! (no, not the dreaded...threaded...) ;)
#!/usr/bin/env ruby -w
require 'monitor'
class FizzThreader
attr_reader :counting
def initialize
@counting = 1
@fizz_went = false
@buzz_went = false
@numbers_went = false
@done_counting = false
@output = ''
@output.extend(MonitorMixin)
end
def fizz
Thread.new do
loop do
@output.synchronize do
if !@fizz_went && !@buzz_went && !@numbers_went
@output << 'Fizz' if @counting%3 == 0
@fizz_went = true
end
end
break if @done_counting && @fizz_went
end
end
end
def buzz
Thread.new do
loop do
@output.synchronize do
if @fizz_went && !@buzz_went && !@numbers_went
@output << 'Buzz' if @counting%5 == 0
@buzz_went = true
end
end
break if @done_counting && @buzz_went
end
end
end
def numbers
Thread.new do
loop do
@output.synchronize do
if @fizz_went && @buzz_went && !@numbers_went
@output << @counting.to_s unless (@counting%3 == 0 ||
@counting%5 == 0)
@numbers_went = true
end
end
break if @done_counting && @numbers_went
end
end
end
def count_upto(i)
Thread.new do
loop do
@output.synchronize do
if @fizz_went && @buzz_went && @numbers_went
@output << "\n"
@counting += 1
@done_counting = true if @counting >= i
@fizz_went = false
@buzz_went = false
@numbers_went = false
end
end
break if @done_counting
end
end
end
def start_counting_upto(i)
@counting_threads = []
@counting_threads << fizz
@counting_threads << buzz
@counting_threads << numbers
@counting_threads << count_upto(i)
@counting_threads.each {|thr| thr.join}
@output
end
end
fizzy_threads = FizzThreader.new
puts fizzy_threads.start_counting_upto(100)
--
Posted via http://www.ruby-forum.com/.