checkio (How much gold)

Our Favorite Trio has found a mysterious metal bar. This bar appears to be made of various metal including gold, iron, copper and tin. The bar does not contain any other metal except these. We do not know the quantity of each metal in the bar, but we do know the proportions of the various alloys. For example: the gold and tin proportion is 1/2, gold and iron -- 1/3, gold and copper -- 1/4. "the gold and tin proportion id 1/2" means that gold and tin together (their sum, not their ratio!) are the 1/2 of the whole bar (the sum of them all). You should calculate the proportion of gold in the entire bar.

The proportions are given as a dictionary where keys are alloy names and values are proportions. The alloy names are presented as strings, which are composed of two metal names separated by a dash (Ex: "gold-tin", "iron-copper", "iron-gold"). The proportions are presented as fractions (fractions.Fraction date type. Read about this module).

You should return the proportion of gold in the bar as a fraction (fractions.Fraction).

Precondition: All tests are solvable.

Input: Alloys names and proportions. A dictionary.

Output: Proportion of gold. A fractions.Fraction.

Example:

?
1
2
3
4
5
6
7
8
9
10
checkio({
    'gold-tin': Fraction(1, 2),
    'gold-iron': Fraction(1, 3),
    'gold-copper': Fraction(1, 4),
    }) == Fraction(1, 24)
checkio({
    'tin-iron': Fraction(1, 2),
    'iron-copper': Fraction(1, 2),
    'copper-tin': Fraction(1, 2),
    }) == Fraction(1, 4)

How it is used: This teaches you how to work with Fraction data type.

我的想法是根据gold数的不同分类讨论

from fractions import Fraction

def cal(target, condition, alloys):
    num = 0
    total = sum(i for i in alloys.values())
    for c in condition:
        for i in c:
            if i == target:
                num += 1
    if num == 0:
        return  1-total/2
    elif num == 2:
        for i in alloys:
            if 'gold' not in i:
                return (total-2*alloys[i])/2
    elif num == 3:
        return (total-1)/2
    else:
        return None

def find(alloys):
    for i in alloys:
        if 'gold' in i:
            s = i.split('-')
            if s[0] == 'gold':
                return s[1], alloys[i]
            else:
                return s[0], alloys[i]

def checkio(alloys):
    condition = [c.split('-') for c in alloys]
    tem = cal('gold', condition, alloys)
    if tem is None:
        another,value = find(alloys)
        return value - cal(another, condition, alloys)
    else:
         return tem

print checkio({"iron-gold":Fraction(1, 2),"iron-copper":Fraction(1, 4),"iron-tin":Fraction(2, 3)})
print checkio({"copper-tin":Fraction(5, 9),"tin-gold":Fraction(1, 2),"gold-copper":Fraction(2, 7)})
#These "asserts" using only for self-checking and not necessary for auto-testing
if __name__ == '__main__':
    assert checkio({
        'gold-tin': Fraction(1, 2),
        'gold-iron': Fraction(1, 3),
        'gold-copper': Fraction(1, 4),
        }) == Fraction(1, 24), "1/24 of gold"
    assert checkio({
        'tin-iron': Fraction(1, 2),
        'iron-copper': Fraction(1, 2),
        'copper-tin': Fraction(1, 2),
        }) == Fraction(1, 4), "quarter"

然后看了第一名的代码,惊呆了
def checkio(alloys):
    """
        Find proportion of gold, assume exist unique solution.
    """
    return 1 - sum([1 - v if 'gold' in k else v for (k, v) in alloys.iteritems()]) / 2


你可能感兴趣的:(checkio (How much gold))