알고리즘/프로그래머스
[프로그래머스]Lv2. 혼자 하는 틱택토(Python)
cha_eyoon
2024. 2. 12. 17:49
https://school.programmers.co.kr/learn/courses/30/lessons/160585
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
문제 접근
정상적이거나 비정상적인 경우를 분리해서 생각하기 힘들었다.
그래서 그냥 그려보고 주어진 테케 3개를 일반화하여 내가 알아낸 부분, 구현할 수 있는 부분(함수)을 먼저 고민해 보았다.
쥐어짜낸 사고의 흐름...정리
- 이기는 경우(가로3+세로3+대각선2)를 체크하는 함수 만들기
- 어떤 자료구조를 사용할지 고민 => O와 X를 카운트해서 딕셔너리에 키와 값 형태로 저장 시도
- 정상/비정상적인 경우 고민
- X의 개수와 O의 개수의 차이가 2이상일 수 없음(O/X 반복 공격이므로) => O는 X의 개수와 같거나 +1인 경우만 가능
- 둘이 동시에 이기는 경우 불가능
- 그럼 X와 O가 각각 이길 때 말이 안되는 경우를 고민
- X가 이긴 경우 => X와 O의 개수가 같음(반대로 같지 않다면 틀림)
- O가 이긴 경우 => X+1과 O의 개수가 같음(반대로 같지 않다면 틀림)
코드
def check(board):
check_dict = {'X': 0, 'O':0, '.': 0}
for i in range(3):
if board[i][0] == board[i][1] == board[i][2]: # 가로 방향에서 동일한 문자인지 확인
check_dict[board[i][0]] += 1
if board[0][i] == board[1][i] == board[2][i]: # 세로 방향에서 동일한 문자인지 확인
check_dict[board[0][i]] += 1
# 대각선으로 동일한 문자가 나열되어 있는지 확인
if board[0][0] == board[1][1] == board[2][2]: # 왼 위 => 오 아래
check_dict[board[0][0]] += 1
if board[2][0] == board[1][1] == board[0][2]: # 오 위 => 왼 아래
check_dict[board[2][0]] += 1
return check_dict
def solution(board):
cur_board = {'X': 0, 'O': 0, '.': 0}
for i in range(3): # 현재 보드의 상태(O와 X의 개수)를 cur_board라는 딕셔너리에 저장
for j in range(3):
cur_board[board[i][j]] += 1
if cur_board['O'] not in (cur_board['X'], cur_board['X'] + 1):
return 0
win_cnt = check(board) # 이긴 경우를 세는 함수
# 동시에 이기는 건 불가 => 애초에 이기면 멈춰야 함
if win_cnt['X'] == 1 and win_cnt['O'] == 1:
return 0
# X가 이기는 경우 X와 O의 개수는 같음
if win_cnt['X'] == 1:
if cur_board['X'] != cur_board['O']:
return 0
# O가 이기는 경우 X보다 O가 1개 많음
if win_cnt['O'] == 1:
if cur_board['O'] != (cur_board['X'] + 1):
return 0
return 1
문제 회고
사실 조건문을 작성하며 2-3개의 테케가 통과하지 않아 고생했다..
첫 조건문의 경우 O의 개수가 X의 개수보다 많거나 적거나의 문제가 아니라 O와 X의 관계성은 같거나 1크거나로 작성해야 함을 깨달았다.