示例#1
0
def run2():
    cout_a, cout_b = deque(), deque()
    a = execute(Input(18), cout_a, pid=0)
    b = execute(Input(18), cout_b, pid=1)
    next(a)
    next(b)
    a_count = b_count = 0
    loop = 0
    while cout_a or cout_b:
        # print((cout_a, cout_b))
        try:
            a.send(cout_b.popleft())
            b_count += 1
        except IndexError as e:
            pass
        try:
            b.send(cout_a.popleft())
            a_count += 1
        except IndexError as e:
            pass
        # print((cout_a, cout_b))
        loop += 1
        if not loop % 10000:
            print(loop, len(cout_a), len(cout_b))

    return a_count, b_count
示例#2
0
            if c not in '#.':
                poi.append(c)
    return grid, start, poi


def moves_func(grid, state):
    location, visited = state
    for p in neighbors4(location):
        v = grid[p]
        if v == '#':
            continue
        if v == '.':
            yield (p, visited)
        else:
            yield (p, visited | {v})


def heur(poi, start, state):
    location, visited = state
    return (len(poi) - len(visited)) + (location != start)


if __name__ == '__main__':
    grid, start_point, goals = parse_grid(Input(24))
    start = (start_point, frozenset('0'))
    moves = partial(moves_func, grid)
    h = partial(heur, goals, start_point)
    p = astar_search(start, h_func=h, moves_func=moves)
    # print(p)
    print(len(p) - 1)
示例#3
0
            parts.append(remainder)
            break
        parts.append(expanded)
        string = remainder
    return ''.join(parts)


def decompress2(string):
    matcher = re.compile(r'\((\d+)x(\d+)\)').match
    length = 0
    i = 0
    while i < len(string):
        m = matcher(string, i)
        if m:
            i = m.end()
            num_chars, repetitions = [int(x) for x in m.groups()]
            length += repetitions * decompress2(string[i:i + num_chars])
            i += num_chars
        else:
            i += 1
            length += 1
    return length


if __name__ == '__main__':
    # assert decompress('A(2x2)BCD(2x2)EFG') == 'ABCBCDEFEFG'
    # assert decompress('(6x1)(1x3)A') == '(1x3)A'
    print(decompress2('X(8x2)(3x3)ABCY'))

    print(decompress2(Input(9).read().strip()))
示例#4
0
                send(*bot.send_high, high)
                bot.values.clear()


def send(to_type, to_id, value):
    if to_type == 'bot':
        bot = BOTS[to_id]
        bot.values.add(value)
        if len(bot.values) > 2:
            raise ValueError("bot {} is full and cannot receive".format(to_id))
        if 61 in bot.values and 17 in bot.values:
            print('ANSWER FOUND: BOT {} compairs 61 and 17'.format(to_id))
    elif to_type == 'output':
        try:
            OUTPUTS[to_id].add(value)
        except KeyError:
            OUTPUTS[to_id] = {value}
    return


if __name__ == '__main__':
    load_instructions(Input(10))
    simulate()
    to_mult = []
    for i in range(3):
        i = str(i)
        pprint(OUTPUTS[i])
        to_mult.append(OUTPUTS[i].pop())
    a, b, c = to_mult
    print(a * b * c)
示例#5
0
    grid = list(map(list, (r for r in transpose(grid))))
    grid = rotate_row(column, offset, grid)
    return list(map(list, (r for r in transpose(grid))))


def interpret_instruction(line, grid):
    if line.startswith('rect'):
        func = make_rect
    elif 'column' in line:
        func = rotate_column
    else:
        func = rotate_row

    args = map(int, re.findall('\d+', line))
    return func(*args, grid)


def print_grid(grid):
    for row in grid:
        print(''.join(row))
    print()


if __name__ == '__main__':
    grid = make_grid(6, 50)
    print_grid(grid)
    for line in Input(8):
        grid = interpret_instruction(line, grid)
        print_grid(grid)
    print(sum(c == ON for row in grid for c in row))
示例#6
0
        try:
            current_sq = grid[pos]
        except KeyError:
            current_sq = 'c'

        if current_sq == 'c':
            current_dir = (current_dir - 1) % 4
            grid[pos] = 'w'
        elif current_sq == 'w':
            grid[pos] = 'i'
        elif current_sq == 'i':
            current_dir = (current_dir + 1) % 4
            grid[pos] = 'f'
        elif current_sq == 'f':
            current_dir = (current_dir + 2) % 4
            del grid[pos]

        yield current_sq
        dr, dc = dirs[current_dir]
        r, c = pos
        pos = (r + dr, c + dc)


if __name__ == '__main__':
    grid, center = make_grid(Input(22))
    flips = 0
    g = burst(center, grid)
    for _ in range(10000000):
        flips += next(g) == 'w'
    print(flips)
示例#7
0
    if not remaining:
        return (0, 0, tuple())

    mx = (0, 0, tuple())
    for comp in (p for p in remaining if num in p):
        l, s, b = search(comp[comp[0] == num], remaining - {comp})
        b = b + (comp, )
        l = len(b)
        s = sum(map(sum, b))
        mx = max((mx, (l, s, b)))
    return mx


def get_most_valuable_bridge(components):
    mx = (0, 0, [])
    for c in (x for x in components if 0 in x):
        l, s, b = search(c[1], components - {c})
        b = b + (c, )
        l = len(b)
        s = sum(map(sum, b))
        mx = max((mx, (l, s, b)))
    return mx[0], mx[1], mx[2][::-1]


if __name__ == '__main__':
    components = parse(Input(24))
    l, s, b = get_most_valuable_bridge(components)
    print('Longest Bridge:', b)
    print('LENGTH:', len(b), 'components')
    print('STRENGTH:', s)
示例#8
0
#G.#.G#
#G..#.#
#...E.#
#######\
""".split('\n')) == 35 * 793 == 27755
assert simulate_fight("""\
#######
#.E...#
#.#..G#
#.###.#
#E#G#G#
#...#G#
#######\
""".split('\n')) == 54 * 536 == 28944
assert simulate_fight("""\
#########
#G......#
#.E.#...#
#..##..G#
#...##..#
#...#...#
#.G...G.#
#.....G.#
#########\
""".split('\n')) == 20 * 937 == 18740

print("Part 1:", simulate_fight(Input(15)))
print(
    "Part 2 (minimise the necessary amount of damage for no elven casualties):",
    simulate_fight(Input(15), intervention=True))
示例#9
0
.......
""".split()


def translate(instructions, keypad):
    x, y = 3, 1
    d_map = {  # south and north are switched because of row, col difference
        'U': 'S',
        'D': 'N',
        'L': 'W',
        'R': 'E',
    }

    code = []
    for line in instructions:
        for d in line.strip():
            nx, ny = point_from_movement((x, y), d_map[d])
            try:
                if keypad[ny][nx] != '.':
                    x, y = nx, ny
            except IndexError:
                print(ny, nx)
                raise
        code.append(keypad[y][x])
    return cat(code)


if __name__ == '__main__':

    print(translate(Input(2), pad2))
示例#10
0
def seq_3(seq):
    for i in range(len(seq) - 2):
        yield seq[i:i + 3]


def is_aba(seq_of_3):
    return seq_of_3[0] == seq_of_3[2] != seq_of_3[1]


def inverted(aba):
    a, b, _ = aba
    return ''.join((b, a, b))


def is_ssl(address):
    sections = re.split(r'\[|\]', address)
    outs = {s for sec in sections[::2] for s in seq_3(sec) if is_aba(s)}
    ins = {s for sec in sections[1::2] for s in seq_3(sec) if is_aba(s)}

    return any(inverted(seq) in ins for seq in outs)


if __name__ == '__main__':
    assert is_tls('abba[mnop]qrst')
    assert not is_tls('aaaa[qwer]tyui')
    assert not is_tls('abcd[bddb]xyyx')
    assert is_tls('ioxxoj[asdfgh]zxcvbn')

    print(sum(is_tls(a) for a in Input(7).read().split()))
    print(sum(is_ssl(a) for a in Input(7).read().split()))
示例#11
0
from common import Input

s = Input(1).read().strip()
numbers = []
for i, n in enumerate(s):
    if s[i - 1] == n:
        numbers.append(n)

print(sum(int(x) for x in numbers))

