[인프런] 3-10 스도쿠 검사 (파이썬)

Jewon Joel Park·2022년 5월 31일
0

문제 출처


문제 설명

9x9 스도쿠 퍼즐이 제대로 작성되었으면 "YES" 출력, 아닐경우 "NO"를 출력하는 코드 작성


풀이 코드

grid = [list(map(int, input().split())) for _ in range(9)]

# 각 행열의 set 길이가 9가 아닐 경우 return False
def check_lines(i, j):
    if len(set(grid[i])) != 9 or len(set(grid[:][j])) != 9:
        return False
    else:
        return True

# 사각형 구역의 set 길이가 9가 아닐 경우 return False
def check_rect(i, j):
    val = []  # 사각형 내 데이터를 모을 리스트 선언
    i //= 3  # 입력받은 좌표를 3으로 나눈 몫을 인덱스로 사용
    j //= 3
    
    for x in range(i * 3, (i + 1) * 3):  # 3으로 나눴으니 다시 3을 곱하여 연산
        for y in range(j * 3, (j + 1) * 3):
            val.append(grid[x][y])
    if len(set(val)) != 9:
        return False
    else:
        return True


flag = True  # 불필요한 연산을 줄이고, 최종 연산 결과를 저장할 flag
for i in range(9):
    if flag:
        for j in range(9):
            if flag:
                # 각 행열이나 단위 사각형 내에 set 길이가 9가 아닐경우 flag를 False로 변환
                if not (check_lines(i, j) and check_rect(i, j)):
                    flag = False
            else:
                break
    else:
        break

if flag:
    print("YES")
else:
    print("NO")

코드 설명

  1. 중복되는 숫자가 없이 완성되어야한다는 점에 착안하여 set 자료구조 채용
  2. 가로세로를 검사할 함수 check_lines()에서 각 행과 열에 모든 개채를 set()에 넣어 그 길이가 9가 아닐 경우 False 반환
  3. 사각형 구역을 검사할 함수 check_rect()는 입력받은 좌표값을 3으로 나눈 몫을 사용함으로써 일정 구획 안에서만 동작할 수 있도록 작성, 이후 해당 구역 내에 있는 모든 개체를 val 리스트에 담아 set()처리한 뒤 길이가 9가 아닐 경우 False 반환
  4. 이후 불필요한 연산을 줄이고 최종결과를 저장할 불리언 변수 flag 생성, flagTrue일 때만 check_lines()check_rect()함수 실행한 뒤 해당 결과가 하나라도 False일 경우의 논리식을 적용하여 flag에 저장
  5. flagTrue일 경우 "YES"출력, 아니면 "NO"출력

P.S.) 다 쓰고 포스팅 하다보니 문득 드는 생각이, 1~9가 아닌 이외의 숫자를 넣어도 내 코드는 정상적으로 동작할 것 같다는 생각이 들었다. 나중에 sum() == 45랑 정수 판별도 논리식에 넣으면 괜찮아 지려나..

profile
10년을 돌고 돌아 마침내 제자리를 찾은 문과 출신 Python 개발자의 인생기록장

0개의 댓글