这是一个在BJDP上学习Coding Kata的时候用到的一个练习,原来打算用Java写的,但是一想正好是学习的好机会。
就用Python了。第一次,写的有些复杂。
这个题目是关于购买图书的打折信息的。
题目来源:
http://codingdojo.org/cgi-bin/wiki.pl?KataPotter
1 class Strategy: 2 def __init__(self, items): 3 self.items = items; 4 self.rate = self.get_discount_rate(); 5 6 def get_discount_rate(self): 7 if len(self.items) == 5: 8 return 0.75; 9 if len(self.items) == 4: 10 return 0.8; 11 if len(self.items) == 3: 12 return 0.9; 13 if len(self.items) == 2: 14 return 0.95; 15 return 1.0; 16 17 def get_price(self): 18 return self.total_price() * self.rate; 19 20 def total_price(self): 21 price = 0.0; 22 for item in self.items: 23 price += item.book.price; 24 return price; 25 26 def count(self): 27 return len(self.items); 28 29 30 class StrategyOptimizer: 31 def optimize(self, strategies): 32 found = False; 33 while True: 34 found = self.replace_53_with_44(strategies); 35 if not found: 36 break; 37 return strategies; 38 39 def replace_53_with_44(self, strategies): 40 strategyMap = {}; 41 strategyMap.clear(); 42 for i in range(0, len(strategies)): 43 strategy = strategies[i]; 44 strategyMap[strategy.count()] = i; 45 46 if (strategyMap != None and len(strategyMap) != 0): 47 if (strategyMap.get(5, None) != None and strategyMap.get(3, None) != None): 48 self.move_book(strategies[strategyMap[5]], strategies[strategyMap[3]]); 49 return True; 50 return False; 51 52 def move_book(self, source, dest): 53 item = self.findAnyDiff(source, dest); 54 if item == None: 55 return; 56 source.items.remove(item); 57 source.rate = source.get_discount_rate(); 58 dest.items.extend([item]); 59 dest.rate = source.get_discount_rate(); 60 return; 61 62 def findAnyDiff(self, source, dest): 63 for item in source.items: 64 if item not in dest.items: 65 return item; 66 return None; 67 68 class Book: 69 def __init__(self, index, name, price): 70 self.index = index; 71 self.name = name 72 self.price = price 73 74 class Item: 75 def __init__(self, book, count): 76 self.book = book 77 self.count = count 78 79 class Cart: 80 items = []; 81 def add_item(self, item): 82 self.items.append(item); 83 84 def pick_most_books(cart): 85 items = []; 86 for i in range(0, len(cart.items)): 87 item = cart.items[i]; 88 if item.count == 0: 89 continue; 90 items.append(Item(item.book, 1)); 91 cart.items[i].count -= 1; 92 return items; 93 94 def is_empty(cart): 95 for item in cart.items: 96 if item.count > 0: 97 return False; 98 return True; 99 100 def count_price(strategies): 101 price = 0; 102 for s in strategies: 103 price += s.get_price(); 104 return price; 105 106 def find_best_solution(cart): 107 strategies = []; 108 price = 0.0; 109 while not is_empty(cart): 110 items = pick_most_books(cart); 111 strategy = Strategy(items); 112 strategies.append(strategy); 113 return strategies; 114 115 def count_best_price(cart): 116 strategies = find_best_solution(cart); 117 so = StrategyOptimizer(); 118 strategies = so.optimize(strategies) 119 price = count_price(strategies); 120 print(price); 121 122 if __name__ == '__main__': 123 item_1 = Item(Book("#1.", "Philosophy Stone", 8), 2); 124 item_2 = Item(Book("#2.", "Secret Chamber", 8), 2); 125 item_3 = Item(Book("#3.", "Prisoner of Azkaban", 8), 2); 126 item_4 = Item(Book("#4.", "Goblet of Fire", 8), 1); 127 item_5 = Item(Book("#5.", "The Order of Phoenix", 8), 1); 128 129 cart = Cart(); 130 cart.add_item(item_1); 131 cart.add_item(item_2); 132 cart.add_item(item_3); 133 cart.add_item(item_4); 134 cart.add_item(item_5); 135 136 count_best_price(cart);