본문 바로가기

알고리즘 삽질장

[인프런] 스도쿠 검사

반응형


문제설명

스도쿠는 9 by 9 크기의 보드가 있을 때, 각 행과 각 열, 그리고 9개의 3 by 3 크기의 보드에 1부터 9까지의 숫자가 중복 없이 나타나도록 보드를 채우면 된다. 예를 들어 다음을 보자.

 

 

위 그림은 스도쿠를 정확하게 푼 경우이다. 각 행에 1~9까지의 숫자가 중복 없이 나오고, 각 열에 1~9까지의 숫자가 중복 없이 나오고, 각 3 by 3짜리 사각형(9개이며, 위에서 색깔로 표시되었다)에 1~9까지의 숫자가 중복 없이 나오기 때문이다. 완성된 9 by 9 크기의 스도쿠가 주어지면 정확하게 풀었으면 'YES', 잘 못 풀었으면 'NO'를 출력해라.

입력조건

  • 첫 줄에 완성된 9 by 9 스도쿠가 주어진다.

출력조건

  • 첫 줄에 'YES' 또는 'NO'를 출력한다.

사고과정

  • 중복되지 않고 1~9 모두 나왔는지 확인하기 위해 집합 자료구조를 활용했다. 그리고 집합 자료구조 길이가 9이면 카운트를 했다.
  • 행과 열을 탐색하는 방법은 어렵지 않았다. 그런데 3 by 3 그룹 사각형을 어떻게 할지 매우 고민했다.. 결국에 구현하긴 했다..
  • 풀이를 보니 1~9 모두 나왔는지 체크하기 위해 카운트를 기록할 리스트를 정의하고 들어갔다. 행,열,그룹 사각형 용 리스트 3개를! 이 카운트 기록 리스트의 인덱스값을 숫자로 하면서 값은 존재 횟수를 의미한다. 이 때, 카운트 리스트 값을 갱신해줄 때, 누적합이 아닌 그냥 1로 할당한다. 그렇게 한 후 카운트 리스트 값의 합(sum)이 9가 아니라면 중복된 숫자가 있음을 의미한다!(누적합이 아니고 그냥 1로 할당하는 것도 인상적이었음)
  • 또다른 포인트는 3 by 3 그룹 사각형을 탐색하는 부분이였는데, 마찬가지로 4중 loop를 활용했다. 대신 1,2번째 loop를 9개의 그룹을 보는 루프로 사용했고 3,4번째 루프를 그룹 내의 9개 원소값을 모두 탐색하는 방법으로 구현했다. 이 방법을 기억해놓아야 겠다!

풀이

- 나의 풀이

arr = [list(map(int, input().split())) for _ in range(9)]
flag = True
# 행, 열 탐색
for i in range(9):
    row = col = set()
    for j in range(9):
        row.add(arr[i][j])
        col.add(arr[j][i])
    if len(row) != 9 or len(col) != 9:
        flag = False
        break
# 3x3 탐색
if flag:
    for k in range(0, 9, 3):
        for m in range(0, 9, 3):
            square = set()
            for i in range(3):
                for j in range(3):
                    square.add(arr[i+k][j+m])
            if len(square) != 9:
                flag = False
                break
if flag:
    print('YES')
else:
    print('NO')

- 강의 풀이

# 강의 Solution -> 숫자 존재 체크를 count 리스트의 인덱스로 체크해서 사용!
# 그리고 count 리스트 합을 활용해 0~9숫자 있는지 체크! 단 count 리스트에 숫자 존재 누적합이 아님!
def check(a):
    # 행, 열 탐색
    for i in range(9):
        ch1 = [0] * 10
        ch2 = [0] * 10
        for j in range(9):
            ch1[a[i][j]] = 1
            ch2[a[j][i]] = 1
        if sum(ch1) != 9 or sum(ch2) != 9:
            return False
    # 3x3 탐색
    # 1.9개의 그룹을 보기
    for i in range(3):
        for j in range(3):
            ch3 = [0] * 10
            # 2. 그룹 내의 행, 열 탐색
            for k in range(3):
                for s in range(3):
                    ch3[a[i*3+k][j*3+s]] = 1
            if sum(ch3) != 9:
                return False
    return True


a = [list(map(int, input().split())) for _ in range(9)]
if check(a):
    print('YES')
else:
    print('NO')
반응형

'알고리즘 삽질장' 카테고리의 다른 글

[인프런] 랜선자르기  (0) 2021.11.14
[인프런] 격자판 회문수  (0) 2021.11.12
[인프런] 봉우리  (0) 2021.11.12
[인프런] 곳감(모래시계)  (0) 2021.11.12
[인프런] 사과나무(다이아몬드)  (0) 2021.11.12