La suite de Robinson.
Écrire une fonction rob :
- Entrée : une chaîne de caractères, dont les caractères sont des chiffres.
- Sortie : une chaîne de caractères construite sur le modèle des exemples ci-dessous.
Si l'entrée est ch = '2434', on lit dans cette chaîne un '2', un '3' et deux '4'. rob(ch) sera '121324'.
Si l'entrée est ch = '1530230', on lit dans cette chaîne deux '0', un '1', un '2', deux '3', un '5'.
La sortie sera '2011122315'.
def rob(ch) :
""" ch est une chaîne de caractères.
La fonction retourne une chaîne de caractères ligne.
ligne est le terme suivant ch dans une suite de Robinson."""
ligne = ''
for x in '0123456789' :
if x in ch : ligne += str(ch.count(x)) + x
return ligne
print(rob('5446401'))
Liste des termes de la suite de Robinson.
Écrire une fonction suiteRob :
- Entrées. Une chaîne de caractères ch, dont les caractères sont des chiffres. Un entier naturel n.
- Sortie. Une liste li des termes successifs d'indices 0 à n de la suite de Robinson construite
à partir du terme initial ch (d'indice 0).
Autrement dit : li[0] = ch, li[1] = rob(ch), li[2] = rob(rob(ch)), li[3] = rob(rob(rob(ch))) ...
def rob(ch) :
""" ch est une chaîne de caractères.
La fonction retourne une chaîne de caractères ligne.
ligne est le terme suivant ch dans une suite de Robinson."""
ligne = ''
for x in '0123456789' :
if x in ch : ligne += str(ch.count(x))+x
return ligne
def suiteRob(ch, n) :
""" ch est une chaîne de caractères.
n est un entier naturel.
La fonction retourne une liste li.
li est la liste des termes d'indices 0 à n de la suite de Robinson
de premier terme ch. """
li = [ch]
for i in range(1,n+1) :
li.append( rob(li[i-1]) )
return li
L = suiteRob('2234',10)
for t in L :
print(t)
Période d'une suite de Robinson.
Dans l'affichage des termes successifs de la suite de Robinson construite à partir de '0', on constate que
les termes sont identiques à partir du rang 10 :
terme d'indice 0 : 0
terme d'indice 1 : 10
terme d'indice 2 : 1011
terme d'indice 3 : 1031
terme d'indice 4 : 102113
terme d'indice 5 : 10311213
terme d'indice 6 : 10411223
terme d'indice 7 : 1031221314
terme d'indice 8 : 1041222314
terme d'indice 9 : 1031321324
terme d'indice 10 : 1031223314
terme d'indice 11 : 1031223314
terme d'indice 12 : 1031223314
On dira que cette suite est de période 1 et de prépériode 10.
Dans l'affichage des termes successifs de la suite de Robinson construite à partir de '15', on constate que
les termes sont identiques à partir du rang 9 :
terme d'indice 0 : 15
terme d'indice 1 : 1115
terme d'indice 2 : 3115
terme d'indice 3 : 211315
terme d'indice 4 : 31121315
terme d'indice 5 : 41122315
terme d'indice 6 : 3122131415
terme d'indice 7 : 4122231415
terme d'indice 8 : 3132132415
terme d'indice 9 : 3122331415
terme d'indice 10 : 3122331415
terme d'indice 11 : 3122331415
terme d'indice 12 : 3122331415
Cette suite est de période 1 et de prépériode 9.
Dans l'affichage des termes successifs de la suite de Robinson construite à partir de '40', on constate que
les termes alternent entre deux valeurs à partir du rang 9 :
terme d'indice 0 : 40
terme d'indice 1 : 1014
terme d'indice 2 : 102114
terme d'indice 3 : 10311214
terme d'indice 4 : 1041121314
terme d'indice 5 : 1051121324
terme d'indice 6 : 104122131415
terme d'indice 7 : 105122132415
terme d'indice 8 : 104132131425
terme d'indice 9 : 104122232415
terme d'indice 10 : 103142132415
terme d'indice 11 : 104122232415
terme d'indice 12 : 103142132415
terme d'indice 13 : 104122232415
terme d'indice 14 : 103142132415
Cette suite sera dite de période 2 et de prépériode 9.
Dans l'affichage des termes successifs de la suite de Robinson construite à partir de '50', on constate que
les termes alternent entre trois valeurs à partir du rang 10 :
terme d'indice 0 : 50
terme d'indice 1 : 1015
terme d'indice 2 : 102115
terme d'indice 3 : 10311215
terme d'indice 4 : 1041121315
terme d'indice 5 : 105112131415
terme d'indice 6 : 106112131425
terme d'indice 7 : 10512213141516
terme d'indice 8 : 10612213142516
terme d'indice 9 : 10513213141526
terme d'indice 10 : 10512223142516
terme d'indice 11 : 10414213142516
terme d'indice 12 : 10512213341516
terme d'indice 13 : 10512223142516
terme d'indice 14 : 10414213142516
terme d'indice 15 : 10512213341516
terme d'indice 16 : 10512223142516
Cette suite sera dite de période 3 et de prépériode 10.
On peut démontrer que toute suite de Robinson est de période 1, 2 ou 3.
Écrire les fonctions suivantes :
- Fonction dansPeriode1() :
- Entrée : li est une liste de termes successifs d'une suite de Robinson.
- Sortie : True si le dernier élément de li est dans un cycle de longueur 1
(la suite de Robinson considérée étant donc de période 1),
False sinon.
Ce cycle de longueur 1 est supposé apparaître déjà dans les éléments de li (on ne demande donc pas de déterminer des
termes de la suite qui ne sont pas encore dans li).
- Fonction dansPeriode2() :
- Entrée : li est une liste de termes successifs d'une suite de Robinson.
- Sortie : True si le dernier élément de li est dans un cycle de longueur 2
(la suite de Robinson considérée étant donc de période 2),
False sinon.
Ce cycle de longueur 2 est supposé apparaître déjà dans les éléments de li (on ne demande donc pas de déterminer des
termes de la suite qui ne sont pas encore dans li).
- Fonction dansPeriode3() :
- Entrée : li est une liste de termes successifs d'une suite de Robinson.
- Sortie : True si le dernier élément de li est dans un cycle de longueur 3
(la suite de Robinson considérée étant donc de période 3),
False sinon.
Ce cycle de longueur 3 est supposé apparaître déjà dans les éléments de li (on ne demande donc pas de déterminer des
termes de la suite qui ne sont pas encore dans li).
def rob(ch) :
""" ch est une chaîne de caractères.
La fonction retourne une chaîne de caractères ligne.
ligne est le terme suivant ch dans une suite de Robinson."""
ligne = ''
for x in '0123456789' :
if x in ch : ligne += str(ch.count(x))+x
return ligne
def suiteRob(ch, n) :
""" ch est une chaîne de caractères.
n est un entier naturel.
La fonction retourne une liste li.
li est la liste des termes d'indices 0 à n de la suite de Robinson
de premier terme ch. """
li = [ch]
for i in range(1,n+1) :
li.append( rob(li[i-1]) )
return li
def dansPeriode1(li) :
""" li est une liste de termes successifs d'une
suite de Robinson.
Soit n le dernier indice de li.
La fonction retourne True si li[n]=li[n-1]."""
n = len(li)-1
if n == 0 : return False
if li[n] == li[n-1] : return True
return False
def dansPeriode2(li) :
""" li est une liste de termes successifs d'une
suite de Robinson.
Soit n le dernier indice de li.
La fonction retourne True si li[n]=li[n-2]
sans que l'on ait li[i]=li[i-1]."""
n = len(li)-1
if n <= 1 : return False
if li[n] == li[n-1] : return False
if li[n] == li[n-2] : return True
return False
def dansPeriode3(li) :
""" li est une liste de termes successifs d'une
suite de Robinson.
Soit n le dernier indice de li.
La fonction retourne True si li[n]=li[n-3]
sans que l'on ait li[i]=li[i-1],
ni li[i]=li[i-2]."""
n = len(li)-1
if n <= 2 : return False
if li[n] == li[n-1] : return False
if li[n] == li[n-2] : return False
if li[n] == li[n-3] : return True
return False
li = suiteRob('0', 11)
print(dansPeriode1(li))
li = suiteRob('0', 10)
print(dansPeriode1(li))
li = suiteRob('40', 11)
print(dansPeriode2(li))
li = suiteRob('40', 10)
print(dansPeriode2(li))
li = suiteRob('50', 13)
print(dansPeriode3(li))
li = suiteRob('50', 12)
print(dansPeriode3(li))
On obtient, conformément aux listes visibles dans l'énoncé :
True
False
True
False
True
False
Calcul de la période d'une suite de Robinson.
Écrire une fonction periode :
- Entrée. Une chaîne de caractères ch, dont les caractères sont des chiffres.
- Sortie. La période (1, 2 ou 3) de la suite de Robinson dont le premier terme est ch.
Dans un second temps, modifier la fonction pour qu'elle retourne également la prépériode.
def rob(ch) :
""" ch est une chaîne de caractères.
La fonction retourne une chaîne de caractères ligne.
ligne est le terme suivant ch dans une suite de Robinson."""
ligne = ''
for x in '0123456789' :
if x in ch : ligne += str(ch.count(x))+x
return ligne
def dansPeriode1(li) :
""" li est une liste de termes successifs d'une
suite de Robinson.
Soit n le dernier indice de li.
La fonction retourne True si li[n] = li[n-1]."""
n = len(li)-1
if n == 0 : return False
if li[n] == li[n-1] : return True
return False
def dansPeriode2(li) :
""" li est une liste de termes successifs d'une
suite de Robinson.
Soit n le dernier indice de li.
La fonction retourne True si li[n] = li[n-2]
sans que l'on ait li[i] = li[i-1]."""
n = len(li)-1
if n <= 1 : return False
if li[n] == li[n-1] : return False
if li[n] == li[n-2] : return True
return False
def dansPeriode3(li) :
""" li est une liste de termes successifs d'une
suite de Robinson.
Soit n le dernier indice de li.
La fonction retourne True si li[n]=li[n-3]
sans que l'on ait li[i]=li[i-1],
ni li[i]=li[i-2]."""
n = len(li)-1
if n <= 2 : return False
if li[n] == li[n-1] : return False
if li[n] == li[n-2] : return False
if li[n] == li[n-3] : return True
return False
def periode(ch):
""" ch est une chaîne de caractères.
La fonction renvoie la période (1 ou 2 ou 3) de
la suite de Robinson partant de ch."""
li = [ch]
indice = 0
while True :
li.append(rob(li[indice]))
indice += 1
if dansPeriode1(li) : return 1
if dansPeriode2(li) : return 2
if dansPeriode3(li) : return 3
def periodeEtPreperiode(ch) :
""" ch est une chaîne de caractères.
La fonction renvoie la période (1 ou 2 ou 3) de
la suite de Robinson partant de ch,
ainsi que la prépériode (liste de ces deux éléments). """
li = [ch]
indice = 0
while True :
li.append(rob(li[indice]))
indice += 1
if dansPeriode1(li) : return [1,indice-1]
if dansPeriode2(li) : return [2,indice-2]
if dansPeriode3(li) : return [3,indice-3]
print(periode('0'))
print(periode('15'))
print(periode('40'))
print(periode('50'))
print(periodeEtPreperiode('0'))
print(periodeEtPreperiode('15'))
print(periodeEtPreperiode('40'))
print(periodeEtPreperiode('50'))
Recherche de générateurs de période 3.
En considérant les entiers comme des chaînes de caractères (0 est assimilé à la chaîne '0', 45 à la chaîne '45'...),
écrire un programme prenant en paramètre un entier positif n
et retournant en sortie la liste des n premiers entiers permettant de générer
une suite de Robinson à période 3.
def rob(ch) :
""" ch est une chaîne de caractères.
La fonction retourne une chaîne de caractères ligne.
ligne est le terme suivant ch dans une suite de Robinson."""
ligne = ''
for x in '0123456789' :
if x in ch : ligne += str(ch.count(x))+x
return ligne
def dansPeriode1(li) :
""" li est une liste de termes successifs d'une
suite de Robinson.
Soit n le dernier indice de li.
La fonction retourne True si li[n]=li[n-1]."""
n = len(li)-1
if n = 0 : return False
if li[n] == li[n-1] : return True
return False
def dansPeriode2(li) :
""" li est une liste de termes successifs d'une
suite de Robinson.
Soit n le dernier indice de li.
La fonction retourne True si li[n]=li[n-2]
sans que l'on ait li[i]=li[i-1]."""
n = len(li)-1
if n <= 1 : return False
if li[n] == li[n-1] : return False
if li[n] == li[n-2] : return True
return False
def dansPeriode3(li) :
""" li est une liste de termes successifs d'une
suite de Robinson.
Soit n le dernier indice de li.
La fonction retourne True si li[n]=li[n-3]
sans que l'on ait li[i]=li[i-1],
ni li[i]=li[i-2]."""
n = len(li)-1
if n <= 2 : return False
if li[n] == li[n-1] : return False
if li[n] == li[n-2] : return False
if li[n] == li[n-3] : return True
return False
def periode(ch):
""" ch est une chaîne de caractères.
La fonction renvoie la période (1 ou 2 ou 3) de
la suite de Robinson partant de ch."""
li = [ch]
indice = 0
while True :
li.append(rob(li[indice]))
indice += 1
if dansPeriode1(li) : return 1
if dansPeriode2(li) : return 2
if dansPeriode3(li) : return 3
def plusPetitPeriode3apres(m) :
""" m est un entier naturel.
Un entier étant considéré comme une chaîne de caractères,
retourne le premier entier supérieur à m générant une suite de Robinson
à période 3."""
k = m+1
while ( periode(str(k)) != 3) :
k += 1
return k
def listePeriode3(n) :
""" n est un entier non nul.
Un entier étant considéré comme une chaîne de caractères,
retourne la liste des n premiers entiers générant une suite de
Robinson à période 3."""
li = []
m = 0
while len(li) < n :
m = plusPetitPeriode3apres(m)
li.append(m)
return li
print(listePeriode3(10))
On obtient :
[50, 57, 58, 59, 67, 75, 76, 85, 95, 167]