글 작성자: 택시 운전사
반응형

숫자 야구 문제 풀어보기

😃 나의 코드

from itertools import permutations

def check_score(question, candidate, s, b):
    strike = 0
    for i in range(len(question)):
        if question[i] == candidate[i]:
            strike += 1
    if s != strike:
        return False
    ball = len(set(question) & set(candidate))-strike 
    if b != ball:
        return False
    return True

def solution(baseball):
    lst = list(permutations([1,2,3,4,5,6,7,8,9], 3))
    for i in baseball:
        for item in lst[:]:
            if not check_score([int(i) for i in list(str(i[0]))], item, i[1], i[2]):
                lst.remove(item)
    return len(lst)

완전 탐색(exhaustive search)를 이용하여 푸는 문제입니다. 길이가 3이고 1~9까지 중복을 허용하지 않기 때문에 가능한 경우의 수가 9_8_7로 매우 작습니다. 따라서 완전 탐색이 가능할 것이라 생각하고 문제를 풀어봅시다.

lst = list(permutations([1,2,3,4,5,6,7,8,9], 3))

우선 길이가 3인 1~9까지 중복을 허용하지 않는 3자리 숫자의 경우의 수를 모두 구하는 건 itertoolspermutations를 이용해서 가능한 경우의 수를 간단하게 만들 수 있습니다.

def check_score(question, candidate, s, b):
    strike = 0
    for i in range(len(question)):
        if question[i] == candidate[i]:
            strike += 1
    if s != strike:
        return False
    ball = len(set(question) & set(candidate))-strike 
    if b != ball:
        return False
    return True

다음에는 전체 경우의 수 중에 질문한 숫자와 비교하여 알맞은 스코어를 반환하는 경우를 찾는 함수를 구현합니다. strike의 경우 앞에서부터 for loop를 이용해 비교하면 됩니다. ball의 경우 각 listset으로 바꿔서 교집합의 크기를 구합니다. 이 크기에서 strike의 값을 빼면 ball이 나옵니다. 이를 제공된 스코어와 비교하여 적합하지 않은 경우 전체 경우의 수에서 제거합니다. 모든 질문을 확인한 뒤, 경우의 수의 크기를 반환하면 문제가 마무리 됩니다.

반응형