문제 링크
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
서론
틱택토는 한 번 해보면 무슨게임인지 바로 알 수 있는 단순한 게임이죠. 오목의 조상? 격 게임입니다.
단순한 구현이지만, 내부 코드의 조건문으로 판단해야 하는 기준이 한두개가 아니기 때문에,
반례를 계속해서 찾으면서 풀어야 하는 문제입니다.
입출력의 예외처리를 연습할 때 풀면 아주 좋은 문제라고 생각합니다.
풀이
이 문제는 5개의 조건문을 통해 풀이가 가능합니다.
1. 'O'의 개수 + 'X'의 개수가 0과 1 사이의 값이고,
2. 'O'의 개수가 'X'의 개수보다 크거나 같고,
3. 'O'와 'X'가 둘 다 승리하지 않고,
4. 'O'가 승리했을 때 'X'의 개수가 더 많지 않고,
5. 'X'가 승리했을 때 'O'의 개수가 'X'의 개수와 일치해야
위 조건들을 만족해야 올바른 틱택토의 모습이 될 수 있습니다.
승리했는가('O'나 'X'가 3개가 연속되어 있는가)의 판단 함수를 따로 작성해서 풀이했습니다.
풀이 코드
import java.util.*;
class Solution {
static boolean isCellsSame(String s, char turn) {
for (char c : s.toCharArray())
if (c != turn) return false;
return true;
}
static boolean existWin(String[] board, char turn) {
// 가로
for (String row: board) {
if (isCellsSame(row, turn)) return true;
}
// 세로
for (int i = 0; i < 3; i++) {
StringBuilder col = new StringBuilder();
for (int j = 0; j < 3; j++) {
col.append(board[j].charAt(i));
}
if (isCellsSame(col.toString(), turn)) return true;
}
// 왼쪽 대각선
StringBuilder diag = new StringBuilder();
for (int i = 0; i < 3; i++) {
diag.append(board[i].charAt(i));
}
if (isCellsSame(diag.toString(), turn)) return true;
// 오른쪽 대각선
StringBuilder diag2 = new StringBuilder();
for (int i = 0; i < 3; i++) {
diag2.append(board[i].charAt(2 - i));
}
if (isCellsSame(diag2.toString(), turn)) return true;
return false;
}
private static boolean isOrderCorrect(String[] board) {
Map<Character, Integer> map = new HashMap<>();
map.put('O', 0);
map.put('X', 0);
map.put('.', 0);
for (String s : board) {
for (char c : s.toCharArray()) {
map.put(c, map.get(c) + 1);
}
}
int ONum = map.get('O');
int XNum = map.get('X');
if (ONum - XNum > 1) return false;
if (ONum < XNum) return false;
boolean OWin = existWin(board, 'O');
boolean XWin = existWin(board, 'X');
if (OWin && XWin) return false;
if (OWin && ONum <= XNum) return false;
if (XWin && ONum != XNum) return false;
return true;
}
public int solution(String[] board) {
int answer = 0;
if (isOrderCorrect(board)) answer = 1;
return answer;
}
}
백준 풀이
백준 문제 링크
7682번: 틱택토
입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 줄은 9개의 문자를 포함하며, 'X', 'O', '.' 중 하나이다. '.'은 빈칸을 의미하며, 9개의 문자는 게임판에서 제일 윗 줄 왼쪽부터의 순서이다. 입
www.acmicpc.net
위 코드를 이용해서, 백준 사이트에 있는 문제도 풀이할 수 있습니다.
단, 위 프로그래머스 문제에서 두 가지만 더 생각해야 합니다.
1. 여기서는 'O'가 선공이 아니고, 'X'가 선공입니다.
2. 최종 상태인가를 판별해야 합니다.
1번은 조건문을 조금 고쳐주면 되고, 2번은 어렵게 생각할 필요 없이 둘 다 승리하지 않았을 경우 빈 칸이 있는지를 확인만 해주면 됩니다.
위 프로그래머스 풀이 코드의 `isOrderCorrect` 함수의 내용을 다음과 같이 고쳐주면 됩니다.
private static boolean isOrderCorrect(String[] board) {
// 위 Map 부분 생략
int ONum = map.get('O');
int XNum = map.get('X');
if (XNum - ONum > 1) return false;
if (ONum > XNum) return false;
boolean OWin = existWin(board, 'O');
boolean XWin = existWin(board, 'X');
if (OWin && XWin) return false;
if (XWin && ONum >= XNum) return false;
if (OWin && ONum < XNum) return false;
if (!(OWin || XWin)) {
for (String s : board) {
for (char c : s.toCharArray()) {
if (c == '.') return false;
}
}
}
return true;
}
부족한 글 봐주셔서 감사합니다. 🙇
풀이와 코드에 부족한 점이나 추가하면 좋을 점이 있으면 댓글 주세요!
'Study > 알고리즘 풀이' 카테고리의 다른 글
[백준] 1504번: 특정한 최단 경로 (C++) (0) | 2023.08.02 |
---|---|
[백준] 2096번: 내려가기 (C++, JAVA) (0) | 2023.08.01 |
[프로그래머스] 소수 찾기 (java 풀이) (0) | 2023.07.26 |
[프로그래머스] 리코쳇 로봇 (Java 풀이) (0) | 2023.07.21 |
[프로그래머스] 과제 진행하기 (Java 풀이) (0) | 2023.07.20 |