코드 출현 2015 - 5일 차

10240 단어 adventofcodepython
Day 5는 관리할 수 있는 만큼 효율적으로 문자열을 처리하게 하는 퍼즐 중 하나입니다. 나는 문자열을 자르는 파이썬의 능력을 좋아합니다. 그것은 언어의 진정한 강점입니다. 퍼즐의 파트 1은 다음과 같습니다.



따라서 문자열이 '좋은'지 여부를 결정하기 위해 해야 할 세 가지 작업이 있습니다.
  • 모음이 3개 이상인지 확인
  • 이중 문자가 있는지 확인하십시오
  • .
  • '금지' 문자열이 포함되어 있지 않은지 확인합니다
  • .

    1. 모음 합산



    Python에서 문자열은 본질적으로 문자 목록이며 목록은 반복 가능합니다. 그래서 for c in 'hello': 와 같은 코드를 작성할 수 있습니다. Iterables는 map() 함수에서 사용할 수 있으며 각 항목에는 함수가 적용되어 있습니다. 예를 들어 아래 예에서와 같이 str.count():

    def count_vowels(s):
        return sum(map(s.count, "aeiou"))
    

    map()의 반환 값도 iterable이므로 sum() 함수로 보낼 수 있습니다. 이것은 문자열에서 모음을 세는 Pythonic(드디어!) 방법을 제공합니다.

    2. 이중문자



    나는 이 부분을 두 개의 문자sliding window로 문자열을 통해 간단한 모양으로 작성했습니다. 정규 표현식을 사용하여 re.search(r'([a-z])\1', s)re.search(r'(.)\1', s) 와 같이 이중 문자를 찾는 megathread 에서 많은 솔루션을 보았습니다. 이 모든 것이 나에게 확인된 것은 정규 표현식이 내 'Python에 대해 더 알아보기' 목록에 올릴 또 다른 주제라는 것입니다.

    def check_double(s):
        for i in range(len(s)-1):
            if s[i] == s[i+1]:
                return True
        return False
    


    3. 금단의 쌍



    나는 결국 이 테스트에 대한 정규식 접근 방식도 찾았지만(예: re.search(r'ab|cd|pq|xy', s) ) 루프를 사용하여 이 테스트를 코딩했습니다.

    def check_forbidden(s):
        for forbidden in ['ab', 'cd', 'pq', 'xy']:
            if forbidden in s:
                return False
        return True
    


    물론 돌이켜 보면 모음을 확인한 것과 정확히 같은 방식으로 코드를 작성할 수 있었습니다.

    def check_forbidden(s):
        return sum(map(s.count, ['ab', 'cd', 'pq', 'xy'])) == 0
    


    어느 쪽이든 작동하며 세 가지 테스트를 결합하여 2부로 이동할 수 있었습니다.



    퍼즐이 갑자기 바뀌는 것은 드문 일이지만, 여기 있습니다. 이제 문자열은 두 가지 테스트만 통과하면 되지만 파트 1의 테스트보다 약간 더 복잡합니다.
  • 겹치지 않고 두 번 나타나는 문자 쌍 확인
  • 첫 글자와 마지막 글자가 같은 세 글자를 확인합니다(가운데 글자에 관계없이)
  • .

    1. 두 번 나타나는 문자 쌍



    정규 표현식에 더 익숙해졌으면 좋겠습니다! 나는 re.search(r'(.)(.).*\1\2', s)와 같은 것을 사용할 수 있었지만, 결국 다음과 같이 작성했습니다.

    def check_duplicates(s):
        for i in range(len(s)-1):
            check = s[i:i+2]
            if check in s[i+2:]:
                return True
        return False
    


    이것은 슬라이딩 윈도우를 사용하여 한 번에 두 문자를 고려한 다음 문자열의 나머지 부분에서 다시 나타나는지 확인합니다. 따라서 문자열mqzxvvskslbxvyjt에 대해 다음을 찾습니다.

     [mq] in zxvvskslbxvyjt
    m [qz] in xvvskslbxvyjt
    mq [zx] in vvskslbxvyjt
    mqz [xv] in vskslbxvyjt, which is a hit!
    


    2. 대칭 삼중항



    이번에는 창에 세 개의 문자가 있는 또 다른 슬라이딩 창입니다.

    def check_triples(s):
        for i in range(len(s)-2):
            if s[i] == s[i+2]:
                return True
        return False
    


    골프



    필연적으로 megathread 에는 한 줄짜리가 있습니다. 다음은 comment by Reddit user Stactic에서 각각 한 줄의 코드로 해결된 두 부분입니다.

    print len([w for w in open('Day5Words.txt') if (re.search(r'([aeiou].*){3,}',w) and re.search(r'(.)\1', w) and not re.search(r'ab|cd|pq|xy', w))])
    
    print len([w for w in open('Day5Words.txt') if (re.search(r'(..).*\1', w) and re.search(r'(.).\1', w))])
    


    많은 골프 코드와 달리 이것은 저와 같은 정규식 초보자에게도 꽤 읽기 쉽습니다!

    6일째, 번쩍이는 불빛!

    좋은 웹페이지 즐겨찾기