Пример #1
0
    if way is None:
        way = [1,0]
    ship = [0,0]

    for (act, off) in actions:
        if act in DIR:
            if anchor:
                ship[DIR.index(act) // 2] += scale(act, off)
            else:
                way[DIR.index(act) // 2] += scale(act, off)
        elif act == "F":
            ship = [ship[0] + off*way[0], ship[1] + off*way[1]]
        elif act in "RL":
            ang = deg_rad(off) if act == "L" else -deg_rad(off)
            way = rot(way, ang)

    return abs(ship[0]) + abs(ship[1])


# Separate actions from offsets.
ACTION_REG = r"(\w{1})(\d+)"


if __name__ == "__main__":
    usage_and_exit(len(argv) != 2)

    input_data = regex(arrange(open_file(argv[1])), (str, int), ACTION_REG)

    print(solve(input_data))
    print(solve(input_data, [10,1], False))
Пример #2
0
        if elem not in two_sum(lst[i:pre + i]):
            bad_elem = elem

    return bad_elem


# Cumulatively sum all elements of the list <ls> through <i>.
cum_sum = lambda ls, i: sum(ls[:i + 1])


def solve2(lst, k):
    """Find in a list <lst> a group of any size whose sum equals <k>."""

    for i in range(len(lst)):
        for j in range(len(lst)):
            if i > j and cum_sum(lst, i) - cum_sum(lst, j) == k:
                part = lst[j + 1:i + 1]

                return min(part) + max(part)

    return None


if __name__ == "__main__":
    usage_and_exit(len(argv) != 2)

    input_data = arrange(open_file(argv[1]), int)

    print(sol1 := solve1(input_data, 25))
    print(solve2(input_data, sol1))
Пример #3
0
def solve(seats):
    """Find the missing seat from the occupied <seats>.

    I used my own implementation of insertion sort to solve this one.  """

    sort_s = [False] * 2**10

    for i in seats:
        sort_s[i] = True

    our_s = 0
    for i, _ in enumerate(sort_s):
        if not sort_s[i] and sort_s[i - 1] and sort_s[i + 1]:
            our_s = i
            break

    return our_s


# Transform the seat ID <s> in a binary number.
binnum = lambda s: int(sub("(?:F|L)", "0", sub("(?:B|R)", "1", s)), 2)


if __name__ == "__main__":
    usage_and_exit(len(argv) != 2)

    input_data = [binnum(seat) for seat in arrange(open_file(argv[1]))]

    print(solve(input_data))
Пример #4
0
    """Find the smallest timestamp, such that all the <buses> follow their
    bus ID, which is indexically paired with <depart>.

    Here I used the Chinese Remainder Theorem, someone well acquainted to
    anyone who does competitive or discrete mathematics.  """

    # Desired residue class for each bus.
    mods = [(b - d) % b for b, d in zip(buses, depart)]

    # Cross multiplication of the elements in the sequence.
    cross_mul = [product(buses) // b for b in buses]

    return sum(
        [c * pow(c, -1, b) * m
         for b, c, m in zip(buses, cross_mul, mods)]) % product(buses)


if __name__ == "__main__":
    usage_and_exit(len(argv) != 2)

    input_file = arrange(open_file(argv[1]))

    bus_data = [int(b) for b in findall(r"\d+", input_file[1])]
    estimate = int(input_file[0])
    depart_data = [
        i for i, d in enumerate(findall(r"\w+", input_file[1])) if d != "x"
    ]

    print(solve1(bus_data, estimate))
    print(solve2(bus_data, depart_data))
Пример #5
0
        prev = deepcopy(current)
        whites = ground(current)

        for black in prev:
            neigh_b = count_neighbours(prev, black)

            if neigh_b not in [1,2]:
                current.remove(black)

        for white in whites:
            neigh_w = count_neighbours(prev, white)

            if neigh_w == 2:
                current.add(white)

    return current


# Extract the individual cardinals from the direction.
CARD_REG = r"(ne|nw|se|sw|e|w)"


if __name__ == "__main__":
    usage_and_exit(len(argv) != 2)

    input_data = [findall(CARD_REG, tile)
                  for tile in arrange(open_file(argv[1]))]

    print(len(sol := solve1(input_data)))
    print(len(solve2(sol, 100)))
Пример #6
0
    count = 0

    for edge in edges(bags):
        if edge[0] == elem:
            count += edge[1][0] * solve2(bags, edge[1][1]) + edge[1][0]

    return count


# Capture the bag name and its contents (ignoring weights).
UNWEIGHTED_REG = r"(?:^|\d+ ?)(.+?) bags?"
# Capture the bag's contents and its weights.
WEIGHTED_REG = r"(\d+) (.+?) bags?"
# Capture the bag name.
VERTEX_REG = r"^(.+?) bags"


if __name__ == "__main__":
    usage_and_exit(len(argv) != 2)

    arranged_data = arrange(open_file(argv[1]))
    unweighted_data = merge([dictf(findall(UNWEIGHTED_REG, f))
                             for f in arranged_data])
    weighted_data = merge([dictf(findall(VERTEX_REG, f) + transfiged
                                 (findall(WEIGHTED_REG, f), (int, str)))
                        for f in arranged_data])

    print(len(solve1(unweighted_data, "shiny gold")))
    print(solve2(weighted_data, "shiny gold"))
Пример #7
0
KEY_VAL_REG = r"(\w{3}):(.+?)(?:\s|$)"
REQ_KEYS = {"byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid"}


def solve(passes, rules=None):
    """Validate the passports <passes> according to <rules> and check the
    required fields (<REQ_KEYS>); if no <rules> are provided, check only
    the required fields.  """

    valid = 0

    for pasp in passes:
        # Dictionary association with {key: value}.
        soc = dict(findall(KEY_VAL_REG, pasp))
        keys = set(findall(KEY_REG, pasp))

        if keys.issuperset(REQ_KEYS) \
           and (rules is None or assoc(soc, rules)):
            valid += 1

    return valid


if __name__ == "__main__":
    usage_and_exit(len(argv) != 2)

    input_data = arrange(open_file(argv[1]), sep="\n\n")

    print(solve(input_data))
    print(solve(input_data, RULEBOOK))
Пример #8
0
        card2 = deck2[0]

        deck1 = deck1[1:]
        deck2 = deck2[1:]

        if len(deck1) >= card1 and len(deck2) >= card2 and recursive:
            sub_deck1 = deepcopy(deck1)[:card1]
            sub_deck2 = deepcopy(deck2)[:card2]

            player1_has_won = solve(sub_deck1, sub_deck2, recursive)[1]
        else:
            player1_has_won = card1 > card2

        if player1_has_won:
            deck1 += [card1, card2]
        else:
            deck2 += [card2, card1]

    return (get_score(deck1) if player1_has_won else get_score(deck2),
            player1_has_won)


if __name__ == "__main__":
    usage_and_exit(len(argv) != 2)

    arranged_data = arrange(open_file(argv[1]), sep="\n\n")
    deck_data = [[int(j) for j in arrange(i)[1:]] for i in arranged_data]

    print(solve(deck_data[0], deck_data[1])[0])
    print(solve(deck_data[0], deck_data[1], True)[0])
Пример #9
0
        changed = False
        neighbours = [[
            count_neighbours(current, (row, seat), adjacent)
            for seat in range(len(current[0]))
        ] for row in range(len(current))]

        for i, row in enumerate(current):
            for j, seat in enumerate(row):
                if seat == State.FREE.value and neighbours[i][j] == 0:
                    current[i][j] = State.OCC.value
                    changed = True
                elif seat == State.OCC.value \
                     and neighbours[i][j] >= threshold:
                    current[i][j] = State.FREE.value
                    changed = True

    return sum([row.count(State.OCC.value) for row in current])


# Replace all the symbols in <st> with numbers.
enumer = lambda st: sub(r"[.]", "2", sub(r"#", "1", sub(r"L", "0", st)))

if __name__ == "__main__":
    usage_and_exit(len(argv) != 2)

    input_data = [[int(i) for i in list(enumer(row))]
                  for row in arrange(open_file(argv[1]))]

    print(solve(input_data, 4))
    print(solve(input_data, 5, False))