• [^] # Re: Python 3

    Posté par (site web personnel) . En réponse au journal résoudre "trouve 24". Évalué à 5.

    Correction, en utilisant les rationnels du module standard fractions :

    #! /usr/bin/python3
    import argparse
    from fractions import Fraction
    add = Fraction.__add__
    sub = Fraction.__sub__
    mul = Fraction.__mul__
    div = Fraction
    signes = {add: '+', sub: '-', mul: ×ばつ', div: '/'}
    class Operation:
     """An operation between two integers, fractions or operations"""
     def __init__(self, a, b, op):
     """Return an operation representing 'a op b':
     a, b integers, fractions or operations
     op operator"""
     self.a = a
     self.b = b
     self.op = op
     self._result = None
     def result(self):
     """Return the result of the operation, as a fraction"""
     if self._result is None:
     a = value(self.a)
     b = value(self.b)
     self._result = self.op(a, b)
     return self._result
     def __str__(self):
     return '(%s%s%s)' % (self.a, signes[self.op], self.b)
    def value(a):
     """Return the value of an integer, a fraction, or the result of an operation"""
     if isinstance(a, Operation):
     return a.result()
     else:
     return a
    def operations(a, b):
     """Yields of feasible operations between two integers, fractions or operations"""
     yield Operation(a, b, add)
     yield Operation(a, b, mul)
     yield Operation(a, b, sub)
     if value(b) != 0:
     yield Operation(a, b, div)
    def calculs(*termes):
     """Yields all feasible computations with multiple integers or fractions"""
     l = len(termes)
     if l == 1:
     # Un seul terme, rien à faire à part le renvoyer tel quel !
     yield termes[0]
     else:
     # Au moins deux termes: on en prend un...
     for i in range(l):
     a = termes[i]
     # ... puis un autre
     for j in range(l):
     if i == j:
     # Ce sont les mêmes termes, ce n'est pas ce qu'on recherche
     continue
     b = termes[j]
     # On parcours les opérations possibles entre eux
     for ab in operations(a, b):
     # On considère le résultat de cette opération comme un nouveu terme
     # remplaçant les deux choisis.
     yield from calculs(ab, *[termes[k] for k in range(l) if k != i and k != j])
    def trouve(nombres, target):
     """Yields all computations of multiple integers or fractions, which result in the given target"""
     for calcul in calculs(*nombres):
     if value(calcul) == target:
     yield calcul
    def main(args=None):
     parser = argparse.ArgumentParser(description="Trouve un ou des moyens d'obtenir 24 avec les nombres donnés")
     parser.add_argument("--all", action='store_true', help="affiche tous les calculs donnant ce résultat, plutôt que seulement le premier trouvé")
     parser.add_argument("--target", type=int, default=24, help="cherche un résultat autre que 24")
     parser.add_argument("numbers", nargs='+', type=int, help="nombres à utiliser")
     args = parser.parse_args(args)
     calculs = trouve(args.numbers, args.target)
     for calcul in calculs:
     print('%s = %d' % (calcul, value(calcul)))
     if not args.all:
     break
    if __name__ == '__main__':
     main()