Algorithm 풀이/SW Expert Academy

[SWEA] 1974. 스도쿠검증_python

yeguu 2022. 8. 26. 01:40

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV5Psz16AYEDFAUq 

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

 

* 문제의 저작권은 SW Expert Academy에 있습니다.


1. 문제

스도쿠는 숫자퍼즐로, 가로 9칸 세로 9칸으로 이루어져 있는 표에 1 부터 9 까지의 숫자를 채워넣는 퍼즐이다.


같은 줄에 1 에서 9 까지의 숫자를 한번씩만 넣고, 3 x 3 크기의 작은 격자 또한, 1 에서 9 까지의 숫자가 겹치지 않아야 한다.
 


입력으로 9 X 9 크기의 스도쿠 퍼즐의 숫자들이 주어졌을 때, 위와 같이 겹치는 숫자가 없을 경우, 1을 정답으로 출력하고 그렇지 않을 경우 0 을 출력한다.


[제약 사항]

1. 퍼즐은 모두 숫자로 채워진 상태로 주어진다.

2. 입력으로 주어지는 퍼즐의 모든 숫자는 1 이상 9 이하의 정수이다.


[입력]

입력은 첫 줄에 총 테스트 케이스의 개수 T가 온다.

다음 줄부터 각 테스트 케이스가 주어진다.

테스트 케이스는 9 x 9 크기의 퍼즐의 데이터이다.


[출력]

테스트 케이스 t에 대한 결과는 “#t”을 찍고, 한 칸 띄고, 정답을 출력한다.

(t는 테스트 케이스의 번호를 의미하며 1부터 시작한다.)

 

 

 

2. 내 풀이

T = int(input())
for tc in range(1, T+1):
    arr = [list(map(int, input().split())) for _ in range(9)]

    # 1) 가로 탐색
    garo_count = 0
    for i in range(9):
        if sum(arr[i]) == 45:
            garo_count += 1

    # 2) 세로 탐색
    # 세로 열만 추출하는 간단한 방법이 뭐 없을까? 구글링으로 무슨 함수를 발견했는데 쓰기 싫음
    sero_count = 0
    for j in range(9):
        sero_sum = 0
        for i in range(9):
            sero_sum += arr[i][j]
        if sero_sum == 45:
            sero_count += 1

    # 3) 격자 탐색
    guk_count = 0
    for x in [0, 3, 6]:
        for y in [0, 3, 6]:
            guk_sum = 0
            for i in range(3):
                for j in range(3):
                    guk_sum += arr[i][j]
                if guk_sum == 45:
                    guk_count += 1

    # 4) 출력
    if garo_count == sero_count == guk_count == 9:
        print(f'#{tc} 1')
    else:
        print(f'#{tc} 0')

-> 노가다로 풀었다.

-> 이렇게 풀면 5로만 채워진 스도쿠를 맞다고 한다.

-> 다시 풀어볼 문제..!

 

 

 

3. 다른 풀이

t = int(input())
for tc in range(1, t+1):
    sudoku = [list(map(int, input().split())) for _ in range(9)]
    result = 1
    
    # 가로축
    for i in range(9):
        nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]
        for j in range(9):
            if sudoku[i][j] in nums:
                nums.remove(sudoku[i][j])
        if len(nums) > 0:
            result = 0
            break
    # 전치
    for i in range(9):
        for j in range(9):
            if i < j:
                sudoku[i][j], sudoku[j][i] = sudoku[j][i], sudoku[i][j]
    # 세로축
    for i in range(9):
        nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]
        for j in range(9):
            if sudoku[i][j] in nums:
                nums.remove(sudoku[i][j])
        if len(nums) > 0:
            result = 0
            break
    # 작은 격자
    dx = [0, 0, 1, 1, 2, 0, 2, 1, 2]
    dy = [0, 1, 0, 1, 0, 2, 1, 2, 2]
    for i in range(0, 7, 3):
        nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]
        for j in range(0, 7, 3):
            for k in range(9):
                x = dx[k]+i
                y = dy[k]+j
                if sudoku[y][x] in nums:
                    nums.remove(sudoku[y][x])
            if len(nums) > 0:
                result = 0
                break

    print(f'#{tc} {result}')