Gesucht: 6 Listen richtig absuchen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
googol
User
Beiträge: 6
Registriert: Montag 16. November 2015, 17:30

Aufgabenstellung, fyi.
Man hat also 6 verschiedene Listen von ints, aus denen genau eine 6-Kombination mit jeweils genau einem Element aus jeder dieser Listen die Lösung ist.

Diese sechs Zahlenlisten auszurechnen ist in python nur Abtippen. Geschenkt. 8)
Das Kriterium der Aufgabe, dass die Zahlen in den jeweils ersten und letzten beiden Ziffern übereinstimmen sollen habe ich so:

Code: Alles auswählen

def getdigits(n) :
	return list(str(n))

def arekperms(n,m,k=2) :
	a=getdigits(n)
	b=getdigits(m)
	for i in range(k):
		if a[-(k+i)] != b[i] :
			return False
	return True
implementiert.
(Unter dem Vorbehalt, dass dieser Code aus meinem Kopf und keine Kopie ist, da ich gerade am falschen Rechner sitze und ich für Programmiergolf noch nicht genug Überblick habe...)
Meine Lösungsidee soweit war damit bisher eine -brute force- list-comprehension, im Stil von

Code: Alles auswählen

result = [ [number1,number2, ..., number6] for number1 in list1 for number2 in list2 ....  for number6 in list6 if arekperms(number1,number2) and arekperms(number2,number3) and ... arekperms(number6,number1) ]
herzunehmen.
Die Lösungsmenge ist in meiner Implementation leer und nach weiterem Nachdenken ist mir auch klar geworden, warum:
Ich weiß ja garnicht, welche Liste hier welche ist, habe aber die Reihenfolge explizit vorgegeben.
Alles was ich weiß, ist das jede Liste nur einmal benutzt werden darf, um sich eine Zahl rauszupicken ( und ja es kommen auch noch Dubletten vor :( ( ... sollte aber mit einer kleinen Funktion oder list(set(ausdruck)) schnell auschließbar sein).
Das Durchprobieren von 6! = 720 Möglichkeiten scheint mir nicht sinnvoll.
Wenn also jemand in Python eine Möglichkeit kennt, eine Variable als Platzhalter für ein Element aus einem übergeordneten Element zur "Querprüfung" auf die Unterelemente eines anderen übergeordneten Elements kennt, bin ich für jeden Input sehr dankbar.
In Haskell weiß ich nicht, wie dieses Problem anzufassen ist, habe aber mit Pythons List-comprehensions sehr gute Erfahrungen gemacht. :mrgreen:
Zuletzt geändert von Anonymous am Montag 16. November 2015, 18:44, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Wer nicht fragt, bleibt dumm. :D
BlackJack

@googol: Vielleicht hilft Dir ja etwas aus dem `itertools`-Modul bei Deinem Ansatz weiter.

`arekperms()` kann man mit „slicing“-Syntax sicher ein bisschen kürzer schreiben, also ohne die Schleife.
googol
User
Beiträge: 6
Registriert: Montag 16. November 2015, 17:30

Danke. :mrgreen:
itertools.combinations() und itertools.permutations() ....
damit kann ich dieses Problem morgen auf meinem Weg und auch andersherum (glaube ich) aufzäumen.
(außerdem fallen mir grade auch noch zwei andere Probleme ein, die so oder ähnlich lösbar sind).

und zu Deinem Slicing-Hinweis: Damit komme ich noch nicht in dem Sinn klar, dass ich es hinschreibe und es funktioniert, wie ich's mir dabei denke. Deswegen mache ichs halt mit den Fingern... :?
liste[::-1] z.B. finde ich schön, funktioniert auch, aber mit liste[a:b] hakts bei mir noch zu oft, als das ich mich das im Alltag traue.
Wer nicht fragt, bleibt dumm. :D
karolus
User
Beiträge: 141
Registriert: Samstag 22. August 2009, 22:34

Hallo

Für die "Vorbereitung" wäre vielleicht sowas geeignet:

Code: Alles auswählen

numbers = 8128, 2882, 8281

def divmod100(number):
    return divmod(number,100)

list(map(divmod100, numbers))
BlackJack

Ich würde da wahrscheinlich wieder mal einen Graphen draus basteln und es dann mit einem Suchalgorithmus auf dem Graphen probieren. Sowas wie: Knoten sind mit Formelnummer (0-5) und vierstelliger Zahl beschriftet und Kanten existieren zwischen allen Knoten bei denen die Formelnummer unterschiedlich ist und die letzten beiden Ziffern des einen Knotens mit den ersten beiden Ziffern des anderen Knotens übereinstimmen. Und dann eine Tiefensuche die maximal sechs Schritte geht und darauf achtet in jedem Schritt eine andere Formelnummer zu haben. Das dann mit allen Punkten der Formelnummer 0 als Startpunkt durchprobieren (oder der Formelnummer mit den wenigsten vierstelligen Ergebnissen falls das einen signifikanten Unterschied machen sollte welche Formelnummer man da nimmt).
BlackJack

Das Vorgehen aus dem letzten Beitrag habe ich mal in C umgesetzt und damit findet mein C64 die Lösung in ca. 10 Sekunden: http://pastebin.com/Kt2jTCbN
BlackJack

Der in meinem vorletzten Beitrag beschriebene Graph mal als Grafik mit der Lösung in Blau gezeichnet:
Bild
Im Gegensatz zu der Umsetzung in C sind Knoten die kein Teil eines Kreises sein können aus dem Graphen entfernt worden, damit es nicht *noch* unübersichtlicher wirkt. :-)
BlackJack

Weil ich mal etwas mit Immutable.js ausprobieren wollte: http://pastebin.com/RHEFVMVf

Immutable.js ist ganz nett weil man trotz interner Iteratoren (vs. Externe in Python) trotzdem recht einfach Teillösungen „lazy“ und „endlos“ machen kann.
Antworten