Python Liste mit integers auf "Kleine Straße" überprüfen?

5 Antworten

Da es nur 6 verschiedene Werte gibt, wäre das Aufschreiben aller Kombinationen aber durchaus eine sinnvolle Implementierung. Auch beim Poker, wo es 13 Werte gibt (und das Ass an beiden Enden stehen kann), kann man das genauso machen.

Edit:
Es gibt 2 Kombinationen für eine große Straße und 3 Kombinationen für eine kleine Straße. Jedenfalls unter der Annahme, dass die Liste sortiert ist, was du aber hilfsweise machen kannst. Dann einfach prüfen:

(enthält 1 AND enthält 2 AND enthält 3 AND enthält 4 ) OR (dasselbe mit 2-5) OR (dasselbe mit 3-6)

Woher ich das weiß:eigene Erfahrung

Edit: Bug behoben?

In kniffel ist die reihenfolge der würfel egal, richtig?

dice = [1,2,3,4,5]

dice.sort()
i = 0
x = 0
j = 0
for d in dice:
  if (d == x+1):
    x = d
    i = i + 1
    if (i > j):
        j = i
  elif (d != x):
    i = 1
    x = d
print(j)

print(i)Das berechnet dir wie lang die längste straße ist.

Wenn du nun ausgeben willst ob es eine kleine oder große straße ist kannst du einfach anstatt print(i) sowas machen wie:

if (i == 5):
  print("Große Straße")  
elif (i == 4):
  print("Kleine Straße")  
else:
  print("Keine Straße :(")

Aber, ganz ehrlich, vergleichen ist auch okay! Gibt ja nur 5 möglichkeiten(3 für die kleien straße, 2 für die große).

Wobei natürlich meine lösung für n würfel mit m seiten funktioniert. Also, funktioniert auch noch wenn du [16,15,17,18,300] da rein packst.


TheDonk 
Beitragsersteller
 23.11.2022, 08:51

Ja die Reihenfolge ist egal. Hab aber ein anderes Problem gefunden:

Sobald der Würfel wie folg aussieht dice = [1,2,1,4,5] sortiert er diese und es sieht so aus dice = [1, 1, 2, 4, 5]]. Nun gibt er mir aus das es sich um eine kleine Straße handelt welche nicht der Fall ist.

Trotzdem danke für den Versuch ich werde dann vermutlich alle möglichen Möglichkeiten aufschreiben und die dann vergleichen.

jort93  23.11.2022, 08:54
@TheDonk

Ja, ist verbuggt, ist mir auch aufgefallen.

jort93  23.11.2022, 09:05
@TheDonk

Ist nicht so einfach tatsächlich. hatte ich mir zu leicht vorgestellt.

TheDonk 
Beitragsersteller
 23.11.2022, 09:06
@jort93

Würde mir das gerne anschauen eine weitere Variable wäre kein großes Problem

jort93  23.11.2022, 09:09
@TheDonk

Müsste jetzt funktionieren. Musste noch mehrere andere sachen ändern.

Soll dann halt auch mit beliebig vielen würfeln mit beliebig vielen seiten funktionieren, weil sonst hat das ja keinen vorteil.

TheDonk 
Beitragsersteller
 23.11.2022, 09:26
@jort93

Dankeschön! konnte keine Fehler finden!

{1, 2, 3, 4}.issubset(dice) 

oder ohne Sets:

1 in dice and 2 in dice and 
3 in dice and 4 in dice

jort93  23.11.2022, 08:34

Und was ist dann mit [2,2,3,4,5]? und [6,3,4,5,6]?

Du müsstest bei so einer lösung alle möglichkeiten aufschreiben. Sind zwar nur 5, 3 für die kleine und 2 für die große, aber genau das will der fragesteller ja vermeiden.

jort93  23.11.2022, 08:40
@jort93

Eine vollständige Lösung mit dem Ansatz würde so aussehen. Und das ist, wie ich die Frage verstehe, genau was der Fragesteller vermeiden will.

if({1, 2, 3, 4, 5}.issubset(dice) or {2, 3, 4, 5, 6}.issubset(dice)):
    print("Große Straße")
