2016-06-04 6 views
0

Ich arbeite an einer relativ neuen Herausforderung in CodeEval namens "Football". Die Beschreibung wird in dem folgenden Link aufgeführt: https://www.codeeval.com/open_challenges/230/Codeval Challenge 230: Fußball, Antwort nur teilweise korrekt

Eingänge sind Zeilen einer Datei von Python zu lesen, und innerhalb jeder Zeile gibt es Listen, getrennt durch ‚|‘, wobei jede Liste repräsentiert ein Land: das erste sein Land " 1 ", zweites Land" 2 "und so weiter.

1 2 3 4 | 3 1 | 4 1

19 11 | 19 21 23 | 31 39 29

Die Ausgänge sind auch Zeilen als Reaktion auf jede aus der Datei gelesene Zeile.

1: 1,2,3; 2: 1; 3: 1,2; 4: 1,3;

11: 1; 19: 1,2; 21: 2; 23: 2; 29: 3; 31: 3; 39: 3;

so unterstützt Land 1 Team 1, 2 und 3 wie in der ersten Zeile der Ausgabe: 1:1,2,3.

Unten ist meine Lösung, und da ich keine Ahnung habe, warum die Lösung nur für die beiden im Beschreibungslink aufgelisteten Beispielfälle funktioniert, möchte ich jeden um Kommentare und Hinweise bitten, wie ich meinen Code korrigieren kann. Vielen Dank für Ihre Zeit und Unterstützung im Voraus.

import sys 

def football(string): 
    countries = map(str.split, string.split('|')) 
    teams = sorted(list(set([i[j] for i in countries for j in range(len(i))]))) 
    results = [] 
    for i in range(len(teams)): 
     results.append([teams[i]+':']) 
     for j in range(len(countries)): 
      if teams[i] in countries[j]: 
       results[i].append(str(j+1)) 
    for i in range(len(results)): 
     results[i] = results[i][0]+','.join(results[i][1:]) 
    return '; '.join(results) + '; ' 

if __name__ == '__main__': 
    lines = [line.rstrip() for line in open(sys.argv[1])] 
    for line in lines: 
     print football(line) 

Antwort

0

Hier ist, wie ich es gelöst:

import sys 

with open(sys.argv[1]) as test_cases: 
    for test in test_cases: 
     if test: 
      team_supporters = {} 
      for nation, nation_teams in enumerate(test.strip().split("|"), start=1): 
       for team in map(int, nation_teams.split()): 
        team_supporters.setdefault(team, []).append(nation) 
      print(*("{}:{};".format(team, ",".join(map(str, sorted(nations)))) 
        for team, nations in sorted(team_supporters.items()))) 

Das Problem ist nicht sehr kompliziert. Wir erhalten eine Zuordnung von Nation (implizit durch ihre Reihenfolge in der Eingabe nummeriert) zu einer Liste von Teams.Wir müssen das umkehren, um eine Ausgabe zu erstellen, die von einem Team auf eine Liste von Nationen abbildet.

Es scheint natürlich, ein Wörterbuch zu verwenden, das auf die gleiche Weise wie die gewünschte Ausgabe abgebildet wird. Wir können enumerate verwenden, um den Nationen Zahlen zu geben, wenn wir über sie iterieren. Die Methode setdefault des Diktats fügt dem Wörterbuch leere Listen hinzu, wenn sie benötigt werden (mit einer collections.defaultdict anstelle eines regulären Wörterbuchs wäre dies eine andere Möglichkeit, dies zu umgehen). Die Reihenfolge der Eingabe und die Reihenfolge, in der die Dinge in den inneren Listen des Wörterbuchs gespeichert sind, müssen nicht berücksichtigt werden.

