Python :: Aufgabe #119

4 Lösungen Lösungen öffentlich

Dart-501 Taschenrechner

Fortgeschrittener - Python von hollst - 19.07.2016 um 11:25 Uhr
Dart ist hinsichtlich seiner Spielregeln und Ausführung eine recht überschaubare Sportart. Bei der Version Dart-501 beginnen beide Spieler mit einem Punktestand von 501 und müssen diesen auf 0 herunterschießen, wobei die 0 mit einem sogenannten Doppeltreffer (Double) erreicht werden muss. Die Zielfläche ist eine Kreisfläche, die in zwanzig gleichgroßen Kreissegmenten mit unterschiedlicher Grundwertigkeit aufgeteilt ist [Bild 1]. Neben den Kreissegmenten gibt es noch drei Kreisringe und das Auge. Das Auge ist eine kleine Kreisfläche um den Mittelpunkt der Zielscheibe. Die drei Kreisringe sind der Triple-Ring (entspricht dem Radius der Zielscheibe), der Double-Ring (entspricht dem halben Radius der Zielscheibe) und der Auge-Ring (Kreisring um das Auge). Beim Treffen eines der Triple- bzw. Double-Kreisring-Segmente wird die Grundwertigkeitszahl verdreifacht bzw. verdoppelt. Der Augering wird bei einem Treffer mit 25 Zählern gewertet und das Auge zählt immer 50 Punkte, es gilt als Doppeltrefferfläche (2 x 25).

In jeder Runde hat ein Spieler drei Darts, d. h. um "auszuknocken" muss er sich zuvor auf höchstens 170 Punkte heruntergeschossen haben (Knockout möglich mit Triple 20, Triple 20, Auge, also 3*20 + 3*20 + 2*25 = 170). Für 170 gibt es nur diese eine Variante (Sequenz) um direkt auszuknocken, für 169 und 168 sogar überhaupt keine. Wird in einer Runde die 0 unterboten oder die 1 erreicht (niemals mit einem Double auf 0 zu bekommen) bzw. die 0 nicht mit einem abschließenden Double erreicht, wird auf den alten Punktestand zurück gesetzt. Somit hat ein Dartspieler in der Finish-Phase eine Menge Kopfrechenarbeit zu leisten. Z. B. gibt es einige Punktestände, bei denen es über 1000 Möglichkeiten (Sequenzen) für ein Knockout gibt. Hier soll die Computerunterstützung ansetzen.

Schreibe ein Programm, das bei einem Punktestand von unterhalb 171 alle möglichen Knockout-Sequenzen berechnet, speichert und ev. anzeigt [z. B. Bild 2].

Lösungen:

1x
vote_ok
von hak (980 Punkte) - 08.09.2016 um 00:12 Uhr
Quellcode ausblenden Python-Code
def find_checkout(target_score):
    if target_score > 170 or target_score < 2 :
        return []
        
    singles = [('s' + str(i), i) for i in range(1,21)] + [('bull', 25) ]
    doubles = [('d' + str(i), 2*i) for i in range(1,21)] + [('dbull', 50) ]
    triples = [('t' + str(i), 3*i) for i in range(1,21)]    

    solutions = []
    for d3 in doubles :
        if d3[1] == target_score :
            solutions.append([d3[0]])
            continue
        elif d3[1] > target_score :
            break
        else:
            for d2 in singles + doubles + triples:
                if d3[1] + d2[1] == target_score :
                    solutions.append([d2[0],d3[0]])
                    continue
                elif d3[1] + d2[1] > target_score :
                    break
                else :
                    for d1 in singles + doubles + triples:
                        if d3[1] + d2[1] + d1[1] == target_score :
                            solutions.append([d1[0],d2[0],d3[0]])
    return solutions
vote_ok
von nitnat (670 Punkte) - 23.04.2017 um 16:29 Uhr
Quellcode ausblenden Python-Code
# Ergebnisraum: Menge aller möglichen Ergebnisse nach drei Würfen

def ergebnisraum():
    
    # nach einem Wurf

    liste=[]
    for i in range(1,21):
        liste.append(["s"+str(i) ,i])      # einfache Zahlen
        liste.append(["d"+str(i), i*2])    # double
        liste.append(["t"+str(i), i*3])    # triple

    liste.append(["s25", 25])              # 25er Ring
    liste.append(["d25", 50])              # bull's eye
    liste.append(["s0", 0])                # daneben geworfen

    # nach drei Würfen, mit Summe der geworfenen Punkte

    liste2=[]
    for i in range(0, len(liste)):
        for j in range(0, len(liste)):
            for k in range(0, len(liste)):
                liste2.append([liste[i], liste[j], liste[k], liste[i][1]+liste[j][1]+liste[k][1]])

    return liste2
   

# Berechnung der möglichen knockout-Kombinationen für bestimmte Punktestände, wobei n der Punktestand ist

