Esempio n. 1
0
def get_passport_info_from_input():
    """
    Fetches the input file and rebuilds passport info as a one-liner
    :return: List string of passport info
    :rtype: [str]
    """
    passport_list = []
    text = ""
    for line in read_input("day_04.txt"):
        if line != "":
            text += f" {line}"
        else:
            passport_list.append(text[1:])
            text = ""
    passport_list.append(text[1:])  # Adding the last one
    return passport_list
Esempio n. 2
0
# Built-in
from time import perf_counter

# Personal
from _shared import read_input

# --------------------------------------------------------------------------------
# > Helpers
# --------------------------------------------------------------------------------

# --------------------------------------------------------------------------------
# > Main
# --------------------------------------------------------------------------------
# Setup
adapters = [int(value) for value in read_input("day_10.txt")]
adapters.insert(0, 0)
adapters.sort()

# Problem 1
diffs = {}
for i in range(len(adapters) - 1):
    current_adapter = adapters[i]
    next_adapter = adapters[i + 1]
    delta = next_adapter - current_adapter
    diffs[delta] = diffs.get(delta, 0) + 1
diffs[3] = diffs.get(3, 0) + 1
print(diffs)
print(diffs[1] * diffs[3])

# Problem 2
Esempio n. 3
0
"""Day 1 challenge"""

# Built-in
from itertools import combinations

# Personal
from _shared import read_input

# --------------------------------------------------------------------------------
# > Main
# --------------------------------------------------------------------------------
values = [int(v) for v in read_input("day_01.txt")]

# First problem
for a, b in combinations(values, 2):
    if (a + b) == 2020:
        print(a * b)
        break

# Second problem
for a, b, c in combinations(values, 3):
    if (a + b + c) == 2020:
        print(a * b * c)
        break
Esempio n. 4
0
        self.history_map[n] = turn_list

    def play_starting_numbers(self):
        """Plays the starting number of the game by saying them"""
        for value in self.starting_numbers:
            self.turn += 1
            self.say_number(value)

    def reset(self):
        """Resets the game state"""
        self.turn = 0
        self.history_map = {}
        self.last_number = None


# --------------------------------------------------------------------------------
# > Main
# --------------------------------------------------------------------------------
starting_numbers = [
    int(value) for value in read_input("day_15.txt")[0].split(",")
]
game = Game(starting_numbers)

# Problem 1
game.play(2020)
print(game.last_number)

# Problem 2
game.play(30000000)
print(game.last_number)
Esempio n. 5
0
        """
        return len(self.completely_invalid_values) > 0


# --------------------------------------------------------------------------------
# > Main
# --------------------------------------------------------------------------------
# Setup
start = perf_counter()
form = Form()
tickets = []
my_ticket = None

# Parsing
section = 0
for line in read_input("day_16.txt"):
    if line == "":
        section += 1
        continue
    if section == 0:
        form.add_rule(line)
    else:
        title = re.match(TITLE_REGEX, line)
        if title is None:
            values = [int(value) for value in line.split(",")]
            ticket = Ticket(form, values)
            if section == 1:
                my_ticket = ticket
            tickets.append(ticket)

# ----- Problem 1 -----
Esempio n. 6
0
"""Day 9 challenge"""

# Built-in
from itertools import combinations

# Personal
from _shared import read_input

# --------------------------------------------------------------------------------
# > Helpers
# --------------------------------------------------------------------------------

# --------------------------------------------------------------------------------
# > Main
# --------------------------------------------------------------------------------
NUMBERS = [int(value) for value in read_input("day_09.txt")]
RANGE = 25

# Problem 1
i = RANGE
while True:
    current_number = NUMBERS[i]
    available_numbers = NUMBERS[i - RANGE:i]
    possible_outputs = {a + b for a, b in combinations(available_numbers, 2)}
    if current_number not in possible_outputs:
        break
    i += 1
invalid_number = current_number
print(invalid_number)

# Problem 2
Esempio n. 7
0
    for line in file_content:
        if line != "":
            merged_answer += f"{line}"
            people += 1
        else:
            group_info.append((merged_answer, people))
            merged_answer = ""
            people = 0
    group_info.append((merged_answer, people))  # Adding the last one
    return group_info


# --------------------------------------------------------------------------------
# > Main
# --------------------------------------------------------------------------------
content = read_input("day_06.txt")
group_data = merge_group_answers_with_count(content)

# Problem 1
total = sum([len(set(answers)) for answers, _ in group_data])
print(total)

# Problem 2
total = 0
for answers, group_size in group_data:
    counter = Counter(answers)
    counter = {
        letter: count
        for letter, count in counter.items() if count >= group_size
    }
    total += len(counter)
Esempio n. 8
0
        :return: The created Seat instance
        :rtype: Seat
        """
        row = cls.compute_binary_split(line[:7], "F")
        col = cls.compute_binary_split(line[7:], "L")
        return Seat(row, col)


# --------------------------------------------------------------------------------
# > Main
# --------------------------------------------------------------------------------
AVAILABLE_SEATS = {(row, col) for row in range(128) for col in range(8)}

# Problem 1
seats = []
for input_line in read_input("day_05.txt"):
    seat = Seat.create_from_input_line(input_line)
    seats.append(seat)
    AVAILABLE_SEATS.remove(seat.loc)
seats.sort(key=lambda x: x.id, reverse=True)
print(seats[0].id)

# Problem 2
# Removes rows from each end until only 1 seat remains
max_row = 127
i = 0
while len(AVAILABLE_SEATS) > 1:
    mod = i // 2
    row_to_remove = max_row - mod if i % 2 else mod
    AVAILABLE_SEATS = {(row, col)
                       for row, col in AVAILABLE_SEATS if row != row_to_remove}
Esempio n. 9
0
        """
        ACTION
        P1: Moves the ship in the direction it is facing (so we simply call the related action)
        P2: Moves the ship N times the distances between the ship and the waypoint
        :param int value: Value from the input file
        :param int problem: The part of the AOC problem
        """
        if problem == 1:
            self.action_mapping[self.facing](value, problem)
        elif problem == 2:
            self.X += self.waypoint_X * value
            self.Y += self.waypoint_Y * value


# --------------------------------------------------------------------------------
# > Main
# --------------------------------------------------------------------------------
# Problem 1
ship = Ship()
for instruction in read_input("day_12.txt"):
    ship.apply_instruction(instruction, 1)
print(ship.X, ship.Y)
print(ship.manhattan_distance)

# Problem 2
ship = Ship()
for instruction in read_input("day_12.txt"):
    ship.apply_instruction(instruction, 2)
print(ship.X, ship.Y)
print(ship.manhattan_distance)
Esempio n. 10
0
def parse_line(input_line):
    """
    Parses the input line to extract its information
    :param str input_line: Line from the input file
    :return: The first number, second number, enforced letter, and the password
    :rtype: (int, int, str, str)
    """
    match = re.match(REGEX, input_line)
    return (
        int(match.group(1)),
        int(match.group(2)),
        match.group(3),
        match.group(4),
    )


first_total, second_total = 0, 0
for line in read_input("day_02.txt"):
    min_, max_, letter, text = parse_line(line)
    # First problem
    letter_count = text.count(letter)
    if min_ <= letter_count <= max_:
        first_total += 1
    # Second problem
    first = text[min_ - 1]
    second = text[max_ - 1]
    if (first == letter or second == letter) and first != second:
        second_total += 1
print(first_total, second_total)
Esempio n. 11
0
        if count == 0:
            return [binary_string]
        else:
            strings = []
            for values in product(["0", "1"], repeat=count):
                string = binary_string
                for value in values:
                    string = string.replace("X", value, 1)
                strings.append(string)
            return strings

    def reset(self):
        """Empties the memory and the mask"""
        self.memory = {}
        self.mask = None


# --------------------------------------------------------------------------------
# > Main
# --------------------------------------------------------------------------------
instructions = read_input("day_14.txt")
program = Program()

# Problem 1
program.run(instructions, 1)
print(sum(program.memory.values()))

# Problem 2
program.run(instructions, 2)
print(sum(program.memory.values()))
Esempio n. 12
0
    @property
    def status_map(self):
        """
        :return: A hashmap that maps string inputs to Status enums
        :rtype: dict
        """
        return {
            "L": self.Status.EMPTY,
            "#": self.Status.OCCUPIED,
            ".": self.Status.FLOOR,
        }


# --------------------------------------------------------------------------------
# > Main
# --------------------------------------------------------------------------------
file_content = read_input("day_11.txt")
grid = Grid.from_file_content(file_content)

# Problem 1
grid.problem_1()
occupied_spots = [spot for spot in grid.spots if spot.status == Spot.Status.OCCUPIED]
print(len(occupied_spots))
grid.reset()

# Problem 2
grid.problem_2()
occupied_spots = [spot for spot in grid.spots if spot.status == Spot.Status.OCCUPIED]
print(len(occupied_spots))
grid.reset()
Esempio n. 13
0
    def jmp(self, program):
        """
        Changes the program's index by the instruction value
        :param Program program: The program calling this instruction
        """
        program.index += self.value

    @staticmethod
    def nop(program):
        """
        Simply moves to the next instruction by increasing the program's index by 1
        :param Program program: The program calling this instruction
        """
        program.index += 1


# --------------------------------------------------------------------------------
# > Main
# --------------------------------------------------------------------------------
instructions = [Instruction(line) for line in read_input("day_08.txt")]
main_program = Program(instructions)

# Problem 1
main_program.run()
print(main_program.acc)

# Problem 2
main_program.run_with_fix()
print(main_program.acc)
Esempio n. 14
0
    :return: The generated value
    :rtype: int
    """
    value = 1
    for i in range(loop_size):
        value = value * subject_number
        value = value % DIVIDER
    return value


# --------------------------------------------------------------------------------
# > Main
# --------------------------------------------------------------------------------
# Initialization
start = perf_counter()
content = read_input("day_25.txt")
CARD_PUBLEY_KEY = int(content[0])
DOOR_PUBLEY_KEY = int(content[1])

# Find the loop sizes
card_loop = get_loop_size(CARD_PUBLEY_KEY)
door_loop = get_loop_size(DOOR_PUBLEY_KEY)
print(f"CARD: {7}, {card_loop}")
print(f"DOOR: {7}, {door_loop}")

# Generate the private key
private_key_1 = transform(CARD_PUBLEY_KEY, door_loop)
private_key_2 = transform(DOOR_PUBLEY_KEY, card_loop)
print(private_key_1)
print(private_key_2)
Esempio n. 15
0
    @classmethod
    def parse_line(cls, input_line):
        match = re.match(REGEX_BAG_TYPE, input_line)
        bag = match.group(1)
        nested_bags = {
            match.group(2): int(match.group(1))
            for match in re.finditer(REGEX_BAG_RULES, input_line)
        }
        return cls(bag, nested_bags)


# --------------------------------------------------------------------------------
# > Main
# --------------------------------------------------------------------------------
rules = [Rule.parse_line(line) for line in read_input("day_07.txt")]
rule_dict = {rule.bag: rule for rule in rules}

# Problem 1
valid_outer_bags = set()
bags_to_check = {
    MAIN_BAG,
}
while True:
    valid_bags = set()
    for bag in bags_to_check:
        new_bags_to_check = {
            rule.bag
            for rule in rules if bag in rule.nested_bags.keys()
        }
        valid_bags.update(new_bags_to_check)
Esempio n. 16
0
def parse_input(content):
    earliest_departure = int(content[0])
    buses = []
    for index, value in enumerate(content[1].split(",")):
        if value == "x":
            continue
        value = int(value)
        buses.append(Bus(value, index))
    return earliest_departure, buses


# --------------------------------------------------------------------------------
# > Main
# --------------------------------------------------------------------------------
content = read_input("day_13.txt")
earliest_departure, buses = parse_input(content)

# Problem 1
best_bus = None
best_timestamp = None
for bus in buses:
    _, pickup_timestamp = bus.closest_to_timestamp(earliest_departure)
    if best_timestamp is None or pickup_timestamp < best_timestamp:
        best_bus = bus
        best_timestamp = pickup_timestamp
print(best_bus.id * (best_timestamp - earliest_departure))  # 161

# Problem 2
# ------------------ Brute force that took way too long ------------------
# found = False
Esempio n. 17
0
"""Day 3 challenge"""

# Personal
from _shared import read_input

# --------------------------------------------------------------------------------
# > Main
# --------------------------------------------------------------------------------
grid = [list(line) for line in read_input("day_03.txt")]
height = len(grid)
width = len(grid[0])
slopes = [[1, 1], [3, 1], [5, 1], [7, 1], [1, 2]]
injury_multiplier = 1

for x_add, y_add in slopes:
    injuries = 0
    x, y = 0, 0
    for i in range(height):
        x = x + x_add - ((x + x_add) // width) * width  # 0 <= X <= width-1
        y += y_add
        # We've reached the end or beyond
        if y >= height:
            break
        # Did we land on a tree?
        if grid[y][x] == "#":
            injuries += 1

    print(injuries)
    injury_multiplier *= injuries

print(injury_multiplier)