Пример #1
0
def bags_inside(color, rules, depth = 0):
    qty = 1
    depth_prefix = '....' * depth
    print('%sLooking for bags inside %s' % (depth_prefix, color))
    for inner_color in rules[color]:
        inner_qty = rules[color][inner_color]
        print('%s....inner_qty for %s: %d' % (depth_prefix, inner_color, inner_qty))
        if inner_qty == 0:
            continue
        qty += inner_qty * bags_inside(inner_color, rules, depth + 1)
    print('%sBags inside %s: %d' % (depth_prefix, color, qty))
    return qty


state = {'rules': {}}
utils.call_for_lines(parse_rules, state)
#for k in sorted(state['rules']):
#    print('%s: %r' % (k, state['rules'][k]))

colors = set(state['rules'].keys())
colors.add('shiny gold')
print('Colors: %r' % colors)

nodes = dict((color, Node()) for color in colors)
for outer_color in state['rules']:
    for inner_color in colors:
        if get_qty(outer_color, inner_color, state['rules']) > 0:
            nodes[inner_color].srcs.add(nodes[outer_color])
#print('Nodes: %r' % nodes)

Пример #2
0
        if p[0] == p2[0] and p[1] == p2[1]:
            return

        p[0] += p_delta[0]
        p[1] += p_delta[1]


state = {
    'field':
    collections.defaultdict(lambda: collections.defaultdict(lambda: 0)),
    'min_x': 0,
    'min_y': 0,
    'max_x': 0,
    'max_y': 0,
}
utils.call_for_lines(process_line, state)

twopoints = 0
for y in range(state['min_y'], state['max_y'] + 1):
    row = state['field'][y]
    cells = []
    for x in range(state['min_x'], state['max_x'] + 1):
        if row[x] > 0:
            if row[x] >= 2:
                twopoints += 1
            cells.append(str(row[x]))
        else:
            cells.append('.')
    print(''.join(cells))

print(twopoints)
Пример #3
0
    def __str__(self):
        return '({} * {}) => {}'.format(self.x, self.y, self.x*self.y)


def execute_command(command, state, _):
    (direction_s, magnitude_s) = command.split(' ')
    magnitude = int(magnitude_s)
    vector = {
        'forward': Vector(magnitude, 0),  # Day 1 only
        'down': Vector(0, magnitude),  # Y coordinate is *depth*, so 'down' increases it
        'up': Vector(0, -magnitude),
    }[direction_s]

    # Day 1
    state['position1'].add(vector)

    if direction_s == 'forward':
        vector = Vector(magnitude, magnitude*state['aim'])
        state['position2'].add(vector)
        #print('day2: Aim of {} added {}, now at {}'.format(state['aim'], vector, state['position2']))
    elif direction_s == 'down':
        state['aim'] += magnitude
    elif direction_s == 'up':
        state['aim'] -= magnitude


state = {'position1': Vector(), 'position2': Vector(), 'aim': 0}
utils.call_for_lines(execute_command, state)
print('Day 1 rules: {}'.format(state['position1']))
print('Day 2 rules: {}'.format(state['position2']))
Пример #4
0

state = {
    'depth1': Depth1(),
    'depth3_windows': [Depth3Window(), Depth3Window(), Depth3Window()],
    'depth3_increase_count': 0,
}


def saw_depth(line, state, line_idx):
    depth = int(line)
    #print('Got depth {}'.format(depth))
    state['depth1'].new_depth(depth)

    for (window_idx, prev_window_idx) in ((0, 2), (1, 0), (2, 1)):
        depth3_window = state['depth3_windows'][window_idx]
        depth3_prev = state['depth3_windows'][prev_window_idx]

        depth3_window.new_depth(depth)
        if depth3_window.depth3 is not None:
            window_depth = depth3_window.depth()
            prev_window_depth = depth3_prev.depth()
            #print('Depth {} has window={}, prev={}'.format(depth, window_depth, prev_window_depth))
            if prev_window_depth is not None and window_depth > prev_window_depth:
                state['depth3_increase_count'] += 1            


utils.call_for_lines(saw_depth, state)
print(state['depth1'].depth_increase_count)
print(state['depth3_increase_count'])
Пример #5
0
            candidate_set = state['allergen_candidates'][allergen]
            print('Previous potential sources of allergen %r: %r' %
                  (allergen, candidate_set))
            candidate_set.intersection_update(ingredients)
            print('After incorporating %r: %r' % (ingredients, candidate_set))
        else:
            print('Potential sources of allergen %r: %r' %
                  (allergen, ingredients))
            state['allergen_candidates'][allergen] = set(ingredients)


state = {
    'ingredient_count': collections.defaultdict(lambda: 0),
    'allergen_candidates': {}
}
utils.call_for_lines(ParseFood, state)
print('')

print('Allergen candidates:')
allergens_by_ingredient = collections.defaultdict(set)
for allergen in sorted(state['allergen_candidates'].keys()):
    allergen_candidates = state['allergen_candidates'][allergen]
    print('%s: %r' % (allergen, allergen_candidates))
    for ingredient in allergen_candidates:
        allergens_by_ingredient[ingredient].add(allergen)
print('')

