Skip to content

Instantly share code, notes, and snippets.

@chrismcg
Created June 10, 2013 10:37
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 chrismcg/5747852 to your computer and use it in GitHub Desktop.
Save chrismcg/5747852 to your computer and use it in GitHub Desktop.
Stockholm to Dublin plane hacking with @paulca
require 'csv'
class Restaurant
attr_accessor :name, :country, :scores
def initialize(name)
@scores = Array.new(11, 0)
@name = name
end
def all_time
scores.inject(&:+)
end
def average
all_time / appearances
end
def weighted_all_time
weighted = []
scores.each_with_index do |score, index|
weighted << score * (index + 1) * (index + 1)
end
weighted.inject(&:+)
end
def appearances
scores.reject(&:zero?).length
end
def to_s(score_method = :all_time)
"#{name}, #{send(score_method)}"
end
end
class RestaurantList
attr_reader :restaurants
attr_accessor :top
def initialize
@restaurants = Hash.new { |h, name| h[name] = Restaurant.new(name) }
@top = 9
load_data
end
def sort_by(&block)
restaurants.sort_by(&block)
end
def sort(&block)
restaurants.sort(&block)
end
def reject(&block)
restaurants.reject(&block)
end
def load_data
Dir['csv/*.csv'].each do |filename|
year = File.basename(filename, '.csv').to_i
CSV.foreach(filename) do |data|
position = data[0].to_i
score = 51 - position
name = data[1].downcase
country = data[3]
restaurants[name].scores[year - 2003] = score
restaurants[name].country = country
end
end
end
end
class CountryList
attr_reader :countries
def initialize(restaurant_list)
countries = Hash.new { |h, country| h[country] = [] }
restaurant_list.restaurants.each do |_, restaurant|
countries[restaurant.country] << restaurant
end
end
end
class TopOfThe
attr_accessor :top
attr_reader :data
def self.score_method(value = nil)
return @score_method if value.nil?
@score_method = value
end
def score_method
self.class.score_method
end
def initialize(data)
@data = data
@top = 9
end
def sorted
data.sort_by { |_, item| -item.send(score_method) }
end
def output
array = []
array << header
sorted[0..top].each_with_index do |(_, item), index|
array << "#{index + 1}: #{item.to_s(score_method)}"
end
array << footer
array.join("\n")
end
def header
title = self.class.name.gsub(/([A-Z])/, ' \1').strip
[title, "-" * title.length].join("\n")
end
def footer
"\n"
end
end
class WeightedAllTime < TopOfThe
score_method :weighted_all_time
end
class AllTime < TopOfThe
score_method :all_time
end
class Average < TopOfThe
score_method :average
end
class Appearances < TopOfThe
score_method :appearances
def sorted
data.sort do |a, b|
left = a[1]
right = b[1]
if left.appearances == right.appearances
right.all_time <=> left.all_time
else
right.appearances <=> left.appearances
end
end
end
end
class BestOfTheRest < TopOfThe
score_method :all_time
def data
super.reject { |_, i| i.scores.any? { |s| s > 40 } }
end
end
restaurant_list = RestaurantList.new
puts WeightedAllTime.new(restaurant_list).output
puts AllTime.new(restaurant_list).output
puts Average.new(restaurant_list).output
puts Appearances.new(restaurant_list).output
puts BestOfTheRest.new(restaurant_list).output
country_list = CountryList.new(restaurant_list)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment