알고리즘/프로그래머스

[프로그래머스]Lv2. 혼자 하는 틱택토(Python)

cha_eyoon 2024. 2. 12. 17:49

https://school.programmers.co.kr/learn/courses/30/lessons/160585

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

문제 접근

 

정상적이거나 비정상적인 경우를 분리해서 생각하기 힘들었다.

그래서 그냥 그려보고 주어진 테케 3개를 일반화하여 내가 알아낸 부분, 구현할 수 있는 부분(함수)을 먼저 고민해 보았다. 

 

쥐어짜낸 사고의 흐름...정리 

  1. 이기는 경우(가로3+세로3+대각선2)를 체크하는 함수 만들기 
    • 어떤 자료구조를 사용할지 고민 => O와 X를 카운트해서 딕셔너리에 키와 값 형태로 저장 시도 
  2. 정상/비정상적인 경우 고민
    • X의 개수와 O의 개수의 차이가 2이상일 수 없음(O/X 반복 공격이므로) => O는 X의 개수와 같거나 +1인 경우만 가능 
    • 둘이 동시에 이기는 경우 불가능
  3. 그럼 X와 O가 각각 이길 때 말이 안되는 경우를 고민   
    1. X가 이긴 경우 => X와 O의 개수가 같음(반대로 같지 않다면 틀림)
    2. 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크거나로 작성해야 함을 깨달았다.