Ejemplo n.º 1
0
                if 0 <= y + dy < n and 0 <= x + dx < m:
                    q += (x + dx, y + dy),
        return not grid[y][x]

    for round in range(1, (steps or 999) + 1):
        q = []
        for x in range(m):
            for y in range(n):
                flashes += flash(q, x, y)
        while q:
            x, y = q.pop()
            if grid[y][x]:
                flashes += flash(q, x, y)
        if set(x for row in grid for x in row) == {0}:
            return round
    return flashes


if __name__ == "__main__":
    change_dir(__file__)

    test(0, solve(steps=1, file='input-test-1'))
    test(35, solve(steps=2, file='input-test-1'))
    test(80, solve(steps=3, file='input-test-1'))
    test(204, solve(steps=10, file='input-test-1'))
    test(1656, solve(steps=100, file='input-test-1'))
    test(1700, solve(steps=100, file='input-real'))

    test(195, solve(steps=200, file='input-test-1'))
    test(273, solve(steps=999, file='input-real'))
Ejemplo n.º 2
0
def solve(part, goal, file):
    dp = [[] for _ in range(151)]
    dp[0].append([])
    jugs = sorted(load_ints(file))

    def backtrack(i, remaining, count=0):
        if i < 0:
            if remaining == 0:
                yield count
        else:
            yield from backtrack(i - 1, remaining, count)
            if remaining >= jugs[i]:
                yield from backtrack(i - 1, remaining - jugs[i], count + 1)

    res = list(backtrack(len(jugs) - 1, goal))
    if part == 2:
        res = list(next(groupby(sorted(res)))[1])
    return len(res)


### THE REST IS TESTS ###

if __name__ == "__main__":
    change_dir(__file__)

    test(4, solve(part=1, goal=25, file='input-test-1'))
    test(4372, solve(part=1, goal=150, file='input-real'))

    test(3, solve(part=2, goal=25, file='input-test-1'))
    test(4, solve(part=2, goal=150, file='input-real'))
Ejemplo n.º 3
0
  s = data[0][0]
  C = Counter(zip(s, s[1:]))

  for _ in range(steps):
    D = Counter()
    for (a, b), v in C.items():
      c = rules[a, b]
      D[a, c] += v
      D[c, b] += v
    C = D

  D = Counter((s[0], s[-1]))
  for (a, b), v in C.items():
    D[a] += v
    D[b] += v
  mc = D.most_common()
  return (mc[0][1] - mc[-1][1]) // 2


### THE REST IS TESTS ###

if __name__ == "__main__":
  change_dir(__file__)

  test(1588, solve(steps=10, file='input-test-1'))
  test(2851, solve(steps=10, file='input-real'))

  test(2188189693529, solve(steps=40, file='input-test-1'))
  test(10002813279337, solve(steps=40, file='input-real'))
Ejemplo n.º 4
0
parens = '([{<)]}>'


def get_score(s):
  stack = []
  for c in s.strip():
    if c in parens[:4]:
      stack += c,
    elif c != parens[parens.index(stack.pop()) + 4]:
      return (points[parens.index(c)], 0)
  score = 0
  while stack:
    score = score * 5 + points[parens.index(stack.pop())]
  return (0, score)


def solve(part, file):
  data = load(file)
  res = filter(None, (get_score(line)[part-1] for line in data))
  return (sum, median)[part-1](res)


if __name__ == "__main__":
  change_dir(__file__)

  test(26397, solve(part=1, file='input-test-1'))
  test(345441, solve(part=1, file='input-real'))  # not 320361

  test(288957, solve(part=2, file='input-test-1'))
  test(3235371166, solve(part=2, file='input-real'))
