Skip to content

Instantly share code, notes, and snippets.

@Systho
Created June 12, 2015 07:10
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 Systho/b9987f44041b934b1ef5 to your computer and use it in GitHub Desktop.
Save Systho/b9987f44041b934b1ef5 to your computer and use it in GitHub Desktop.
Podium class to handle ranking, might be useful in the future
class Podium
def initialize(results)
@results = results
end
def rank_for(key)
score = results[key]
return 0 if score.nil?
index = reverse_results_hash.keys.index(score)
(0...index).to_a.sum{|prev_index| ranked_at(prev_index ).size } + 1
end
def ranked(rank)
return [] unless (1..max_rank).cover?(rank)
reverse_results_array.each do |_, keys|
return keys if keys.length >= rank
rank -= keys.length
end
[]
end
def max_rank
results.size
end
private
attr_reader :results
def ranked_at(index)
reverse_results_array[index].last
end
def reverse_results_hash
@reverse_results_hash ||= results.keys.group_by{|k| results[k] }.sort.reverse!.to_h
end
def reverse_results_array
@reverse_results_array ||= reverse_results_hash.to_a
end
end
require 'podium'
RSpec.describe Podium do
let(:results){ Hash.new }
subject { Podium.new(results)}
describe "#rank_for(key)" do
it "returns the position if all the keys have different scores" do
results[:blue]= 10
results[:red]= 5
results[:green]= 1
expect(subject.rank_for(:blue)).to eq 1
expect(subject.rank_for(:red)).to eq 2
expect(subject.rank_for(:green)).to eq 3
end
it "handles keys having the same score by allowing them to all have the lowest possible rank" do
results[:blue]= 10
results[:red]= 5
results[:white]= 5
results[:green]= 1
expect(subject.rank_for(:blue)).to eq 1
expect(subject.rank_for(:red)).to eq 2
expect(subject.rank_for(:white)).to eq 2
expect(subject.rank_for(:green)).to eq 4
end
it "returns 0 if the key is not part of the results" do
expect(subject.rank_for(:unknown)).to eq 0
end
end
describe "#ranked(rank)" do
it "returns the keys at the position if all the keys have different scores" do
results[:blue]= 10
results[:red]= 5
results[:green]= 1
expect(subject.ranked(1)).to eq [:blue]
expect(subject.ranked(2)).to eq [:red]
expect(subject.ranked(3)).to eq [:green]
end
it "handles keys having the same score by allowing them to be retrieved by any of the possible rank" do
results[:blue]= 10
results[:red]= 5
results[:white]= 5
results[:green]= 1
expect(subject.ranked(1)).to eq [:blue]
expect(subject.ranked(2)).to eq [:red, :white]
expect(subject.ranked(3)).to eq [:red, :white]
expect(subject.ranked(4)).to eq [:green]
end
it "returns an empty array if the rank is higher than the number of results" do
expect(subject.ranked(1)).to eq []
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment