summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/alphametiken.py116
-rwxr-xr-xsrc/buffet_lotterie.py46
-rwxr-xr-xsrc/faehre_fuellen.py100
-rwxr-xr-xsrc/mobile.py76
-rw-r--r--src/pong.py79
-rwxr-xr-xsrc/zahlenspiel.py52
6 files changed, 469 insertions, 0 deletions
diff --git a/src/alphametiken.py b/src/alphametiken.py
new file mode 100755
index 0000000..fb4324c
--- /dev/null
+++ b/src/alphametiken.py
@@ -0,0 +1,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())
diff --git a/src/buffet_lotterie.py b/src/buffet_lotterie.py
new file mode 100755
index 0000000..82a7796
--- /dev/null
+++ b/src/buffet_lotterie.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+# getestet mit Python 2.7.8 und 3.4.2
+'''Findet die optimale Lösung für die Buffet-Lotterie'''
+
+from math import floor
+
+ANZAHL_TEILNEHMER = 6
+SILBEN = ['In', 'for', 'ma', 'tik', 'kann', 'uns', 'wei', 'sen', 'wer', 'als', \
+ 'Nächs', 'ter', 'kommt', 'zum', 'Spei', 'sen']
+
+def denke(anzahl_teilnehmer, silben):
+ '''Findet die optimale Lösung für die Buffet-Lotterie'''
+ teilnehmer = anzahl_teilnehmer
+ fehlt_noch = float("inf")
+ einfluss = 0
+ offset = 0
+ while fehlt_noch > 0:
+ runden = floor((len(silben) + offset) / teilnehmer)
+ # runden Runden ist das Geburtstagskind dran, bis einer gehen darf
+
+ offset = ((len(silben) + offset - 1) % teilnehmer) % (teilnehmer - 1)
+ # nach runden Runden fängt Teilnehmer Nummer `offset` an,
+ # 0 ist das Geburtstagskind
+
+ einfluss += runden
+ # Geburtstagskind kann insgesamt `runden`-mal dem Essen näher kommen
+ fehlt_noch = (offset - 1) % (teilnehmer - 1) + 1
+ # um jetzt dran sein zu müssen, hätte das Geburtstagskind
+ # `fehlt_noch`-mal zwei SILBEN sagen müssen
+
+ print("Nach " + str(runden) + " Runden fängt der " + str(offset + 1) + \
+ ". an. Es sind dann noch " + str(teilnehmer - 1) + \
+ " Teilnehmer im Spiel.")
+ if runden > 0: # falls das Geburtstagskind dran kam
+ print("Es fehlten " + str(fehlt_noch) + " bis zum Geburtstagskind")
+ if fehlt_noch < einfluss:
+ print("Das Geburtstagskind muss erst " + str(fehlt_noch) + \
+ "-mal 'zwei Silben' und dann nur noch 'eine Silbe'" + \
+ "sagen, bis es dran ist.")
+ break
+
+ teilnehmer -= 1 # einer geht
+
+if __name__ == "__main__":
+ denke(ANZAHL_TEILNEHMER, SILBEN)
diff --git a/src/faehre_fuellen.py b/src/faehre_fuellen.py
new file mode 100755
index 0000000..2c84b5d
--- /dev/null
+++ b/src/faehre_fuellen.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+# getestet mit Python 2.7.8 und 3.4.2
+'''Stellt zwei Strategien zur Lösung der Fähre-Füllen-Aufgabe'''
+
+BEISPIEL = []
+BEISPIEL.append(
+ "5,23; 4,41; 3,33; 13,13; 9,12; 4,38; 6,34; 5,37; 4,11; 3,74; 10,62")
+BEISPIEL.append(
+ "4,14; 3,63; 3,92; 7,95; 5,23; 3,30; 4,86; 15,06")
+BEISPIEL.append("6,96; 5,06; 3,77; 3,95; 3,91; 3,54; 4,26; " + \
+ "4,03; 5,43; 4,04; 4,43; 4,12; 2,78")
+
+
+# das BEISPIEL wird geparst
+for j in range(len(BEISPIEL)):
+ BEISPIEL[j] = [float(k.replace(",", ".")) for k in BEISPIEL[j].split("; ")]
+
+# vorgegebene Konstanten in Meter umgerechnet
+FAEHRENLAENGE = 20
+FAEHRENBREITE = 3
+ABSTAND = 0.3
+
+# `abfolge`: Eine Liste mit Längen von Autos
+# gibt ein dict zurück, welches "anzahl" und "länge" aller Autos enthält
+def strategie_a(vabfolge):
+ '''Sortiert eine Abfolge von Fahrzeugen möglichst weit links ein'''
+ abfolge = vabfolge[:]
+ # `faehre` hält die Anzahl an Fahrzeugen und deren Gesamtlänge in einem dict
+ faehre = {"anzahl": [0] * FAEHRENBREITE, "länge": [0] * FAEHRENBREITE}
+
+ while len(abfolge):
+ success = False
+ # Fahrzeuge werden aus der Schlange gepopt
+ fahrzeug = abfolge.pop()
+
+ # jetzt wird das Fahrzeug möglichst weit links eingeordnet
+ for k in range(FAEHRENBREITE):
+ # dazu wird bei allen Parkreihen überprüft, ob das Fahrzeug passt
+ if fahrzeug + faehre["länge"][k] < \
+ FAEHRENLAENGE - ABSTAND * (faehre["anzahl"][k] - 1):
+
+ faehre["länge"][k] += fahrzeug
+ faehre["anzahl"][k] += 1
+
+ print(str(fahrzeug) + " wurde eingeordnet in die Reihe " + \
+ str(k))
+ success = True
+ break
+
+ if success == False:
+ print("Das Fahrzeug " + str(fahrzeug) + " hat nicht mehr gepasst")
+ # ...und abfahren
+ break
+
+ # Wichtig: in `faehre["länge"][x]` ist der ABSTAND nicht einberechnet
+ return faehre
+
+# siehe `strategie_a`
+def strategie_b(vabfolge):
+ '''Sortiert eine Abfolge von Fahrzeugen möglichst gleichmäßig ein'''
+ abfolge = vabfolge[:]
+ faehre = {"anzahl": [0] * FAEHRENBREITE, "länge": [0] * FAEHRENBREITE}
+
+ spalte = 0
+ while len(abfolge):
+ success = False
+ fahrzeug = abfolge.pop()
+ # Fahrzeuge werden möglichst gleichmäßig von links nach rechts verteilt
+ for k in range(FAEHRENBREITE):
+ diese_spalte = spalte + k
+ if diese_spalte >= FAEHRENBREITE:
+ diese_spalte -= FAEHRENBREITE
+
+ if fahrzeug + faehre["länge"][diese_spalte] < FAEHRENLAENGE \
+ - ABSTAND * (faehre["anzahl"][diese_spalte] - 1):
+
+ faehre["länge"][diese_spalte] += fahrzeug
+ faehre["anzahl"][diese_spalte] += 1
+
+ print(str(fahrzeug) + " wurde eingeordnet in Reihe " + \
+ str(diese_spalte))
+ success = True
+ break
+
+ if success == False:
+ print("Das Fahrzeug " + str(fahrzeug) + " hat nicht mehr gepasst")
+ break
+
+ spalte += 1
+ if spalte == FAEHRENBREITE:
+ spalte = 0
+
+ return faehre
+
+if __name__ == "__main__":
+ print("\n=== Strategie A ===\n")
+ print(strategie_a(BEISPIEL[0][:]))
+ print("\n=== Strategie B ===\n")
+ print(strategie_b(BEISPIEL[0][:]))
diff --git a/src/mobile.py b/src/mobile.py
new file mode 100755
index 0000000..481325c
--- /dev/null
+++ b/src/mobile.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+# getestet mit Python 2.7.8 und 3.4.2
+'''Verteilt und gleicht ein Mobile aus'''
+
+from math import floor
+
+# python list mit Elementen in der Form
+# (Position, [Gewicht oder Liste]),
+# wobei Position auf der linken Seite negativ ist
+MOBILE = [(-4, [(-2, [(0, 1)]), (1, [(0, 2)])]), \
+ (-1, [(0, 2)]), (2, [(0, 3)]), (4, [(0, 2)])]
+
+FIGUREN = [2, 3, 1, 2, 3]
+
+def split(fig):
+ '''gibt eine Liste zurück, in der die Elemente
+aus `fig` auf 4er-Balken aufgeteilt sind'''
+ _fig = fig[:]
+ if len(_fig) > 4:
+ temp = [[] for j in range(4)]
+ for k, item in enumerate(_fig):
+ temp[k % 4].append(item)
+
+ _fig = list(filter(None, temp))
+
+ temp = []
+ for afig in _fig:
+ summe = 0
+ for (_, k) in afig:
+ summe += k
+
+ myweight = summe
+ # Gewicht Inhalt
+ temp.append((myweight, split(afig)))
+
+ _fig = temp
+ return _fig
+
+def weight(fig):
+ '''gibt ein ausgeglichenes Mobile zurück'''
+ res = []
+
+ if len(fig) % 2 == 1:
+ # ist die Anzahl an Elementen ungerade,
+ # muss eines - hier das mittlerste - auf die Position 0
+ middle = int(floor(len(fig) / 2))
+ res.append((0, fig[middle][1]))
+ del fig[middle]
+
+ for j in range(len(fig)):
+ # Die Position des Elements wird auf das Gewicht des
+ # gegenüberliegenden Elements gesetzt, sodass sich
+ # jeweils das Element mit dem Gegenüber ausgleicht
+ side = -1 if j < len(fig) / 2 else 1
+ opposite = len(fig) - j - 1
+
+ figure = list(fig[j])
+ if type(figure[1]) is list:
+ figure[1] = weight(figure[1])
+
+ # Position Inhalt
+ element = (fig[opposite][0] * side, figure[1])
+ res.append(element)
+
+ return res
+
+def mobile(liste):
+ '''erstellt ein Mobile aus einer Liste von Figuren'''
+ inp = list([(j, j) for j in liste]) # der Input wird aufbereitet
+ splitted = split(inp)
+ weighted = weight(splitted)
+ return weighted
+
+if __name__ == "__main__":
+ print(mobile(FIGUREN))
diff --git a/src/pong.py b/src/pong.py
new file mode 100644
index 0000000..574253a
--- /dev/null
+++ b/src/pong.py
@@ -0,0 +1,79 @@
+# zustand.Ball
+# Ball.xKoordinate()
+# Ball.yKoordinate()
+#
+# zustand.listeBall()
+# zustand.Schlaeger
+# Schlaeger.identifikation()
+# Schlaeger.yKoordinate()
+# Schlaeger.punktzahl()
+# zustand.listeSchlaeger()
+#
+# zug.ausgabe(text)
+# zug.nachOben()
+# zug.nachUnten()
+
+import math
+
+def zug(id, zustand, zug):
+ if not "round" in globals():
+ # in der ersten Runde nur initialisieren
+ globals()["t_ballX"] = globals()["letztes_ballX"] = getBall(zustand).xKoordinate()
+ globals()["t_ballY"] = globals()["letztes_ballY"] = getBall(zustand).yKoordinate()
+ globals()["deltaX"] = globals()["deltaY"] = globals()["round"] = globals()["count"] = 0
+ return
+
+ globals()["round"] += 1
+
+# zug.ausgabe("Runde " + str(globals()["round"]))
+
+ globals()["t_ballX"] = getBall(zustand).xKoordinate()
+ globals()["t_ballY"] = getBall(zustand).yKoordinate()
+
+ if (globals()["t_ballX"] < 15 and globals()["deltaX"] <= 0) or (globals()["t_ballX"] > 50 and globals()["deltaX"] >= 0) \
+ or (globals()["t_ballY"] < 5) or (globals()["t_ballY"] > 55):
+ globals()["letztes_ballX"], globals()["letztes_ballY"] = globals()["t_ballX"], globals()["t_ballY"]
+ globals()["count"] = 0
+
+ if globals()["count"] != 0:
+ globals()["deltaX"] = float((globals()["t_ballX"] - globals()["letztes_ballX"]) / globals()["count"])
+ globals()["deltaY"] = float((globals()["t_ballY"] - globals()["letztes_ballY"]) / globals()["count"])
+ globals()["count"] += 1
+
+ bounces = 0
+ if globals()["deltaX"] != 0:
+ schritte = abs(0 + globals()["t_ballX"] / globals()["deltaX"])
+ #nach `schritte` Runden ist der Ball beim anderen Spieler
+ bounces = math.floor((globals()["t_ballY"] + abs(globals()["deltaY"] * schritte)) / 60)
+# zug.ausgabe("Achtung: ")
+# zug.ausgabe(bounces)
+# zug.ausgabe(schritte)
+
+ if globals()["deltaX"] < 0:
+ schritte = abs(0 - globals()["t_ballX"]) / globals()["deltaX"]
+ target_ballY = ((globals()["t_ballY"] + abs(globals()["deltaY"] * schritte)) % 60)
+ else:
+ target_ballY = 30
+
+ if globals()["t_ballX"] > 55 or globals()["t_ballX"] < 10:
+ target_ballY = globals()["t_ballY"]
+
+ if getMe(zustand, id).yKoordinate() > target_ballY - 3:
+ zug.nachOben()
+ else:
+ if getMe(zustand, id).yKoordinate() < target_ballY - 3:
+ zug.nachUnten()
+
+###
+def getMe(zustand, id):
+ if zustand.listeSchlaeger()[0].identifikation() == id:
+ return zustand.listeSchlaeger()[0]
+ return zustand.listeSchlaeger()[1]
+
+def getEnemy(zustand, id):
+ if zustand.listeSchlaeger()[0].identifikation() == id:
+ return zustand.listeSchlaeger()[1]
+ return zustand.listeSchlaeger()[0]
+
+def getBall(zustand):
+ return zustand.listeBall()[0]
diff --git a/src/zahlenspiel.py b/src/zahlenspiel.py
new file mode 100755
index 0000000..e8891f9
--- /dev/null
+++ b/src/zahlenspiel.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+# getestet mit Python 2.7.8 und 3.4.2
+'''Berechnet einen Bruch zur Übung des Kürzens'''
+
+from random import randrange
+
+def gcd(vala, valb):
+ '''Berechnet den größten gemeinsamen Teiler nach Euklid'''
+ while valb:
+ vala, valb = valb, vala % valb
+ return vala
+
+def bruch(stufe):
+ '''Berechnet einen ungekürzten Bruch vala/valb
+mit gekürztem Bruch valp/valq nach Schwierigkeits`stufe`.
+`stufe` ist 0 (leicht), 1 (mittel) oder 2 (schwer)'''
+
+ length = 4 if stufe == 0 else 5
+
+ erfolg = False
+ while not erfolg:
+ suchen = True
+ while suchen:
+ valp = randrange(1, (stufe + 1) * 10)
+ valq = randrange(stufe * 10 - valp, (stufe + 1) * 10 - valp)
+ suchen = (gcd(valp, valq) != 1) # falls nicht kürzbar
+
+ valx = 2
+ suchen = True
+ while suchen:
+ vala, valb = valp * valx, valq * valx
+
+ if len(str(vala)) + len(str(valb)) == length:
+ suchen = False
+ erfolg = True
+ else:
+ valx += 1
+ if len(str(vala)) + len(str(valb)) > length:
+ suchen = erfolg = False # neue Zahlen generieren
+
+ return vala, valb, valp, valq
+
+def aufgaben(stufe, anzahl):
+ '''gibt `anzahl` Aufgaben mit `stufe` (0 - leicht, 2 - schwer) aus'''
+ for _ in range(anzahl):
+ vala, valb, valp, valq = bruch(stufe)
+ print(str(vala) + " / " + str(valb) + \
+ " = " + str(valp) + " / " + str(valq))
+
+if __name__ == "__main__":
+ aufgaben(randrange(4), randrange(1, 10))