#!/usr/bin/env python3 # Nicht als root ausführen. # Die Ausführung dauert bis zu zwei Minuten, abhängig von der Länge des Alphametiks. # Die Generierung dauert 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"] # Liste der Buchstaben erstellen aus `wort` def buchstaben_liste(wort): buchstaben = [] for c in wort: if (c not in "+-*/= ") and (c not in buchstaben): buchstaben.append(c) return buchstaben # Ersetzt einen Buchstaben aus `b` in einem Wort `wort` nacheinander durch `0-9` # und ruft sich selbst auf. Ist `b` leer, wird das Alphametik auf Richtigkeit getestet # und ggf. zu `lösungen` hinzugefügt. # Zurückgegeben wird eine Liste mit Lösungen, Element der Liste ist der Rechnungsstring und ein dict def ersetze(b, wort, benutzte_zahlen = [], lösungen = [], alle_buchstaben = None): if alle_buchstaben == None: alle_buchstaben = b if len(b): 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(b[0], str(j)) ersetze(b[1:], m_wort, m_benutzte_zahlen, lösungen, 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 lösungen.append(lsg) return lösungen # gibt ein zufälliges Alphametik mit `länge` "Ziffern" vor dem Gleichheitszeichen zurück def generiere(länge = 1): while True: rechnung_ok = False while rechnung_ok == False: # sucht nach wahren Gleichungen alphametik = "x" + "_x" * länge + "=y" # Template für Rechnung for j in range(länge + 1): # zufällige Rechenzeichen einsetzen alphametik = alphametik.replace("_", random.choice(["+", "-", "*", "/"]), 1) alphametik = alphametik.replace("y", str(random.randrange(1, 9))) # Ergebnis for j in range(länge + 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]) l = ersetze(buchstaben_liste(alphametik), alphametik) if len(l) > 0: return alphametik # Geschafft, wir haben eines gefunden! if __name__ == "__main__": l = ersetze(buchstaben_liste(Alphametik), Alphametik) if len(l) == 0: print("Keine Lösungen vorhanden") else: print("Es konnten folgende Lösungen gefunden werden:") print(l) print(generiere())