Skip to content

Instantly share code, notes, and snippets.

@rafaelss
Created September 5, 2011 00:05
Show Gist options
  • Save rafaelss/1193748 to your computer and use it in GitHub Desktop.
Save rafaelss/1193748 to your computer and use it in GitHub Desktop.
Countdown Quiz

Countdown - Numbers Round

To run the code you must follow the commands below:

gem install riot # or sudo gem intall riot
git clone git://gist.github.com/1193748.git
cd 1193748
ruby -I. countdown_test.rb

I choose use riot as test framework. I'm using it in some small projects and I'm liking it a lot.

About the code, I tried to build it using the simplest way instead of make it too complex and hard to understand. I think it's not finding all possible results for all input sources. An example of this is the last test, as I commented there, the closest result was not what the test is checking. Also, I put a timeout of 30 seconds, like the original game. I don't know if I should do this, but I tried to keep in the same format as it's showed on TV :)

class Countdown
include Timeout
def self.start(source, target)
cached_results = []
source.sort_by! { |n| -n }
source.each do |n|
source.each do |i|
cached_results << n + i
cached_results << n * i
cached_results << n / i
cached_results << i / n
cached_results << n - i
cached_results << i - n
end
end
closest_result = 0
operators = [ :+, :-, :*, :/ ]
timeout(30) do
loop do
result = 0
source.each do |value|
next if value == 0
operator = operators.shuffle.first
next if value == 1 && (operator == :* || operator == :/)
result = if result == 0
cached_results.shuffle.first.send(operator, value)
else
result.send(operator, value)
end
end
closest_result = result if (target - result).abs < (target - closest_result).abs
return result if result == target
end
end
rescue Timeout::Error
closest_result
end
end
require "rubygems"
require "timeout"
require "riot"
require "active_support/core_ext/enumerable"
require "countdown"
context "Countdown" do
context "round #1" do
setup { Countdown.start([ 100, 5, 5, 2, 6, 8 ], 522) }
asserts_topic.equals(522)
end
context "round #2" do
setup { Countdown.start([ 25, 7, 5, 6, 6, 9 ], 814) }
asserts_topic.equals(814)
end
context "round #3" do
setup { Countdown.start([ 7, 8, 2, 5, 8, 4 ], 622) }
asserts_topic.equals(622)
end
context "round #4" do
setup { Countdown.start([ 75, 100, 5, 2, 9, 4 ], 612) }
asserts_topic.equals(612)
end
context "round #4" do
setup { Countdown.start([ 100, 75, 50, 25, 2, 10 ], 976) }
asserts_topic.equals(976)
end
context "round #5" do
setup { Countdown.start([ 7, 7, 1, 2, 9, 1 ], 220) }
asserts_topic.equals(220)
end
context "round #6" do
setup { Countdown.start([ 3, 5, 5, 4, 1, 7 ], 878) }
asserts_topic.equals(878)
end
context "round #7" do
setup { Countdown.start([ 4, 8, 50, 1, 4, 8 ], 596) }
asserts_topic.equals(596)
end
context "round #8" do
setup { Countdown.start([ 75, 2, 8, 5, 10, 10 ], 926) }
asserts_topic.equals(926)
end
context "round #9" do
setup { Countdown.start([ 3, 51, 17, 29, 7, 71 ], 93475) }
asserts_topic.equals(93429) # the closest result is 93478, but I can't figure out how get this result
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment