diff options
Diffstat (limited to 'gearing-up-for-destruction/matthieu')
| -rw-r--r-- | gearing-up-for-destruction/matthieu/solution.py | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/gearing-up-for-destruction/matthieu/solution.py b/gearing-up-for-destruction/matthieu/solution.py new file mode 100644 index 0000000..6d4eee3 --- /dev/null +++ b/gearing-up-for-destruction/matthieu/solution.py @@ -0,0 +1,62 @@ +# coding=utf-8 +from fractions import Fraction + +def solution(pegs): + # This function is based on the formulat I figured out on paper + # using what I could find online about gears, I used the + # (number of gears entraining one other) / (number of gears entraned by one other) + # Using the distances, I can express the sizes of all gears from the first one + # and then, using the formula, I can find x + + # The developed formula shows that the signs + / - are present half of the time + # However, the x present in the last part changes if the number is event/pair + # (because of the signs, when n is pair, it adds up to the one present in the other branch + # of the equation, if n is impair, it removes 2x from the single x on the other branch, resulting + # in a negative x in the other branch + + sm = 0 + # Avoid .append by creating a sized array + distances = [pegs[0]] + [0] * (len(pegs) - 1) + + # We calculate the points between the pegs, (except the first one) + for i, v in enumerate(pegs): + if i != 0: + distances[i] = pegs[i] - pegs[i - 1] + + # Derived from the formula + for i, v in enumerate(distances[1:]): + sm += (-1) ** (i) * (2 * v) + + denom = 1 + + # If the number of pegs is pair, we divide by 3 + if len(pegs) % 2 == 0: + denom = 3 + + # Avoid .append by creating a sized array + sizes = [sm / denom] + [0] * (len(pegs) - 1) + + # calculate all the gear sizes + for i, v in enumerate(distances): + if v == distances[0]: + continue + + size = v - sizes[i - 1] + sizes[i] = size + + # all gears must be >= + if size < 1: + return [-1, -1] + + # used to simplify the fraction + f = Fraction(sm, denom) + + # the first gear must be >= 1 + if f < 1: + return [-1, -1] + + return [f.numerator, f.denominator] + + +assert solution([4, 17, 50]) == [-1, -1], "invalid" +assert solution([4, 30, 50]) == [12, 1], "invalid" |
