Système unaire

Un système unaire représente les entiers naturels avec un seul symbole.

C’est le système utilisé par le prisonnier dans sa cellule, ou Robinson sur son île, pour compter les jours.
Les Allemands l’appellent Bierdeckelnotation, et l’utilisent pour compter les bières au bistro.

Dans l’antiquité on comptait les soldats de la façon suivante. Chaque soldat prenait un caillou et le mettait sur un tas. Le tas contenait alors l’équivalent en caillou du nombre de soldats.

Le mot calcul vient d’ailleurs de mot calculus, signifiant petit caillou en latin.

Représenter un nombre

Nous pouvons choisir n’importe quel symbole pour représenter un nombre. Par exemple le symbole 🍎:

  • 3 peut être représenté comme 🍎🍎🍎

  • 5 comme 🍎🍎🍎🍎🍎.

  • L’absence de symboles représente le nombre zéro.

Voici donc la représentation des nombres 0, 1, et 3.

a = ''
b = '🍎'
c = '🍎🍎🍎'

Comparaison

En Python, les opérateurs de comparaison numériques (>, >=, <, …) sont aussi valides pour la comparaison de nombres sous forme unaire.

C’est dû au fait que Python permet de comparer des chaines de caractères. Le résultat de la comparaison est basé sur l’ordre alphabétique et correspond à l’ordre utilisé dans un dictionnaire. Un mot court commençant avec les mêmes lettres apparait avant le mot plus long.

'🍎🍎' > '🍎'
True

Et encore un exemple d’égalité (==)

'🍎🍎🍎' == '🍎'
False

et l’inégalité (!=)

'🍎' != '🍎🍎'
True

Conversion

Pour faire la conversion entre les deux systèmes, nous définissons les fonctions:

  • unaire(d) pour transformer un décimal d en unaire

  • decimal(u) pour transformer un unaire u en décimal

Nous utilisons l’opérateur de répétition * pour créer la séquence unaire.

def unaire(d):
    return '🍎' * d

Voici donc la représentation unaire de 5:

unaire(5)
'🍎🍎🍎🍎🍎'

Pour l’autre sens nous utilisons la fonction len() pour trouver la représentation décimale.

def decimal(u):
    return len(u)

Voici donc la représentation décimale de 🍎🍎🍎:

decimal('🍎🍎🍎')
3

Incrémentation

Un des algorithmes élémentaires est celui qui donne le successeur à un nombre. On parle aussi d’incrémentation et nous pouvons la définir comme

def inc(u):
    return u + '🍎'

Donc le successeur de 2 est 3.

inc('🍎🍎')
'🍎🍎🍎'

Décrémentation

La décrémentation est effectuée par la suppression du dernier symbole et trouve le prédécesseur d’un nombre.

def dec(u):
    return u[:-1]

Notre algorithme calcule correctement le prédécesseur de 3 qui est 2.

dec('🍎🍎🍎')
'🍎🍎'

Compter

Nous pouvons maintenant définir un algorithme qui compte.
Ci-dessous nous mettons la variable u à zéro et incrémentons 5 fois.

u = ''
while u != '🍎🍎🍎🍎🍎':
    u = inc(u)
    print(u)
🍎
🍎🍎
🍎🍎🍎
🍎🍎🍎🍎
🍎🍎🍎🍎🍎

Cet algorithme utilise uniquement les éléments

  • affectation =

  • la fonction inc()

  • la boucle while

Addition

L’addition se traduit par la concaténation de deux séquences qui représentent un nombre. Ici l’opérateur + est l’opérateur de concaténation de deux chaînes.

def add(a, b):
    return a + b

L’addition de 2 et 3 et donne le résultat 5.

add('🍎🍎', '🍎🍎🍎')
'🍎🍎🍎🍎🍎'

Soustraction

La soustraction se traduit par la suppression d’un nombre de caractères correspondant au deuxième nombre.

En Python nous utilison l’opérateur de tranche [m:n] pour enlever un certain nombre de symboles.

def sub(a, b):
    return a[:-len(b)]
sub('🍎🍎🍎🍎🍎', '🍎🍎')
'🍎🍎🍎'

Notre système unaire ne peut pas représenter des nombres négatifs. Or la soustraction pourrait donner des résultats négatifs. Que fait notre fonction sub si le résultat donnerait un nombre négatif? Un message d’erreur serait une possibilité, mais en occurrence la fonction retourne tout simplement 0.

sub('🍎🍎', '🍎🍎🍎🍎🍎')
''

Multiplication

La multiplication de deux entiers naturels s’effectue par substitution de chaque symbole de la séquence du premier par une copie de la séquence du deuxième.

def mul(a, b):
    return b * len(a)

La multiplication de 2 et 3 donne correctement 6 comme résultat.

mul('🍎🍎', '🍎🍎🍎')
'🍎🍎🍎🍎🍎🍎'

Division

La division se traduit par la soustraction successive de b de a. Le nombre de soustractions q est le quotient. Ce qui reste de a est le reste de la division.

La fonction retourne quotient et reste

def div(a, b):
    q = ''
    while a > b:
        a = sub(a, b)
        q = inc(q)
    return q, a

Donc 7 divisé par 2 donne 3 (🍎🍎🍎) comme quotient et 1 (🍎) comme reste.

div('🍎🍎🍎🍎🍎🍎🍎', '🍎🍎')
('🍎🍎🍎', '🍎')

Table de multiplication

Nous sommes maintenant capable de définir un algorithme qui affiche le livret de 3 affiché pour 1 à 7.

u = ''
while u < '🍎🍎🍎🍎🍎🍎🍎':
    u = inc(u)
    a = mul(u, '🍎🍎🍎')
    print(a)
🍎🍎🍎
🍎🍎🍎🍎🍎🍎
🍎🍎🍎🍎🍎🍎🍎🍎🍎
🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎
🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎
🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎
🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