L'idée est la suivante:
Je pars de a
Pour chaque lettre à ajouter, j'ai le choix entre a, b et c.
Je commence par éliminer la dernière lettre ajoutée.
J'essaye ensuite avec la 1ere des 2 qui restent et je regarde si ça passe. Si oui, j'ajoute la lettre; sinon j'essaye avec la suivante. Si ca ne passe pas non plus, je change la dernière lettre du mot par une autre (c'est à dire celle qui n'est ni la dernière ni l'avant dernière)
Exemple:
a => ab => aba
=> abab pas bon, abac ok => abaca => abacab
=> abacaba => abacabab pas bon, abacabac non plus, je change la dernière lettre par c (ni a la dernière, ni b l'avant dernière) => abacabc
=> abacabca
etc...
Ca c'est pour l'idée, l'implémentation est un poil plus tordue:
Stockage en mémoire: un tableau de groupes de 4 bits notés ABCD
AB peut valoir 00 (lettre a), 01 (lettre b), 10 (lettre c) et 11 (lettre non calculée encore).
CD peut valoir 00 (cette lettre apparaît pour première fois), 01 (cette lettre apparaît avant-dernière position, soit 2 lettres avant celle-ci), 10 (3 lettres avant) ou 11 (4 lettres avant)
Du coup, pour voir si une lettre passe, il faut regarder si le mot de k lettres à partir de la fin se répète juste avant la k-ième lettre avant la fin; et ce pour tout k. Comme un tel mot doit forcément finir par la même lettre que celle que je viens d'écrire, je peux remonter rapidement à toutes les instances de cette lettre pour gagner du temps. Je m'arrête quand je suis à plus de la moitié du tableau parcourue.
Bien sûr, il y a en plus de ça 3 petites variables qui indiquent à combien de lettres se truve le dernier a, b ou c; à chaque tour on en incrémente 2 et on réinitialise la 3ème.
voilà voilà