from collections import namedtuple
from itertools import product
import re
Rect = namedtuple('Rect', ['width', 'height'])
Rotate = namedtuple('Rotate', ['dimension', 'pos', 'move_by'])


def range_offset(end, offset):
    for i in range(end):
        yield i, (i+offset)%end

def solve_p1(commands, width, height):
    screen = [['.']*width for i in range(height)]

    for cmd in commands:
        if isinstance(cmd, Rect):
            for x, y in product(range(cmd.width), range(cmd.height)):
                screen[y][x] = '#'
        elif isinstance(cmd, Rotate):
            if cmd.dimension == 'column':
                values = tuple(line[cmd.pos] for line in screen)

                for y, ny in range_offset(len(values), cmd.move_by):
                    screen[ny][cmd.pos] = values[y]
                    
            elif cmd.dimension == 'row':
                values = tuple(screen[cmd.pos])

                for x, nx in range_offset(len(values), cmd.move_by):
                    screen[cmd.pos][nx] = values[x]
            else:
                raise Exception("Unknown dimension: {}".format(cmd.dimension))
                
    
    return "\n".join(''.join(line) for line in screen)+"\n" 

rect_re = re.compile(r'rect (\d+)x(\d+)')
rotate_re = re.compile(r'rotate (row|column) (?:x|y)=(\d+) by (\d+)')
def load_data(inputfile):
    """
    Converts the data from the input file into something usable 
    by the solve functions.
    """
    commands = []
    for line in inputfile:
        if line.startswith('rect'):
            matches = rect_re.match(line)
            width, height = matches.groups()
            commands.append(Rect(int(width), int(height)))
        elif line.startswith('rotate'):
            matches = rotate_re.match(line)
            dimension, pos, move_by = matches.groups()
            commands.append(Rotate(dimension, int(pos), int(move_by)))
        else:
            raise Exception("Bad line: {}".format(line))

    return commands

if __name__ == '__main__':
    with open('input.txt', 'r') as inputfile:
        data = load_data(inputfile)

    print("Part 1 Solution")
    print(solve_p1(data, 50, 6))
    print(sum(1 if d == '#' else 0 for d in solve_p1(data, 50, 6)))
