Skip to content

Instantly share code, notes, and snippets.

@jg75
Last active March 8, 2019 22:20
Show Gist options
  • Save jg75/885ea916453eebf7153d38bbf10bafbe to your computer and use it in GitHub Desktop.
Save jg75/885ea916453eebf7153d38bbf10bafbe to your computer and use it in GitHub Desktop.
"""
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