#!/usr/local/bin/python3

import re

if __name__ == '__main__':
    with open('../input/2015-05.txt') as f:
        lines = [l.rstrip() for l in f.readlines()]

    def is_nice(string):
        bad_strings = ['ab', 'cd', 'pq', 'xy']
        no_bad_strings = not any(bad for bad in bad_strings if bad in string)

        vowels = set('aeiou')
        enough_vowels = len([c for c in string if c in vowels]) >= 3

        has_double_char = any(a == b for a, b in zip(string, string[1:]))

        # regex alternatives:
        # no_bad_strings = re.search(r'ab|cd|pq|xy', string) is None
        # enough_vowels = len(re.findall(r'[aeiou]', string)) >= 3
        # has_double_char = re.search(r'(.)\1', string) is not None

        return no_bad_strings and enough_vowels and has_double_char

    nice_strings = list(filter(is_nice, lines))
    print('Number of nice strings:', len(nice_strings))

    # Part Two
    def new_nice(string):
        has_repeated_pair = re.search(r'(.{2}).*\1', string) is not None
        has_repeat_one_apart = re.search(r'(.).\1', string) is not None
        return has_repeated_pair and has_repeat_one_apart

    new_nice_strings = list(filter(new_nice, lines))
    print('Number of new nice strings:', len(new_nice_strings))

@@ -30,16 +30,1408 @@
 ort re%0A%0A
+%0Adef is_nice(candidate):%0A    %22%22%22Check if candidate string passes nice rules%0A%0A    Returns True if a string is nice, and False otherwise.%0A%0A    A 'nice' string has the following properties:%0A      *  It contains at least vowels %5Baeiou%5D%0A      *  It contains one letter that appears twice in a row%0A      *  It does not contain the strings %5Bab, cd, pq, xy%5D%0A%0A    Nice strings much have all of these properties.%0A    %22%22%22%0A    pass%0A%0A%0Adef test_nice_strings():%0A    %22%22%22is_nice validates 'nice' strings matching certain rules%0A%0A    A 'nice' string has the following properties:%0A      *  It contains at least vowels %5Baeiou%5D%0A      *  It contains one letter that appears twice in a row%0A      *  It does not contain the strings %5Bab, cd, pq, xy%5D%0A%0A    Nice strings much have all of these properties.%0A    %22%22%22%0A    known_nice_strings = %5B%0A        'ugknbfddgicrmopn',%0A        'aaa'%5D%0A    assert all(is_nice(s) for s in known_nice_strings)%0A%0A%0Adef test_naughty_strings():%0A    %22%22%22is_nice rejects strings that are known to be invalid%22%22%22%0A    known_naughty_strings = %5B%0A        'jchzalrnumimnmhp',     # no double letter%0A        'haegwjzuvuyypxyu',     # contains 'xy'%0A        'dvszwmarrgswjxmb'%5D     # only one vowel%0A    for naughty_string in known_naughty_strings:%0A        # Can't shortcut with all because %60not None%60 returns True%0A        assert is_nice(naughty_string) is not None%0A        assert not is_nice(naughty_string)%0A%0A%0A
 if __nam

Add (failing) tests