Ejemplo n.º 5
0
        block.split('\n') for block in '\n'.join(lines).split('inp w\n')[1:]
    ]
    model = [0] * 14
    stack = []
    for i, block in enumerate(blocks):
        if block[3] == 'div z 1':
            x = int(block[14].split(' ')[-1])
            stack.append((i, x))
        elif block[3] == 'div z 26':
            y = int(block[4].split(' ')[-1])
            j, x = stack.pop()
            diff = x + y
            if diff < 0:
                i, j, diff = j, i, -diff
            if part == 1:
                model[i] = 9
                model[j] = 9 - diff
            else:
                model[i] = 1 + diff
                model[j] = 1
    return int(''.join(map(str, model)))


### THE REST IS TESTS ###

if __name__ == "__main__":
    change_dir(__file__)

    test(93997999296912, solve(part=1, file='input-real'))
    test(81111379141811, solve(part=2, file='input-real'))
Ejemplo n.º 6
0
        elif tokens[0] == 'rotate' and tokens[1] == 'based':
            if part == 1:
                s = rotate_by_letter(s, tokens[-1])
            else:
                s = rotate_by_letter_inverse(s, tokens[-1])
        else:
            raise Exception('no match', line)
    return ''.join(s)


### THE REST IS TESTS ###

if __name__ == "__main__":
    change_dir(__file__)

    test('ebcda', ''.join(swap_pos(list('abcde'), 4, 0)))
    test('edcba', ''.join(swap_letter(list('ebcda'), 'd', 'b')))
    test('abcde', ''.join(reverse(list('edcba'), 0, 4)))
    test('bcdea', ''.join(rotate_left(list('abcde'), 1)))
    test('eabcd', ''.join(rotate_right(list('abcde'), 1)))
    test('bdeac', ''.join(move(list('bcdea'), 1, 4)))
    test('abdec', ''.join(move(list('bdeac'), 3, 0)))
    test('ecabd', ''.join(rotate_by_letter(list('abdec'), 'b')))
    test('decab', ''.join(rotate_by_letter(list('ecabd'), 'd')))

    test('decab', solve(part=1, input='abcde', file='input-test-1'))
    test('baecdfgh', solve(part=1, input='abcdefgh', file='input-real'))

    for x in range(8):
        for y in range(8):
            test('abcdefgh',
Ejemplo n.º 7
0
#!/usr/bin/env python3

from collections import Counter
from functools import reduce

from common.util import load_csv, test, change_dir


def solve(days, file):
    data = [*map(int, load_csv(file)[0])]
    return sum(
        reduce(
            lambda c, _: Counter({x - 1: v
                                  for x, v in c.items()
                                  if x}) + Counter({
                                      6: c[0],
                                      8: c[0]
                                  }), range(days), Counter(data)).values())


if __name__ == "__main__":
    change_dir(__file__)

    test(26, solve(days=18, file='input-test-1'))
    test(362740, solve(days=80, file='input-real'))

    test(26984457539, solve(days=256, file='input-test-1'))
    test(1644874076764, solve(days=256, file='input-real'))
Ejemplo n.º 8
0
        x0, x1 = x1 - q * x0, x0
    if x1 < 0:
        x1 += b0
    return x1


def load_discs(file):
    return [parse_nums(line)[3::-2] for line in load(file)]


def solve(part, file):
    discs = load_discs(file)
    if part == 2:
        discs.append([0, 11])
    for i in range(len(discs)):
        x, size = discs[i]
        discs[i][0] = (x + i + 1) % size
    return -sub(*chinese_remainder(discs))


### THE REST IS TESTS ###

if __name__ == "__main__":
    change_dir(__file__)

    test(5, solve(part=1, file='input-test-1'))
    test(148737, solve(part=1, file='input-real'))

    test(85, solve(part=2, file='input-test-1'))
    test(2353212, solve(part=2, file='input-real'))
Ejemplo n.º 9
0
    return {(x + 1, y + 1): enhance_x_y(x, y)
            for y in range(-1, n + 1) for x in range(-1, n + 1)}


def solve(part, file):
    data = load_blocks(file)
    algo = [c == '#' for c in data[0][0]]
    grid = {(x, y): c == '#'
            for y, line in enumerate(data[1]) for x, c in enumerate(line)}

    outside = 0
    n = len(data[1])
    for _ in range((2, 50)[part - 1]):
        grid = enhance(grid, algo, outside, n)
        outside = algo[outside * 255]
        n += 2
    return sum(grid.values())


### THE REST IS TESTS ###

if __name__ == "__main__":
    change_dir(__file__)

    test(35, solve(part=1, file='input-test-1'))
    test(5249, solve(part=1, file='input-real'))

    test(3351, solve(part=2, file='input-test-1'))
    test(15714, solve(part=2, file='input-real'))
Ejemplo n.º 10
0
    "perfumes": 1,
}

