Skip to content

Instantly share code, notes, and snippets.

@adammck
Created March 17, 2009 15:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adammck/80588 to your computer and use it in GitHub Desktop.
Save adammck/80588 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
# vim: noet
capitals = {
"England" => "london",
"France" => "paris",
"Germany" => "berlin",
"Spain" => "madrid",
"Italy" => "rome",
}
def normalize(items)
# calculate the total of all weights
total = (items.inject(0) do |total, item|
total += item[1]
end).to_f
# create a new array with the
# weights replaced with ratios
items.collect do |str, weight|
[str, (weight/total)]
end
end
# Returns a random string from an
# array of [string, weight] pairs
def pick(items)
choice = rand
normalize(items).each do |str, weight|
return str if choice <= weight
choice -= weight
end
end
# build a separate array to keep track of weights for each country,
# so we can prioritize questions that the user often gets wrong
weights = capitals.keys.collect do |country|
[country, 1]
end
# keep playing until this script
# is terminated (with ctrl+c)
while true
choice = pick(weights)
# ask a question, get an answer
print "What is the capital of #{choice.upcase}? "
if gets.strip.downcase == capitals[choice].downcase
puts "Correct!"
# correct answer; increase the weight of all others,
# causing this country to appear less frequently
weights.each_index do |n|
weights[n][1] += 1 unless\
weights[n][0] == choice
end
else
puts "The answer is: #{capitals[choice].upcase}"
# wrong answer, so increase the weight of
# this country, so it appears more often
weights.each_index do |n|
weights[n][1] += 1 if\
weights[n][0] == choice
end
end
puts "Weights are now: #{weights.inspect}"
puts # blank line
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment