Exercices de Michel Couprie: solutions aux séries 1 et 2, en Python
Eh oui, c'est la semaine de congé, du coup j'ai un peu levé le pied en matières informatiques. Mais pour ne pas laisser les choses en désuétude, voici quelque chose que j'avais fait avant le début du congé, partagé avec quelques favorisés, et qui pourrait être utile à d'autres.
Quand on veut apprendre à programmer, ou qu'on veut se faire la main sur un langage en particulier, on apprécie d'avoir à disposition des petits problèmes d'algorithmique de difficulté et de complexité croissantes. Pour ma part, quand je m'ennuie j'aime beaucoup avoir un problème que je peux résoudre en moins d'une heure, une sorte de "one-shot" pour se changer les idées.
En fouillant un peu j'ai trouvé cette liste de problèmes, proposé par Michel Couprie. ces problèmes (34 en tout) sont classés par difficulté croissante en quatre paliers. Voici mes solutions pour les problèmes des deux premiers paliers (les deux suivants suivront si je m'ennuie ce soir).
# Solutions aux exercices proposes par Michel Couprie a l'adresse:
# http://www.esiee.fr/~coupriem/Exos/exos/exos.html
#
# Il peut y avoir d'autres approches, evidemment, je ne fournis celles-ci qu'a
# titre d'exemples.
# 2009/04/08, 2009-04-09 - Jean Karim Bockstael - jkb@jkbockstael.be
#------------------------------------------------------------------------------
# DIFFICULTE 1
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# 01 - Factorielle
# http://www.esiee.fr/~coupriem/Exos/Enonces/fact
def factorielle_iterative(n):
res = 1
while (n > 1):
res *= n
n -= 1
return res
def factorielle_recursive(n):
if n < 2:
return 1
else:
return n * factorielle_recursive(n - 1)
#------------------------------------------------------------------------------
# 02 - Inversion d'un tableau
# http://www.esiee.fr/~coupriem/Exos/Enonces/inverse
def inversion_tableau_iterative(tab):
tmp = []
if len(tab) < 2:
return tab
for i in (len(tab), 0, -1):
tmp.append(tab[i - 1])
return tmp
def inversion_tableau_recursive(tab):
if len(tab) < 2:
return tab
else:
return inversion_tableau_recursive(tab[1:]) + [tab[0]]
def inversion_tableau_pythonienne(tab):
return tab[-1::-1]
#------------------------------------------------------------------------------
# 03 - Minimum et maximum sur un tableau en une seule passe
# http://www.esiee.fr/~coupriem/Exos/Enonces/minmax
def min_et_max(tab):
if len(tab) < 1:
return {}
res = {'min' : tab[0], 'max' : tab[0]}
for i in range(1, len(tab)):
if (tab[i] < res['min']):
res['min'] = tab[i]
if (tab[i] > res['max']):
res['max'] = tab[i]
return res
#------------------------------------------------------------------------------
# 04 - Palindrome ou non, en ignorant les espaces
# http://www.esiee.fr/~coupriem/Exos/Enonces/palindrome
def est_palindrome(texte):
if len(texte) < 2:
return True
tmp = texte.replace(' ', '')
return (tmp == tmp[-1::-1])
#------------------------------------------------------------------------------
# 05 - Solution d'un polynome par Horner
# http://www.esiee.fr/~coupriem/Exos/Enonces/polynome
def solution_horner(poly, value):
# avec poly de la forme [coeff, ...] sans vide, poids fort au debut
# donc on note explicitement les coefficiens nuls
result = poly[0]
for i in range(1, len(poly)):
result *= value
result += poly[i]
return result
#------------------------------------------------------------------------------
# 06 - Estimation de Pi
# http://www.esiee.fr/~coupriem/Exos/Enonces/calculpi
from random import random
from math import sqrt
def estimation_pi(nb_points):
def radius(x_coord, y_coord):
return sqrt(x_coord ** 2 + y_coord ** 2)
cnt = 0.0
for i in range(0, nb_points):
if radius(random(), random()) < 1:
cnt += 1
return cnt / nb_points * 4
#------------------------------------------------------------------------------
# 07 - Suite "cube de chiffres du terme precedent"
# http://www.esiee.fr/~coupriem/Exos/Enonces/cubes
def suite_cube_chiffres(depart):
def somme_cubes_chiffres(nombre):
tmp = str(nombre)
res = 0
for i in range(0, len(tmp)):
res += int(tmp[i]) ** 3
return res
if (depart % 3 != 0) or (depart < 0):
return "Le premier element doit etre un multiple positif de 3."
res = [depart]
while res[-1] != somme_cubes_chiffres(res[-1]):
res.append(somme_cubes_chiffres(res[-1]))
return res[-1]
#------------------------------------------------------------------------------
# 08 - Crible d'Eratosthene
# http://www.esiee.fr/~coupriem/Exos/Enonces/eratos
def crible_eratosthene(limite):
res_bool = [False, False]
for i in range(2, limite + 1):
res_bool.append(True)
for i in range(2, limite + 1):
for j in range(2, i / 2 + 1):
if (i % j == 0) and (i / j != 1):
res_bool[i] = False
res_num = []
for i in range(2, limite + 1):
if res_bool[i]:
res_num.append(i)
return res_num
#------------------------------------------------------------------------------
# 09 - Test de la primalite d'un entier
# http://www.esiee.fr/~coupriem/Exos/Enonces/premier
def est_premier(nombre):
if (nombre < 2):
return False
premiers = crible_erathosthene(nombre / 2 + 1)
for i in premiers:
if (nombre % i == 0):
return False
return True
#------------------------------------------------------------------------------
# 10 - Produit scalaire de deux vecteurs
# http://www.esiee.fr/~coupriem/Exos/Enonces/prodscal
def produit_scalaire(vec1, vec2):
if (len(vec1) != len(vec2)) or \
(len(vec1) < 1) or \
(len(vec2) < 1):
return "Arguments incorrects"
tmp = 0
for i in range(0, len(vec1)):
tmp += vec1[i] * vec2[i]
return tmp
#------------------------------------------------------------------------------
# 11 - Puissance N d'un nombre, en effectuant moins de N-1 multiplications
# http://www.esiee.fr/~coupriem/Exos/Enonces/puissance
def puissance(base, expo):
if (expo < 0):
return "L'exposant doit etre positif ou nul"
tmp = 1
while (expo > 1):
tmp *= (base * base)
expo -= 2
if (expo == 1):
tmp *= base
return tmp
#------------------------------------------------------------------------------
# 12 - Calcul de la racine carree
# http://www.esiee.fr/~coupriem/Exos/Enonces/raccar
def racine_carree(nbr, precision):
# Estimation a la louche
rac = 0
while (nbr > rac ** 2):
rac += 1
if (nbr == rac ** 2):
return rac
# Affinement
for i in range(0, precision):
rac = (rac + nbr / rac) / 2.0
return rac
#------------------------------------------------------------------------------
# 13 - Calcul de la racine cubique
# http://www.esiee.fr/~coupriem/Exos/Enonces/raccube
def racine_cubique(nbr, precision):
# Estimation a la louche
rac = 0
while (nbr > rac ** 3):
rac += 1
if (nbr == rac ** 3):
return rac
# Affinement
for i in range(0, precision):
rac = (2 * rac + nbr / (rac ** 2)) / 3.0
return rac
#------------------------------------------------------------------------------
# 14 - Recherche sequentielle sur un tableau
# http://www.esiee.fr/~coupriem/Exos/Enonces/rechseq
# Meme chose que l'exercice 03
#------------------------------------------------------------------------------
# 15 - Fonction sin(x)
# http://www.esiee.fr/~coupriem/Exos/Enonces/sinus
def sinus(x, precision):
def factorielle(n):
return factorielle_iterative(n)
result = 0.0
for n in range(0, precision):
result += ((-1) ** n) * ((x ** (2 * n + 1)) / (factorielle(2 * n + 1)))
return result
#------------------------------------------------------------------------------
# 16 - Symetrie d'une matrice
# http://www.esiee.fr/~coupriem/Exos/Enonces/symetrique
def est_symetrique(matrice):
if (len(matrice) != len(matrice[0])):
return False # Une matrice doit etre carree pour etre symetrique
for i in range(0, len(matrice)):
for j in range(0, i):
if matrice[i][j] != matrice[j][i]:
return False
return True
#------------------------------------------------------------------------------
# 17 - Affichage du triangle de Pascal
# http://www.esiee.fr/~coupriem/Exos/Enonces/trpascal
def triangle_de_pascal(rangees):
print "1"
print "1 1"
prevline = [1, 1]
for i in range(3, rangees + 1):
thisline = [1]
for j in range(1, i - 1):
thisline.append(prevline[j] + prevline[j - 1])
thisline.append(1)
for j in range(0, i - 1):
print str(thisline[j]) + " ",
print str(thisline[-1])
prevline = thisline
#------------------------------------------------------------------------------
# DIFFICULTE 2
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# 18 - Determiner si deux chaines sont anagrammes
# http://www.esiee.fr/~coupriem/Exos/Enonces/anagrame
def sont_anagrammes(chaine1, chaine2):
chaine1 = chaine1.strip(" ,.;:?!'\"-_").lower()
chaine2 = chaine2.strip(" ,.;:?!'\"-_").lower()
return (list(chaine1).sort() == list(chaine2).sort())
#------------------------------------------------------------------------------
# 19 - Convolution
# http://www.esiee.fr/~coupriem/Exos/Enonces/convolution
def convolution(tabA, tabH):
# A de taille 100x100, H de taille 7x7
tabB = [[0] * 100] * 100
for i in range(0, 100):
for j in range(0, 100):
if ((i in range(0, 3) or i in range(97, 100)) or \
(j in range(0, 3) or j in range(97, 100))):
tabB[i][j] = tabA[i][j]
else: # i,j in (4, 97)
for m in range(0, 7):
for n in range(0, 7):
tabB[i][j] += tabA[i + m - 3][j + n - 3] * tabH[m][n]
return tabB
#------------------------------------------------------------------------------
# 20 - Fusion de deux tableaux tries
# http://www.esiee.fr/~coupriem/Exos/Enonces/fusion
def fusion_tableaux_tries(tab1, tab2):
cur1 = 0
cur2 = 0
tab3 = []
while (cur1 < len(tab1)) and (cur2 < len(tab1)):
if tab1[cur1] < tab2[cur2]:
tab3.append(tab1[cur1])
cur1 += 1
else:
tab3.append(tab2[cur2])
cur2 +=1
# Un des deux tableaux a ete entierement copie, reste a vider l'autre
while (cur1 < len(tab1)):
tab3.append(tab1[cur1])
cur1 += 1
while (cur2 < len(tab2)):
tab3.append(tab2[cur2])
cur2 += 1
return tab3
#------------------------------------------------------------------------------
# 21 - Conjecture Hongroise (note: on l'appelle aussi "probleme de Collatz")
# http://www.esiee.fr/~coupriem/Exos/Enonces/hongrois
def hongroise(depart):
if (depart == 1):
print "1 4 2 1 4 2 ..."
else:
print str(depart),
if (depart % 2 == 0):
hongroise(depart / 2)
else:
hongroise(3 * depart + 1)
#------------------------------------------------------------------------------
# 22 - Regroupement des valeurs paires et impaires
# http://www.esiee.fr/~coupriem/Exos/Enonces/pairimpair
def paires_impaires(tab):
res = []
for i in range(0, len(tab)):
if (tab[i] % 2 == 0):
res.append(tab[i])
for i in range(0, len(tab)):
if (tab[i] % 2 != 0):
res.append(tab[i])
return res
#------------------------------------------------------------------------------
# 23 - Afficher les nombres parfaits compris entre 1 et N
# http://www.esiee.fr/~coupriem/Exos/Enonces/parfaits
def nombres_parfaits(limite):
res = []
for nb in range(1, limite + 1):
sommediv = 0
for di in range(1, nb / 2 + 1):
if (nb % di == 0):
sommediv += di
if (sommediv == nb):
res.append(nb)
return res
#------------------------------------------------------------------------------
# 24 - Determiner la periode d'un signal digital
# http://www.esiee.fr/~coupriem/Exos/Enonces/periode
def periode_signal(tab):
per = 0
fini = False
while (not fini) and (per < len(tab) - 1):
per +=1
# Verification de cette hypothese
for cur in range(0, per):
fini = (tab[cur] == tab[cur + per])
if (fini):
return per
else:
return 0
#------------------------------------------------------------------------------
# 25 - Plus grand plateau dans le graphique d'une fonction monotone
# http://www.esiee.fr/~coupriem/Exos/Enonces/plateau
def plus_grand_plateau(tab):
plat_max = 1
plat_tmp = 0
for i in range(1, len(tab)):
if tab[i] == tab[i - 1]:
plat_tmp += 1
else:
plat_tmp = 1
if plat_tmp > plat_max:
plat_max = plat_tmp
return plat_max
#------------------------------------------------------------------------------
# 26 - Calcul de la racine carree entiere d'un entier
# http://www.esiee.fr/~coupriem/Exos/Enonces/racent
def racine_carree_entiere(nbr):
rac = 0
while (nbr > rac ** 2):
rac += 1
if (nbr == rac ** 2):
return rac
else:
return rac - 1
#------------------------------------------------------------------------------
# 27 - Conversion Romain-arabe
# http://www.esiee.fr/~coupriem/Exos/Enonces/romains
def romain_vers_arabe(romannumber):
romandigits = { 'I': 1, 'V': 5, 'X': 10, 'L': 50 }
number = 0
for i in range(1, len(romannumber)):
if (romandigits[romannumber[i]] > romandigits[romannumber[i - 1]]):
number -= romandigits[romannumber[i - 1]]
else:
number += romandigits[romannumber[i - 1]]
number += romandigits[romannumber[-1]]
return digit
#------------------------------------------------------------------------------
# 28 - Transcodage octal-decimal
# http://www.esiee.fr/~coupriem/Exos/Enonces/transcodage
def octal_vers_decimal(octnum):
number = 0
octalnumber = str(octnum)
for i in range(0, len(octalnumber)):
number += int(octalnumber[i]) * (8 ** (len(octalnumber) - i - 1))
return number