ops_part_2 = {'cats': gt, 'trees': gt, 'pomeranians': lt, 'goldfish': lt}


def solve(part, file):
    data = load(file)
    sues = {}
    for line in data:
        m = re.split(r'[:, ]+', line)
        sues[int(m[1])] = {
            item: int(count)
            for item, count in zip(*[iter(m[2:])] * 2)
        }
    ops = (ops_part_2 if part == 2 else {})
    for num, info in sues.items():
        if all(
                ops.get(item, eq)(count, my_sue[item])
                for item, count in info.items()):
            yield num


### THE REST IS TESTS ###

if __name__ == "__main__":
    change_dir(__file__)

    test([40], list(solve(part=1, file='input-real')))
    test([241], list(solve(part=2, file='input-real')))
Ejemplo n.º 11
0
                yield x, *tup


def scores(ingredients, calories):
    ing = list(ingredients.values())
    for tup in pick_sum(len(ing), 101):
        if not calories or calories == sum(i[4] * t for i, t in zip(ing, tup)):
            yield reduce(mul, (max(0, sum(i[x] * t for i, t in zip(ing, tup)))
                               for x in range(4)))


def solve(part, file):
    ingredients = {}
    for line in load(file):
        name, spec = line.split(':')
        ingredients[name] = Ingredient(*parse_nums(spec))

    return max(scores(ingredients, 500 * (part - 1)))


### THE REST IS TESTS ###

if __name__ == "__main__":
    change_dir(__file__)

    test(62842880, solve(part=1, file='input-test-1'))
    test(18965440, solve(part=1, file='input-real'))

    test(57600000, solve(part=2, file='input-test-1'))
    test(15862900, solve(part=2, file='input-real'))
Ejemplo n.º 12
0
def solve(part, file):
  cube_input = [(line[:2] == 'on', parse_nums(line)) for line in load(file)]

  cubes = {}
  for on, cube in cube_input:
    if part == 2 or is_within(cube, 50):
      cube = tuple(cube)
      for other_cube in list(cubes):
        if is_overlapping(cube, other_cube):
          del cubes[other_cube]
          for piece in cut_cube(other_cube, cube):
            cubes[piece] = area(piece)
      if on:
        cubes[cube] = area(cube)
  return sum(cubes.values())


### THE REST IS TESTS ###

if __name__ == "__main__":
  change_dir(__file__)

  test(39, solve(part=1, file='input-test-1'))
  test(590784, solve(part=1, file='input-test-2'))
  test(474140, solve(part=1, file='input-test-3'))
  test(606484, solve(part=1, file='input-real'))

  test(2758514936282235, solve(part=2, file='input-test-3'))
  test(1162571910364852, solve(part=2, file='input-real'))
Ejemplo n.º 13
0
#!/usr/bin/env python3

from common.util import load_tokens, test, change_dir


def solve(part, file):
    data = load_tokens(file)
    h = d = a = 0
    for line in data:
        dir, x = line[0][0], int(line[1])
        if dir == 'f':
            h += x
            a += d * x
        else:
            d += (1 | -(dir == 'u')) * x
    return h * [d, a][part == 2]


if __name__ == "__main__":
    change_dir(__file__)

    test(150, solve(part=1, file='input-test-1'))
    test(1746616, solve(part=1, file='input-real'))

    test(900, solve(part=2, file='input-test-1'))
    test(1741971043, solve(part=2, file='input-real'))
