summaryrefslogtreecommitdiff
path: root/gearing-up-for-destruction/matthieu/solution.py
blob: 6d4eee314c60e6485915f10cc22cc3a787f0e2a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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"