Skip to content

Instantly share code, notes, and snippets.

@atopuzov
Created December 8, 2016 12:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save atopuzov/5bfe0378a51cd9d39945633ff10ccdc7 to your computer and use it in GitHub Desktop.
Save atopuzov/5bfe0378a51cd9d39945633ff10ccdc7 to your computer and use it in GitHub Desktop.
#!/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