2.5 Problème de mots
Combien de mots de lettres formé à partir de l’alphabet contiennent la séquence ? Pour résoudre se problème, remarquons premièrement que contrairement aux problèmes précédents, nous ne cherchons pas à exclure une séquence des mots acceptable, mais plutôt à compter uniquement ceux qui la contiennent. Une première approche consisterait à travailler avec le complément, ce qui peut être accompli de manière très similaire à ce que nous avons fait dans le problème des chaînes ternaires. Nous allons cependant prendre une approche différente et chercher plutôt à les compter directement. L’idée est à nouveau de travailler avec un automate, mais cette fois en considérant un point de départ bien déterminé, et un point d’arriver correspondant aux mots qui contiennent la séquence.
L’idée est de lire un mot lettre par lettre, de gauche à droite, en commençant à notre état initiale que nous avons dénoté dans l’automate. Après avoir lu chaque lettre, on se déplace dans l’automate vers l’état correspondant à lettre que nous avons lu. Lorsque l’on rencontre un , on se déplace vers l’état suivant (dénoté ), si la lettre suivante est aussi un , on continue vers le troisième état (dénoté ), et de même, si la lettre suivante est un , on se déplace vers le dernier état (dénoté ). Lorsque nous avons atteint l’état , cela signifie que notre mot contient la séquence . De plus, lorsque nous sommes aux états ou et que la lettre lu ne correspond pas à ce que nous avons besoin pour former la séquence , alors on revient à notre état initiale. Si on dénote par et les suites correspondant à chacun des états, alors on obtient le système d’équations définies par récurrence suivant:
De plus, comme au départ, avant de commencer la lecture, nous sommes à l’état , on définit les valeurs initiales comme étant . Comme nous sommes intéressé par les mots de lettres qui contiennent la séquence , nous cherchons à trouver le nombre de mots qui seront à l’état après étapes, c’est à dire on cherche la valeur de . On peut alors utiliser le code Python suivant:
1 from sympy import *2 from pandas import *3 init_printing()45 def x(n):6 if n == 0:7 return 18 else:9 return 3*x(n-1) + 3*y(n-1) + 2*z(n-1)1011 def y(n):12 if n == 0:13 return 014 else:15 return x(n-1)1617 def z(n):18 if n == 0:19 return 020 else:21 return y(n-1) + z(n-1)2223 def w(n):24 if n == 0:25 return 026 else:27 return z(n-1) + 4*w(n-1)2829 DataFrame({30 "x_n": [x(n) for n in range(0,11)],31 "y_n": [y(n) for n in range(0,11)],32 "z_n": [z(n) for n in range(0,11)],33 "w_n": [w(n) for n in range(0,11)]34 })
Ce qui nous permet d’obtenir facilement le tableau suivant:
| 0 | 1 | 0 | 0 | 0 |
| 1 | 3 | 1 | 0 | 0 |
| 2 | 12 | 3 | 1 | 0 |
| 3 | 47 | 12 | 4 | 1 |
| 4 | 185 | 47 | 16 | 8 |
| 5 | 728 | 185 | 63 | 48 |
| 6 | 2865 | 728 | 248 | 255 |
| 7 | 11275 | 2865 | 976 | 1268 |
| 8 | 44372 | 11275 | 3841 | 6048 |
| 9 | 174623 | 44372 | 15116 | 28033 |
| 10 | 687217 | 174623 | 59488 | 127248 |
Il y a donc mots de lettres qui contiennent la séquence .
Il est aussi possible d’utiliser la même approche que pour les problèmes de chaînes binaires et ternaires, mais dans ce cas, les choses se compliquent un peu. En effet, les automates que nous avons utilisés pour résoudre ces problèmes nous permettent de compter le nombre de chaînes ou de mots qui excluent une certaine séquence. On peut donc travailler avec le complément. Il nous est cependant nécessaire de créer deux états distincts pour les . Un premier pour les mots de lettres se terminant par un seul , et un autre pour les mots de lettres se terminant par au moins deux (Que nous dénotons par ).
En dénotant par la suite des mots qui se termine par , on obtient donc le système de récurrences suivant:
avec les valeurs initiales et .
Ce qui peut être facilement implémenté dans Python. Il faut cependant faire attention, car, comme nous l’avons mentionné plus tôt, notre automate travaille avec le complément. Comme il y a mots de lettres au total, le nombre de mots de lettre qui contiennent la séquence est donc:
1 from sympy import *2 from pandas import *3 init_printing()45 def a(n):6 if n == 1:7 return 18 else:9 return b(n-1) + c(n-1) + d(n-1)1011 def b(n):12 if n == 1:13 return 114 else:15 return a(n-1) + b(n-1) + c(n-1) + d(n-1)1617 def c(n):18 if n == 1:19 return 120 else:21 return a(n-1) + b(n-1) + c(n-1) + d(n-1) + e(n-1)2223 def d(n):24 if n == 1:25 return 126 else:27 return a(n-1) + b(n-1) + c(n-1) + d(n-1) + e(n-1)2829 def e(n):30 if n == 1:31 return 032 else:33 return a(n-1) + e(n-1)3435 def total(n):36 return 4**n3738 def sansAAB(n):39 return a(n) + b(n) + c(n) + d(n) + e(n)4041 def avecAAB(n):42 return total(n) - sansAAB(n)4344 tableau = DataFrame({45 "Tout": [total(n) for n in range(1,11)],46 "Sans AAB": [sansAAB(n) for n in range(1,11)],47 "Avec AAB": [avecAAB(n) for n in range(1,11)]48 })49 tableau.index = [n for n in range(1,11)]50 tableau
Ce qui nous permet d’obtenir le tableau suivant:
| Tout | Sans AAB | Avec AAB | |
| 1 | 4 | 4 | 0 |
| 2 | 16 | 16 | 0 |
| 3 | 64 | 63 | 1 |
| 4 | 256 | 248 | 8 |
| 5 | 1024 | 976 | 48 |
| 6 | 4096 | 3841 | 255 |
| 7 | 16384 | 15116 | 1268 |
| 8 | 65536 | 59488 | 6048 |
| 9 | 262144 | 234111 | 28033 |
| 10 | 1048576 | 921328 | 127248 |
Comme pour notre première approche, nous obtenons à nouveau qu’il y a mots de lettres qui contiennent la séquence .