La suite de Conway et la classification périodique des "éléments"

De Wiki du LAMA (UMR 5127)
Aller à la navigation Aller à la recherche

La suite de Conway, aussi appelée suite audioactive ou Look and Say sequence pour « Regarde et Dit » en anglais, est une suite mathématique créée par J. H. Conway en 1986.

Définition

Comme dit précédemment, la suite de Conway est une suite « audioactive ». Un terme se détermine en lisant le terme précédent.

Un terme est une chaîne de caractères constituée de chiffres.

Si l'on pose comme premier terme , on peut lire ce terme dans la vie courante comme « trois trois ».

Notre terme suivant sera donc . En appliquant cette même méthode, on trouvera les termes suivants :

,

,

,

,

Et ainsi de suite.

On remarque que la méthode qui permet de passer du terme à son terme suivant est une méthode de compression appelée Run-length encoding (RLE)

Les fonctions qui permettent de calculer cette suite sont les suivantes :

def termeSuivant(terme):
    """Fonction qui retourne le terme suivant de la suite de Conway.
    Entrée: Chaîne de caractères ;
    Sortie: Chaîne de caractères ;"""

    nouveauTerme = ""
    c_actuel = terme[0]
    c_compte = 0

    for c in terme:

        if (c != c_actuel):
            nouveauTerme += str(c_compte) + c_actuel
            c_actuel = c
            c_compte = 1
        else:
            c_compte += 1

    nouveauTerme += str(c_compte) + c_actuel
        
    return nouveauTerme



def conway(n,premierTerme = "1",afficher = True):
    """Fonction qui affiche, puis retourne la suite de Conway jusqu'à un rang n.
    Entrée: n = Entier ; premietTerme (option) = Chaîne de caractère ; afficher (option) = Booléen.
    Sortie: Tableau de chaînes de caractère"""

    terme = premierTerme
    resultat = [""] * n
    
    for i in range(0,n):

        resultat[i] = terme

        if (afficher):
            print(terme)

        terme = termeSuivant(terme)

    return resultat

Exemple d'exécution :

>>> conway(5,premierTerme='42',afficher=False)
['42', '1412', '11141112', '31143112', '132114132112']

>>> termeSuivant('311212322')
'13211211121322'

Propriétés et théorèmes

Conway s'est demandé ce qu'il se passerait si l'on dérive n fois une chaîne de caractères d'entiers positifs.

Notion d'atome

Conway s'est rendu compte que peu importe la chaîne de départ choisi, on retrouve plusieurs fois certaines sous-chaînes.

Il en déduira le théorème de la séparation, qui décrit si une chaîne peut être découpée en deux sous-chaînes (la partie gauche et la partie droite) selon certains critères énoncés plus loin.

  • On appellera donc atome ou élément toute chaîne qui ne peut pas être coupée selon ce théorème.
  • On appellera composés les chaînes constituées de plusieurs atomes.


Propriétés

Voici les propriétés de certains théorèmes qu'il a trouvé.

  • Si le premier terme de la suite ne contient pas de chiffre 4 ou supérieur, alors les descendants de la suite n'auront pas de chiffre 4 ou supérieur.


Le théorème « chimique »

  • Les descendants de n'importe quel des 92 éléments de notre tableau périodique sont des combinaisons de ces éléments.
  • En dérivant assez de fois n'importe quel de ces éléments excepté l'hydrogène, on retrouvera l'ensemble des 92 éléments de notre tableau périodique.
  • En dérivant assez de fois n'importe quel chaîne de caractères autre que "" et "22", on retrouvera l'ensemble des 92 éléments de notre tableau périodique.

Le théorème « arithmétique »

  • Excepté pour les premiers termes de la suite et pour les premiers termes "" et "22", la longueur des termes de la suite croit exponentiellement selon une constante :

avec la longueur du i-ème terme de la suite.

Courbe Conway Lambda.png
  • L'abondance de ces éléments tendent vers des valeurs constantes, toutes positives.


Afin d'approximer et de vérifier expérimentalement la valeur de , on peut calculer à l'aide de la fonction conway() vue précédemment un terme de rang n très grand et faire la division de sa longueur par la longueur du terme qui le précède.



Malheureusement, la fonction est gourmande en ressources et prend près de 10 minutes pour calculer le 65ème.

Il fallait donc soit changer le langage de programmation, soit changer l'algorithme.

En copiant la fonction conway() en langage C++, le temps de traitement n'a pas changé significativement.

J'ai fini par utiliser la fonction suivante, qui m'a permis de calculer 75 termes en quelques minutes.

import time
def conway(nbr=80):
    n = "1"
    for i in range(nbr):
        n=n.replace('111','ca').replace('222','cb').replace('11','ba').replace('22','bb').replace('33','bc').replace('1','aa').replace('2','ab').replace('3','ac').replace('a','1').replace('b','2').replace('c','3')
        yield n

Malgré ce gain de temps, il est difficile de stocker la suite. En effet, un fichier texte contenant les 70 premiers termes de la suite (avec comme premier terme "3") pèse plus d'un gigaoctet.

Au final, on peut trouver avec et ou avec et

Le théorème « cosmologique »

  • Toute chaîne de caractères décomposée assez de fois est une combinaison d'éléments du tableau périodique.

