정답률 60% 짜리 문제이다. 문제 읽으면서 떠오르는 대로 코드를 짰다.
문제는 여기
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
1. 문제 요구사항 분석
- N명의 참가자는 각각 1부터 N번을 차례대로 배정받습니다.
- 1번↔2번, 3번↔4번, ... , N-1번↔N번의 참가자끼리 게임을 진행합니다.
- 다음 라운드에 진출할 참가자의 번호는 다시 1번부터 N/2번을 차례대로 배정받습니다.
- 만약 1번↔2번 끼리 겨루는 게임에서 2번이 승리했다면 다음 라운드에서 1번을 부여받고, 3번↔4번에서 겨루는 게임에서 3번이 승리했다면 다음 라운드에서 2번을 부여받게 됩니다.
- 게임은 최종 한 명이 남을 때까지 진행됩니다.
- A번 참가자와 B번 참가자는 서로 붙게 되기 전까지 항상 이긴다고 가정합니다.
여기서 2번과 3번만 주의해서 봤으면 문제를 풀기는 쉬웠다.
2. 코드 구현
2.1 상대를 구하는 코드
우선 2번을 코드로 구현해봤다.
def enemy(player: int) -> int:
return player % 2 == 0 and player - 1 or player + 1
나를 기준으로 홀수면 상대방은 +1을 한 참가자이고, 짝수면 내 앞의 참가자이다.
2.2 플레이를 리셋하는 코드
3번 요구사항도 비슷하다. 짝수면 그대로 리셋시키면 되고, 홀수면 나눈 해에다가 나머지를 더하면 된다.
def reset_player(player: int) -> int:
return player // 2 + (player % 2)
2.3 경기를 구현하는 코드
상대와 나를 리셋시키는 코드만 구현했다면 경기를 구현하는 것은 쉽다. 나는 요즘 재귀 함수와 클로져를 자주 사용해서 그런지, 순회를 이용하기보다는 재귀 함수로 코드를 짰다.
def fight():
nonlocal answer, a, b
answer += 1 # 경기 횟수
enemy_a = enemy(a)
if enemy_a == b: # 상대가 b와 같을 때 재귀를 탈출
return
a = reset_player(a)
b = reset_player(b)
fight()
2.4 전체 코드
def enemy(player: int) -> int:
return player % 2 == 0 and player - 1 or player + 1
def reset_player(player: int) -> int:
return player // 2 + (player % 2)
def solution(n, a, b):
answer = 0
def fight():
nonlocal answer, a, b
answer += 1
enemy_a = enemy(a)
if enemy_a == b:
return
a = reset_player(a)
b = reset_player(b)
fight()
fight()
return answer