1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# getestet mit Python 2.7.8 und 3.4.2
'''Generiert oder löst Alphametiken'''
# Nicht als root ausführen.
# Die Ausführung dauert bis zu zwei Minuten, abhängig von der Länge des
# Alphametiks. Die Generierung dauert unter Umständen 5 Minuten oder länger.
# Programm löst das Alphametik "SUCHEN-MACHT=SPASS"
# und generiert eines mit einem Rechenzeichen
import re, random
ALPHAMETIK = "SUCHEN-MACHT=SPASS"
ZAHLEN = ["EINS", "ZWEI", "DREI", "VIER", "FÜNF", \
"SECHS", "SIEBEN", "ACHT", "NEUN", "ZEHN"]
#RECHENZEICHEN = ["+", "-", "*", "/"]
RECHENZEICHEN = ["+", "-"] # schneller
def buchstaben_liste(wort):
'''Erstellt eine Liste der Buchstaben'''
buchstaben = []
for char in wort:
if (char not in RECHENZEICHEN) \
and (char not in buchstaben) \
and (char not in " ="):
buchstaben.append(char)
return buchstaben
def ersetze(buchst, wort, \
benutzte_zahlen=None, loesungen=None, alle_buchstaben=None):
'''Ersetzt einen Buchstaben aus `buchst` in einem Wort `wort` \
nacheinander durch `0-9` und ruft sich selbst auf. \
Ist `buchst` leer, wird das Alphametik auf Richtigkeit getestet
und ggf. zu `loesungen` hinzugefügt. \
Zurückgegeben wird eine Liste mit Lösungen. \
Element der Liste ist der Rechnungsstring und ein dict.'''
if alle_buchstaben == None:
alle_buchstaben = buchst
if benutzte_zahlen == None:
benutzte_zahlen = []
if loesungen == None:
loesungen = []
if len(buchst):
for j in range(10):
if j in benutzte_zahlen: # jede Zahl nur einmal verwenden
continue
m_benutzte_zahlen = benutzte_zahlen[:]
m_benutzte_zahlen.append(j)
m_wort = wort.replace(buchst[0], str(j))
ersetze(buchst[1:], m_wort, m_benutzte_zahlen, \
loesungen, alle_buchstaben)
else:
if re.search(r"\b0", wort):
# 0 als erste Ziffer in einer Zahl ist nicht erlaubt
return
if eval(wort.replace("=", "==")):
lsg = [wort, dict()]
for j, k in zip(alle_buchstaben, benutzte_zahlen):
lsg[1][j] = k
loesungen.append(lsg)
return loesungen
def loese(alpham):
'''kleiner Wrapper, der die Benutzung von `ersetze` vereinfacht'''
return ersetze(buchstaben_liste(alpham), alpham, None, None, None)
def generiere(laenge=1):
'''gibt ein zufälliges Alphametik mit `laenge` \
"Ziffern" vor dem Gleichheitszeichen zurück'''
while True:
rechnung_ok = False
while rechnung_ok == False: # sucht nach wahren Gleichungen
alphametik = "x" + "_x" * laenge + "=y" # Template für Rechnung
for j in range(laenge + 1): # zufällige Rechenzeichen einsetzen
alphametik = alphametik.replace("_", \
random.choice(RECHENZEICHEN), 1)
alphametik = alphametik.replace("y", str(random.randrange(1, 9)))
# Ergebnis
for j in range(laenge + 2):
alphametik = alphametik.replace("x", \
str(random.randrange(1, 9)), 1)
rechnung_ok = eval(alphametik.replace("=", "=="))
# jetzt passende Alphametiken suchen oder weitersuchen
for j in range(1, 10):
alphametik = alphametik.replace(str(j), ZAHLEN[j - 1])
loe = loese(alphametik)
if len(loe) > 0:
return alphametik # Geschafft, wir haben eines gefunden!
if __name__ == "__main__":
LOESUNG = loese(ALPHAMETIK)
if len(LOESUNG) == 0:
print("Keine Lösungen vorhanden")
else:
print("Es konnten folgende Lösungen gefunden werden:")
print(LOESUNG)
print(generiere())
|