Learning Python with Advent of Code Walkthroughs

Dazbo's Advent of Code solutions, written in Python

Infinite Tower

Advent of Code 2015 - Day 1

Day 1: Not Quite Lisp

Useful Links

Concepts and Packages Demonstrated

LoggingTiming and ProgressReading filesenumerate

Problem Intro

Welcome to the very first AoC problem! This one is a nice gentle warm up.

We’re told Santa is in a large apartment building. We’re told to assume it has an infinite number of floors, both upwards and downwards. The ground floor is 0. Higher floors are numbered with positive integers: 1, 2, 3, etc. And underground floors are negative, e.g. -1, -2, etc.

Our input is simply opening and closing brackets. E.g.

(()(()(

Every "(" means ascend one floor, and every ")" means descend one floor.

Part 1

To what floor do the instructions take Santa?

This is easy enough. All the ups minus all the downs will give us the floor we arrive at, when all the instructions have been processed.

import os
import time

SCRIPT_DIR = os.path.dirname(__file__) 
INPUT_FILE = "input/input.txt"

UP = "("
DOWN = ")"

def main():
    input_file = os.path.join(SCRIPT_DIR, INPUT_FILE)
    with open(input_file, mode="rt") as f:
        data = f.read()

    up_count = data.count(UP)
    down_count = data.count(DOWN)

    print(f"Final floor: {up_count-down_count}")

if __name__ == "__main__":
    t1 = time.perf_counter()
    main()
    t2 = time.perf_counter()
    print(f"Execution time: {t2 - t1:0.4f} seconds")

This code:

Part 2

Find the position of the first character that causes Santa to enter the basement (floor -1).

Instead of just adding up the total number of UPs and DOWNs, we now need to keep track of the current floor number, as we progress through the instructions. We need to determine which instruction first causes Santa to reach floor -1.

This is my additional code for Part 2, added to the main() method:

    floor = 0
    for i, char in enumerate(data, 1):
        if char == UP:
            floor += 1
        else:
            floor -= 1

        if floor == -1:
            print(f"Basement reached at instruction {i}")
            break

Note the use of enumerate(). This is a function that provides an automatic counter, whenever we iterate over a collection. See an overview here. I’m using enumerate to count which instruction I’m currently processing. When we hit floor -1, we identify which instruction position we’re currently on.

Note that when I call enumerate(), I’m passing an extra parameter, which is the number we want the counter to start on. If we didn’t supply this 1, then the counter would start at 0.

And the final output looks like this:

Final floor: 232
Basement reached at instruction 1783
Execution time: 0.0005 seconds

0.5ms. So pretty quick too.