Beispiel #1
0
def get_aws_instance_info(proxy):
    def state(instance):
        try:
            return instance.state['Name']
        except Exception:
            return 'UNKNOWN'

    def groups(instance):
        return ','.join([g['GroupId'] for g in instance.security_groups])

    keys = [aws_name_from_tag, attr('instance_id'), attr('instance_type'),
            state, attr('public_ip_address'), attr('private_ip_address'),
            attr('key_name'), groups]
    headers = ['Name', 'ID', 'Type', 'State', 'Public IP', 'Private IP',
               'Key Name', 'Security Groups']

    return headers, [[f(i) for f in keys] for i in proxy.get_instances()]
Beispiel #2
0
def get_aws_volume_info(proxy):
    def instance_id(volume):
        for a in volume.attachments:
            if a['State'] == 'attached':
                return a['InstanceId']
        return ''

    def instance_name(instances):
        instance_dict = {i.id: aws_name_from_tag(i) for i in instances}

        def _instance_name(volume):
            _id = instance_id(volume)
            if _id != '':
                return instance_dict[_id]

            return ''

        return _instance_name

    def device(volume):
        for a in volume.attachments:
            if a['State'] == 'attached':
                return a['Device']
        return ''

    keys = [
        aws_name_from_tag,
        attr('id'),
        attr('state'),
        attr('size'),
        attr('availability_zone'),
        instance_name(proxy.get_instances()),
        instance_id,
        device]

    headers = ['Name', 'Volume ID', 'State', 'Size', 'Zone',
               'Instance Name', 'Instance ID', 'Device']

    return headers, [[f(v) for f in keys] for v in proxy.get_volumes()]
Beispiel #3
0
def trace(asteroids):
    for i in range(len(asteroids)):
        asteroid = asteroids[i]
        for j in range(i + 1, len(asteroids)):
            other = asteroids[j]
            x, y = (a - b for a, b in zip(asteroid.coords, other.coords))
            slope = (y / x) if x != 0 else infinity
            positive = other.coords > asteroid.coords
            asteroid.traces[(slope, positive)].append(other)
            other.traces[(slope, not positive)].append(asteroid)

    # sort by distance
    for asteroid in asteroids:
        sortByDistance = compose(Point(asteroid.coords).manhattan, Point, attr('coords'))
        for slope in asteroid.traces:
            asteroid.traces[slope] = sorted(asteroid.traces[slope], key=sortByDistance)
        
    return asteroids
Beispiel #4
0
from utils import cmap, compose, invoker, at, attr
from functools import partial, reduce
from itertools import permutations
from aoc.intcode import Runner

parse = compose(list, cmap(int), invoker('split', ','))

def solve(input, intcode):
    runner = Runner(iter(input))
    runner.run(intcode)
    return intcode, runner

one = compose(at(-1), attr('output'), at(1), partial(solve, [1]), parse)
two = compose(attr('output'), at(1), partial(solve, [2]), parse)
Beispiel #5
0
            other.traces[(slope, not positive)].append(asteroid)

    # sort by distance
    for asteroid in asteroids:
        sortByDistance = compose(Point(asteroid.coords).manhattan, Point, attr('coords'))
        for slope in asteroid.traces:
            asteroid.traces[slope] = sorted(asteroid.traces[slope], key=sortByDistance)
        
    return asteroids

def laserize(asteroid):
    # sorter of asteroid tracings depending on the laser movement
    def laserSort(slope, positive):
        prioritize_if = lambda value: 0 if value else 1
        startPointingUp = prioritize_if(slope == infinity and not positive)
        clockwise = (prioritize_if(positive), slope)
        return startPointingUp, clockwise
    
    rotation = cycle(sorted(asteroid.traces.keys(), key=unpack(laserSort)))
    while any(asteroid.traces.values()):
        aligned = asteroid.traces[next(rotation)]
        if aligned:
            yield aligned.pop(0)


# since we already split traces by line and direction, we simply need to count how many different line/directions there are
countAdjacent = compose(len, attr('traces'))
one = compose(countAdjacent, partial(max, key=countAdjacent), trace, parse)

formatResult = lambda asteroid: asteroid.coords[0]*100 + asteroid.coords[1]
two = compose(formatResult, next, lambda laser: islice(laser, 200 - 1, None), laserize, partial(max, key=countAdjacent), trace, parse)
Beispiel #6
0
gravitate = lambda body, towards, velocity: velocity + Point(
    tuple(sign(b - a) for a, b in zip(body.position, towards.position)))

adjust = lambda system: [
    alter('velocity',
          compose(*[partial(gravitate, body, other) for other in rest]))(body)
    for body, rest in isolate(system)
]
move = lambda system: [
    alter('position', lambda position: position + body.velocity)(body)
    for body in system
]
step = compose(move, adjust)

energy = compose(sum, cmap(abs))
potential = compose(energy, attr('position'))
kinetic = compose(energy, attr('velocity'))
total_energy = lambda system: sum(
    potential(body) * kinetic(body) for body in system)


# We can see that gravity forces among planets affects each axis independently; i.e. the update to each
# coordinate of the velocity vectors solely depend on the relative positions of the planets along that axis.
# This means repeating cycles happen independently across all axis, so we can find the full-system repeating cycle length
# by computing the least common multiple of all axis cycle lengths.
def first_repeat(system):
    dimension = system[0].position.dimension
    # serializer of one axis for comparison between system states
    serialize_axis = lambda system, axis: [
        body.position[axis] for body in system
    ] + [body.velocity[axis] for body in system]
Beispiel #7
0
        elif turn == Robot.RIGHT:
            return Point((b, -a))
        raise "Invalid turn"


parse = compose(list, cmap(int), invoker('split', ','))


def solve(intcode, grid):
    robot = Robot(Runner())
    robot.paint_all(intcode, grid)
    return grid, robot


makeGrid = lambda defaults={}: defaultdict(lambda: BLACK, defaults)


def display(grid):
    xs = sorted([p[0] for p, color in grid.items() if color == WHITE])
    ys = sorted([p[1] for p, color in grid.items() if color == WHITE])
    paintWhite = lambda color: color if color == WHITE else ' '
    # for some reason we need to flip it vertically for it to display properly
    return '\n'.join(''.join(
        paintWhite(grid[(i, j)]) for i in range(xs[0], xs[-1] + 1))
                     for j in range(ys[-1], ys[0] - 1, -1))


one = compose(len, attr('painted'), at(1), unpack(solve), lambda intcode:
              (intcode, makeGrid()), parse)
two = compose(display, at(0), unpack(solve), lambda intcode:
              (intcode, makeGrid({(0, 0): WHITE})), parse)