Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge in changes from main repo #4

Merged
merged 1 commit into from
May 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion exercises/book-store/book_store.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
def calculate_total(books):
def total(basket):
pass
32 changes: 16 additions & 16 deletions exercises/book-store/book_store_test.py
Original file line number Diff line number Diff line change
@@ -1,58 +1,58 @@
import unittest

from book_store import calculate_total
from book_store import total


# Tests adapted from `problem-specifications//canonical-data.json` @ v1.4.0

class BookStoreTest(unittest.TestCase):
def test_only_a_single_book(self):
self.assertEqual(calculate_total([1]), 800)
self.assertEqual(total([1]), 800)

def test_two_of_the_same_book(self):
self.assertEqual(calculate_total([2, 2]), 1600)
self.assertEqual(total([2, 2]), 1600)

def test_empty_basket(self):
self.assertEqual(calculate_total([]), 0)
self.assertEqual(total([]), 0)

def test_two_different_books(self):
self.assertEqual(calculate_total([1, 2]), 1520)
self.assertEqual(total([1, 2]), 1520)

def test_three_different_books(self):
self.assertEqual(calculate_total([1, 2, 3]), 2160)
self.assertEqual(total([1, 2, 3]), 2160)

def test_four_different_books(self):
self.assertEqual(calculate_total([1, 2, 3, 4]), 2560)
self.assertEqual(total([1, 2, 3, 4]), 2560)

def test_five_different_books(self):
self.assertEqual(calculate_total([1, 2, 3, 4, 5]), 3000)
self.assertEqual(total([1, 2, 3, 4, 5]), 3000)

def test_two_groups_of_4_is_cheaper_than_group_of_5_plus_group_of_3(self):
self.assertEqual(calculate_total([1, 1, 2, 2, 3, 3, 4, 5]), 5120)
self.assertEqual(total([1, 1, 2, 2, 3, 3, 4, 5]), 5120)

def test_two_groups_of_4_is_cheaper_than_groups_of_5_and_3(self):
self.assertEqual(calculate_total([1, 1, 2, 3, 4, 4, 5, 5]), 5120)
self.assertEqual(total([1, 1, 2, 3, 4, 4, 5, 5]), 5120)

def test_group_of_4_plus_group_of_2_is_cheaper_than_2_groups_of_3(self):
self.assertEqual(calculate_total([1, 1, 2, 2, 3, 4]), 4080)
self.assertEqual(total([1, 1, 2, 2, 3, 4]), 4080)

def test_two_each_of_first_4_books_and_1_copy_each_of_rest(self):
self.assertEqual(calculate_total([1, 1, 2, 2, 3, 3, 4, 4, 5]), 5560)
self.assertEqual(total([1, 1, 2, 2, 3, 3, 4, 4, 5]), 5560)

def test_two_copies_of_each_book(self):
self.assertEqual(calculate_total([1, 1, 2, 2, 3, 3, 4, 4, 5, 5]), 6000)
self.assertEqual(total([1, 1, 2, 2, 3, 3, 4, 4, 5, 5]), 6000)

def test_three_copies_of_first_book_and_2_each_of_remaining(self):
self.assertEqual(
calculate_total([1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 1]), 6800)
total([1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 1]), 6800)

def test_three_each_of_first_2_books_and_2_each_of_remaining_books(self):
self.assertEqual(
calculate_total([1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 1, 2]), 7520)
total([1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 1, 2]), 7520)

def test_four_groups_of_4_are_cheaper_than_2_groups_each_of_5_and_3(self):
self.assertEqual(
calculate_total([1, 1, 2, 2, 3, 3, 4, 5, 1, 1, 2, 2, 3, 3, 4, 5]),
total([1, 1, 2, 2, 3, 3, 4, 5, 1, 1, 2, 2, 3, 3, 4, 5]),
10240)


Expand Down
36 changes: 19 additions & 17 deletions exercises/book-store/example.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,46 +4,48 @@
discount = [1.0, 1.0, 0.95, 0.9, 0.8, 0.75]


def groupCost(g):
return len(g) * discount[len(g)]
def group_cost(group):
return len(group) * discount[len(group)]


class Grouping:
def __init__(self, groups=None):
self.groups = [set()] if groups is None else groups

def total(self):
return sum(map(groupCost, self.groups)) * BASE_COST
return sum(map(group_cost, self.groups)) * BASE_COST

def dup(self):
return Grouping(list(map(set, self.groups)))

def add_to_valid(self, b):
"""Returns all possible groupings from current grouping adding book b
def add_to_valid(self, book):
"""Returns all possible groupings from the
current grouping adding book
"""
other = self.dup()
other.groups.sort(key=lambda g: len(g))
results = []
for i, g in enumerate(other.groups):
if b not in g:
o2 = other.dup()
o2.groups[i].add(b)
results.append(o2)
for index, group in enumerate(other.groups):
if book not in group:
other2 = other.dup()
other2.groups[index].add(book)
results.append(other2)
if not results:
other.groups.append(set([b]))
other.groups.append(set([book]))
return [other]
return results

def __lt__(self, other):
return self.total() < other.total()


def step(rs, b):
return [g for r in rs for g in r.add_to_valid(b)]
def step(basket, book):
return [group for groupings in basket
for group in groupings.add_to_valid(book)]


def calculate_total(books):
if len(books) == 0:
def total(basket):
if len(basket) == 0:
return 0
start = Grouping([{books[0]}])
return round(min(reduce(step, books[1:], [start])).total())
start = Grouping([{basket[0]}])
return round(min(reduce(step, basket[1:], [start])).total())