Python Implementation of Problem 31
View source code here on GitHub!
Problem Solution
Project Euler Problem 31
This took a while to get in a form that I was happy with. I wanted something more flexible than "let's take 8 for loops", so I did my best to make this as modular as I could think to do.
Problem:
In England the currency is made up of pound, £, and pence, p, and there are eight coins in general circulation:
1p, 2p, 5p, 10p, 20p, 50p, £1 (100p) and £2 (200p). It is possible to make £2 in the following way:
1×£1 + 1×50p + 2×20p + 1×5p + 1×2p + 3×1p How many different ways can £2 be made using any number of coins?
- python.src.p0031.coin_combinations(amount: int, units: Sequence[int], counts: MutableSequence[int]) int
1"""
2Project Euler Problem 31
3
4This took a while to get in a form that I was happy with. I wanted something
5more flexible than "let's take 8 for loops", so I did my best to make this as
6modular as I could think to do.
7
8Problem:
9
10In England the currency is made up of pound, £, and pence, p, and there are
11eight coins in general circulation:
12
131p, 2p, 5p, 10p, 20p, 50p, £1 (100p) and £2 (200p).
14It is possible to make £2 in the following way:
15
161×£1 + 1×50p + 2×20p + 1×5p + 1×2p + 3×1p
17How many different ways can £2 be made using any number of coins?
18"""
19from typing import Iterable, MutableSequence, Sequence
20
21
22def calculate(counts: Iterable[int], units: Iterable[int]) -> int:
23 return sum(a * b for a, b in zip(counts, units))
24
25
26def coin_combinations(amount: int, units: Sequence[int], counts: MutableSequence[int]) -> int:
27 answer = total = 0
28 while total <= amount:
29 total = calculate(counts, units)
30 if total == amount:
31 # print(
32 # ", ".join(
33 # "{:03}p * {{:03}}".format(unit) for unit in units
34 # ).format(*counts)
35 # )
36 answer += 1
37 counts[-1] += 1
38 key = len(counts)
39 while total > amount:
40 key -= 1
41 counts[key] = 0
42 counts[key - 1] += 1
43 total = calculate(counts, units)
44 if key == 1:
45 break
46 return answer
47
48
49def main() -> int:
50 units = (200, 100, 50, 20, 10, 5, 2, 1)
51 counts = [0 for _ in units]
52 return coin_combinations(200, units, counts)