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}')