Day 11: Corporate Policy

Day 11.1

Increment


In [26]:
alphabet = list('abcdefghijklmnopqrstuvwxyz')
N = len(alphabet)

def to_num(s):
    return [ord(ch) - 97  for ch in list(s)]

def to_char(n):
    return ''.join([chr(int(d) + 97) for d in n])

def num_increment(l):
    if l[-1] == N - 1:
        return(num_increment(l[:-1]) + [0])
    else:
        l[-1] += 1
        return l

def increment(s):
    return to_char(num_increment(to_num(s)))

Password requirements


In [50]:
def straight(s):
    l = to_num(s)
    for i in range(len(s[:-2])):
        if l[i] == l[i + 1] - 1 == l[i + 2] - 2:
            return True
    return False

def iol(s):
    if ('i' in s) or ('l' in s) or ('o' in s):
        return False
    return True

def non_overlapping(s):
    i = 0
    count = 0
    while (i < len(s) - 1):
        if s[i] == s[i + 1]:
            count += 1
            i += 2
        else:
            i += 1
    return (count >= 2)

Next password finder


In [53]:
def next_password(password):
    p = increment(password)
    while (not straight(p)) or (not iol(p)) or (not non_overlapping(p)):
        p = increment(p)
    return p

Test

- hijklmmn meets the first requirement (because it contains the straight hij) but fails the second requirement requirement (because it contains i and l). - abbceffg meets the third requirement (because it repeats bb and ff) but fails the first requirement. - abbcegjk fails the third requirement, because it only has one double letter (bb). - The next password after abcdefgh is abcdffaa. - The next password after ghijklmn is ghjaabcc, because you eventually skip all the passwords that start with ghi..., since i is not allowed.

In [58]:
def test():
    p = 'hijklmmn'
    assert(straight(p) and not iol(p))
    p = 'abbceffg'
    assert(non_overlapping(p) and not straight(p))
    p = 'abbcegjk'
    assert(not non_overlapping(p))
    p = 'abcdefgh'
    assert(next_password(p) == 'abcdffaa')
    p = 'ghijklmn'
    assert(next_password(p) == 'ghjaabcc')

In [59]:
%%time
test()


CPU times: user 52.4 s, sys: 0 ns, total: 52.4 s
Wall time: 52.4 s

Solution


In [60]:
%%time
next_password('cqjxjnds')


CPU times: user 1.85 s, sys: 0 ns, total: 1.85 s
Wall time: 1.85 s
Out[60]:
'cqjxxyzz'

Day 11.2


In [61]:
%%time
next_password('cqjxxyzz')


CPU times: user 6.85 s, sys: 0 ns, total: 6.85 s
Wall time: 6.85 s
Out[61]:
'cqkaabcc'