Last active
March 8, 2019 22:20
-
-
Save jg75/885ea916453eebf7153d38bbf10bafbe to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Sum of multiples. | |
l the limit | |
m the multiple | |
c the count the number of multiples (l / m) | |
s the sum of (mc + mc^2) / 2 for each multiple of m to l | |
for multiple multiples, subtract the sum of the multiples | |
that are common between the multiples | |
sum of multiples of 2 & 3 up to and including 20: 173 | |
sum of 2's multiples: 2 + 4 + 6 + 8 + 10 + 12 + 14 + 16 + 18 + 20 = 110 | |
sum of 3's multiples: 3 + 6 + 9 + 12 + 15 + 18 = 63 | |
sum of common multiples: 6 + 12 + 18 = 36 | |
110 + 63 - 36 = 173 | |
""" | |
import argparse | |
import math | |
def sum_of_one_set_of_multiples(multiples, limit=20, inclusive=False): | |
"""Sum of multiples.""" | |
total = 0 | |
for multiple in multiples: | |
count = limit // multiple if inclusive else (limit - 1) // multiple | |
low = multiple * count | |
high = multiple * count ** 2 | |
total += (low + high) / 2 | |
return int(total) | |
def lcm(a, b): | |
"""Get the least common multiple of two numbers.""" | |
gcd = math.gcd(a, b) | |
if gcd == 1: | |
return a * b | |
return a if gcd == b else b | |
def lcms(multiples, limit=20, inclusive=False): | |
"""Get a list of least common multiples.""" | |
lcms = list() | |
limit_check = limit if inclusive else (limit - 1) | |
for a in multiples: | |
for b in reversed(multiples): | |
if a == b: | |
return lcms | |
next_lcm = lcm(a, b) | |
if next_lcm <= limit_check: | |
lcms.append(next_lcm) | |
def sum_of_common_multiples(multiples, limit=20, inclusive=False): | |
"""Sum of the common multiples.""" | |
least_common_multiples = lcms( | |
multiples, limit=limit, inclusive=inclusive | |
) | |
return sum_of_one_set_of_multiples( | |
least_common_multiples, limit=limit, inclusive=inclusive | |
) | |
def sum_of_multiples(multiples, limit=20, inclusive=False): | |
"""Get the sum of multiples.""" | |
total = sum_of_one_set_of_multiples( | |
multiples, limit=limit, inclusive=inclusive | |
) | |
total_common = sum_of_common_multiples( | |
multiples, limit=limit, inclusive=inclusive | |
) | |
return int(total - total_common) | |
def parse_args(): | |
"""Parse input arguments.""" | |
parser = argparse.ArgumentParser(description="Sum of multiples") | |
parser.add_argument( | |
"-i", "--inclusive", | |
action="store_true", | |
help="The limiter should be inclusive" | |
) | |
parser.add_argument( | |
"-l", "--limit", | |
default=20, | |
type=int, | |
help="The limiter for multiples" | |
) | |
parser.add_argument( | |
"multiples", | |
type=int, | |
nargs="+", | |
help="A list of factors to sum multiples of" | |
) | |
return parser.parse_args() | |
if __name__ == "__main__": | |
arguments = vars(parse_args()) | |
multiples = arguments.pop("multiples") | |
print(sum_of_multiples(multiples, **arguments)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment