Intro

This one wasn’t too bad, so I’m gonna get right to it. You can find my full solutions repo here.

Solution

The three components of this puzzle aren’t too bad. To find whether a number has adjacent digits that are the same, you can simply pull the last digit and loop your way through the number using modulo (testing for equality at each step).

def has_adjacent_digits(number):
    cur_digit = number % 10
    number = number // 10
    while number > 0:
        last_digit = cur_digit
        cur_digit = number % 10
        if last_digit == cur_digit:
            return True
        number = number // 10
    return False

Determining whether the digits are monotonically decreasing is done in a similar way, the test is just greater than instead of equality.

def is_decreasing(number):
    cur_digit = number % 10
    number = number // 10
    while number > 0:
        last_digit = cur_digit
        cur_digit = number % 10
        if cur_digit > last_digit:
            return False
        number = number // 10
    return True

Testing a number to make sure that it has a “strict” double (two matching digits that are not part of a larger matching sequence) was a little trickier but not too bad. I didn’t have too hard of a time solving it, but I’m not really happy with the form of the code. As it stands, this function feels a bit sloppy and I’m sure there’s a better way to accomplish this.

def has_strict_double(number):
    cur_digit = number % 10
    number = number // 10
    trail_digit = -1
    while number > 0:
        last_digit = cur_digit
        cur_digit = number % 10
        # If there is a next digit, check that it and the trailing digit
        # aren't the same as cur_digit.
        if last_digit == cur_digit and number > 9:
            future_digit = ((number // 10) % 10)
            if cur_digit != future_digit and cur_digit != trail_digit:
                return True
        # If this is the last digit, check the trailing digit against 
        # cur_digit.
        elif last_digit == cur_digit and trail_digit != cur_digit:
            return True
        number = number // 10
        trail_digit = last_digit
    return False

The counting part is simple. Loop from the lower bound to the upper and test the criteria at each number. Increase the running totals for values that meet the criteria. Bam.

Again, you can find my full solutions repo here.