elif({1, 2, 3, 4}.issubset(dice) or {2, 3, 4, 5}.issubset(dice) or {3, 4, 5, 6}.issubset(dice)):
    print("Kleine Straße")
else:
    print("Keine Straße :(")

Es ist keine schlechte Lösung, aber der Fragesteller hat explizit gesagt dass er eine andere sucht, wo er nicht alle möglichkeiten aufschreiben muss.

Neuerfan1  23.11.2022, 08:52
@jort93

Aus meiner Sicht ist das Aufschreiben aller Kombinationen dennoch zielführend.

ralphdieter  23.11.2022, 09:25
@jort93

Ich habe ihn so verstanden, dass er nicht alle passenden Listen aufschreiben will. Das wären nämlich wirklich viele.

Mit meiner Antwort kann er sich das sparen. Die anderen 4 vier Fälle könnte man – wenn es unbedingt sein muss – auch in einer Schleife abbacken:

def strasse( dice ):
  for size in (5, 4):
    for start in range(1, 6-size+2):
      test = frozenset(range(start, start+size))
      if test.issubset(dice):
        print( f"\aStraße mit Länge {size} ab {start}" )
        return test
  print( "keine Straße gefunden :-(" )
  return None

Aber wenn es nur eine Übungsaufgabe ist, halte ich es für sinnvoller, die 5 Tests explizit hinzuschreiben.

jort93  23.11.2022, 09:26
@ralphdieter

Also, bei uns hätte der prof die aufgabe vermutlich so formuliert dass es für n würfel mit m seiten funktionieren muss...

Aber wenn es nur 5 würfel mit je 6 seiten sind, ist das natürlich eine gute lösung.

ralphdieter  23.11.2022, 09:29
@jort93

Die Anzahl der Würfel ist doch uninteressant. Und rate mal, warum ich "6-size+2" schrieb.

"size in (5, 4)" könnte man je nach Aufgabenstellung noch anpassen.

jort93  23.11.2022, 09:45
@ralphdieter

Ja stimmt, ich glaube dein code funktioniert für die aufgabenstellung.

Für die anzahl der seiten müsste man start+size ändern, weil so funktioniert es auch z.B. nicht für 5 zwanzigseitige würfel.

Wahrscheinlich müsste sowas gehen
Ist aber nicht wirklich getestet
dice = [2,1,2,3,4]
ok = False
dice.sort()
for i in range(len(dice)-3):
	cur = dice[i]
	checkCur = True
	for j in range(i+1,i+4):
		if dice[j] == cur + 1:
			cur += 1
		else:
			checkCur = False
			break
	if checkCur:
		ok = True
		break
print(ok)
Woher ich das weiß:Studium / Ausbildung – Informatikstudent

jort93  23.11.2022, 08:24

Ne, funktioniert nicht.

[3,1,2,4,5]

gibt false aus.

Verstehe aber tbh deinen code nicht, daher weiß ich nicht was damit nicht stimmt.

whgoffline  23.11.2022, 09:05
@jort93

Sind doch auch nicht vier in Folge, oder habe ich was falsch verstanden...?

jort93  23.11.2022, 09:12
@whgoffline

Noch nie kniffel gespielt?

Da tust du alle würfel in einen würfelbecher, die haben keine reihenfolge.

whgoffline  23.11.2022, 09:15
@jort93

Achso....dann hast du recht, dann ist mein code eigentlich nicht zu gebrauchen :/

jort93  23.11.2022, 09:20
@whgoffline

Naja, du könntest davor dice.sort() benutzen um sie zu sortieren, wenn es sortiert funktioniert.

Testet aber auch nur auf kleine straße, oder?

whgoffline  23.11.2022, 09:31
@jort93

Ja, das könnte funktionieren und ja, dass testet nur auf kleine Straße. Habe das sort() mal ergänzt

Hier eine Python 3.10 Lösung:

from itertools import pairwise

dice = sorted(set(dice))
streets = [[dice[0]]]

for x, y in pairwise(dice):
    if y-x == 1:
        streets[-1].append(y)
    else:
        streets.append([y])

m = max(map(len, streets))

In streets sind alle Straßen, m ist die Länge der längsten Straße