Created
December 8, 2016 12:48
-
-
Save atopuzov/5bfe0378a51cd9d39945633ff10ccdc7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# Aleksandar Topuzovic <aleksandar dot topuzovic at gmail dot com> | |
import re | |
rect_regex = re.compile("rect (?P<n>\d+)x(?P<m>\d+)") | |
rotate_regex = re.compile("rotate (?P<what>column|row) (x|y)=(?P<cid>\d+) by (?P<by>\d+)") | |
class Cmd(object): | |
pass | |
class Rect(Cmd): | |
def __init__(self, n, m): | |
self.n = n | |
self.m = m | |
def __repr__(self): | |
return "Rect({!r}, {!r})".format(self.n, self.m) | |
def paint(self, scr): | |
scr.rect(self.n, self.m) | |
class Rotate(Cmd): | |
pass | |
class RotateRow(Rotate): | |
def __init__(self, y, by): | |
self.y = y | |
self.by = by | |
def __repr__(self): | |
return "RotateRow({!r}, {!r})".format(self.y, self.by) | |
def paint(self, scr): | |
scr.rotate_row(self.y, self.by) | |
class RotateColumn(Rotate): | |
def __init__(self, x, by): | |
self.x = x | |
self.by = by | |
def __repr__(self): | |
return "RotateColumn({!r}, {!r})".format(self.x, self.by) | |
def paint(self, scr): | |
scr.rotate_column(self.x, self.by) | |
def create_rect(n, m): | |
return Rect(int(n), int(m)) | |
def create_rotate(what, cid, by): | |
_cid = int(cid) | |
_by = int(by) | |
if what == "column": | |
return RotateColumn(_cid, _by) | |
elif what == "row": | |
return RotateRow(_cid, _by) | |
raise Exception("This should not happen!") | |
matchers = { | |
rect_regex: create_rect, | |
rotate_regex: create_rotate | |
} | |
def parse_line(line): | |
for regex, func in matchers.iteritems(): | |
match = regex.match(line) | |
if match is not None: | |
return func(**match.groupdict()) | |
raise Exception('Unable to parse "{}"!'.format(line)) | |
def get_input(): | |
with open('input.txt') as f: | |
lines = f.readlines() | |
lines2 = [ | |
"rect 3x2", | |
"rotate column x=1 by 1", | |
"rotate row y=0 by 4", | |
"rotate column x=1 by 1" | |
] | |
return map(parse_line, lines) | |
class Screen(object): | |
BLANK = "." | |
FULL = "#" | |
def __init__(self, w=50, h=4): | |
self.w = w | |
self.h = h | |
self._screen = [[self.BLANK for _ in xrange(self.w)] | |
for _ in xrange(self.h)] | |
def display(self): | |
print "-" * self.w | |
print "\n".join("".join(char for char in row) for row in self._screen) | |
print "-" * self.w | |
def paint(self, x, y): | |
self._screen[y][x] = self.FULL | |
def rect(self, n, m): | |
for x in xrange(n): | |
for y in xrange(m): | |
self.paint(x, y) | |
def _rotate(self, lst, by): | |
part1 = lst[:-by] | |
part2 = lst[-by:] | |
return part2 + part1 | |
def rotate_row(self, y, by): | |
row = self._screen[y] | |
self._screen[y] = self._rotate(row, by) | |
def rotate_column(self, x, by): | |
column = [self._screen[y][x] for y in xrange(self.h)] | |
new_column = self._rotate(column, by) | |
for y, pixel in enumerate(new_column): | |
self._screen[y][x] = pixel | |
def lit_pixels(self): | |
return sum(sum(1 if pixel == self.FULL else 0 for pixel in row) | |
for row in self._screen) | |
def paint(scr, instructions): | |
for instruction in instructions: | |
instruction.paint(scr) | |
def test_screen(): | |
scr = Screen(7, 3) | |
scr.rect(3, 2) | |
scr.rotate_column(1, 1) | |
scr.rotate_row(0, 4) | |
scr.rotate_column(1, 1) | |
scr.display() | |
def main(): | |
instructions = get_input() | |
scr = Screen(50, 6) | |
paint(scr, instructions) | |
scr.display() | |
print "Lit pixels:", scr.lit_pixels() | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment