Formation I.S.N.

Palindrome

Exercice : lecture double-sens

On appelle palindrome un mot qui se lit dans les deux sens comme "sos" ou "radar".

Entrée Un mot (type str).
Sortie True si l'entrée est un palindrome, False sinon.
  • définition récursive
  • une solution
  • traceur
  • Si le mot est la chaîne vide, c'est un palindrome. Si le mot ne contient qu'une seule lettre, c'est un palindrome.
  • Dans les autres cas,
    le mot est un palindrome
    si et seulement si
    la première et la dernière lettre sont égales et le mot tronqué de ses première et dernière lettres est un palindrome.

def est_palindrome(mot) :
	if len(mot) < 2 : return True
	else : return (mot[0] == mot[-1]) and est_palindrome(mot[1:-1])


print(est_palindrome('sos'))
print(est_palindrome('raar'))
print(est_palindrome('KarineAllaEnIrak'.lower()))
print(est_palindrome('gloup'))

Décomposons un peu avec des traces :


def trace(f):
	decale = 0
	def g(mot):
		nonlocal decale
		if len(mot) < 2 : pass
		else :
			print('|  ' * decale + '|--', f.__name__, '(', mot ,') ', end = '= ' )
			print( f.__name__, '(', mot[1:-1] ,') '  )
		decale += 1
		valeur = f(mot)
		print('|  ' * decale ,   f.__name__, '(', mot,') =', repr(valeur) )
		decale -= 1
		return valeur
	return g



def est_palindrome(mot) :
	return  (len(mot) < 2) or  ( (mot[0] == mot[-1]) and est_palindrome(mot[1:-1]) )

est_palindrome = trace(est_palindrome)    
est_palindrome('KarineAllaEnIrak'.lower())

Complément Python

On peut faire disparaître complétement le if du code proposé ci-dessus :


 
def est_palindrome(mot) :
	return  (len(mot) < 2) or  ( (mot[0] == mot[-1]) and est_palindrome(mot[1:-1]) )


print(est_palindrome('sos'))
print(est_palindrome('raar'))
print(est_palindrome('KarineAllaEnIrak'.lower()))
print(est_palindrome('gloup'))

Pour comprendre comment ce code fonctionne, il faut savoir que la seconde partie du test :
(mot[0] == mot[-1]) and est_palindrome(mot[1:-1])
n'est pas évaluée lorsque le premier test
len(mot) < 2
est évalué à True.

De la même façon, lorsque
(mot[0] == mot[-1])
est évalué à False, la seconde partie du and :
est_palindrome(mot[1:-1])
n'est pas évaluée et dans ce cas, les appels récursifs ne descendent pas jusqu'au cas d'un mot de longueur au plus 1.

Complément Python

Une autre façon de traiter la question :


def est_palindrome(mot) :
	return all( mot[i] == mot[-1-i] for i in range(len(mot)) )
	 
   
print( est_palindrome('KarineAllaEnIrak'.lower()) )
print( est_palindrome('radar' ))
print( est_palindrome('radada' ))
print( est_palindrome(''))

Consultez la doc.