백준 알고리즘 - 2503. 숫자야구
2024. 3. 5. 23:36ㆍ코딩 테스트/백준
https://www.acmicpc.net/problem/2503
2503번: 숫자 야구
첫째 줄에는 민혁이가 영수에게 몇 번이나 질문을 했는지를 나타내는 1 이상 100 이하의 자연수 N이 주어진다. 이어지는 N개의 줄에는 각 줄마다 민혁이가 질문한 세 자리 수와 영수가 답한 스트
www.acmicpc.net
전체 코드
def create_num_flag_table():
num_flag_table = [True] * 1000
for num in range(123, 1000):
num_str = str(num)
# 중복된 숫자가 있으면 제거 - ex) 144, 211, 331...
if num_str[0] == num_str[1] or num_str[1] == num_str[2] or num_str[2] == num_str[0]:
num_flag_table[num] = False
# 0이 포함된 숫자 조합 제거 - ex) 150, 200, 401
if num_str[0] == '0' or num_str[1] == '0' or num_str[2] == '0':
num_flag_table[num] = False
return num_flag_table
def uncheck_num_flag_table(num_flag_table, target_num, strike, ball):
target_num_str = str(target_num)
for cur_num in range(123, 1000):
# 이미 False 플래그된 숫자는 pass한다.
if not num_flag_table[cur_num]:
continue
cur_num_str = str(cur_num)
cur_strike = 0
cur_ball = 0
# j, k는 각각 입력 숫자 문자열, 현재 순회 중인 숫자 문자열의 포인터이다.
# 각각의 for loop로 순회한 후 각 포인터에 해당하는 문자를 비교한다.
# 문자가 동일한 경우 다음과 같이 진행한다.
# j == k인 경우 포인터 위치가 일치하므로 strike, 다른 위치에 있는 경우 ball이다.
# 각각 조건에 일치하는 strike, ball의 카운트를 증가한다.
for j in range(3):
for k in range(3):
if target_num_str[j] == cur_num_str[k]:
if j == k:
cur_strike += 1
else:
cur_ball += 1
# 현재 숫자가 전달한 strike, ball 개수와 일치하는지 확인힌다.
# 둘 중 하나라도 일치하지 않으면 조건에 맞지 않는 숫자이므로 False 플래그를 설정한다
if not (cur_strike == strike and cur_ball == ball):
num_flag_table[cur_num] = False
def solution(game_data_list: list):
num_flag_table = create_num_flag_table()
for num, strike, ball in game_data_list:
uncheck_num_flag_table(num_flag_table, num, strike, ball)
# 123~999까지의 True인 숫자의 개수를 구한다.
count = sum([1 for i in range(123, 1000) if num_flag_table[i]])
return count
##--------- submit ---------
n = int(input())
game_data_list = []
for _ in range(n):
num, strike, ball = map(int, input().split(' '))
game_data_list.append([num, strike, ball])
print(solution(game_data_list))
여담
조합, 순열로 푸는 방법을 열심히 고민했으나 실패하였다. 결국 해설을 봤는데, 0~999 크기의 Boolean 리스트를 생성한 후 True로 초기화한다. 이후 123~999 인덱스의 순회를 진행하며 전달한 숫자, strike, ball 정보를 통해 가능성이 없는 숫자를 False 플래그 처리하는 방법을 사용하였다. 정보를 제공할 수록 False 플래그 처리된 숫자가 증가하게 된다. 게임 정보 제공이 완료되면 123~999의 인덱스를 순회하여 True인 정보를 count한다.
0~999 크기에 Boolean 플래그 리스트 테이블을 사용하는 아이디어를 떠오르기 쉽지 않았다. 각 숫자 인덱스들이 가능한 숫자 조합이라는 것인데 상당히 기교를 부린 것 같은 느낌이 들었다.
다른 풀이를 보니 순열을 사용하는 코드가 있었다. 해당 코드로 다시 한번 구현해볼 필요가 있다.
추후 조합, 순열들을 사용하여 최적화 혹은 더 깔끔한 코드 작성이 가능한지 여부 확인 필요하다.
'코딩 테스트 > 백준' 카테고리의 다른 글
백준 알고리즘 - 2563. 색종이 (0) | 2024.03.06 |
---|---|
백준 알고리즘 1931. 회의실 배정 (0) | 2024.03.05 |
백준 알고리즘 - 11399. ATM (0) | 2024.03.05 |
백준 알고리즘 - 11047. 동전 0 (0) | 2024.03.05 |
백준 알고리즘 - 2231. 분해합 (0) | 2024.03.05 |