while True:
    unique_candidates = set(
        list(candidates)[0]
        for (allergen, candidates) in state['allergen_candidates'].items()
Пример #6
0
    state['wx'] += wp_vector[0] * magnitude
    state['wy'] += wp_vector[1] * magnitude
    if rotate:
        normalized_rotate = rotate % 360
        clockwise_rotations = int(normalized_rotate / 90)
        #print('Rotating %r aka %d (%d turns), starting at (%d, %d' % (line, normalized_rotate, clockwise_rotations, wx, wy))
        for _ in range(clockwise_rotations):
            wx = state['wx']
            wy = state['wy']
            state['wx'] = wy
            state['wy'] = -wx
    print('State after %r: %r' % (line, state))


state = {'x': 0, 'y': 0, 'wx': 10, 'wy': 1}
utils.call_for_lines(moveit, state)
print('At (%d, %d), %d from origin' %
      (state['x'], state['y'], abs(state['x']) + abs(state['y'])))
"""
.....|.....
.....|.....
.....|.o...
.....|.....
.....|.....
=====*=====
.....|.....
.....|.....
.....|.....
.....|.....
.....|.....
Пример #7
0
def find_combinations(deltas):
    if len(deltas) == 1:
        return 1

    deltas = deltas[:]
    delta = deltas.pop(0)
    deltas[0] += delta
    if deltas[0] > 3:
        return 1 * find_combinations(deltas)
    else:
        return 2 * find_combinations(deltas)


state = {'jolts': [0]}
utils.call_for_lines(foo, state)
jolts = sorted(state['jolts'])
jolts.append(jolts[-1] + 3)

deltas = []
curr_jolts = 0
for jolt in jolts:
    deltas.append(jolt - curr_jolts)
    curr_jolts = jolt
#combinations = find_combinations(deltas)
print(deltas)

# I don't understand the logic here, but through looking at the two examples, it seems that
# the answer is to look for runs of 1's in the "deltas" list.
#
# Number of runs of 4 1's = a
Пример #8
0
        elif c in ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'):
            curr_token.append(c)
        else:
            raise Exception('Unknown character %r at pos %d of %r' %
                            (c, i, line))
    if stack:
        raise Exception('Missing close paren in %r' % line)
    finish_token(curr_token, curr_tokens)
    val = eval_expr(curr_tokens)
    print('{0}: {1}'.format(line, val))
    state['sum'] += val


def eval_expr(tokens):
    #print('Evaluating %r' % tokens)
    val = tokens.pop(0)
    while tokens:
        token = tokens.pop(0)
        if token == '+':
            val += tokens.pop(0)
        elif token == '*':
            val *= tokens.pop(0)
        else:
            raise Exception('Unexpected token %r' % token)
    return val


state = {'sum': 0}
utils.call_for_lines(calculate, state)
print('Grand total: %d' % state['sum'])
Пример #9
0
    acc = state['acc']

    if ip == len(state['instructions']):
        print('Program terminating normally with acc=%d.' % acc)
        sys.exit(0)
    elif ip > len(state['instructions']) or ip < 0:
        print('Program terminating abnormally, inslen=%d, ip=%d, acc=%d' % (len(state['instructions']), ip, acc))
        sys.exit(1)
    ins = state['instructions'][ip]

    visited = state['visited']
    if ip in visited and not state['solved_pt1']:
        print('**PART 1 SOLUTION** -- ip=%d, acc=%d' % (ip, acc))
        state['solved_pt1'] = True

    if acc in visited[ip]:
        print('Infinite loop: Already visited ip=%d with acc=%d' % (ip, acc))
        sys.exit(0)
    visited[ip].add(acc)
    
    ins[0](ins[1], state)
    new_ip = state['ip']
    new_acc = state['acc']
    print('Executing %s: ip=%d, acc=%d --> ip=%d, acc=%d' % (ins[2], ip, acc, new_ip, new_acc))
    

state = {'instructions': [], 'ip': 0, 'acc': 0, 'visited': collections.defaultdict(set), 'solved_pt1': False}
utils.call_for_lines(parse_code, state)
while True:
    step(state)
Пример #10
0
    mask_0 = 0
    mask_1 = 0
    for bit in range(36):
        mask_char = mask[35 - bit]
        if mask_char == '0':
            mask_0 |= 1 << bit
        elif mask_char == '1':
            mask_1 |= 1 << bit
    print('mask_0: {0} ({0:036b})'.format(mask_0))
    print('mask_1: {0} ({0:036b})'.format(mask_1))
    state['mask_0'] = mask_0
    state['mask_1'] = mask_1


def do_line(line, state):
    if line.startswith('mask'):
        do_mask(line, state)
    else:
        do_write(line, state)


state = {
    'mask_0': 0,
    'mask_1': 0,
    'memory': collections.defaultdict(lambda: 0)
}
utils.call_for_lines(do_line, state)
for addr in sorted(state['memory'].keys(), key=int):
    print('{0}: {1} ({1:036b})'.format(addr, state['memory'][addr]))
print(functools.reduce(operator.add, state['memory'].values()))
Пример #11
0
        new_candidates = []
        for candidate in candidates:
            #print('Candidate {} has value {} (?= {})'.format(''.join(candidate), candidate[bit_idx], desired_bit))
            if candidate[bit_idx] == desired_bit:
                new_candidates.append(candidate)
        candidates = new_candidates
        bit_idx += 1
    #print('Found value: {}'.format(''.join(candidates[0])))
    return ''.join(candidates[0])


state = {
    'all_numbers': [],
    'bit_count': collections.defaultdict(lambda: [0, 0]),
}
utils.call_for_lines(find_set_bits, state)

# Day 1
gamma_rate = []
epsilon_rate = []
for bit in state['bit_count'].values():
    if bit[0] > bit[1]:
        gamma_rate.append('0')
        epsilon_rate.append('1')
    else:
        gamma_rate.append('1')
        epsilon_rate.append('0')
gamma_rate = ''.join(gamma_rate)
gamma_num = int(gamma_rate, base=2)
epsilon_rate = ''.join(epsilon_rate)
epsilon_num = int(epsilon_rate, base=2)