Die Ausgabe, die wir unter Verwendung von str.format Aufrufen und dem Standard-Leerzeichentrennzeichen der print-Funktion erstellen. Wenn das letzte Semikolon nicht gewünscht wäre, hätte ich stattdessen print("; ".join("{}:{}.format(...))) verwendet. Da die Ausgabe nach Team auf der obersten Ebene und nach Nation in den inneren Listen sortiert werden muss, machen wir einige sorted Aufrufe, wo nötig.

Das Sortieren der inneren Listen ist wahrscheinlich nicht einmal notwendig, da die Nationen in der Reihenfolge verarbeitet wurden, deren Zahlen von der Reihenfolge abgeleitet wurden, die sie in der Eingabezeile hatten. Glücklicherweise ist der Algorithmus von Python Timsort sehr schnell auf bereits sortierte Eingabe, so dass unser Code auch mit ein bisschen unnötiger Sortierung immer noch schnell genug ist.

+0

Hallo Blckknght, danke für deine Lösung. Es ist in der Tat eine bessere als meine, da der Prozess einfacher ist. Ich habe auch über neue Dinge gelernt, wie Sie die 'enumerate' aufrufen können, um nicht bei 0 zu starten, und Sie können' setdefault' verwenden. Also was 'team_supporters.setdefault (team, []). Append (nation)' tut, ist, wenn ich richtig verstehe: es sucht nach 'key' mit dem Wert' team' um die 'nation' hinzuzufügen, aber wenn die 'team' Taste ist noch nicht im Wörterbuch, dann' setdefault' fügt eine leere Liste [] mit 'key' als die vorher nicht existierende neue' team' hinzu? Danke noch einmal! – Nahua

+0

Habe gerade mit setdefault ein bisschen gespielt und es bestätigt. Danke nochmal für die tollen Tipps! – Nahua

1

Nachdem ich absichtlich einen Versuch fehlgeschlagen habe, den kompletten Testeingang und meine Ausgabe auszufüllen, habe ich das Problem gefunden. Die Linie:

teams = sorted(list(set([i[j] for i in countries for j in range(len(i))]))) 

wird die Ausgabe problematisch in Bezug auf die Sortierung machen. Zum Beispiel ist hier ein Probe-Eingang:

10 20 | 43 23 | 27 | 25 | 11 1 12 43 | 33 18 3 43 41 | 31 3 45 4 36 | 25 29 | 1 19 39 | 39 12 16 28 30 37 | 32 | 11 10 7 

und es erzeugt die Ausgabe:

1:5,9; 10:1,12; 11:5,12; 12:5,10; 16:10; 18:6; 19:9; 20:1; 23:2; 25:4,8; 27:3; 28:10; 29:8; 3:6,7; 30:10; 31:7; 32:11; 33:6; 36:7; 37:10; 39:9,10; 4:7; 41:6; 43:2,5,6; 45:7; 7:12; 

Aber die Herausforderung erwartet, dass die Ausgabe-Teams von Zahlen in aufsteigender Reihenfolge sortiert werden, die nicht durch die oben erreicht wird genannten Code, da die Zahlen im String-Format vorliegen, nicht im Integer-Format. Daher ist die Lösung einfach eine Taste Hinzufügen des Teams Liste sortiert nach Auftrag für integer aufsteigend:

teams = sorted(list(set([i[j] for i in countries for j in range(len(i))])), key=lambda x:int(x)) 

Mit einer kleinen Änderung in dieser Linie, geht der Code durch die Tests. Ein Beispiel für die Ausgabe wie folgt aussieht:

1:5,9; 3:6,7; 4:7; 7:12; 10:1,12; 11:5,12; 12:5,10; 16:10; 18:6; 19:9; 20:1; 23:2; 25:4,8; 27:3; 28:10; 29:8; 30:10; 31:7; 32:11; 33:6; 36:7; 37:10; 39:9,10; 41:6; 43:2,5,6; 45:7; 

Bitte lassen Sie mich wissen, wenn Sie eine bessere und effizientere Lösung für die Herausforderung haben. Ich würde gerne bessere Codes oder großartige Vorschläge zur Verbesserung meiner Programmierkenntnisse lesen.

+0

Danke für die Bereitstellung der Testfall und Ausgabe! Es half mir zu identifizieren, dass ich meine Wörterbuchschlüssel als Zeichenfolgen anstelle von ganzen Zahlen sortierte. – Todd

+0

Hallo Todd, du bist willkommen! Es macht mich glücklich, dass das, was ich geschrieben habe, jemand anderem helfen könnte, das Problem zu lösen :) – Nahua

Verwandte Themen