Listes

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 :

  1. 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).
  2. 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).
  3. 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]