Beispiel #1
0
def main():
    input_ = load_from_file("day17_input.txt")

    # PART 1
    input_init = np.zeros((len(input_), len(input_[0]), 1), dtype=np.int8)
    for i1, line in enumerate(input_):
        for i2, c in enumerate(line):
            input_init[i1, i2, 0] = 1 if c == "#" else 0
    evolutions_pt1 = [input_init]
    for i in range(6):
        evolutions_pt1.append(evolve(evolutions_pt1[-1]))

    sol_pt1 = np.sum(evolutions_pt1[-1])
    print(sol_pt1)
    assert sol_pt1 == 368  # Solution for my input

    # PART 2
    input_init_pt2 = np.zeros(shape=(len(input_), len(input_[0]), 1, 1),
                              dtype=np.int)
    for i1, line in enumerate(input_):
        for i2, c in enumerate(line):
            input_init_pt2[i1, i2, 0, 0] = 1 if c == "#" else 0
    evolutions_pt2 = [input_init_pt2]
    for i in range(6):
        evolutions_pt2.append(evolve_pt2(evolutions_pt2[-1]))

    sol_pt2 = np.sum(evolutions_pt2[-1])
    print(sol_pt2)
    assert sol_pt2 == 2696  # Solution for my input
Beispiel #2
0
def main():
    input_ = load_from_file("day11_input.txt")
    init_grid = [list(line) for line in input_]

    # PART 1
    grids_pt1 = [init_grid]
    while True:
        previous = grids_pt1[-1]
        evolved = evolve_grid(evolve_point, previous)

        if grids_eq(previous, evolved):
            break
        else:
            grids_pt1.append(evolved)

    sol_pt1 = occurence_in_grid(grids_pt1[-1], "#")
    print(sol_pt1)

    assert sol_pt1 == 2261  # My solution

    # PART 2
    grids_pt2 = [init_grid]
    while True:
        previous = grids_pt2[-1]
        evolved = evolve_grid(evolve_point_pt2, previous)

        if grids_eq(previous, evolved):
            break
        else:
            grids_pt2.append(evolved)

    sol_pt2 = occurence_in_grid(grids_pt2[-1], "#")
    print(sol_pt2)

    assert sol_pt2 == 2039  # My solution
Beispiel #3
0
def main():
    input_ = load_from_file("day15_input.txt")

    # PART 1
    d_pt1, dd_pt1 = init(input_[0])
    for i in range(len(d_pt1), 2020):
        prev_val = d_pt1[i - 1]
        if len(dd_pt1[prev_val]) == 1:
            d_pt1[i] = 0
            dd_pt1[0].append(i)
        else:
            new_val = dd_pt1[prev_val][1] - dd_pt1[prev_val][0]
            d_pt1[i] = new_val
            dd_pt1[new_val].append(i)

    sol_pt1 = d_pt1[2020 - 1]
    print(sol_pt1)
    assert sol_pt1 == 1280  # Solution for my input

    # PART 2
    d_pt2, dd_pt2 = init(input_[0])
    for i in range(len(d_pt2), 30000000):
        prev_val = d_pt2[i - 1]
        if len(dd_pt2[prev_val]) == 1:
            d_pt2[i] = 0
            dd_pt2[0].append(i)
        else:
            new_val = dd_pt2[prev_val][1] - dd_pt2[prev_val][0]
            d_pt2[i] = new_val
            dd_pt2[new_val].append(i)

    sol_pt2 = d_pt2[30000000 - 1]
    print(sol_pt2)
    assert sol_pt2 == 651639  # Solution for my input
Beispiel #4
0
def main():
    input_ = load_from_file("day10_input.txt")
    numbers = [int(line) for line in input_]

    input_sorted = [0]
    input_sorted.extend(sorted(numbers))
    input_sorted.append(input_sorted[-1] + 3)

    diff1, diff3 = 0, 0
    diff3_index = []

    for i in range(len(input_sorted) - 1):
        if input_sorted[i+1] - input_sorted[i] == 1:
            diff1 += 1
        if input_sorted[i+1] - input_sorted[i] == 3:
            diff3 += 1
            diff3_index.append(i+1)

    # PART 1
    solt_pt1 = diff1 * diff3
    print(solt_pt1)

    assert solt_pt1 == 2030  # My solution

    diff3_index.insert(0, 0)

    # PART 2
    chunks = (
        input_sorted[diff3_index[i]:diff3_index[i+1]]
        for i in range(len(diff3_index) - 1)
    )
    sol_pt2 = prod(map(count_possible_traversals, chunks))
    print(sol_pt2)

    assert sol_pt2 == 42313823813632  # My solution
Beispiel #5
0
def main():
    input_ = load_from_file("day9_input.txt")
    numbers = [int(line) for line in input_]

    for i in range(25, len(numbers)):
        if numbers[i] not in nondiagonal_sums(numbers[i - 25:i]):
            sol_pt1 = numbers[i]
            index_ = i
            break

    print(sol_pt1)
    assert sol_pt1 == 1492208709  # My solution

    preceeding_nums = numbers[:index_]
    sliding_window_sums = {}
    for i in range(2, 100):
        sliding_window_sums[i] = list(
            map(sum, sliding_window(i, preceeding_nums)))
        if sol_pt1 in sliding_window_sums[i]:
            index_of_sum = sliding_window_sums[i].index(sol_pt1)
            contigous_range = numbers[index_of_sum:index_of_sum + i]
            sol_pt2 = min(contigous_range) + max(contigous_range)
            break

    print(sol_pt2)
    assert sol_pt2 == 238243506  # My solution
Beispiel #6
0
def main():
    input_ = load_from_file("day2_input.txt")

    sol_count_pt1, sol_count_pt2 = 0, 0

    # PART 1
    for i in input_:
        boundaries, letter, string = i.split(" ")
        lower, upper = map(int, boundaries.split("-"))
        letter = letter[0]
        if lower <= string.count(letter) <= upper:
            sol_count_pt1 += 1

    print(sol_count_pt1)

    # PART 2
    for i in input_:
        positions, letter, string = i.split(" ")
        pos1, pos2 = map(lambda x: x - 1, map(int, positions.split("-")))
        letter = letter[0]
        if string[pos1] == letter and string[pos2] != letter:
            sol_count_pt2 += 1
            continue
        if string[pos1] != letter and string[pos2] == letter:
            sol_count_pt2 += 1
            continue

    print(sol_count_pt2)

    # Correct solutions for my input
    assert sol_count_pt1 == 454
    assert sol_count_pt2 == 649
Beispiel #7
0
def main():
    input_ = load_from_file("day18_input.txt")

    sol_pt1 = sum(evaluate(line) for line in input_)
    print(sol_pt1)
    assert sol_pt1 == 67800526776934  # Solution for my input

    sol_pt2 = sum(evaluate_pt2(line) for line in input_)
    print(sol_pt2)
    assert sol_pt2 == 340789638435483  # Solution for my input
Beispiel #8
0
def test_search_for_print_books():
    """ Check if book_loader.search_for_print_books(xml_content) returns the correct number of validated results.
    """
    url = "http://www.worldcat.org/search?q=lean+in&fq=%20(%28x0%3Abook+x4%3Aprintbook%29)%20%3E%20ln%3Aeng&se=&sd=&qt=facet_fm_checkbox&refinesearch=true&refreshFormat=undefined"
    xml_content = load_from_file('data/worldcatxml.html')

    int_results = book_loader.search_for_print_books(xml_content)

    # Expect list of 10 results total, with each result as a string that can also be converted into an int
    assert len(int_results) == 10
    assert type(int_results) is list
    for current_result in int_results:
        _validate_result(current_result)
Beispiel #9
0
def main():
    input_ = load_from_file("day8_input.txt")

    instructions = [Instruction(line) for line in input_]

    # PART 1
    solve_pt1(instructions)
    print(sol_pt1)
    assert sol_pt1 == 1553  # My solution

    # PART 2
    solve_pt2(instructions)
    print(sol_pt2)
    assert sol_pt2 == 1877  # My solution
Beispiel #10
0
def main():
    input_ = load_from_file("day16_input.txt")

    # My ticket and nearby tickets are separated by an empty line.
    empty_line_ix1 = input_.index("")
    empty_line_ix2 = input_.index("", empty_line_ix1 + 1)

    ticket_fields = [
        TicketField.from_line(input_[i]) for i in range(empty_line_ix1)
    ]

    my_ticket = TicketValues.from_line(input_[empty_line_ix2 - 1])

    tickets = [
        TicketValues.from_line(input_[i])
        for i in range(empty_line_ix2 + 2, len(input_))
    ]

    sol_pt1 = 0
    err_indexes = set()
    for i, t in enumerate(tickets):
        for val in t.vals:
            if all(val not in tf for tf in ticket_fields):
                sol_pt1 += val
                err_indexes.add(i)

    print(sol_pt1)
    assert sol_pt1 == 32835  # Solution for my input

    # PART 2
    valid_tickets = [
        tickets[i] for i in range(len(tickets)) if i not in err_indexes
    ]

    possible_field_nums = defaultdict(list)
    for tf in ticket_fields:
        for i in range(20):
            ith_ticket_vals: Iterable[int] = (itemgetter(i)(t.vals)
                                              for t in valid_tickets)
            if all(ticket_val in tf for ticket_val in ith_ticket_vals):
                possible_field_nums[tf.name].append(i)

    # print(possible_field_nums)
    # Positions were solved by hand, from the dictionary of possible field numbers
    # above.
    departure_ticket_positions = (1, 2, 6, 13, 14, 15)
    sol_pt2 = prod(itemgetter(*departure_ticket_positions)(my_ticket.vals))
    print(sol_pt2)
    assert sol_pt2 == 514662805187  # Solution for my input
Beispiel #11
0
def main():
    input_ = load_from_file("day5_input.txt")

    seat_ids = sorted(calculate_seat_id(line) for line in input_)

    # PART 1
    sol_pt1 = max(seat_ids)
    print(sol_pt1)

    # PART 2
    range_boundary = len(seat_ids)
    min_ = seat_ids[0]
    for i in range(min_, min_ + range_boundary):
        if i not in seat_ids:
            sol_pt2 = i
            print(sol_pt2)

    # Correct solutions for my input
    assert sol_pt1 == 904
    assert sol_pt2 == 669
Beispiel #12
0
def main():
    input_ = load_from_file("day4_input.txt")

    passports = extract_and_join_groups_separated_by_str(" ".join, input_)

    # PART 1
    sol_count_pt1 = sum(
        is_valid_passport_pt1(p)
        for p in passports)  # Oh yeaaah, gimme that sum of bools...
    print(sol_count_pt1)

    # PART 2
    sol_count_pt2 = sum(
        is_valid_passport_pt1(p) and is_valid_passport_pt2(p)
        for p in passports)  # Oh yeaaah, gimme that sum of bools...
    print(sol_count_pt2)

    # Correct solutions for my input
    assert sol_count_pt1 == 260
    assert sol_count_pt2 == 153
Beispiel #13
0
def main():
    input_ = load_from_file("day13_input.txt")

    # PART 1
    earliest_ts = int(input_[0])
    bus_ids = parse_ints(input_[1])
    wait_times = []
    for id_ in bus_ids:
        first_larger = first((i for i in count(start=0, step=id_) if i >= earliest_ts))
        wait_times.append(first_larger - earliest_ts)
    min_wait = min(wait_times)
    sol_pt1 = min_wait * bus_ids[wait_times.index(min_wait)]

    print(sol_pt1)
    assert sol_pt1 == 2382  # Solution for my input

    # PART 2
    sol_pt2 = solve_pt2(parse_ints_pt2(input_[1]))
    print(sol_pt2)
    assert sol_pt2 == 906332393333683  # Solution for my input
Beispiel #14
0
def main():
    input_ = load_from_file("day6_input.txt")

    # PART 1
    sol_pt1 = sum(
        (len(set(g))
         for g in extract_and_join_groups_separated_by_str("".join, input_)))
    print(sol_pt1)

    # PART 2
    sol_pt2 = sum(
        len(
            reduce(lambda x, y: x.intersection(y), (set(person)
                                                    for person in group)))
        for group in extract_groups_separated_by_str(input_))

    print(sol_pt2)

    # Correct solutions for my input
    assert sol_pt1 == 6911
    assert sol_pt2 == 3473
Beispiel #15
0
def main():
    input_ = load_from_file("day12_input.txt")

    init_ship_pos = ShipPosition(x=0, y=0, direction="E")
    instructions = [Instruction(line[:1], int(line[1:])) for line in input_]

    # PART 1
    moves = accumulate(move, instructions, initial=init_ship_pos)
    last_pos_pt1 = last(moves)
    sol_pt1 = abs(last_pos_pt1)
    print(sol_pt1)

    assert sol_pt1 == 441  # Solution for my input

    # PART 2
    init_with_waypoint = CompPosition(init_ship_pos, WaypointPosition(10, 1))
    moves_pt2 = accumulate(move_pt2, instructions, initial=init_with_waypoint)
    last_pos_pt2 = last(moves_pt2)
    sol_pt2 = abs(last_pos_pt2.ship)
    print(sol_pt2)

    assert sol_pt2 == 40014  # Solution for my input
Beispiel #16
0
def main():
    input_ = load_from_file("day7_input.txt")

    bags = {
        i: Bag(line.split("contain")[0][:-6])
        for i, line in enumerate(input_)
    }

    for i, line in enumerate(input_):
        contain_part = line.split("contain")[1].strip(" .")
        for q_cc in qty_and_colour_code_from_str(contain_part):
            for k, b in bags.items():
                if q_cc[0] == b.colour_code:
                    bags[i].contains_with_qty.append((b, q_cc[1]))

    sol_pt1, sol_pt2 = 0, 0
    shiny_gold_bag = Bag("shiny gold")
    for k, v in bags.items():
        if v == shiny_gold_bag:
            shiny_gold_bag = v  # Get the reference on the "real" shiny gold bag
            break

    # PART 1
    for b in bags.values():
        if shiny_gold_bag == b:
            continue
        if is_in(shiny_gold_bag, b):
            sol_pt1 += 1

    print(sol_pt1)

    # PART 2
    sol_pt2 = shiny_gold_bag.can_hold()
    print(sol_pt2)

    # Correct solutions for my input
    assert sol_pt1 == 296
    assert sol_pt2 == 9339
Beispiel #17
0
def main():
    input_ = load_from_file("day1_input.txt")
    numbers = [int(line) for line in input_]

    # PART 1
    for i1, x in enumerate(numbers):
        for y in numbers[i1:]:
            if x + y == 2020:
                sol_pt1 = x * y
                break
    print(sol_pt1)

    # PART 2
    for i1, x in enumerate(numbers):
        for i2, y in enumerate(numbers[i1:]):
            for z in numbers[i2:]:
                if x + y + z == 2020:
                    sol_pt2 = x * y * z
                    break
    print(sol_pt2)

    # Correct solutions for my input
    assert sol_pt1 == 658899
    assert sol_pt2 == 155806250
Beispiel #18
0
class TestCreateBookFromWorldcat(object):
    # TODO - pull all html_content for worldcat to a class-level attribute
    worldcat_html = load_from_file('data/worldcat.html')

    goodreads_html = load_from_file('data/goodreads.html')

    test_api_key = 'test-test-test'
    @classmethod
    def setup_class(cls):
        """ setup any state specific to the execution of the given class (which
        usually contains tests).
        """
        os.environ['GOODREADS_API_KEY'] = cls.test_api_key

    @classmethod
    def teardown_class(cls):
        """ teardown any state that was previously setup with a call to
        setup_class.
        """
        os.environ.pop('GOODREADS_API_KEY')

    def _fake_requests_response(self, content):
        mock_resp = MagicMock()
        mock_resp.content = content
        return mock_resp

    def test_create_book_from_worldcat_id(self):
        """
        :return:
        """
        oclc_id = 813526963

        values = {
            _stable_key(args=('http://www.worldcat.org/oclc/813526963',)):
                self._fake_requests_response(self.worldcat_html),
            _stable_key(args=('https://www.goodreads.com/book/isbn',), kwargs=dict(params=dict(key=self.test_api_key, isbn='9780385349949'))):
                self._fake_requests_response(self.goodreads_html),
        }

        def requests_get_side_effect(*args, **kwargs):
            key = _stable_key(args=args, kwargs=kwargs)
            return values[key]

        mock_get = MagicMock()
        mock_get.side_effect = requests_get_side_effect

        with patch('requests.get', new=mock_get):
            current_book = book_loader.create_book_from_worldcat_id(oclc_id)

        assert current_book.book_id == 813526963


    def test_load_book_from_worldcat_details_page(self):
        """
        :return:
        """
        worldcat_details_page_url = "http://www.worldcat.org/oclc/813526963"
        oclc_id = 813526963

        book = book_loader._load_book_from_worldcat_details_page(self.worldcat_html, worldcat_details_page_url, oclc_id)

        # Expect the book object to have all the expected attributes
        assert book.book_id == 813526963
        assert book.title == 'Lean in : women, work, and the will to lead'
        assert book.publisher == 'New York : Alfred A. Knopf, 2013.'
        assert book.worldcaturl == 'http://www.worldcat.org/oclc/813526963'
        assert book.page_count == '228'
        assert 'United States' in book.summary
        assert 'TEDTalk' in book.summary
        assert book.coverurl == 'http://coverart.oclc.org/ImageWebSvc/oclc/+-+814170863_140.jpg?SearchOrder=+-+OT,OS,TN,GO,FA'


    def test_load_title_from_worldcat_details_page(self):
        """
        :return:
        """

        pass


    def test_load_authors_from_worldcat_details_page(self):
        """
        :return:
        """

        worldcat_details_page_url = "http://www.worldcat.org/oclc/813526963"
        oclc_id = 813526963

        author_list = book_loader._load_authors_from_worldcat_details_page(self.worldcat_html)

        assert type(author_list) is list
        assert len(author_list) == 2

        for author_obj in author_list:
            assert ("Sheryl" in author_obj.author_name or "Nell" in author_obj.author_name)


    def test_load_isbns_from_worldcat_details_page(self):
        """
        :return:
        """

        isbn10_list, isbn13_list = book_loader._load_isbns_from_worldcat_details_page(self.worldcat_html)

        for current_isbn in isbn10_list:
            assert (len(current_isbn.isbn10) == 10 and current_isbn.isbn10 == '0385349947')

        for current_isbn in isbn13_list:
            assert (len(current_isbn.isbn13) == 13 and current_isbn.isbn13 == '9780385349949')


    def test_load_goodreads_info_from_goodreads_api(self):
        """
        :return:
        """

        isbn13 = '9780385349949'

        goodreads_info_obj = book_loader._load_goodreads_info_from_goodreads_api(self.goodreads_html)

        assert (goodreads_info_obj.goodreads_ratings_count >= 100000)
        assert (goodreads_info_obj.goodreads_rating >= 3.50)
        assert (goodreads_info_obj.goodreads_work_id == '21865596')
        assert (goodreads_info_obj.goodreads_review_count >= 220000)