Merge branch 'master' of https://codefirst.iut.uca.fr/git/nathan.boileau/Scripted
commit
b14c97deaf
@ -0,0 +1,154 @@
|
|||||||
|
# file cryptarithme.py
|
||||||
|
# brief solution générique des cryptarithme
|
||||||
|
# author Johan Lachenal
|
||||||
|
# date 17 Octobre 2022
|
||||||
|
# ce fichier contient l'algorithme générique résolvant les cryptarithmes, plus tard il contiendra un générateur aléatoire de cryptarithme
|
||||||
|
|
||||||
|
# Pour que le résolveur d'énigmes de cryptarithme fonctionne, il est nécessaire d'effectuer la commande :
|
||||||
|
# pip install cpmpy
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
import re
|
||||||
|
import itertools
|
||||||
|
from cpmpy import *
|
||||||
|
|
||||||
|
# brief résout un cryptarithme donné et affiche le résultat
|
||||||
|
# param ListeMots liste des mots du cryptarithme entré
|
||||||
|
# param ListeOperateurs liste des opérateurs du cryptarithme entré
|
||||||
|
# param ListeLettres liste des lettres associés à des variables du cryptarithme
|
||||||
|
# param ListePosition liste temporaire servant à prendre les positions des variables dans la liste ListeLettres pour un mot que l'on remet ensuite a null
|
||||||
|
# param ListePostion liste de liste de positions des variables dans la liste ListeLettres
|
||||||
|
# param exposant10 liste temporaire servant à prendre les exposants pour chacune des lettres d'un mot
|
||||||
|
# param exposants10 liste de liste d'exposant pour chque mot
|
||||||
|
# param ConstraintAssemblingList liste des operations entre les variables d'un mot
|
||||||
|
# param equalposition postion du egal dans la liste des opérateurs
|
||||||
|
# param BigFirstEquationConstraintPart partie de contrainte avant le egal
|
||||||
|
# param BigSecondEquationConstraintPart partie de contrainte après le egal
|
||||||
|
# param model, model auquel on ajoute les contraintes
|
||||||
|
|
||||||
|
def cryptarithmeGenerique (s):
|
||||||
|
|
||||||
|
ListeMots=[]
|
||||||
|
ListeOperateurs=[]
|
||||||
|
ListeLettres=[]
|
||||||
|
ListePosition=[]
|
||||||
|
ListePositions=[]
|
||||||
|
exposant10=[]
|
||||||
|
exposants10=[]
|
||||||
|
ConstraintAssemblingList=[]
|
||||||
|
BigFirstEquationConstraintPart=[]
|
||||||
|
equalposition=0
|
||||||
|
# attrape la liste de lettres
|
||||||
|
|
||||||
|
lettres = "".join(set(re.findall("[A-Z]", s)))
|
||||||
|
|
||||||
|
# attrape la liste de mots
|
||||||
|
|
||||||
|
mots = s.split()
|
||||||
|
if(mots[0]=='-'):
|
||||||
|
print("pas de - comme opérateur devant la chaîne de caractère")
|
||||||
|
return
|
||||||
|
for i in range(0,len(mots),2):
|
||||||
|
ListeMots.append(mots[i])
|
||||||
|
# print(ListeMots)
|
||||||
|
|
||||||
|
# attrape la liste d'opérateurs
|
||||||
|
for i in range(1,len(mots),2):
|
||||||
|
ListeOperateurs.append(mots[i])
|
||||||
|
# print(ListeOperateurs)
|
||||||
|
|
||||||
|
# associe à une lettre ses possibilités
|
||||||
|
|
||||||
|
for i in range(0,len(lettres)):
|
||||||
|
ListeLettres.append([lettres[i],intvar(0,9, shape=1)])
|
||||||
|
# print(ListeLettres)
|
||||||
|
|
||||||
|
# associe pour chaque mot une liste des positions des variables contenu dans ListeLettres
|
||||||
|
|
||||||
|
for i in ListeMots:
|
||||||
|
# print(i)
|
||||||
|
for y in i:
|
||||||
|
# print(y)
|
||||||
|
for w in range(0,len(ListeLettres)):
|
||||||
|
# print(w)
|
||||||
|
# print(ListeLettres[w][0])
|
||||||
|
if(y==ListeLettres[w][0]):
|
||||||
|
ListePosition.append(w)
|
||||||
|
break
|
||||||
|
ListePositions.append(ListePosition)
|
||||||
|
ListePosition=[]
|
||||||
|
# print(ListePositions)
|
||||||
|
|
||||||
|
# associe pour chaque mot une liste d'exposant
|
||||||
|
|
||||||
|
for y in ListeMots:
|
||||||
|
for i in range(0,len(y)):
|
||||||
|
exposant10.append(10**i)
|
||||||
|
exposants10.append(exposant10)
|
||||||
|
exposant10=[]
|
||||||
|
# print(exposants10)
|
||||||
|
|
||||||
|
# creation des parties de la contrainte globale du cryptarithme
|
||||||
|
|
||||||
|
for i in range(0,len(ListeMots)):
|
||||||
|
ConstraintAssemblingList.append(sum([ListeLettres[ListePositions[i][y]][1]*10**(len(ListeMots[i])-y) for y in range(0,len(ListeMots[i]))]))
|
||||||
|
# print(ConstraintAssemblingList)
|
||||||
|
|
||||||
|
# assemblage des parties de la contrainte globale du cryptarithme avant le =
|
||||||
|
|
||||||
|
for i in range(0,len(ListeOperateurs)):
|
||||||
|
if(ListeOperateurs[i]=='+'):
|
||||||
|
BigFirstEquationConstraintPart.append(ConstraintAssemblingList[i]+ConstraintAssemblingList[i+1])
|
||||||
|
if(ListeOperateurs[i]=='-'):
|
||||||
|
BigFirstEquationConstraintPart.append(ConstraintAssemblingList[i]-ConstraintAssemblingList[i+1])
|
||||||
|
if(ListeOperateurs[i]=='*'):
|
||||||
|
BigFirstEquationConstraintPart.append(ConstraintAssemblingList[i]*ConstraintAssemblingList[i+1])
|
||||||
|
if(ListeOperateurs[i]=='/'):
|
||||||
|
BigFirstEquationConstraintPart.append(ConstraintAssemblingList[i]/ConstraintAssemblingList[i+1])
|
||||||
|
if(ListeOperateurs[i]=='='):
|
||||||
|
equalposition=i
|
||||||
|
break
|
||||||
|
# print(BigFirstEquationConstraintPart[0])
|
||||||
|
|
||||||
|
# assemblage des parties de la contrainte globale du cryptarithme après le =
|
||||||
|
|
||||||
|
BigSecondEquationConstraintPart=ConstraintAssemblingList[equalposition+1]
|
||||||
|
for i in range(equalposition,len(ListeOperateurs)):
|
||||||
|
if(ListeOperateurs[i]=='+'):
|
||||||
|
BigSecondEquationConstraintPart.append(ConstraintAssemblingList[i]+ConstraintAssemblingList[i+1])
|
||||||
|
if(ListeOperateurs[i]=='-'):
|
||||||
|
BigSecondEquationConstraintPart.append(ConstraintAssemblingList[i]-ConstraintAssemblingList[i+1])
|
||||||
|
if(ListeOperateurs[i]=='*'):
|
||||||
|
BigSecondEquationConstraintPart.append(ConstraintAssemblingList[i]*ConstraintAssemblingList[i+1])
|
||||||
|
if(ListeOperateurs[i]=='/'):
|
||||||
|
BigSecondEquationConstraintPart.append(ConstraintAssemblingList[i]/ConstraintAssemblingList[i+1])
|
||||||
|
# print(BigSecondEquationConstraintPart)
|
||||||
|
|
||||||
|
# Création du model et de ses contraintes
|
||||||
|
|
||||||
|
model = Model()
|
||||||
|
|
||||||
|
# Mise en place de la contrainte globale
|
||||||
|
|
||||||
|
model += (BigFirstEquationConstraintPart[0] == BigSecondEquationConstraintPart)
|
||||||
|
|
||||||
|
# Mise en place de la contrainte où toutes les lettres sont différentes
|
||||||
|
|
||||||
|
model += AllDifferent(ListeLettres[i][1] for i in range(0,len(ListeLettres)))
|
||||||
|
|
||||||
|
# Mise en place de la contrainte disant que les premières lettres des mots sont différentes de 0
|
||||||
|
|
||||||
|
for i in range(0,len(ListeMots)):
|
||||||
|
model += (ListeLettres[ListePositions[i][0]][1]) > 0
|
||||||
|
|
||||||
|
|
||||||
|
if model.solve():
|
||||||
|
print(s)
|
||||||
|
for i in range(0,len(ListeMots)):
|
||||||
|
print(ListeMots[i]," =",[x.value() for x in [ListeLettres[ListePositions[i][y]][1] for y in range(0,len(ListeMots[i]))]])
|
||||||
|
else:
|
||||||
|
print("No solution found")
|
||||||
|
|
||||||
|
cryptarithmeGenerique("SEND + MORE = MONEY");
|
||||||
|
cryptarithmeGenerique("HUIT + HUIT = SEIZE");
|
||||||
|
# cryptarithmeGenerique("UN + UN + NEUF = ONZE");
|
Loading…
Reference in new issue