본문 바로가기
PS/Codewars

[Codewars]4kyu - The observed PIN

by DawIT 2021. 1. 31.
320x100

 

이 문제는 문제가 좋다기보다는 파이썬의 새로운 모듈을 알게 된 문제여서 글을 쓴다..

 

문제는 간단하다. 비밀번호로 추정되는 숫자가 들어오는데, 확실하지 않아서 해당 수에서 인접한(상하좌우, 대각선 제외) 숫자까지 모두 눌러봐야 하는 상황에서 가능한 모든 비밀번호를 return하면 된다. 나는 이렇게 힘들게 작성했다.

 

def get_pins(observed):
    a = []
    for char in observed:
        num = int(char)
        temp = [num]
        if num == 0:
            temp.append(8)
            a.append(temp)
            continue
        if num == 8:
            temp.append(0)
        if num - 1 >= 1 and num % 3 != 1:
            temp.append(num-1)
        if num + 1 <= 9 and num % 3 != 0:
            temp.append(num+1)
        if num + 3 <= 9:
            temp.append(num+3)
        if num - 3 >= 1:
            temp.append(num-3)
        
        a.append(temp)
    
    answerli = set([str(num) for num in a[0]])
    count = 1
    while count < len(a):
        temp = set()
        temp = answerli.copy()
        for p in temp:
            for digit in a[count]:
                t = p
                t += str(digit)
                answerli.add(t)
        answerli = answerli - temp
        count += 1
    
    return list(answerli)

 

일단 첫번째로 인접한 수를 찾는 방법을 저렇게 if문을 나열할 것이 아니라 0부터 9까지 list등으로 표현하는게 훨씬 간단했을 것 같다. 숫자가 10개밖에 없으니 그 방법이 훨씬 더 보기 좋을 것이다.

 

그리고 하단에는 while과 for문으로 열심히 모든 경우의 수를 구하기 위해 써놨는데, 가장 많은 clever를 받은 코드는 다음과 같았다.

 

from itertools import product

ADJACENTS = ('08', '124', '2135', '326', '4157', '52468', '6359', '748', '85790', '968')

def get_pins(observed):
    return [''.join(p) for p in product(*(ADJACENTS[int(d)] for d in observed))]

 

바로 itertools 의 product를 사용하는 것이다! itertools 모듈에서 자주 쓰이는 3가지에는 순열, 조합, 그리고 데카르트 곱이 있다. 각각 combinations, permutations, product 이다.

 

combinations 함수는 리스트에서 중복 없이 원소를 뽑는 경우를 반환해준다.

 

combinatios(리스트,개수) 로 사용한다.

 

permutations는 중복을 허용하는 경우를 반환해준다.

 

permutations(리스트,개수) 로 사용한다.

 

이 문제에서 사용된 product 는 두 개 이상의 리스트 혹은 문자열에서 모든 조합을 반환해준다.

 

여기서는 product(*list) 의 형태로 사용해서 해당 리스트의 원소끼리 만들수 있는 조합을 반환했고 product(string,repeat=int) 의 형태로 사용할 수도 있다.

'PS > Codewars' 카테고리의 다른 글

[Codewars]5kyu - Sum of pairs  (0) 2021.01.31

댓글