Aller au contenu

Écrire les entiers sans les chiffres⚓︎

Supposons que le clavier devant nous soit abîmé : aucune des touches permettant de saisir des chiffres ne fonctionne ! Comment faire pour représenter les entiers ? Pour les additionner et les multiplier ? Les soustraire ?

On choisit tout d'abord de représenter zéro par un tuple vide ZERO = tuple().

On fournit de plus la fonction successeur qui prend la représentation d'un entier \(n\) en argument et renvoie celle de son successeur \(n+1\) :

🐍 Script Python
def successeur(n):
    return (n,)

Remarque

L'appel successeur(ZERO) renvoie ((),) qui représente donc le nombre UN.

On ne demande pas de travailler avec ces notations sous forme de tuples.

Avec ces deux éléments, valeur de départ ZERO et fonction successeur, il est possible de représenter tous les entiers.

🐍 Console Python
>>> ZERO = tuple()
>>> UN     = successeur(ZERO)
>>> DEUX   = successeur(UN)
>>> TROIS  = successeur(DEUX)
>>> QUATRE = successeur(TROIS)
>>> CINQ   = successeur(QUATRE)
>>> SIX    = successeur(CINQ)
>>> SEPT   = successeur(SIX)
>>> HUIT   = successeur(SEPT)
Remarque

La fonction successeur et les « entiers » définis ci-dessus sont directement accessibles dans le corps du programme. Il est inutile de les retaper.

Vous devez compléter trois fonctions addition, multiplication et soustraction ci-dessous prenant chacune en arguments les représentations a et b de deux entiers et renvoyant respectivement leur somme (a plus b), leur produit (a fois b) et leur différence (a moins b).

Les valeurs de a et b ne devront pas être modifiées lors du traitement.

Les calculs sur les entiers ne seront effectués qu'à l'aide de la fonction successeur et des fonctions codées précédemment.

Attention

Si b est plus grand que a, la différence « a moins b » n'est pas possible dans l'ensemble des entiers positifs.

Dans ce cas, la fonction soustraction lèvera une erreur liée à une valeur incorrecte. Pour ce faire, on utilisera l'instruction raise ValueError.

Exemples

🐍 Console Python
>>> addition(UN, UN) == DEUX
True
>>> addition(TROIS, DEUX) == CINQ
True
>>> multiplication(ZERO, CINQ) == ZERO
True
>>> multiplication(DEUX, TROIS) == SIX
True
>>> soustraction(CINQ, TROIS) == DEUX
True
# Testsbksl-nl# un + un == deuxbksl-nlassert addition(UN, UN) == DEUXbksl-nl# trois + cinq == huitbksl-nlassert addition(TROIS, DEUX) == CINQbksl-nl# zéro py-str cinq == zérobksl-nlassert multiplication(ZERO, CINQ) == ZERObksl-nl# deux py-str trois == sixbksl-nlassert multiplication(DEUX, TROIS) == SIXbksl-nl# cinq - trois == deuxbksl-nlassert soustraction(CINQ, TROIS) == DEUXbksl-nl# trois - cinq -> Opération impossiblebksl-nltry:bksl-nl soustraction(DEUX, CINQ)bksl-nlexcept ValueError:bksl-nl passbksl-nlbksl-nl# Tests supplémentairesbksl-nlZERO = tuple()bksl-nlnombres = [ZERO]bksl-nlfor k in range(1, 1py-und000):bksl-nl nombres.append(successeur(nombres[-1]))bksl-nlfrom random import randrangebksl-nlbksl-nlfor test in range(10):bksl-nl ipy-unda = randrange(0, 30)bksl-nl ipy-undb = randrange(0, 30)bksl-nl ipy-unda, ipy-undb = tuple(sorted([ipy-unda, ipy-undb]))bksl-nl a = nombres[ipy-unda]bksl-nl b = nombres[ipy-undb]bksl-nl # Test de la sommebksl-nl attendu = nombres[ipy-unda + ipy-undb]bksl-nl assert addition(a, b) == attendu, f"Erreur sur l'addition de '{ipy-unda}' et '{ipy-undb}'"bksl-nl # Test de la différence validebksl-nl attendu = nombres[ipy-undb - ipy-unda]bksl-nl assert (bksl-nl soustraction(b, a) == attendubksl-nl ), f"Erreur sur la soustraction de '{ipy-undb}' et '{ipy-unda}'"bksl-nl # Test de la différence invalidebksl-nl try:bksl-nl soustraction(a, b)bksl-nl except ValueError:bksl-nl passbksl-nl except:bksl-nl raise AssertionError(f"Erreur sur la soustraction de '{ipy-unda}' et '{ipy-undb}'. Il faut lever une erreur de valeur.")bksl-nl # Test du produitbksl-nl attendu = nombres[ipy-unda py-str ipy-undb]bksl-nl assert (bksl-nl multiplication(a, b) == attendubksl-nl ), f"Erreur sur le produit de '{ipy-undb}' et '{ipy-unda}'"bksl-nlbksl-nl ∞/∞

