Sean McLemon | Advent of Code

Home | Czech | Blog | GitHub | Advent Of Code | Notes


2019-12-04 - Secure Container

(original .ipynb)

Day 4 puzzle input is a pair of integers which represent a range of integers (mine is 256310-732736). Part 1 involves filtering integers in these range according to a handful of specified rules and counting how many integers satisfy these conditions. Part 2 is the same but with one additional rule.

# 256310-732736

def is_six_digit(number):
    return 6 == len(str(number))

def within_range(number, range_from, range_to):
    return number >= range_from and number <= range_to

def has_adjacent_digits(number):
    digits = [ int(c) for c in str(number) ]
    previous_digit = None
    
    for digit in digits:
        if previous_digit == digit:
            return True
        previous_digit = digit
    return False
    
def increasing_digits(number):
    digits = [ int(c) for c in str(number) ]
    
    previous_digit = -1
    
    for digit in digits:
        if digit < previous_digit:
            return False
        previous_digit = digit
    return True

def valid_password(number):
    return is_six_digit(number) and within_range(number, 256310, 732736) and has_adjacent_digits(number) and increasing_digits(number)


# assert True == valid_password(111111)
assert False == valid_password(223450)
assert False == valid_password(123789)


#     111111 meets these criteria (double 11, never decreases).
#     223450 does not meet these criteria (decreasing pair of digits 50).
#     123789 does not meet these criteria (no double).


valid_passwords = [ n for n in range(0, 1000000) if valid_password(n) ]

print(len(valid_passwords))
979
from functools import reduce

def has_adjacent_2_digits(number):
    digits = [ int(c) for c in str(number) ]
    previous_digit = None
    run_length = 1
    runs = []
    
    for digit in digits:
        if previous_digit == digit:
            run_length += 1
        else:
            runs.append(run_length)
            run_length = 1
            
        previous_digit = digit
    runs.append(run_length)
    
    return len([ n for n in runs if n == 2 ]) >= 1

def valid_password(number, range_from, range_to):
    six_digit = is_six_digit(number)
    range_ok = within_range(number, range_from, range_to)
    two_adjacent = has_adjacent_2_digits(number)
    increasing = increasing_digits(number)

    return six_digit and within_range(number, range_from, range_to) and two_adjacent and increasing

assert False == valid_password(111111, 0, 1000000)
assert False == valid_password(223450, 0, 1000000)
assert False == valid_password(123789, 0, 1000000)
assert True == valid_password(112233, 0, 1000000)
assert False == valid_password(123444, 0, 1000000)
assert True == valid_password(111122, 0, 1000000)

valid_passwords = [ n for n in range(0, 1000000) if valid_password(n, 256310, 732736) ]
print(len(valid_passwords))
635