Example #1
0
    preamble_len: int
        The length of the preceding numbers to check

    Returns
    -------
    int
        The first number that is not the sum of the preamble

    """
    input = list(map(int, input.splitlines()))
    preamble = deque(input[:preamble_len], maxlen=preamble_len)
    for number in input[preamble_len:]:
        if any((number - preambley in preamble for preambley in preamble)):
            preamble.append(number)
        else:
            return number


assert get_propertyless_number(test_input, 5) == 127

propertyless_number = get_propertyless_number(get_puzzle_input(9), 25)
print(f"Part 1: {propertyless_number}")

input = list(map(int, get_puzzle_input(9).splitlines()))
index = input.index(propertyless_number)
for i in range(1, index):
    for j in range(index):
        if sum(input[j:i + j]) == propertyless_number:
            print(f"Part 2: {min(input[j:i+j]) + max(input[j:i+j])}")
            break
Example #2
0
39
11
1
32
25
35
8
17
7
9
4
2
34
10
3"""
joltages = get_puzzle_input(10).splitlines()
joltages = list(map(int, joltages))
joltages.extend([0, max(joltages) + 3])
joltages.sort()
diffences = list(map(operator.sub, joltages[1:], joltages[:-1]))
arr = np.array(diffences)
print(
    f"Part 1: {np.flatnonzero(arr == 3).size * np.flatnonzero(arr == 1).size}")

# Part 2
consecutive_adapters = list(
    map(len, "".join("-" if x == 1 else "*" for x in diffences).split("*")))
addiitonal_combinations = [1, 1, 2, 4, 7]
print(
    f"Part 2: {reduce(operator.mul, [addiitonal_combinations[num_adapters] for num_adapters in consecutive_adapters])}"
)
Example #3
0
a
b
c

ab
ac

a
a
a
a

b"""
# groups = test_input.split("\n\n")
groups = get_puzzle_input(6, is_viv=True).split("\n\n")
total = 0
print(sum(len(set(group.replace("\n", ""))) for group in groups))

for group in groups:
    people = Counter(group)["\n"] + 1
    counts = Counter(group)
    for key, value in counts.items():
        if value == people:
            total += 1

# total = 0
# for group in groups:
#     setty = set(ascii_lowercase)
#     for person in group.splitlines():
#         setty = setty.intersection({*person})
Example #4
0
from helpers.utils import get_puzzle_input

test_input = """1-3 a: abcde
1-3 b: cdefg
2-9 c: ccccccccc"""
# all_data = test_input.split("\n")
all_data = get_puzzle_input(2, is_viv=True).split("\n")
total = 0
for password_data in all_data:
    bits = password_data.split(" ")
    pos_1, pos_2 = bits[0].split("-")
    pos_1, pos_2 = int(pos_1) - 1, int(pos_2) - 1
    char = bits[1][0]
    password = bits[2]
    if (password[pos_1] + password[pos_2]).count(char) == 1:
        print("Valid")
        total += 1
    else:
        print("Invalid")
print(total)
Example #5
0
        The puzzle input
    right: int
        number of places to move right
    down: int
        NUmber of rows to move down

    Returns
    -------

    """

    row_width = len(input.splitlines()[0])
    lines = input.splitlines()
    num_rows = len(input.splitlines())
    index = 0
    tree_count = 0
    for i in range(down, num_rows, down):
        index += right
        if index > row_width - 1:
            index -= row_width
        if lines[i][index] == "#":
            tree_count += 1
    return tree_count


for right, down in new_rules:
    tree_list.append(get_tree_count(get_puzzle_input(3), right, down))

print(f"Part 1 {tree_list[1]}")
print(f"Part 2 {math.prod(tree_list)}")
Example #6
0
    ----------
    puzzle_input: str
        The puzzle input (new line delimited passwords and their associated rules)

    Returns
    -------
    int
        Number of valid passwords
    """
    counter_part_1 = 0
    counter_part_2 = 0
    for pwd in puzzle_input.split("\n"):
        bits = pwd.split(" ")
        lower_limit, upper_limit = bits[0].split("-")
        letter, pwd_letter_counts = bits[1][0], Counter(bits[2])
        if int(upper_limit) >= pwd_letter_counts[letter] >= int(lower_limit):
            counter_part_1 += 1
        part_two_password = Counter(f"{bits[2][int(lower_limit)-1]}{bits[2][int(upper_limit)-1]}")
        if part_two_password[letter] == 1:
            counter_part_2 += 1

    return counter_part_1, counter_part_2


# Test the function
assert get_valid_passwords_count(test_input) == (2, 1)

# Part 1
print(get_valid_passwords_count(get_puzzle_input(2)))

Example #7
0
    return False


def check_pid(pid):
    if len(pid) != 9:
        return False
    try:
        int(pid)
        return True
    except ValueError as e:
        return False


count = 0
count_p2 = 0
for passport in get_puzzle_input(4, is_viv=True).split("\n\n"):
    # for passport in test_input.split("\n\n"):
    key_value_dict = {}
    passport_info = passport.split()
    for passport_info_bit in passport_info:
        key, value = passport_info_bit.split(":")
        if key in ["byr", "eyr", "iyr"]:
            value = int(value)
        key_value_dict[key] = value
    if len(key_value_dict) == 8:
        count += 1
    elif len(key_value_dict) == 7 and "cid" not in key_value_dict:
        count += 1
    if all([
            1920 <= key_value_dict.get("byr", 0) <= 2002,
            2010 <= key_value_dict.get("iyr", 0) <= 2020,
Example #8
0
from helpers.utils import get_puzzle_input
test_input = """1721
979
366
299
675
1456"""
reports = get_puzzle_input(1, is_viv=True).split("\n")
# reports = test_input.split("\n")
reports = list(map(int, reports))
for expense in reports:
    for expense_2 in reports:
        for expense_3 in reports:
            if int(expense_2) + int(expense) + int(expense_3) == 2020:
                print(int(expense_2) * int(expense) * int(expense_3))



Example #9
0
from helpers.utils import get_puzzle_input
test_input = """..##.........##.........##.........##.........##.........##.......
#...#...#..#...#...#..#...#...#..#...#...#..#...#...#..#...#...#..
.#....#..#..#....#..#..#....#..#..#....#..#..#....#..#..#....#..#.
..#.#...#.#..#.#...#.#..#.#...#.#..#.#...#.#..#.#...#.#..#.#...#.#
.#...##..#..#...##..#..#...##..#..#...##..#..#...##..#..#...##..#.
..#.##.......#.##.......#.##.......#.##.......#.##.......#.##.....
.#.#.#....#.#.#.#....#.#.#.#....#.#.#.#....#.#.#.#....#.#.#.#....#
.#........#.#........#.#........#.#........#.#........#.#........#
#.##...#...#.##...#...#.##...#...#.##...#...#.##...#...#.##...#...
#...##....##...##....##...##....##...##....##...##....##...##....#
.#..#...#.#.#..#...#.#.#..#...#.#.#..#...#.#.#..#...#.#.#..#...#.#"""
# rows = test_input.split("\n")
rows = get_puzzle_input(3, is_viv=True).split("\n")
del rows[0]
trees = 0
position = 0
total = 1
rules = [(1, 1), (3, 1), (5, 1), (7, 1), (1, 2)]
for right, down in rules:
    trees = 0
    position = 0
    row_number = 0
    for line in rows:
        if down > 1:
            row_number += 1
            if row_number % 2 != 0:
                continue
        position += right
        position = position % len(line)
        if line[position] == "#":
Example #10
0
import itertools
from collections import defaultdict
import re
from helpers.utils import get_puzzle_input
test_input = """mask = 000000000000000000000000000000X1001X
mem[42] = 100
mask = 00000000000000000000000000000000X0XX
mem[26] = 1"""
mem = defaultdict(int)
prog = re.compile(r"([01X]{36}|\d+)")

for input_set in get_puzzle_input(14).split("mask = "):
    if not input_set:
        continue
    a = [prog.findall(line) for line in input_set.splitlines()]
    mask = a[0][0]
    for mem_address, numby in a[1:]:
        a = bin(int(mem_address))
        listy_p1 = []
        # listy_p2 = []
        c = ["0"] * (len(mask) - len(a[2:]))
        c = "".join(c)
        a = c + a[2:]
        # for ind, num in enumerate(a):
        # 	if mask[ind] != num and mask[ind] != "X":
        # 		listy_p1.append(mask[ind])
        # 	else:
        # 		listy_p1.append(num)

        listy_p2 = [
            mask[ind] if mask[ind] != num and mask[ind] != "0" else num
Example #11
0
        "hcl": {
            "type": "string",
            "pattern": "^#[0-9a-f]{6}$"
        },
        "ecl": {
            "type": "string",
            "pattern": "^(blu|amb|brn|gry|grn|hzl|oth)$"
        },
        "pid": {
            "type": "string",
            "pattern": "^([0-9]{9})$"
        },
    },
}

test_input = get_puzzle_input(4)
part_1_valid_count = 0
part_2_valid_count = 0
passport_strings = test_input.split("\n\n")
int_keys = {"byr", "iyr", "eyr"}
for passport in passport_strings:
    fields = {
        k: (int(v) if k in int_keys else v)
        for k, v in (e.split(":") for e in passport.split())
    }
    part_1_valid_count += set(schema["required"]).issubset(set(fields.keys()))
    try:
        validate(instance=fields, schema=schema)
    except exceptions.ValidationError as err:
        continue
    part_2_valid_count += 1
Example #12
0
import numpy as np
from helpers.utils import get_puzzle_input

test_input = """939
7,13,x,x,59,x,31,19"""

time_stamp, bus_intervals = get_puzzle_input(13).split("\n")
time_stamp = int(time_stamp)
bus_intervals = [int(n) for n in bus_intervals.split(",") if n != "x"]
series = []
for interval in bus_intervals:
    time_series = 0
    time_series_array = []
    while time_series < time_stamp:
        time_series += interval
        time_series_array.append(time_series)
    series.append(time_series_array)


def find_nearest(array, value):
    array = np.asarray(array)
    idx = (np.abs(array - value)).argmin()
    return array[idx]


offset = [
    find_nearest(np.array(array), time_stamp) % time_stamp for array in series
]
mins_to_wait = min(offset)
bus = bus_intervals[np.array(offset).argmin()]
print(bus)
Example #13
0
LLLL.LL.LL
L.LL.LL.LL
L.LLLLL.LL
..L.L.....
LLLLLLLLLL
L.LLLLLL.L
L.LLLLL.LL"""

grid = {}
x = 0
y = 0
adjacency = [(i, j) for i in (-1, 0, 1) for j in (-1, 0, 1)
             if not (i == j == 0)]
max_x = 0
max_y = 0
for position in get_puzzle_input(11):
    if position == "\n":
        y += 1
        x = 0
        continue
    grid[(x, y)] = position
    max_x = x
    x += 1
    max_y = y

run = True
z = 0
while run:
    z += 1
    new_grid = {}
    for position, seat_info in grid.items():
Example #14
0
import networkx
import itertools
from helpers.utils import get_puzzle_input
import matplotlib.pyplot as plt

# # Part 2
# test_input = """shiny gold bags contain 2 dark red bags.
# dark red bags contain 2 dark orange bags.
# dark orange bags contain 2 dark yellow bags.
# dark yellow bags contain 2 dark green bags.
# dark green bags contain 2 dark blue bags.
# dark blue bags contain 2 dark violet bags.
# dark violet bags contain no other bags."""
bag_count = 0
edgey_edges = []
for line in get_puzzle_input(7).splitlines():
    bags = re.findall(pattern=r"(\b(?:\S+\s+){2}(?:bag))", string=line)
    if "no other bag" in bags:
        continue
    numbers = re.findall(pattern=r"(\b\d)", string=line)
    edges = list(itertools.combinations(bags, 2))
    edges = edges[:len(bags) - 1]
    for ind, number in enumerate(numbers):
        edges[ind] = (*edges[ind], int(number))
    edgey_edges.extend(edges)
graph = networkx.DiGraph()
graph.add_weighted_edges_from(edgey_edges)
a = {
    x[0]
    for x in networkx.edge_dfs(graph, 'shiny gold bag', orientation='reverse')
}
Example #15
0
from helpers.utils import get_puzzle_input
from collections import Counter

# part 1
print(
    sum(
        len({*group.replace("\n", "")})
        for group in get_puzzle_input(6).split("\n\n")))

# part 2
counter = 0
for group in get_puzzle_input(6).split("\n\n"):
    count = group.count("\n") + 1
    letters = Counter(group)
    for letter in {*group.replace("\n", "")}:
        if letters[letter] == count:
            counter += 1
Example #16
0
                    "nop", "jmp"
            } and not self.changed_index and not self.index in self.changed_indices:
                self.changed_index = True
                self.changed_indices.append(self.index)
            if self.changed_index and self.index == self.changed_indices[-1]:
                instruction_type = "nop" if instruction_type == "jmp" else "jmp"
            self.__getattribute__(instruction_type)(amount)
            if self.index not in self.indexes:
                self.indexes.add(self.index)
            else:
                self.refresh()
        print(f"Part 2: {self.accumulator}")

    def refresh(self):
        print(f"Refreshing and starting again!! \n\n\n")
        self.indexes = {0}
        self.changed_index = False
        self.accumulator = 0
        self.index = 0


gc = GameConsole(test_input)
gc.run()
assert gc.accumulator == 5
gc.repair()
assert gc.accumulator == 8

gc_full = GameConsole(get_puzzle_input(8))
gc_full.run()
gc_full.repair()
Example #17
0
from helpers.utils import get_puzzle_input
import numpy as np

test_input = """class: 0-1 or 4-19
row: 0-5 or 8-19
seat: 0-13 or 16-19

your ticket:
11,12,13

nearby tickets:
3,9,18
15,1,5
5,14,9"""

rules, my_ticket, nearby_tickets = get_puzzle_input(16).split("\n\n")
# create the rules
prog = re.compile(r"([a-z A-Z]+): (\d+)-(\d+) or (\d+)-(\d+)")
prog_2 = re.compile(r"(\d+)-(\d+)")
a = prog.findall(rules)
b = prog_2.findall(rules)

my_ticket = list(map(int, my_ticket.split("\n")[1].split(",")))

rules_dict = {
    x[0]: [[int(x[1]), int(x[2])], [int(x[3]), int(x[4])]]
    for x in a
}
error = 0
valid_tickets = set()
for ticket in nearby_tickets.splitlines()[1:]:
Example #18
0
            self.y += (self.waypoint_y * amount)
        if direction == "N":
            self.waypoint_y += amount
        elif direction == "S":
            self.waypoint_y -= amount
        elif direction == "E":
            self.waypoint_x += amount
        elif direction == "W":
            self.waypoint_x -= amount

    def instruction(self, instruction):
        for line in instruction.split("\n"):
            type = line[0]
            amount = int(line[1:])
            print(type, amount)
            print(f"Old waypoint at {self.waypoint_x}, {self.waypoint_y}")
            print(f"OG ship at {self.x}, {self.y}")
            if type in {"L", "R"}:
                self.turn(type, amount)
            else:
                self.move(type, amount)
            print(f"new waypoint {self.waypoint_x},{self.waypoint_y}")
            print(f"new x, y {self.x}, {self.y}")
            print("\n")
        print(self.x, self.y)
        self.manhattan_distance()


ship = Ship()
ship.instruction(get_puzzle_input(12))
Example #19
0
from helpers.utils import get_puzzle_input
test_input = """BFFFBBFRRR
FFFBBBFRRR
BBFFBBFRLL"""
# passes = test_input.split("\n")
passes = get_puzzle_input(5, is_viv=True).split("\n")
all_id = []
for b_pass in passes:
    print(b_pass)
    row = b_pass[:7]
    column = b_pass[7:]
    plane = [i for i in range(128)]
    seats = [i for i in range(8)]
    for char in row:
        num_rows_to_keep = int(len(plane) / 2)
        if char == "B":
            plane = plane[num_rows_to_keep:]
        else:
            plane = plane[:num_rows_to_keep]
    for char in column:
        num_col_to_keep = int(len(seats) / 2)
        if char == "L":
            seats = seats[:num_col_to_keep]
        else:
            seats = seats[num_col_to_keep:]
    id = plane[0] * 8 + seats[0]
    all_id.append(id)
    print(f"Row: {plane[0]}, Column: {seats[0]}, ID: {id}")
print(max(all_id))
all_id.sort()
for index, id in enumerate(all_id):