human
Write me a the Python code you requested given the following:
I am working on the file "2017/iker/Ferran AoC 2017.ipynb".
The first task is:
Day 22
Useless day just takes memory and time
Can you write Python code for it?
assistant
#Here is the Python code you requested.

test_input = """..#
#..
...""".splitlines()

import numpy as np
from collections import defaultdict

def parse_grid(f_input):
    grid = defaultdict(lambda: '.')
    size = 0
    for l in f_input:
        hash_row = {hash(np.array([size, i], dtype=np.int16).tostring()): v for i, v in enumerate(list(l.rstrip()))}
        grid.update(hash_row)
        size += 1
    return grid, size

class Virus(object):
    def __init__(self, grid, size):
        self.grid = grid  # enclosing the hashes and states of infected positions
        self.pos = np.array([(size - 1) // 2, (size - 1) // 2], dtype=np.int16)  # initially in the center of a positive grid
        self.facing = np.array([-1, 0], dtype=np.int16)  # initially facing up in our coords
        self.count_infect = 0
    def burst(self):
        hash_pos = hash(self.pos.tostring())
        rotation = np.array([[0, -1], [1, 0]], dtype=np.int16)
        self.facing = np.dot(rotation, self.facing)
        if self.grid[hash_pos] == '#':
            self.grid[hash_pos] = '.'
            self.facing *= -1
        else:
            self.grid[hash_pos] = '#'
            self.count_infect += 1
        self.pos += self.facing

def count_infect(grid, size, n):
    test_virus = Virus(grid, size)
    for _ in range(n):
        test_virus.burst()
    return test_virus.count_infect

grid, size = parse_grid(test_input)

%%timeit
count_infect(grid, size, 10000)

directions = 'nesw'
directions2move = {'n': (0, 1), 's': (0, -1), 'e': (1, 0), 'w': (-1, 0)}

def parse(lines):
    nodes = []
    size = len(lines[0].strip())
    v = size // 2
    for i, line in enumerate(lines):
        for j, c in enumerate(line.strip()):
            if c == '#':
                nodes.append((j-v, (i-v)*(-1)))
    return set(nodes)

def burst(infected_nodes, pos, direction):
    x, y = pos

    # next direction
    if pos in infected_nodes:
        i = (directions.index(direction) + 1) % 4

        infected_nodes.remove(pos)

    else:
        i = (directions.index(direction) - 1) % 4

       ...