La conséquence de ceci est que chaque chaîne autre que "" et "22" a une longueur qui croit selon , et l'abondance de chacun de ces atomes approche les valeurs décrite précédemment.

Le théorème de la « séparation »

Notation :

X signifie un chiffre non nul.

«  » désigne une chaîne qui se termine par X.

«  » désigne une chaîne qui se commence par X.

«  » désigne une répétition de X, i fois. (e.g. )


Une chaîne GD ayant été décomposé au moins 2 fois peut se découper en deux chaînes G et D si l'une des conditions suivantes est respectée.

Pour et  :

G (partie gauche) D (partie droite)
ou ou ou
ou ou ou

Tableau périodique

En suivant les théorèmes énoncés précédemment, on retrouve le tableau périodique avec l'abondance des atomes, leurs numéro et les chaînes correspondantes.

Voici les 20 premiers atomes des 92 éléments du tableau périodique :

Abondance n dans la dérivée de
102.56285249 92 U 3
9883.5986392 91 Pa 13
7581.9047125 90 Th 1113
6926.9352045 89 Ac 3113
5313.7894999 88 Ra 132113
4076.3134078 87 Fr 1113122113
3127.0209328 86 Rn 311311222113
2398.7998311 85 At Ho.1322113
1840.1669683 84 Po 1113222113
1411.6286100 83 Bi 3113322113
1082.8883285 82 Pb Pm.123222113
830.70513293 81 Tl 111213322113
637.25039755 80 Hg 31121123222113
488.84742982 79 Au 132112211213322113
375.00456738 78 Pt 111312212221121123222113
287.67344775 77 Ir 3113112211322112211213322113
220.68001229 76 Os 1321132122211322212221121123222113
169.28801808 75 Re 111312211312113221133211322112211213322113
315.56655252 74 W Ge.Ca.312211322212221121123222113
242.07736666 73 Ta 13112221133211322112211213322113


L'abondance d'un atome est en moyenne le nombre de fois qu'il apparait sur 1 million d'atomes.

On remarque que la décomposition de rhénium (Re) est combinaison du germanium (Ge), du calcium (Ca) et du tungstène (W).

La suite de Robinson

Définition

La suite de Robinson est une modification de la suite de Conway. En effet, on ne fait plus de compression RLE, mais on compte le nombre de fois qu'un chiffre apparait dans toute la chaîne.

En posant comme premier terme de la suite , on trouvera les termes suivants :

Et ainsi de suite.

Le programme permettant de calculer cette suite est le suivant :

def termeSuivantRobinson(terme):
    """Fonction qui retourne le terme suivant de la suite de Robinson.
    Entrée: Chaîne de caractères ;
    Sortie: Chaîne de caractères ;"""

    resultat = ""
    maximum = 0

    for c in terme:

        c = int(c)

        if (c > maximum):

            maximum = c

    for i in range(maximum, -1, -1):

        compte = 0
        
        for c in terme:

            if (int(c) == i):

                compte += 1
        if (compte != 0):
            resultat += str(compte) + str(i)

    return resultat
            
            
    
def robinson(n,premierTerme = "0",afficher = True):
    """Fonction qui affiche, puis retourne la suite de Robinson jusqu'à un rang n.
    Entrée: n = Entier ; premietTerme (option) = Chaîne de caractère ; afficher (option) = Booléen.
    Sortie: Tableau de chaînes de caractère"""

    terme = premierTerme
    resultat = [""] * n
    
    for i in range(0,n):

        resultat[i] = terme

        if (afficher):
            print(terme)

        terme = termeSuivantRobinson(terme)

    return resultat

Exemple d'exécution :

>>> robinson(6,premierTerme='21',afficher=False)
['21', '1211', '1231', '131221', '132231', '232221']

>>> termeSuivantRobinson('111352211321')
'15233261'


Propriétés

Exemple de boucle avec la prepériode et la période

En décomposant i fois un terme de la suite, la suite bouclera avec j descendants par boucle.

On appelle i la préperiode, et j la période de la suite.


On peut le vérifier expérimentalement avec cette fonction :

def trouverBoucle(premierTerme="0"):
    """Fonction qui trouve à quel rang la suite de Robinson boucle.
    Entrée : premierTerme (option): Chaîne de caractères ;
    Sortie : Tuple d'entiers. (prépreiode,periode)"""
    
    robinson = [premierTerme]
    dernierTerme = premierTerme
    
    i = 0   #Rang a partir duquel la suite boucle : préperiode
    j = 0   #Taille de la boucle : periode

    while (chaineDansListe(dernierTerme,robinson[:len(robinson) - 1]) == -1):   #Tant que le dernier terme n'est pas dans la suite
        
        robinson += [termeSuivantRobinson(dernierTerme)]

        dernierTerme = robinson[len(robinson) - 1]

        i += 1

    j = i - chaineDansListe(dernierTerme,robinson[:len(robinson) - 1])
    
    return (i,j + 1)

Approfondissements possibles

  • On pourrait utiliser les chiffres romains au lieu des chiffres arabes pour générer notre suite.

Source et documents annexes

Source

  • Conway, J. H. "The Weird and Wonderful Chemistry of Audioactive Decay." §5.11 dans Open Problems in Communication and Computation (Ed. T. M. Cover and B. Gopinath). New York: Springer-Verlag, pp. 173-188, 1987.

Annexes