프로그래머스의 숫자 야구 게임 문제
각자 서로 다른 1~9까지 3자리 임의의 숫자를 정한 뒤 서로에게 3자리의 숫자를 불러서 결과를 확인합니다. 그리고 그 결과를 토대로 상대가 정한 숫자를 예상한 뒤 맞힙니다.
- 숫자는 맞지만, 위치가 틀렸을 때는 볼
- 숫자와 위치가 모두 맞을 때는 스트라이크
- 숫자와 위치가 모두 틀렸을 때는 아웃
A : 123
B : 1스트라이크 1볼.
A : 356
B : 1스트라이크 0볼.
A : 327
B : 2스트라이크 0볼.
A : 489
B : 0스트라이크 1볼.
이때 가능한 답은 324와 328 두 가지입니다.
질문한 세 자리의 수, 스트라이크의 수, 볼의 수를 담은 2차원 배열 baseball이 매개변수로 주어질 때, 가능한 답의 개수를 return 하도록 solution 함수를 작성해주세요.
'''
6/10 1차 시도
만들 수 있는 모든 경우의 숫자조합을 만들어 놓고(1~9의 숫자를 중복하지 않고 순서와 상관있이 3개 뽑음)
각 시도마다 불가능한 녀석들을 지워가며 후보들을 줄이는 방식으로 풀이.
'''
CONSTANT = dict()
CONSTANT['size'] = 3
def solution(baseball):
answer = 0
candidates = baseball_number_set_maker()
candidates_dict = {str(candidate): 1 for candidate in candidates}
IDX_TRIAL = 0
IDX_STRIKE = 1
IDX_BALL = 2
while(baseball):
this_turn = baseball.pop(0)
trial = str(this_turn[IDX_TRIAL])
guess_strike = this_turn[IDX_STRIKE]
guess_ball = this_turn[IDX_BALL]
for candidate in candidates_dict:
strike = 0
ball = 0
if candidates_dict[candidate] == 1:
for idx in range(len(trial)):
if trial[idx] == candidate[idx]:
strike += 1
for jdx in range(len(this_turn)):
if trial[idx] == candidate[jdx]:
ball += 1
ball -= strike
if guess_ball == ball and guess_strike == strike:
pass
else:
candidates_dict[candidate] = 0
else:
pass
for candidate in candidates_dict:
if candidates_dict[candidate] == 1:
answer += 1
return answer
def baseball_number_set_maker():
NUMBERS = [x for x in range(1, 10)]
number_set = list()
str = ''
attaching_number(str, NUMBERS, number_set)
return number_set
def attaching_number(making, number_remain, number_set):
if len(making) == CONSTANT['size']:
number_set.append(int(making))
return
else:
for idx in range(0, len(number_remain)):
new_making = making + str(number_remain[idx])
new_number_remain = number_remain.copy()
del new_number_remain[idx]
attaching_number(new_making, new_number_remain, number_set)
if __name__ == '__main__':
baseball = [[123, 1, 1], [356, 1, 0], [327, 2, 0], [489, 0, 1]] # 2
print(solution(baseball))
‘itertool’을 한 번 사용해보겠다고 다짐하고는 다시 직접 전체 조합을 recursive로 만들어냈다.
깔끔하게 만들지도 못하면서.. 왜 굳이 직접 만들었을까..
쓸데없는 상수(대문자)와 적합하지 못한 변수명 그리고 난잡한 for문으로 끔찍한 모습으로 문제를 푼 것 같다.
- 굳이 왜 recursive를 사용해서 모든 조합을 만들지 않아도 아래처럼. 멋지게 모든 경우의 조합을 만들어 낼 수 있다.
(다른 분의 코드!)for i in range(111,1000): ch = str(i) if ch[0] == ch[1] or ch[0] == ch[2] or ch[1] == ch[2]: continue if ch[0] == '0' or ch[1] == '0' or ch[2] == '0': continue