[BOJ: 2503] - Python / 파이썬 - 숫자 야구

o_jooon_·2024년 2월 26일
0

BOJ

목록 보기
32/44
post-thumbnail

서론

브루트포스, 구현 문제입니다.
스트라이크와 볼 처리를 어떻게 해야할지 떠오르지 않아 다른 분들의 코드를 참고하였습니다.

난이도

실버 3


문제

조건

시간 제한메모리 제한
1 초128 MB

정보문화진흥원 정보 영재 동아리에서 동아리 활동을 하던 영수와 민혁이는 쉬는 시간을 틈타 숫자야구 게임을 하기로 했다.

영수는 1에서 9까지의 서로 다른 숫자 세 개로 구성된 세 자리 수를 마음속으로 생각한다. (예: 324)
민혁이는 1에서 9까지의 서로 다른 숫자 세 개로 구성된 세 자리 수를 영수에게 묻는다. (예: 123)
민혁이가 말한 세 자리 수에 있는 숫자들 중 하나가 영수의 세 자리 수의 동일한 자리에 위치하면 스트라이크 한 번으로 센다. 숫자가 영수의 세 자리 수에 있긴 하나 다른 자리에 위치하면 볼 한 번으로 센다.
예) 영수가 324를 갖고 있으면

429는 1 스트라이크 1 볼이다.
241은 0 스트라이크 2 볼이다.
924는 2 스트라이크 0 볼이다.
영수는 민혁이가 말한 수가 몇 스트라이크 몇 볼인지를 답해준다.
민혁이가 영수의 세 자리 수를 정확하게 맞추어 3 스트라이크가 되면 게임이 끝난다. 아니라면 민혁이는 새로운 수를 생각해 다시 영수에게 묻는다.
현재 민혁이와 영수는 게임을 하고 있는 도중에 있다. 민혁이가 영수에게 어떤 수들을 물어보았는지, 그리고 각각의 물음에 영수가 어떤 대답을 했는지가 입력으로 주어진다. 이 입력을 바탕으로 여러분은 영수가 생각하고 있을 가능성이 있는 수가 총 몇 개인지를 알아맞혀야 한다.

아래와 같은 경우를 생각해보자.

민혁: 123
영수: 1 스트라이크 1 볼.
민혁: 356
영수: 1 스트라이크 0 볼.
민혁: 327
영수: 2 스트라이크 0 볼.
민혁: 489
영수: 0 스트라이크 1 볼.
이때 가능한 답은 324와 328, 이렇게 두 가지이다.

영수는 동아리의 규율을 잘 따르는 착한 아이라 민혁이의 물음에 곧이곧대로 정직하게 답한다. 그러므로 영수의 답들에는 모순이 없다.

민혁이의 물음들과 각각의 물음에 대한 영수의 답이 입력으로 주어질 때 영수가 생각하고 있을 가능성이 있는 답의 총 개수를 출력하는 프로그램을 작성하시오.


입력

첫째 줄에는 민혁이가 영수에게 몇 번이나 질문을 했는지를 나타내는 1 이상 100 이하의 자연수 N이 주어진다. 이어지는 N개의 줄에는 각 줄마다 민혁이가 질문한 세 자리 수와 영수가 답한 스트라이크 개수를 나타내는 정수와 볼의 개수를 나타내는 정수, 이렇게 총 세 개의 정수가 빈칸을 사이에 두고 주어진다.


출력

첫 줄에 영수가 생각하고 있을 가능성이 있는 답의 총 개수를 출력한다.


예시

예제 입력 1

4
123 1 1
356 1 0
327 2 0
489 0 1

예제 출력 1

2

풀이

permutations를 활용하여 3자리 숫자의 모든 경우(nums)를 만들어 주었습니다.
tmp를 생성한 이유는 nums에서 조건에 맞지 않는 수를 remove로 제거해주어도 되지만 더 쉽고 간편하게 하기 위해서입니다.
enumerate를 활용하여 입력한 숫자를 str 형태로 바꾼 후, 첫 번째 수부터 세 번째 수까지 비교를 하였습니다.
-> nums에서 현재 탐색 중인 수(check)와 입력받은 수(num)의 각 세 자리를 비교하며 위치와 수가 같다면 스트라이크의 갯수(cnt_s)를 증가시켜주고, 위치는 다르지만 수가 현재 탐색 중인 수(check)에 포함되어 있다면 볼의 갯수(cnt_b)를 증가시켜줍니다.
비교가 끝나면 증가시킨 스트라이크와 볼의 갯수와 입력 받은 수를 비교하여 모두 같다면 tmp에 추가시켜줍니다.
그 후, 3자리 숫자들의 모음(nums)을 현재 조건에 맞는 수들(tmp)로 변경시켜주어 조건에 맞지 않는 수들을 제거합니다.

위 과정을 n번만큼 반복하면 정답이 도출됩니다.

코드

import sys
from itertools import permutations
input = sys.stdin.readline

n = int(input())
nums = list(permutations(list(range(1, 10)), 3))	# 1부터 9까지의 3자리 숫자 모음 생성

for _ in range(n):
    num, s, b = map(int, input().split())
    tmp = []	# 현재 조건에 맞는 숫자가 들어갈 배열

    for check in nums:		# 3자리 숫자 모음 탐색
        cnt_s, cnt_b = 0, 0	# 스트라이크와 볼의 갯수

        for i, str_num in enumerate(str(num)):	# 입력한 숫자를 문자열로 바꾸어 숫자의 위치와 값을 한 번에 확인
            if int(str_num) == check[i]:		# 현재 탐색중인 숫자와 입력한 숫자 중 위치와 값이 같은 수가 있다면
                cnt_s += 1						# 스트라이크 갯수 증가
            if int(str_num) != check[i] and int(str_num) in check:	# 위치는 다르나 숫자가 포함되어 있다면
                cnt_b += 1						# 볼 갯수 증가

        if s == cnt_s and b == cnt_b:			# 스트라이크와 볼의 갯수가 입력값과 같다면
            tmp.append(check)					# tmp에 현재 숫자 추가
    nums = tmp									# 기존 3자리 숫자의 모음을 현재까지의 조건에 맞는 숫자의 모듬으로 변경

print(len(nums))								# 최종 조건에 맞는 수들의 길이 출력

실행 결과

profile
iOS개발 공부 중입니다.

0개의 댓글