From 5d3189d7345dd3b26a5753a16020ed4f7df0c4b1 Mon Sep 17 00:00:00 2001 From: schneefux Date: Sun, 23 Nov 2014 12:18:04 +0100 Subject: Verschieben aller Dateien in Unterordner --- src/alphametiken.py | 116 +++++++++++++++++++++++++++++++++++++++++++++++++ src/buffet_lotterie.py | 46 ++++++++++++++++++++ src/faehre_fuellen.py | 100 ++++++++++++++++++++++++++++++++++++++++++ src/mobile.py | 76 ++++++++++++++++++++++++++++++++ src/pong.py | 79 +++++++++++++++++++++++++++++++++ src/zahlenspiel.py | 52 ++++++++++++++++++++++ 6 files changed, 469 insertions(+) create mode 100755 src/alphametiken.py create mode 100755 src/buffet_lotterie.py create mode 100755 src/faehre_fuellen.py create mode 100755 src/mobile.py create mode 100644 src/pong.py create mode 100755 src/zahlenspiel.py (limited to 'src') 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)) -- cgit v1.3.1