2 minute read

Advent of Code (Day 1)

Part 1

Key part of the question:

The newly-improved calibration document consists of lines of text; each line originally contained a specific calibration value that the Elves now need to recover. On each line, the calibration value can be found by combining the first digit and the last digit (in that order) to form a single two-digit number.

For example:

1abc2
pqr3stu8vwx
a1b2c3d4e5f
treb7uchet

In this example, the calibration values of these four lines are 12, 38, 15, and 77. Adding these together produces 142.

Game Plan

So now, we need to find the first digit and last digit. Then we need remember two things, Two pointer!!!

one pointer to find the first digit from left to right another pointer to find the last digit from right to left

Python Code

def get_number(text):
    first_digit = None
    last_digit = None
    # find first digit from left to right
    for char in text:
        if char.isdigit():
            first_digit = int(char)
            # found so we need to break
            break
    # find last digit from right to left
    for char in reversed(text):
        if char.isdigit():
            last_digit = int(char)
            # found so we need to break
            break
    # since alway two digit therefore time ten for first digit
    return first_digit * 10 + last_digit

Part 2

Key part of the question:

one, two, three, four, five, six, seven, eight, and nine also count as valid “digits”.

Game PLan

hmmm, so now if we find a digit, we will mark it as first or last digit otherwise we check if the seen characters can form a word that is digit

How we can check if seen characters can form a word that is a digit?

  1. keep track of the characters that we have seen
  2. when it is not a digit, then add the character to seen characters, then see if it a substring of one, two ,three….

Python

mapping = {
    "one": 1,
    "two": 2,
    "three": 3,
    "four": 4,
    "five": 5,
    "six": 6,
    "seven": 7,
    "eight": 8,
    "nine": 9,
}

def get_number2(text):
    # seen characters
    seen = ""
    first_digit = None
    last_digit = None
    for char in text:
        if char.isdigit():
            first_digit = int(char)
            break
        else:
            # add to seen characters
            seen += char
            # check if digit is a substring of the seen characters
            valid_substring = [
                substring for substring in mapping.keys() if substring in buffer
            ]
            # check if it has substring
            if valid_substring:
                # get the digit from mapping
                first_digit = mapping[valid_substring[0]]
                break
    seen = ""
    for char in reversed(text):
        if char.isdigit():
            last_digit = int(char)
            break
        else:
            # add char to front coz we are finding in reverse other
            seen = char + seen
            valid_substring = [
                substring for substring in mapping.keys() if substring in buffer
            ]
            if valid_substring:
                last_digit = mapping[valid_substring[0]]
                break
    return first_digit * 10 + last_digit