BlackJack hatte ja auf die Advent of Code Aufgabensammlung hingewiesen.
Meine Lösung kommt mir (abgesehen davon, dass sie etwas aufwändiger ist, als notwendig wäre, um das Ergebnis zu berechnen), an ein paar Stellen etwas seltsam vor. Beispielsweise habe ich bisher noch nie das "for … else" Konstrukt verwendet; hier erschien es mir sinnvoll, aber ist es das wirklich? Für das grid habe ich ein set gewählt, aus dem Items gelöscht oder in es hinzugefügt werden (für Teil 2 dann ein defaultdict). Da bin ich mir auch etwas unsicher, ob das nicht zu sehr "zurecht gefummelt" ist. Über Kommentare oder Vorschläge würde ich mich freuen:
(Python 3)
Code: Alles auswählen
from collections import namedtuple
import fileinput
import re
Corner = namedtuple('Corner', 'x y')
def turn_on(grid, first_corner, second_corner):
for i in range(first_corner.x, second_corner.x + 1):
for j in range(first_corner.y, second_corner.y + 1):
grid.add((i, j))
return grid
def turn_off(grid, first_corner, second_corner):
for i in range(first_corner.x, second_corner.x + 1):
for j in range(first_corner.y, second_corner.y + 1):
try:
grid.remove((i, j))
except:
pass
return grid
def toggle(grid, first_corner, second_corner):
for i in range(first_corner.x, second_corner.x + 1):
for j in range(first_corner.y, second_corner.y + 1):
try:
grid.remove((i, j))
except KeyError:
grid.add((i, j))
return grid
ACTIONS = {
re.compile(r'\s*toggle'):toggle,
re.compile(r'\s*turn\s+on'): turn_on,
re.compile(r'\s*turn\s+off'): turn_off,
}
VALUES = re.compile(r'\s*(?P<x1>[0-9]+)\s*,\s*(?P<y1>[0-9]+)\s*through\s*(?P<x2>[0-9]+)\s*,(?P<y2>\s*[0-9]+)$')
def main():
grid = set()
for line in fileinput.input():
line = line.strip()
for predicate, action in ACTIONS.items():
if re.match(predicate, line):
break
else:
print('Error:', line)
values = re.search(VALUES, line)
try:
first_corner = Corner(*map(int, values.group('x1', 'y1')))
second_corner = Corner(*map(int, values.group('x2', 'y2')))
except AttributeError:
pass
grid = action(grid, first_corner, second_corner)
print('Total:', len(grid))
if __name__ == '__main__':
main()
Edit:
Die Aufgabenstellung ist, eine zeilenbasierte Steuerungsdatei einzulesen und anhand der Informationen Lichter in einem 1000x1000 Raster an oder auszuschalten. Das Schema ist: (toggle|turn on|turn off) x1,y1 through x2,y2 Die Koordinaten geben zwei Eckten eines Rechtecks an.