Created
November 15, 2017 21:15
-
-
Save omarqureshi/450c7479e5af9fbcc12f1138371a82d3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "minitest/autorun" | |
class Potter | |
attr_accessor :items | |
PRICE_PER_BOOK = 8 | |
def initialize(items) | |
@items = items.sort | |
@current_value = items.first | |
end | |
def self.copy_discounts | |
{ | |
1 => 1, | |
2 => 0.95, | |
3 => 0.9, | |
4 => 0.8, | |
5 => 0.75 | |
} | |
end | |
def self.price_for_set(set) | |
raise 'MUST BE UNIQUE' unless set == set.uniq | |
# set must be a list of unique numbers | |
copy_discounts[set.size] * set.size * PRICE_PER_BOOK | |
end | |
def self.calculate_prices(sets) | |
sets.map { |set| price_for_set(set) }.inject(:+) || 0 | |
end | |
def self.rebalance_sets(sets) | |
intersection = sets.inject(:&) | |
others = sets.map { |set| set - intersection}.flatten.sort | |
size_of_sets = sets.size | |
sets = [] | |
size_of_sets.times do | |
arr = intersection.clone | |
sets << arr | |
end | |
others.each_with_index do |o, i| | |
sets[i % size_of_sets] << o | |
end | |
sets | |
end | |
def show_price | |
sets = [] | |
last_value = nil | |
set = [] | |
sets_index = 0 | |
items.each do |i| | |
if i == last_value | |
sets_index += 1 | |
else | |
sets_index = 0 | |
end | |
sets[sets_index] ||= [] | |
sets[sets_index] << i | |
last_value = i | |
end | |
before_rb = Potter.calculate_prices(sets) | |
sets = Potter.rebalance_sets(sets) | |
after_rb = Potter.calculate_prices(sets) | |
before_rb > after_rb ? after_rb : before_rb | |
end | |
end | |
class TestPotter < Minitest::Test | |
def test_truth | |
assert true | |
end | |
def test_basics | |
assert_equal(0, price([])) | |
assert_equal(8, price([0])) | |
assert_equal(8, price([1])) | |
assert_equal(8, price([2])) | |
assert_equal(8, price([3])) | |
assert_equal(8, price([4])) | |
assert_equal(8 * 2, price([0, 0])) | |
assert_equal(8 * 3, price([1, 1, 1])) | |
end | |
def test_simplediscounts | |
assert_equal(8 * 2 * 0.95, price([0, 1])) | |
assert_equal(8 * 3 * 0.9, price([0, 2, 4])) | |
assert_equal(8 * 4 * 0.8, price([0, 1, 2, 4])) | |
assert_equal(8 * 5 * 0.75, price([0, 1, 2, 3, 4])) | |
end | |
def test_several_discounts | |
assert_equal(8 + (8 * 2 * 0.95), price([0, 0, 1])) | |
assert_equal(2 * (8 * 2 * 0.95), price([0, 0, 1, 1])) | |
assert_equal((8 * 4 * 0.8) + (8 * 2 * 0.95), price([0, 0, 1, 2, 2, 3])) | |
assert_equal(8 + (8 * 5 * 0.75), price([0, 1, 1, 2, 3, 4])) | |
end | |
def test_edge_cases | |
assert_equal(2 * (8 * 4 * 0.8), price([0, 0, 1, 1, 2, 2, 3, 4])) | |
assert_equal(3 * (8 * 5 * 0.75) + 2 * (8 * 4 * 0.8), | |
price([0, 0, 0, 0, 0, | |
1, 1, 1, 1, 1, | |
2, 2, 2, 2, | |
3, 3, 3, 3, 3, | |
4, 4, 4, 4])) | |
end | |
def price(arr) | |
Potter.new(arr).show_price | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment