Esempio n. 1
0
def test_load_input():
    filepath = Path(__file__).parent / "sample_input_1.txt"
    expected = [
        ("mask", "", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X"),
        ("mem", "8", "11"),
        ("mem", "7", "101"),
        ("mem", "8", "0"),
    ]
    assert load_input(filepath) == expected
Esempio n. 2
0
def test_load_input():
    filepath = Path(__file__).parent / "sample_input.txt"
    expected = [
        Password(PasswordPolicy(1, 3, "a"), "asdf"),
        Password(PasswordPolicy(2, 5, "b"), "aaabbbbaaab"),
        Password(PasswordPolicy(2, 4, "c"), "accca"),
        Password(PasswordPolicy(1, 2, "d"), "ghjkl"),
    ]
    assert load_input(filepath) == expected
Esempio n. 3
0
def test_load_input():
    expected = {
        "start": {"A", "b"},
        "A": {"b", "c", "end", "start"},
        "b": {"A", "d", "end", "start"},
        "c": {"A"},
        "d": {"b"},
        "end": {"A", "b"},
    }
    assert load_input("sample_input.txt") == expected
Esempio n. 4
0
 def test_step(self):
     filepath = Path(__file__).parent / "sample_input.txt"
     layout = load_input(filepath)
     sim = SeatingSimulation(layout)
     expected = [
         "#.##.##.##",
         "#######.##",
         "#.#.#..#..",
         "####.##.##",
         "#.##.##.##",
         "#.#####.##",
         "..#.#.....",
         "##########",
         "#.######.#",
         "#.#####.##",
     ]
     expected = [list(string) for string in expected]
     sim.step()
     assert sim.current == expected
Esempio n. 5
0
def test_load_input():
    sample_path = Path(__file__).parent / "sample_input_1.txt"
    expected_rules = Rules(
        {
            0: "4 1 5",
            1: "2 3 | 3 2",
            2: "4 4 | 5 5",
            3: "4 5 | 5 4",
            4: '"a"',
            5: '"b"',
        }
    )
    expected_cases = [
        "ababbb",
        "bababa",
        "abbbab",
        "aaabbb",
        "aaaabbb",
    ]
    expected = (expected_rules, expected_cases)
    assert load_input(sample_path) == expected
Esempio n. 6
0
        for b_move in possible_three_rolls:
            possible_b_space = simplify(b_space + sum(b_move))
            possible_b_score = b_score + possible_b_space
            if possible_b_score >= max_score:
                b_wins += 1
            else:
                sub_a_wins, sub_b_wins = play(
                    a_space,
                    possible_b_space,
                    a_score,
                    possible_b_score,
                    next_move,
                    max_score,
                )
                a_wins += sub_a_wins
                b_wins += sub_b_wins
    else:
        print("Next move var invalid")
    return a_wins, b_wins


if __name__ == "__main__":
    p1_start, p2_start = load_input()
    a_wins, b_wins = play(p1_start, p2_start)
    winner = max({
        "A": a_wins,
        "B": b_wins
    }.items(), key=lambda item: item[1])[0]
    print(f"A wins {a_wins}, B wins {b_wins}, {winner} wins the most")
    print(f"Answer is {max(a_wins, b_wins)}")
Esempio n. 7
0
            y: int,
            character: str,
    ) -> int:
        to_check = product([-1, 0, 1], [-1, 0, 1])
        count = 0
        max_x = len(layout[0]) - 1
        max_y = len(layout) - 1
        for dx, dy in to_check:
            if dx == 0 and dy == 0:
                continue
            x2 = x
            y2 = y
            while True:
                x2 = x2 + dx
                y2 = y2 + dy
                if x2 < 0 or y2 < 0 or x2 > max_x or y2 > max_y:
                    break
                elif layout[y2][x2] == character:
                    count += 1
                    break
                elif layout[y2][x2] == "L":
                    break
        return count


if __name__ == "__main__":
    filepath = Path(__file__).parent / "input.txt"
    layout = load_input(filepath)
    sim = SeatingSimulation(layout)
    print(sim.run())
Esempio n. 8
0
from part1 import load_input, parse_input


def most_asleep_on_same_minute(guards):
    guard_id = None
    guard_minute_count = 0
    guard_sleepiest_minute = 0
    for guard in guards:
        minute, sleep_count = sleepiest_minute(guards[guard])
        if sleep_count > guard_minute_count:
            guard_minute_count = sleep_count
            guard_id = guard
            guard_sleepiest_minute = minute

    return guard_id, guard_sleepiest_minute


def sleepiest_minute(guard):
    count = [0] * 60
    for shift in guard.keys():
        for minute in range(len(count)):
            if guard[shift][minute]:
                count[minute] += 1
    return count.index(max(count)), count[count.index(max(count))]


if __name__ == '__main__':
    guards = parse_input(load_input())
    guard_id, minute = most_asleep_on_same_minute(guards)
    print(guard_id * minute)
Esempio n. 9
0
                    allergen_candidates[allergen_2].discard(candidate)
                updated = True
                break
        if not updated:
            raise NotImplementedError
    return answers


if __name__ == "__main__":
    SAMPLE_INPUT = [
        FoodEntry({"mxmxvkd", "kfcds", "sqjhc", "nhms"}, {"dairy", "fish"}),
        FoodEntry({"trh", "fvjkl", "sbzzf", "mxmxvkd"}, {"dairy"}),
        FoodEntry({"sqjhc", "fvjkl"}, {"soy"}),
        FoodEntry({"sqjhc", "mxmxvkd", "sbzzf"}, {"fish"}),
    ]

    from datetime import datetime
    start = datetime.now()
    filepath = Path(__file__).parent / "input.txt"
    strs = load_input(filepath)
    # strs = SAMPLE_INPUT
    allergens = resolve_allergens(strs)
    answer = ",".join(
        map(lambda x: x[1], sorted(list(allergens.items()),
                                   key=lambda x: x[0])))
    end = datetime.now()
    time = (end - start).total_seconds()
    print(time)
    print(allergens)
    print(answer)
Esempio n. 10
0
from typing import Iterable, Tuple
from part1 import load_input


def calculate_endpoint(
    instructions: Iterable[Tuple[str, int]],
    start: Tuple[int, int, int] = (0, 0, 0)
) -> Tuple[int, int, int]:
    x, y, aim = start
    for direction, number in instructions:
        if direction == "forward":
            x += number
            y += number * aim
        elif direction == "down":
            aim -= number
        elif direction == "up":
            aim += number
        else:
            raise ValueError(f"Direction not recognised: {direction}")
    return x, y, aim


if __name__ == "__main__":
    instructions = load_input()
    x, y, aim = calculate_endpoint(instructions)
    print(x * -1 * y)
Esempio n. 11
0
from __future__ import annotations

from itertools import permutations

from part1 import load_input, magnitude, SFNumber, snail_sum


def find_max_pair_sum(numbers: list[SFNumber]) -> int:
    max_ = 0
    for pair in permutations(numbers, 2):
        max_ = max(max_, magnitude(snail_sum(pair)))
    return max_


if __name__ == "__main__":
    numbers = load_input()
    print(find_max_pair_sum(numbers))
Esempio n. 12
0
from functools import reduce
import operator
from pathlib import Path
from typing import List, Tuple

from part1 import load_input, TobogganMap


def multiply_collisions(map_: TobogganMap, vectors: List[Tuple[int,
                                                               int]]) -> int:
    collision_counts = map(lambda vector: map_.traverse(vector), vectors)
    return reduce(operator.mul, collision_counts, 1)


if __name__ == "__main__":
    filepath = Path(__file__).parent / "input.txt"
    map_ = TobogganMap(load_input(filepath))
    cases = [
        (1, 1),
        (3, 1),
        (5, 1),
        (7, 1),
        (1, 2),
    ]
    print(multiply_collisions(map_, cases))
Esempio n. 13
0
from collections import namedtuple
from typing import List, Optional

from part1 import load_input, Parser

InputTuple = namedtuple("InputTuple", "noun, verb")


def find_inputs(program: List[str], target_value: str) -> Optional[InputTuple]:
    for noun in range(100):
        for verb in range(100):
            custom_program = program.copy()
            custom_program[1] = noun
            custom_program[2] = verb
            parser = Parser(custom_program)
            parser.execute()
            output = parser.program[0]
            if output == target:
                return InputTuple(noun, verb)
    return None


if __name__ == "__main__":
    program = load_input()
    target = "19690720"
    inputs = find_inputs(program, target)
    if inputs is None:
        print("No input found for target")
    else:
        print(100 * inputs.noun + inputs.verb)
Esempio n. 14
0
    coordinate_set = []
    for y in range(y_size):
        for x in range(x_size):
            coordinate_set.append((x + x_pos, y + y_pos))
    return coordinate_set


def populate_grid(claims_data):
    for claim in claims_data.keys():
        for coordinates in claims_data[claim]:
            grid[coordinates[1]][coordinates[0]].append(claim)


def check_claims(claims_data):
    for k in claims_data.keys():
        overlapped = False
        for coordinates in claims_data[k]:
            if len(grid[coordinates[1]][coordinates[0]]) > 1:
                overlapped = True
                break
        if overlapped == False: return k


if __name__ == '__main__':
    data = part1.load_input()
    grid = [[[] for _ in range(1000)] for _ in range(1000)]
    claims_data = parse_claims(data)
    populate_grid(claims_data)

    print(check_claims(claims_data))
Esempio n. 15
0
#! python3

import part1

if __name__ == '__main__':
    data = part1.load_input('day_2_input')

    testword_list = []

    #for entry in data
    for entry in range(len(data)):
        #loop through every iteration of it
        #put them in a dict
        testwords = []
        for x in range(len(data[entry])):
            testwords.append(data[entry][:x] + data[entry][x + 1:])
        testword_list.append(testwords)

    for lst in range(len(testword_list)):
        for word in testword_list[lst]:
            for ex in range(lst + 1, len(testword_list)):
                if word in testword_list[ex]:
                    print(word)
Esempio n. 16
0
 def test_run(self):
     filepath = Path(__file__).parent / "sample_input.txt"
     layout = load_input(filepath)
     sim = SeatingSimulation(layout)
     assert sim.run() == 37
Esempio n. 17
0
from __future__ import annotations

from part1 import load_input, step


def find_sync_step(grid: list[list[int]], max_steps: int = 1000) -> int:
    for i in range(max_steps):
        grid, flashes = step(grid)
        if flashes == len(grid) * len(grid[0]):
            return i + 1
    raise ValueError(f"Sync point not found within {max_steps} steps")


if __name__ == "__main__":
    grid = load_input()
    sync_point = find_sync_step(grid, 1000)
    print(sync_point)
Esempio n. 18
0
from collections import defaultdict
from itertools import product

from part1 import count_dangerous_areas, load_input, Line2D, Point2D


def map_vent_density_full(lines: list[Line2D]) -> dict[Point2D, int]:
    vent_count: dict[Point2D, int] = defaultdict(lambda: 0)
    for line in lines:
        x_step = 1 if line.start.x <= line.end.x else -1
        y_step = 1 if line.start.y <= line.end.y else -1
        x_values = range(line.start.x, line.end.x + x_step, x_step)
        y_values = range(line.start.y, line.end.y + y_step, y_step)
        if line.is_diagonal:
            for x, y in zip(x_values, y_values):
                vent_count[Point2D(x, y)] += 1
        else:
            for x, y in product(x_values, y_values):
                vent_count[Point2D(x, y)] += 1
    return vent_count


if __name__ == "__main__":
    lines = load_input()
    vents = map_vent_density_full(lines)
    danger_count = count_dangerous_areas(vents)
    print(danger_count)
Esempio n. 19
0
def test_count_valid_passwords_sample_data():
    passwords = load_input(Path("sample_input.txt"))
    assert count_valid_passwords(passwords) == 3
Esempio n. 20
0
        last = next_
    return pairs


def get_freqs_after_steps(template: list[str], recipes: dict[tuple[str, str],
                                                             str],
                          steps: int) -> dict[str, int]:
    pairs: dict[tuple[str, str], int] = to_pairs(template)
    first = template[0]
    for _ in range(steps):
        pairs = step_pairs(pairs, recipes)

    freqs: dict[str, int] = DefaultDict(lambda: 0)
    # To avoid counting twice, only count right item
    # Count first item on its own as this will only be on the left
    freqs[first] += 1
    for (_, b), count in pairs.items():
        freqs[b] += count
    return freqs


if __name__ == "__main__":
    from datetime import datetime

    start = datetime.now()
    template, recipes = load_input()
    freqs = get_freqs_after_steps(template, recipes, 40)
    print(max(freqs.values()) - min(freqs.values()))
    end = datetime.now()
    print((end - start).total_seconds())
Esempio n. 21
0
    """

    def simplify_risk(x):
        while x > 9:
            x -= 9
        return x

    grid = []
    for y in range(len(tile) * 5):
        y_tile = y // len(tile)
        source_y = y % len(tile)
        row = []
        for x_tile in range(5):
            x_segment = [simplify_risk(x + x_tile + y_tile) for x in tile[source_y]]
            row.extend(x_segment)
        grid.append(row)
    return grid


if __name__ == "__main__":
    from datetime import datetime

    start = datetime.now()
    tile = load_input()
    grid = generate_grid(tile)
    length = find_shortest_path(grid, 1000000)

    end = datetime.now()
    print(length)
    print((end - start).total_seconds())
Esempio n. 22
0
        current = "start"
        visited.append("start")

    for option in paths[current]:
        if option == "end":
            new_visited = visited.copy()
            new_visited.append("end")
            routes.append(new_visited)
        elif option == "start":
            continue
        elif second_small_used and option == option.lower(
        ) and option in visited:
            continue
        else:
            if option == option.lower() and option in visited:
                new_second_small_used = True
            else:
                new_second_small_used = second_small_used
            new_visited = visited.copy()
            new_visited.append(option)
            routes.extend(
                find_routes(paths, option, new_visited, new_second_small_used))

    return routes


if __name__ == "__main__":
    map_ = load_input()
    routes = find_routes(map_)
    print(len(routes))
Esempio n. 23
0
from part1 import calc_minute_sleep_frequencies, load_input


def list_guards(logs: List[Tuple[datetime, str]]) -> Set[str]:
    guards = set()
    for _, text in logs:
        shift_start_match = re.match(r"Guard (?P<guard>\S*) begins shift",
                                     text)
        if shift_start_match:
            guards.add(shift_start_match.groupdict()["guard"])
    return guards


if __name__ == "__main__":
    # filename = "input_sample.txt"
    filename = "input.txt"
    logs = load_input(filename)
    guards = list_guards(logs)
    # Dict of guard to (minute, times slept)
    guard_most_slept_minute: Dict[str, Tuple[int, int]] = {}
    for guard in guards:
        freqs = calc_minute_sleep_frequencies(logs, guard)
        guard_most_slept_minute[guard] = max(freqs.items(),
                                             key=lambda item: item[1])
    most_common_guard_minute = max(guard_most_slept_minute.items(),
                                   key=lambda item: item[1][1])
    guard, (minute, count) = most_common_guard_minute
    print(
        f"Guard {guard}, minute {minute}, times {count}. Answer {int(guard[1:])*minute}"
    )
Esempio n. 24
0

def most_common(numbers: List[str]) -> str:
    count: Dict[str, int] = {}
    for number in numbers:
        count[number] = count.get(number, 0) + 1
    return "1" if count.get("1", 0) >= count.get("0", 0) else "0"


def calc_oxygen_rating(numbers: List[str]) -> str:
    return filter_numbers(numbers, most_common)


def calculate_co2_rating(numbers: List[str]) -> str:
    def least_common(numbers: List[str]) -> str:
        count: Dict[str, int] = {}
        for number in numbers:
            count[number] = count.get(number, 0) + 1
        return "0" if count.get("0", 0) <= count.get("1", 0) else "1"

    return filter_numbers(numbers, least_common)


if __name__ == "__main__":
    input_ = load_input()
    oxygen_str = calc_oxygen_rating(input_)
    co2_string = calculate_co2_rating(input_)
    print(oxygen_str, co2_string)
    print(int(oxygen_str, 2), int(co2_string, 2))
    print(int(oxygen_str, 2) * int(co2_string, 2))
Esempio n. 25
0
        elif type_ == 3:
            # Maximum
            return max(values)
        elif type_ == 5:
            # Greater than
            if values[0] > values[1]:
                return 1
            return 0
        elif type_ == 6:
            # Less than
            if values[0] < values[1]:
                return 1
            return 0
        elif type_ == 7:
            # Equal to
            if values[0] == values[1]:
                return 1
            return 0
        else:
            raise ValueError("Unrecognised/unexpected packet type")
    else:
        raise ValueError("Unrecognised packet type")


if __name__ == "__main__":
    hex_str = load_input()
    bin_str = hexes_to_bin(hex_str)
    packets = split_packets(bin_str)
    answer = evaluate_packet(packets[0])
    print(answer)