Skip to content

Instantly share code, notes, and snippets.

@omarqureshi
Created November 15, 2017 21:15
Show Gist options
  • Save omarqureshi/450c7479e5af9fbcc12f1138371a82d3 to your computer and use it in GitHub Desktop.
Save omarqureshi/450c7479e5af9fbcc12f1138371a82d3 to your computer and use it in GitHub Desktop.
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