# --- HDR --- #bksl-nldef successeur(n):bksl-nl return (n,)bksl-nlbksl-nlbksl-nlZERO = tuple()bksl-nlUN = successeur(ZERO)bksl-nlDEUX = successeur(UN)bksl-nlTROIS = successeur(DEUX)bksl-nlQUATRE = successeur(TROIS)bksl-nlCINQ = successeur(QUATRE)bksl-nlSIX = successeur(CINQ)bksl-nlSEPT = successeur(SIX)bksl-nlHUIT = successeur(SEPT)bksl-nl# --- HDR --- #bksl-nldef addition(a, b):bksl-nl ...bksl-nlbksl-nlbksl-nldef multiplication(a, b):bksl-nl ...bksl-nlbksl-nlbksl-nldef soustraction(a, b):bksl-nl ...bksl-nlbksl-nlbksl-nl# Testsbksl-nl# un + un == deuxbksl-nlassert addition(UN, UN) == DEUXbksl-nl# trois + cinq == huitbksl-nlassert addition(TROIS, DEUX) == CINQbksl-nl# zéro py-str cinq == zérobksl-nlassert multiplication(ZERO, CINQ) == ZERObksl-nl# deux py-str trois == sixbksl-nlassert multiplication(DEUX, TROIS) == SIXbksl-nl# cinq - trois == deuxbksl-nlassert soustraction(CINQ, TROIS) == DEUXbksl-nl# trois - cinq -> Opération impossiblebksl-nltry:bksl-nl soustraction(DEUX, CINQ)bksl-nlexcept ValueError:bksl-nl passbksl-nlbksl-nl# --- HDR --- #ajoutepy-undunbksl-nldef successeur(n):bksl-nl return (n,)bksl-nlbksl-nlbksl-nlZERO = tuple()bksl-nlUN = successeur(ZERO)bksl-nlDEUX = successeur(UN)bksl-nlTROIS = successeur(DEUX)bksl-nlQUATRE = successeur(TROIS)bksl-nlCINQ = successeur(QUATRE)bksl-nlSIX = successeur(CINQ)bksl-nlSEPT = successeur(SIX)bksl-nlHUIT = successeur(SEPT)bksl-nl# --- HDR --- #bksl-nlbksl-nlbksl-nldef addition(a, b):bksl-nl etapes = ZERObksl-nl somme = abksl-nl while etapes != b:bksl-nl etapes = successeur(etapes)bksl-nl somme = successeur(somme)bksl-nl return sommebksl-nlbksl-nlbksl-nldef multiplication(a, b):bksl-nl etapes = ZERObksl-nl produit = ZERObksl-nl while etapes != b:bksl-nl etapes = successeur(etapes)bksl-nl produit = addition(produit, a)bksl-nl return produitbksl-nlbksl-nlbksl-nldef soustraction(a, b):bksl-nl difference = ZERObksl-nl while b != a:bksl-nl if difference == a:bksl-nl raise ValueErrorbksl-nl difference = successeur(difference)bksl-nl b = successeur(b)bksl-nl return differencebksl-nlbksl-nlbksl-nl# Testsbksl-nl# un + un == deuxbksl-nlassert addition(UN, UN) == DEUXbksl-nl# trois + cinq == huitbksl-nlassert addition(TROIS, DEUX) == CINQbksl-nl# zéro py-str cinq == zérobksl-nlassert multiplication(ZERO, CINQ) == ZERObksl-nl# deux py-str trois == sixbksl-nlassert multiplication(DEUX, TROIS) == SIXbksl-nl# cinq - trois == deuxbksl-nlassert soustraction(CINQ, TROIS) == DEUXbksl-nl# trois - cinq -> Opération impossiblebksl-nltry:bksl-nl soustraction(DEUX, CINQ)bksl-nlexcept ValueError:bksl-nl passbksl-nlbksl-nl

A

Commentaires⚓︎

{{ IDE('exo_corr') }}

On adapte dans cet exercice une partie des axiomes de Peano permettant de construire les entiers naturels 0, 1, 2, ... .

On a proposé dans le corrigé des solutions itératives. Il est aussi possible d'utiliser des fonctions annexes récursives :

🐍 Script Python
def addition(a, b):
    def addition_rec(somme, etapes):
        if etapes == b:
            return somme
        else:
            return addition_rec(
                successeur(somme),
                successeur(etapes)
                )

    return addition_rec(a, ZERO)


def multiplication(a, b):
    def multiplication_rec(produit, etapes):
        if etapes == b:
            return produit
        else:
            return multiplication_rec(
                addition(produit, a),
                successeur(etapes)
                )

    return multiplication_rec(ZERO, ZERO)


def soustraction(a, b):
    def soustraction_rec(b, difference):
        if difference == a:
            raise ValueError
        elif b == a:
            return difference
        else:
            return soustraction_rec(
                successeur(b),
                successeur(difference)
            )
    return soustraction_rec(b, ZERO)

Z

Aide pour addition

Additionner a et b c'est déterminer le b-ième successeur de a. On pourra utiliser une variable temporaire initialisée à ZERO (et pas au nombre 0 !) afin de « compter » le nombre de successeurs calculés.

Aide pour multiplication

Multiplier a et b c'est additionner b fois a à lui-même.

Aide pour soustraction

Soustraire b à a c'est déterminer l'« entier » qu'il faut ajouter à b pour obtenir a. On pourra donc calculer les différents successeurs de b jusqu'à obtenir a. Il faudra prendre soin de garder trace du « nombre » de successeurs calculés.

Un test astucieux sur la valeur de ce « nombre » permet de repérer les soustractions impossibles.

Retour en haut de la page