Ejemplo n.º 14
0
def solve(part, file):
    rule_block, goal = load_blocks(file)
    rules = [line.split(' => ') for line in rule_block]
    goal = goal[0]

    def expand(s):
        for a, b in rules:
            for m in re.finditer(a, s):
                s2 = list(s)
                s2[m.start():m.end()] = b
                yield ''.join(s2)

    if part == 1:
        return len(set(expand(goal)))

    return len(re.findall(r'[A-Z]', goal)) \
        - goal.count('Rn') - goal.count('Ar') \
        - 2 * goal.count('Y') - 1


### THE REST IS TESTS ###

if __name__ == "__main__":
    change_dir(__file__)

    test(4, solve(part=1, file='input-test-1'))
    test(7, solve(part=1, file='input-test-2'))
    test(535, solve(part=1, file='input-real'))

    test(212, solve(part=2, file='input-real'))
Ejemplo n.º 15
0
#!/usr/bin/env python3

from math import floor, ceil

from common.util import load, parse_nums, test, change_dir


def compute(data, cost_fn, *possible):
    return min(sum(cost_fn(abs(x - y)) for x in data) for y in possible)


def solve(part, file):
    data = [*map(parse_nums, load(file))][0]
    if part == 1:
        return compute(data, lambda x: x, sorted(data)[len(data) // 2])
    else:
        avg = sum(data) / len(data)
        return compute(data, lambda x: x * (x + 1) // 2,
                       *{floor(avg), ceil(avg)})


if __name__ == "__main__":
    change_dir(__file__)

    test(37, solve(part=1, file='input-test-1'))
    test(343441, solve(part=1, file='input-real'))

    test(168, solve(part=2, file='input-test-1'))
    test(98925151, solve(part=2, file='input-real'))
Ejemplo n.º 16
0
#!/usr/bin/env python3

from common.util import load, test, change_dir, parse_nums


def solve(part, file, lo=0, hi=0):
    ranges = sorted(parse_nums(line) for line in load(file))
    res = 0
    for x, y in ranges:
        if lo + 1 <= x - 1:
            if part == 1:
                return lo + 1
            res += x - lo - 1
        lo = max(lo, y)
    return res + hi - lo


### THE REST IS TESTS ###

if __name__ == "__main__":
    change_dir(__file__)

    test(3, solve(part=1, hi=9, file='input-test-1'))
    test(19449262, solve(part=1, hi=4294967295, file='input-real'))

    test(2, solve(part=2, hi=9, file='input-test-1'))
    test(119, solve(part=2, hi=4294967295, file='input-real'))
Ejemplo n.º 17
0

def solve(part, file):
    data = load_csv(file)[0]
    pos = 0
    dir = 0 + 1j
    grid = defaultdict(int)
    first_revisit = None
    for step in data:
        dir *= 1j if step[0] == 'L' else -1j
        for _ in range(int(step[1:])):
            pos += dir
            grid[pos] += 1
            if grid[pos] > 1 and first_revisit is None:
                first_revisit = pos
    if part == 2:
        pos = first_revisit
    return int(abs(pos.real) + abs(pos.imag))


if __name__ == "__main__":
    change_dir(__file__)

    test(5, solve(part=1, file='input-test-1'))
    test(2, solve(part=1, file='input-test-2'))
    test(12, solve(part=1, file='input-test-3'))
    test(236, solve(part=1, file='input-real'))

    test(4, solve(part=2, file='input-test-4'))
    test(182, solve(part=2, file='input-real'))
Ejemplo n.º 18
0
        for room, fold in zip(rooms, [[3, 3], [1, 2], [0, 1], [2, 0]]):
            room[:] = [room[0], *fold, room[1]]
    return tuple(hall), tuples(rooms)


def solve(part, file):
    hall, rooms = load_amphibians(part, file)

    seen = set()
    q = [(0, hall, rooms)]
    while q:
        weight, hall, rooms = heappop(q)
        if (hall, rooms) not in seen:
            seen.add((hall, rooms))
            if is_victory(hall, rooms):
                return weight
            for w, h, r in possible_moves(hall, rooms, part * 2):
                heappush(q, (weight + w, h, r))


### THE REST IS TESTS ###

if __name__ == "__main__":
    change_dir(__file__)

    test(12521, solve(part=1, file='input-test-1'))
    test(10411, solve(part=1, file='input-real'))

    test(44169, solve(part=2, file='input-test-1'))
    test(46721, solve(part=2, file='input-real'))
Ejemplo n.º 19
0
#!/usr/bin/env python3

from common.util import test, load_ints, change_dir


def solve(part, file):
    data = load_ints(file)
    return sum(map(int.__lt__, data, data[part * 2 - 1:]))


if __name__ == "__main__":
    change_dir(__file__)

    test(7, solve(part=1, file='input-test-1'))
    test(1215, solve(part=1, file='input-real'))

    test(5, solve(part=2, file='input-test-1'))
    test(1150, solve(part=2, file='input-real'))
Ejemplo n.º 20
0
    {
        keys.NAME: 'id',
        keys.REGEX: [('Detail/(\d+)', '$1')],
        keys.SOURCE: '1'
    },
    {
        keys.NAME: 'title',
        keys.REGEX: [('<h1>\s*(.*?)</h1>', '$1')],
    },
    {
        keys.NAME: 'source',
        keys.REGEX: [('【来源:(.*?)】', '$1')],
    },
    {
        keys.NAME: 'date',
        keys.REGEX: [('【时间:(.*?)】', '$1')],
    },
    {
        keys.NAME: 'content',
        keys.REGEX: [('<div id="fontzoom">([\s\S]*?)</div>', '$1')],
        keys.REMOVE_HTML: '1',
        keys.POST_REPLACES: [('&rdquo;', ''), ('&ldquo;', '')]
    },
]

if __name__ == '__main__':
    from pathlib import Path

    rule_name = Path(__file__).name.split('.')[0]
    r = util.test('http://sg.vegnet.com.cn/News/Detail/1220502', rule_name)
Ejemplo n.º 21
0
            vars[args[0]] += 1
        elif instruction == 'tpl':
            vars[args[0]] *= 3
        elif instruction == 'hlf':
            vars[args[0]] //= 2
        elif instruction == 'jmp':
            idx += int(args[0]) - 1
        elif instruction == 'jio':
            if vars[args[0]] == 1:
                idx += int(args[1]) - 1
        elif instruction == 'jie':
            if vars[args[0]] % 2 == 0:
                idx += int(args[1]) - 1
    return vars


def solve(var, part, file):
    instructions = load_instructions(file)
    return sim(instructions, {'a': part - 1, 'b': 0})[var]


### THE REST IS TESTS ###

if __name__ == "__main__":
    change_dir(__file__)

    test(2, solve('a', part=1, file='input-test-1'))
    test(184, solve('b', part=1, file='input-real'))

    test(231, solve('b', part=2, file='input-real'))
Ejemplo n.º 22
0
      if seen[y] > val2:
        seen[y] = val2
        heappush(q, (val2, y))


def solve(part, file):
  boss_hp, boss_damage = (parse_nums(line)[0] for line in load(file))

  start = Fight(mana=500, player_hp=50, boss_hp=boss_hp)

  def is_goal(fight):
    return fight.boss_hp <= 0

  def expand(fight):
    for spell, cost in spell_costs.items():
      result = fight.copy()
      if result.round(boss_damage, spell, part == 2) != False:
        yield cost, result

  return djyk(start, expand, is_goal)


### THE REST IS TESTS ###

if __name__ == "__main__":
  change_dir(__file__)

  test(953, solve(part=1, file='input-real'))

  test(1289, solve(part=2, file='input-real'))
Ejemplo n.º 23
0
def hashgen(input, ignore_invalid=False):
    seen = set()
    for i in count():
        hash = md5((input + str(i)).encode('utf-8')).hexdigest()
        if hash[:5] == '00000':
            if not (ignore_invalid and
                    (not hash[5].isdigit() or hash[5] not in '01234567'
                     or hash[5] in seen)):
                yield hash[5], hash[6]
                seen.add(hash[5])


def solve(part, file):
    input = load(file)[0]
    g = hashgen(input, part == 2)
    code = [next(g) for _ in range(8)]
    if part == 2:
        code = sorted((x[::-1] for x in code), key=itemgetter(1))
    return ''.join(c[0] for c in code)


if __name__ == "__main__":
    change_dir(__file__)

    test('18f47a30', solve(part=1, file='input-test-1'))
    test('1a3099aa', solve(part=1, file='input-real'))

    test('05ace8e3', solve(part=2, file='input-test-1'))
    test('694190cd', solve(part=2, file='input-real'))
Ejemplo n.º 24
0
      res[x, y] = '#'
    elif grid[x, y] == '#':
      res[x, y] = '.#'[count in {2, 3}]
    else:
      res[x, y] = '.#'[count == 3]
  return res


def solve(part, steps, file):
  grid = load_grid_dict(file)
  max_x = max_y = None
  if part == 2:
    max_x = max(x for x, _ in grid)
    max_y = max(y for _, y in grid)
    grid[0, 0] = grid[0, max_y] = grid[max_x, 0] = grid[max_x, max_y] = '#'
  for _ in range(steps):
    grid = step(grid, max_x, max_y)
  return sum(x == '#' for x in grid.values())


### THE REST IS TESTS ###

if __name__ == "__main__":
  change_dir(__file__)

  test(4, solve(part=1, steps=4, file='input-test-1'))
  test(814, solve(part=1, steps=100, file='input-real'))

  test(14, solve(part=2, steps=4, file='input-test-1'))
  test(924, solve(part=2, steps=100, file='input-real'))  # not 861
Ejemplo n.º 25
0
def find_code(row, col):
    codes = accumulate(repeat(20151125), lambda z, _: (z * 252533) % 33554393)
    for (x, y), code in zip(diag_count(), codes):
        if x == col and y == row:
            return code


def solve(file):
    row, col = parse_nums(load(file)[0])
    return find_code(row, col)


### THE REST IS TESTS ###

if __name__ == "__main__":
    change_dir(__file__)

    expected = [
        [20151125, 18749137, 17289845, 30943339, 10071777, 33511524],
        [31916031, 21629792, 16929656, 7726640, 15514188, 4041754],
        [16080970, 8057251, 1601130, 7981243, 11661866, 16474243],
        [24592653, 32451966, 21345942, 9380097, 10600672, 31527494],
        [77061, 17552253, 28094349, 6899651, 9250759, 31663883],
        [33071741, 6796745, 25397450, 24659492, 1534922, 27995004],
    ]
    actual = [[find_code(col, row) for row in range(1, 7)]
              for col in range(1, 7)]
    test(expected, actual)

    test(8997277, solve(file='input-real'))
Ejemplo n.º 26
0

def solve(part, file):
  data = load(file)
  total = 0
  for line in data:
    seqs = re.split(r'\[|\]', line)
    outs, ins = seqs[::2], seqs[1::2]
    if part == 1:
      total += not any(map(has_abba, ins)) and any(map(has_abba, outs))
    else:
      total += any(bab in s for bab, s in product(find_babs(outs), ins))

  return total


if __name__ == "__main__":
  change_dir(__file__)

  test(1, solve(part=1, file='input-test-1'))
  test(0, solve(part=1, file='input-test-2'))
  test(0, solve(part=1, file='input-test-3'))
  test(1, solve(part=1, file='input-test-4'))
  test(110, solve(part=1, file='input-real'))

  test(1, solve(part=2, file='input-test-5'))
  test(0, solve(part=2, file='input-test-6'))
  test(1, solve(part=2, file='input-test-7'))
  test(1, solve(part=2, file='input-test-8'))
  test(242, solve(part=2, file='input-real'))
Ejemplo n.º 27
0

def count_safe(s, n):
    safe = 0
    for _ in range(n):
        safe += s.count('.')
        s = step(s)
    return safe


### THE REST IS TESTS ###

if __name__ == "__main__":
    change_dir(__file__)

    test('.^^^^', steps('..^^.', 1))
    test('^^..^', steps('..^^.', 2))

    test('^^^...^..^', steps('.^^.^.^^^^', 1))
    test('^.^^.^.^^.', steps('.^^.^.^^^^', 2))
    test('..^^...^^^', steps('.^^.^.^^^^', 3))
    test('.^^^^.^^.^', steps('.^^.^.^^^^', 4))
    test('^^..^.^^..', steps('.^^.^.^^^^', 5))
    test('^^^^..^^^.', steps('.^^.^.^^^^', 6))
    test('^..^^^^.^^', steps('.^^.^.^^^^', 7))
    test('.^^^..^.^^', steps('.^^.^.^^^^', 8))
    test('^^.^^^..^^', steps('.^^.^.^^^^', 9))

    test(38, count_safe('.^^.^.^^^^', 10))

    input = load_string('input-real')
Ejemplo n.º 28
0
  if num_groups == 1:
    yield (nums,)
  else:
    num_set = set(nums)
    goal = sum(nums) // num_groups

    for y in range(1, len(nums)):
      for combo in sorted(combinations(nums, y), key=lambda x: reduce(mul, x)):
        if sum(combo) == goal:
          remaining = sorted(num_set - set(combo))
          for other_combos in partition(remaining, num_groups - 1):
            yield combo, *other_combos


def solve(part, file):
  data = load_ints(file)
  combos = next(partition(data, 2 + part))
  return reduce(mul, combos[0])


### THE REST IS TESTS ###

if __name__ == "__main__":
  change_dir(__file__)

  test(99, solve(part=1, file='input-test-1'))
  test(11846773891, solve(part=1, file='input-real'))

  test(44, solve(part=2, file='input-test-1'))
  test(80393059, solve(part=2, file='input-real'))
Ejemplo n.º 29
0
  return Item(cost, damage, armor)


def solve(part, file):
  boss = parse_character(load(file))
  shop = parse_shop()
  players = []
  for weapon in shop['Weapons']:
    for armor in chain(shop['Armor'], [None]):
      for num_rings in range(3):
        for rings in permutations(shop['Rings'], num_rings):
          stats = combine(weapon, armor, *rings)
          player = Character(100, stats.damage, stats.armor)
          players.append((stats.cost, player))

  players.sort()
  if part == 1:
    return next(cost for cost, player in players if fight(player, boss))
  else:
    return next(cost for cost, player in reversed(players) if not fight(player, boss))


### THE REST IS TESTS ###

if __name__ == "__main__":
  change_dir(__file__)

  test(1, fight(Character(8, 5, 5), Character(12, 7, 2)))
  test(78, solve(part=1, file='input-real'))
  test(148, solve(part=2, file='input-real'))
Ejemplo n.º 30
0
  def run_bot():
    for b in bots:
      if len(bots[b]) == 2:
        (is_out_lo, lo_id), (is_out_hi, hi_id) = splits[b]
        if (is_out_lo or len(bots[lo_id]) < 2) and (is_out_hi or len(bots[hi_id]) < 2):
          return b

  outs = defaultdict(list)

  while ((b := run_bot()) is not None):
    lo, hi = sorted(bots[b])
    if compares and (lo, hi) == compares:
      return b
    bots[b] = []
    (is_out_lo, lo_id), (is_out_hi, hi_id) = splits[b]
    (outs if is_out_lo else bots)[lo_id] += lo,
    (outs if is_out_hi else bots)[hi_id] += hi,

  return outs[0][0] * outs[1][0] * outs[2][0]


if __name__ == "__main__":
  change_dir(__file__)

  test(2, solve(compares=(2, 5), file='input-test-1'))
  test(56, solve(compares=(17, 61), file='input-real'))

  test(30, solve(file='input-test-1'))
  test(7847, solve(file='input-real'))