diff --git a/coco.py b/coco.py old mode 100755 new mode 100644 index 2e1a0eb44e5373fe03d602d4ddb7f264a68aa8fc..0089f4605fb66a5219b8b6628bb6acb33241d4f8 --- a/coco.py +++ b/coco.py @@ -1,81 +1,54 @@ -#!/usr/bin/python3 -""" -Program to solve the 5 men and the coconuts problem -""" +#!/usr/bin/env python +-""" +-Program to solve the 5 men and the coconuts problem +-""" -def splitthem(quant, running_count): - """ - take a quantity and return False if it is not one more than - equally divisible by 5 +def f(n, n_people=5, remainder=1): + """Calculates next step above in coconut problem""" + return n * n_people / (n_people - 1) + remainder - Otherwise, subtract 1 and subtract 1/5 of the remaining - when the split is done, update the running count for whichever - first zero value - """ - if quant[0] % 5 != 1: - return False +def split_shares(n, n_people=5, remainder=1): + """Calculates share removed and remaining coconuts""" + n -= remainder + return n / n_people, n * (n_people - 1) / n_people - share_amt = (quant[0]-1)//5 - for k in range(5): - if running_count[k] == 0: - running_count[k] = share_amt - break - quant[0] -= (1 + share_amt) - return True +def solve(n_people=5): + """Solves the coconut problem for n people""" + # Assumes the last step is evenly divisible by the number of people + # as well as by the number of people - 1 + lcm = n_people * (n_people - 1) # Least Common Multiple -def testnum(num, running_count): - """ - for a given number test to see if it will succeed using the - logic for split defined in splitthem 5 times. + i = 0 + while True: + multiplier = ( + i * (n - 1) + (n - 2)) # This keeps the t_-1 round divisible by 0 + # to reduce the search space + result = f(multiplier * lcm, n_people) + for _ in range(n_people - 1): + result = f(result, n_people) + i += 1 - Then test to see that it is equally divisible by 5 - - When successful the running_count will be updated - one last time for the final split. - """ - for _ in range(5): - if not splitthem(num, running_count): - return False - - if num[0] % 5 == 0: - share_amt = num[0]//5 - for i in range(5): - running_count[i] += share_amt - - return True - return False - - -def main(): - """ - Main driver for the brute force solver - - choose a number and see if the result can be found and return - or print an error - - """ - test_quantity = 1000000 - - num = [0] - for test_num in range(1, test_quantity): - running_count = [0, 0, 0, 0, 0] - - num[0] = test_num - if testnum(num, running_count): - print("The Number Was %d" % test_num) - print(running_count) - - total = sum(running_count) - - print("Total %d, plus 5 for the monkey!" - " Original starting count %d" % (total, test_num)) - return - - print("Not found in %d tries." % test_quantity) + if result % 1 == 0: + return int(result), i if __name__ == "__main__": - main() + n_people = 5 + total, n_tries = solve(n_people) + + print(f"The total number of coconuts was: {total}") + print(f"Numbers tested: {n_tries}") + + # This calculates each person's overnight stash + stashes = [] + for i in range(n_people): + a, total = split_shares(total, n_people) + stashes.append(int(a)) + + share = int(total / n_people) + print(f"In the morning, each person received a share of: {share}") + for i, amt in enumerate(stashes): + print(f"Person {i} ended up with {amt + share}")