SHOW:
|
|
- or go back to the newest paste.
| 1 | # -------------- tasks/escher_tasks/task_9__treasures.py ---------------- | |
| 2 | ||
| 3 | ||
| 4 | def treasures(info, limit): | |
| 5 | - | return [] |
| 5 | + | |
| 6 | limit = int(limit * 1000) | |
| 7 | keys = sorted(info, | |
| 8 | key=lambda k: info[k]["price"] / info[k]["weight"], | |
| 9 | reverse=True) | |
| 10 | ||
| 11 | res = {}
| |
| 12 | - | from tasks.escher_tasks.task_9__treasures import treasures |
| 12 | + | for k in keys: |
| 13 | can_take = limit // info[k]["weight"] | |
| 14 | will_take = min(can_take, info[k]["amount"]) | |
| 15 | - | def test_treasures(): |
| 15 | + | res[k] = will_take |
| 16 | limit -= will_take * info[k]["weight"] | |
| 17 | - | assert treasures( |
| 17 | + | |
| 18 | return [f"{k}: {res[k]}" for k in info if res[k] > 0]
| |
| 19 | ||
| 20 | ||
| 21 | from itertools import product | |
| 22 | ||
| 23 | - | assert treasures( |
| 23 | + | |
| 24 | def treasures_2(info, limit): | |
| 25 | ||
| 26 | limit = int(limit * 1000) | |
| 27 | ||
| 28 | counts = {}
| |
| 29 | for k in info: | |
| 30 | can_put = limit // info[k]["weight"] | |
| 31 | will_put = min(can_put, info[k]["amount"]) | |
| 32 | counts[k] = will_put | |
| 33 | ||
| 34 | res = [0 for _ in info] | |
| 35 | best_price = 0 | |
| 36 | ||
| 37 | for combination in product(*[range(counts[k] + 1) for k in info]): | |
| 38 | total_price = sum([amount * info[k]["price"] | |
| 39 | for k, amount in zip(info, combination)]) | |
| 40 | total_weight = sum([amount * info[k]["weight"] | |
| 41 | for k, amount in zip(info, combination)]) | |
| 42 | ||
| 43 | if total_weight <= limit and total_price > best_price: | |
| 44 | res = combination | |
| 45 | best_price = total_price | |
| 46 | ||
| 47 | return [f"{k}: {count}" for k, count in zip(info, res) if count]
| |
| 48 | ||
| 49 | ||
| 50 | def treasures_3(info, limit): | |
| 51 | ||
| 52 | limit = int(limit * 1000) | |
| 53 | best_results = [[0 for _ in info]] | |
| 54 | ||
| 55 | for i in range(1, limit + 1): | |
| 56 | results = [best_results[-1].copy()] | |
| 57 | ||
| 58 | for _idx, k in enumerate(info): | |
| 59 | if i < info[k]["weight"]: | |
| 60 | continue | |
| 61 | ||
| 62 | res = best_results[i - info[k]["weight"]].copy() | |
| 63 | res[_idx] += 1 | |
| 64 | if res[_idx] > info[k]["amount"]: | |
| 65 | continue | |
| 66 | results.append(res) | |
| 67 | ||
| 68 | get_price = lambda res: sum(i * info[k]["price"] | |
| 69 | for i, k in zip(res, info)) | |
| 70 | best_results.append(max(results, key=get_price)) | |
| 71 | ||
| 72 | return [f"{k}: {i}" for k, i in zip(info, best_results[-1]) if i]
| |
| 73 | ||
| 74 | ||
| 75 | # ---------------- tests/test_escher_tasks/test_task_9__treasures.py ------------------ | |
| 76 | ||
| 77 | ||
| 78 | import pytest | |
| 79 | from tasks.escher_tasks.task_9__treasures import ( | |
| 80 | treasures, treasures_2, treasures_3) | |
| 81 | ||
| 82 | ||
| 83 | @pytest.mark.parametrize("func", [treasures, treasures_2, treasures_3])
| |
| 84 | def test_treasures(func): | |
| 85 | ||
| 86 | assert func( | |
| 87 | {'golden coin': {'price': 100, 'weight': 50, 'amount': 200},
| |
| 88 | 'silver coin': {'price': 10, 'weight': 20, 'amount': 1000},
| |
| 89 | 'ruby': {'price': 1000, 'weight': 200, 'amount': 2}}, 5
| |
| 90 | ) == ['golden coin: 92', 'ruby: 2'] | |
| 91 | ||
| 92 | assert func( | |
| 93 | {'golden coin': {'price': 100, 'weight': 50, 'amount': 100},
| |
| 94 | 'silver coin': {'price': 10, 'weight': 20, 'amount': 100},
| |
| 95 | 'ruby': {'price': 1000, 'weight': 200, 'amount': 1}}, 7.5
| |
| 96 | ) == ['golden coin: 100', 'silver coin: 100', 'ruby: 1'] | |
| 97 |