numbers = []
for i, n in enumerate(s):
    opposite = (i + len(s) // 2) % len(s)
    if s[opposite] == n:
        numbers.append(n)

print(sum(int(x) for x in numbers))
示例#12
0
    if not pos:
        pos = (0, maze[0].index('|'))
    if not delta:
        delta = (1, 0)

    steps = 1
    x, y = pos
    dx, dy = delta
    letters = []
    while maze[x][y] != '+':
        x += dx
        y += dy
        if maze[x][y] == ' ':
            return ''.join(letters), steps
        if maze[x][y] not in '+-|':
            letters.append(maze[x][y])
        steps += 1

    other_dir = DELTAS - {(-dx, -dy)}
    for dx, dy in other_dir:
        if maze[x + dx][y + dy] != ' ':
            x += dx
            y += dy
            let, s = follow_path(maze, (x, y), (dx, dy))
            return ''.join(letters) + let, steps + s


if __name__ == '__main__':
    maze = make_maze(Input(19))
    print(follow_path(maze))
示例#13
0
            inst = 'jnz'
        # print(instructions[index], ' at ', index, ' changed to ', [inst, args])
        instructions[index] = [inst, args]

    def out(x):
        yield resolve(x)

    instruction_set = {
        'cpy': cpy,
        'inc': inc,
        'dec': dec,
        'jnz': jnz,
        'tgl': tgl,
        'out': out,
    }

    a = 0
    while True:
        register = {
            'a': a,
            'b': 0,
            'c': 0,
            'd': 0,
            'i': 0,
        }

        if verify(execute(register, instruction_set, Input(25)), register):
            print('DONE: ', a)
            break
        a += 1
示例#14
0
    return int(re.findall('\d+', room)[0])


def decrypt_name(line):
    name = line.rsplit('-', 1)[0]
    ID = get_id(line)
    offset = ID % 26
    mapping = {
        chr(i + ord('a')): chr(ord('a') + (i + offset) % 26)
        for i in range(0, 27)
    }
    mapping['-'] = ' '
    trans = str.maketrans(mapping)
    name = name.translate(trans)
    return line, name


if __name__ == '__main__':
    assert is_real('aaaaa-bbb-z-y-x-123[abxyz]')
    assert is_real('a-b-c-d-e-f-g-h-987[abcde]')
    assert is_real('not-a-real-room-404[oarel]')
    assert not is_real('totally-real-room-200[decoy]')

    print(sum(get_id(l) for l in Input(4) if is_real(l.strip())))

    print(decrypt_name('qzmt-zixmtkozy-ivhz-343'))

    for line, name in (decrypt_name(line) for line in Input(4)):
        if 'north' in name:
            print(line, name)
示例#15
0
if __name__ == '__main__':

    def cpy(x, y):
        register[y] = resolve(x)

    def inc(x):
        register[x] += 1

    def dec(x):
        register[x] -= 1

    def jnz(x, y):
        register['i'] += resolve(y) - 1 if resolve(x) != 0 else 0

    instruction_set = {
        'cpy': cpy,
        'inc': inc,
        'dec': dec,
        'jnz': jnz,
    }
    register = {
        'a': 0,
        'b': 0,
        'c': 1,
        'd': 0,
        'i': 0,
    }

    register = execute(register, instruction_set, Input(12))
    print(register)
示例#16
0
        return self.__class__(x, y, z)

    def __abs__(self):
        x = abs(self.x)
        y = abs(self.y)
        z = abs(self.z)
        return self.__class__(x, y, z)

    def __repr__(self):
        return "HexPoint({s.x}, {s.y}, {s.z})".format(s=self)


def hex_distance(a, b=(0, 0, 0)):
    if not isinstance(a, HexPoint):
        a = HexPoint(*a)
    if not isinstance(b, HexPoint):
        b = HexPoint(*b)
    d = abs(a - b)
    return (d.x + d.y + d.z) // 2


if __name__ == '__main__':
    pos = HexPoint(0, 0, 0)
    furthest = 0
    for d in Input(11).read().strip().split(','):
        pos += DIR[d]
        furthest = max((hex_distance(pos), furthest))
    print(pos)
    print(hex_distance(pos))
    print("Furthest:", furthest)
示例#17
0
from common import Input, transpose, cat
from collections import Counter

if __name__ == '__main__':

    data = Input(6).read().split()

    t_data = [col for col in transpose(data)]
    couters = [Counter(m) for m in t_data]

    frequenc_items = [m.most_common(1)[0][0] for m in couters]

    print(cat(frequenc_items))
示例#18
0
from common import Input
from my_utils.graphs import dijkstra_all_paths
import re

graph = {}

for line in Input(12):
    node, *connections = re.findall(r'\d+', line)
    graph[node] = connections

moves = lambda x: graph[x]
paths = dijkstra_all_paths('0', moves).parents
print(len(paths))

remaining_nodes = set(graph) - set(paths)
groups = [paths]
while remaining_nodes:
    group = set(dijkstra_all_paths(remaining_nodes.pop(), moves).parents)
    remaining_nodes -= group
    groups.append(group)
print(len(groups))
示例#19
0
from common import Input
import re

data = Input(9).read()
data = re.sub(r'!.', '', data)

level = 0
score = 0
garbage_count = 0
not_garbage = True
i = 0
while i < len(data):
    c = data[i]
    if c == '<' and not_garbage:
        not_garbage = False
        garbage_count -= 1
    if c == '>':
        not_garbage = True
    if c == '{':
        level += 1 * not_garbage
        score += level * not_garbage
    if c == '}':
        level += (-1 * not_garbage)
    garbage_count += not not_garbage
    i += 1

print(score, garbage_count)
示例#20
0
            particles -= set(g)


def parse_input(inp):
    particles = set()
    for i, line in enumerate(inp):
        parts = re.findall(r'<(.+?)>', line)
        parts = [np.array(list(map(int, p.split(',')))) for p in parts]
        particles.add(Particle(*parts, id=i))
    return particles


def nearest_origin_long_term(particles, prune=True):
    ticks = tick_till_moving_away(particles, prune)
    print('simulated', ticks, 'ticks')

    def key_func(p):  # all manhattan >= |vec| so unnecessary
        """key is a tuple because velocity away from origin will always
        tump position, and acceleration will always trump both for greater t"""
        return magnitude(p.acc), abs(-p.pos @ p.vel), magnitude(p.pos)

    return min(particles, key=key_func)


if __name__ == '__main__':
    particles = parse_input(Input(20))
    p = nearest_origin_long_term(particles, prune=True)
    print(p)
    print('Particle #', p.id, sep='')
    print(len(particles))
示例#21
0
def parse(Input):
    units = frozenset(
        tuple(map(int, x)) for x in re.findall(r'(\d+)/(\d+)', Input.read()))
    return units
示例#22
0
from common import Input

data = [int(x) for x in Input(5)]

i = 0
counter = 0

try:
    while i > -1:
        if data[i] < 3:
            data[i] += 1
            i += data[i] - 1
        else:
            data[i] -= 1
            i += data[i] + 1
        counter += 1
except IndexError:
    print(counter)
示例#23
0
    weight_count = lambda x: weights_list.count(x)
    odd_weight, correct_weight, *_ = sorted(weights_list, key=weight_count)
    diff = odd_weight - correct_weight
    odd_child = [w for w in weights if weights[w] == odd_weight][0]
    message = 'Tree is unbalanced: "{}" weighs {}, but should weigh {}.'
    message = message.format(odd_child.name, odd_child.weight,
                             odd_child.weight - diff)
    raise UnbalancedTree(message)


if __name__ == '__main__':
    parent = {}
    weight = {}

    for line in Input(7):
        m = re.match(r'^(\w+) \((\d+)\)(?: -> (.*))?$', line)
        name, w, children = m.groups()
        weight[name] = int(w)
        if name not in parent:
            parent[name] = None
        if not children: continue
        for c in children.split(', '):
            parent[c] = name

    base = [n for n in parent if parent[n] is None][0]
    print('Base Program:', base)

    tree = build_tree(base, parent, weight)
    try:
        w = weigh_balanced_tree(tree)
示例#24
0
        if verbose:
            print(' after: ', data)
    return data


if __name__ == '__main__':
    data = 'abcde'
    instructions = """swap position 4 with position 0
swap letter d with letter b
reverse positions 0 through 4
rotate left 1 step
move position 1 to position 4
move position 3 to position 0
rotate based on position of letter b
rotate based on position of letter d""".splitlines()

    instructions = compile_instructions(instructions)
    ans = execute(data, instructions)
    print(ans)
    assert ans == 'decab'

    instructions = compile_instructions(Input(21))
    data = 'abcdefgh'
    data = execute(data, instructions)
    print(data)

    for p in itertools.permutations('fbgdceah'):
        if execute(p, instructions, verbose=False) == 'fbgdceah':
            print(''.join(p))
            break
示例#25
0
                continue
            if avail >= used:
                pairs[x, y].add((i, j))

    return grid, pairs


def moves_func(grid, state):
    empty, target = state
    transfers = [(x, y) for x, y in neighbors4(empty) if (x, y) in grid]
    for n in transfers:
        if grid[empty][SIZE] > grid[n][USED]:
            yield (n, empty if n == target else target)


def heur_func(state):
    _, target = state
    return cityblock_distance(target)


if __name__ == '__main__':
    grid, pairs = parse(Input(22))
    print(sum(len(s) for s in pairs.values()))
    empty = [n for n in grid if grid[n][USED] == 0][0]
    moves_func = functools.partial(moves_func, grid)
    maxx = max(n[0] for n in grid)
    start = (empty, (maxx, 0))
    path = astar_search(start, heur_func, moves_func=moves_func)
    print(path)
    print(len(path) - 1)
示例#26
0
def distribute_cycle(mem):
    blocks = len(mem)
    while True:
        i = max(range(blocks), key=lambda x: mem[x])
        items = mem[i]
        mem[i] = 0
        while items:
            i = (i + 1) % blocks
            mem[i] += 1
            items -= 1
        yield tuple(mem)


if __name__ == '__main__':

    mem = [int(x) for x in Input(6).read().split()]
    states = {tuple(mem)}

    for c, state in enumerate(distribute_cycle(mem), 1):
        if state in states:
            print(c)
            break
        states.add(state)

    goal = tuple(mem)
    for c, state in enumerate(distribute_cycle(mem), 1):
        if state == goal:
            print(c)
            break
示例#27
0
    elif cmd.startswith('rotate row'):
        screen[A, :] = rotate(screen[A,:], B)
    elif cmd.startswith('rotate col'):
        screen[:,A] = rotate(screen[:, A], B)
        

def rotate(items, n): return np.append(items[-n:], items[:-n])

def Screen(): return np.zeros((6, 50), dtype = np.int)

def run(commands, screen):
    for cmd in commands:
        interpret(cmd,screen)
    return screen


screen = run(Input(8), Screen())
print(np.sum(screen))
for row in screen:
    # print(cat(' @'[pixel] for pixel in row))
    #  print([' @'[pixel] for pixel in row])
    # print([[pixel] for pixel in row])
    print(cat( ' @' if pixel == 1 else '  ' for pixel in row))


# a = np.zeros((6,6), dtype=int)

# b = [1,2, 3]

# c = [' @'[m] for m in b]
# print(c)
示例#28
0
from my_utils.iteration import transpose
from common import Input
import re

if __name__ == '__main__':

    t = [[101, 301, 501],
    [102, 302, 502],
    [103, 303, 503],
    [201, 401, 601],
    [202, 402, 602],
    [203, 403, 603]]



    tris = re.findall('\d+', Input(3).read())
    tris = [tris[s+offset:s+9:3] for s in range(0,len(tris),9) for offset in range(3)]
    tris = [sorted(map(lambda i: int(i), tri)) for tri in tris]
    possible = (sum(tri[:2]) > tri[2] for tri in tris)
    print(sum(possible))
示例#29
0
            yield False
            continue

        scanner = get_scanner_pos(width, step + start_step)
        print(step, step + start_step, scanner) if verbose else 0

        if scanner == 0:
            yield True
        else:
            yield False


def get_scanner_pos(width, step):
    period = width + width - 2
    if step % period == 0:
        return 0
    else:
        return -1


def find_min_delay(layers):
    for i in count():
        if not any(severity_gen(layers, i)):
            return i


if __name__ == '__main__':
    layers = dict(tuple(map(int, (line.split(': ')))) for line in Input(13))
    test_layers = {0: 3, 1: 2, 4: 4, 6: 4}
    print(find_min_delay(layers))
示例#30
0
                next_floor = state.floor[e] | set(obj)
                if not valid_floor(prev_floor) or not valid_floor(next_floor):
                    continue
                floors = list(state.floor)
                floors[state.elevator] = prev_floor
                floors[e] = next_floor
                yield State(e, tuple(floors))

def valid_floor(floor):
    chips = [x[0] for x in floor if x[1].startswith('micro')]
    gens = [x[0] for x in floor if x[1].startswith('gen')]
    if gens:
        if chips:
            if any(c not in gens for c in chips):
                return False
    return True

def sum_dist_from_top(state):
    total = 0
    for value, floor in enumerate(reversed(state.floor)):
        total += value*len(floor)
    return total


if __name__ == '__main__':
    start = initalize(Input(11))
    pprint(start)
    path = astar_search(start, h_func=sum_dist_from_top, moves_func=get_moves)
    pprint(path)
    print(len(path)-1, ' steps needed.')