def knockout(n):
    ergebnisse = ergebnisraum()
    ergebnisliste = []

    
    if n > 170 or n < 2:
        print ("Bei einem Punktesstand von", n, "ist kein knockout möglich!")
    else:   
        for i in range(0, len(ergebnisse)):                                     # gehe alle Ergebnisse aus dem Ergebnisraum durch
        
            if ergebnisse[i][3] == n and ergebnisse[i][2][0][0]== "d":          # wenn ein Ergebnis in Höhe des aktuellen Punktestandes UND double out...
            
                ergebnisliste.append((ergebnisse[i][0][0], ergebnisse[i][1][0], ergebnisse[i][2][0])) # ... dann schreibe die Kombination in die Ergebnisliste

            
        if ergebnisliste == []:                                                 # wenn Ergebnisliste leer, kein Knockout möglich
            print ("Bei einem Punktesstand von", n, "ist kein knockout möglich!")
        else:
            print ("Bei einem Punktesstand von", n, "gibt es folgende", len(ergebnisliste), "möglichen knockout-Kombinationen:")
            print (ergebnisliste)

# optional: Anzeige aller möglichen Kombinationen für alle Ergebnisse von 2-170
# for i in range(2, 171):
#    knockout(i)
vote_ok
von AlexGroeg (2010 Punkte) - 04.01.2020 um 09:28 Uhr
Quellcode ausblenden Python-Code
# -*- coding: utf-8 -*-
# Python 3.7
# https://trainyourprogrammer.de/python-119-dart-501-taschenrechner.html

import itertools

disc = {'t20': 60, 't19': 57, 't18': 54, 't17': 51, 'db25': 50, 't16': 48, 't15': 45, 't14': 42, 'd20': 40,
        't13': 39, 'd19': 38, 'd18': 36, 't12': 36, 'd17': 34, 'd16': 32, 't11': 33, 'd15': 30, 't10': 30, 
        'd14': 28, 't9': 27, 'd13': 26, 'sb25': 25,'d12': 24, 't8': 24, 'd11': 22, 't7': 21, 's20': 20, 'd10': 20, 
        's19': 19, 's18': 18, 'd9': 18, 't6': 18, 's17': 17, 's16': 16, 'd8': 16, 's15': 15, 't5': 15, 
        's14': 14, 'd7': 14, 's13': 13, 's12': 12, 'd6': 12, 't4': 12, 's11': 11, 's10': 10, 'd5': 10, 
        's9': 9, 't3': 9, 's8': 8, 'd4': 8, 's7': 7, 's6': 6,'d3': 6, 't2': 6, 's5': 5, 
        's4': 4, 'd2': 4, 's3': 3, 't1': 3, 's2': 2, 'd1': 2, 's1': 1 }

dart = []
for k, v in disc.items():
    if v not in dart:
        dart.append(v)

rest = 171
loesungen = 0    

while rest > 0:
    anzahl = 0
    n = 3  
    while n > 0:
        for i in list(itertools.combinations_with_replacement(dart, n)):
            L = []
            if sum(i) == rest:
                for x in i:
                    for k, v in disc.items():
                        if v == x:
                            L.append(k)
                            break               
                print(L)
                anzahl += 1 
        n -= 1              
    print(" Für {} gibt es {} Lösungen.\n".format(rest, anzahl))
    loesungen += anzahl
    rest -= 1
    
print('Das sind zusammen {} Lösungen.'.format(loesungen))

vote_ok
von satn1241 (3090 Punkte) - 17.04.2020 um 21:44 Uhr
Quellcode ausblenden Python-Code
# Mögliche Punkte für einen Wurf
singles = [0] + list(range(1, 21)) + [25]
doubles = list(range(2, 41, 2)) + [50]
triples = list(range(3, 61, 3))
alle = singles + doubles + triples

# Beschriftungen für die Würfe
s = " ".join(["s%d" % i for i in range(1, 21)])
werte_singles = s.split()
werte_singles = ["s0"] + werte_singles + ["s25"]

d = " ".join(["d%d" % i for i in range(1, 21)])
werte_doubles = d.split()
werte_doubles += ["d25"]

t = " ".join(["t%d" % i for i in range(1, 21)])
werte_triples = t.split()

werte_alle = werte_singles + werte_doubles + werte_triples


# Punkte und Beschriftungen zu Dictionary zusammenfügen
def list_to_dict(liste1, liste2):
    zipped_liste = zip(liste1, liste2)
    op = dict(zipped_liste)
    return op


dict_alle = list_to_dict(werte_alle, alle)

# Checkouts berechnen
for ends in range(1, 171):
    options = []
    erster = 1
    for i in werte_alle:
        rest1 = ends - dict_alle[i]
        erster += 0
        if rest1 == 0 and 44 > erster > 21:
            option = [i, "s0", "s0"]
            options.append(option)
        elif rest1 > 0:
            zweiter = 0
            for j in werte_alle:
                rest2 = rest1 - dict_alle[j]
                zweiter += 1
                if rest2 == 0 and 44 > zweiter > 21:
                    option = [i, j, "s0"]
                    options.append(option)
                elif rest2 > 0:
                    dritter = 0
                    for k in werte_alle:
                        dritter += 1
                        rest3 = rest2 - dict_alle[k]
                        if rest3 == 0 and 44 > dritter > 21:
                            option = [i, j, k]
                            options.append(option)
    print(ends, ": ", "Wege: ", len(options), "  ", options)