상세 컨텐츠

본문 제목

Baekjoon(Kotlin) - 2580. 스도쿠

Problems(Kotlin)/Baekjoon

by KDLiam 2023. 9. 5. 18:30

본문

URL : https://www.acmicpc.net/problem/2580

 

2580번: 스도쿠

스도쿠는 18세기 스위스 수학자가 만든 '라틴 사각형'이랑 퍼즐에서 유래한 것으로 현재 많은 인기를 누리고 있다. 이 게임은 아래 그림과 같이 가로, 세로 각각 9개씩 총 81개의 작은 칸으로 이루

www.acmicpc.net

 

[ RESULT ]

import java.io.BufferedReader
import java.io.BufferedWriter
import java.io.InputStreamReader
import java.io.OutputStreamWriter

val br = BufferedReader(InputStreamReader(System.`in`))
val bw = BufferedWriter(OutputStreamWriter(System.out))

fun main() {
    val board = Array(9) { IntArray(9) }

    // 스도쿠 판 입력
    for (i in 0 until 9) {
        val line = br.readLine().split(" ").map { it.toInt() }
        for (j in 0 until 9) { board[i][j] = line[j] }
    }

    solveSudoku(board)
    printBoard(board)

    br.close()
    bw.close()
}

fun solveSudoku(board: Array<IntArray>): Boolean {
    for (row in 0 until 9) {
        for (col in 0 until 9) {
            if (board[row][col] == 0) {
                for (num in 1..9) {
                    if (isValid(board, row, col, num)) {
                        board[row][col] = num
                        if (solveSudoku(board)) { return true }
                        board[row][col] = 0
                    }
                }
                return false
            }
        }
    }
    return true
}

fun isValid(board: Array<IntArray>, row: Int, col: Int, num: Int): Boolean {
    // 가로, 세로, 3x3 구역에서 중복 확인
    for (i in 0 until 9) {
        if (board[row][i] == num || board[i][col] == num || board[3 * (row / 3) + i / 3][3 * (col / 3) + i % 3] == num) { return false }
    }
    return true
}

fun printBoard(board: Array<IntArray>) {
    for (i in 0 until 9) {
        for (j in 0 until 9) { bw.write("${board[i][j]} ") }
        bw.write("\n")
    }
}

 

 

[ FAILS ]

import java.io.BufferedReader
import java.io.BufferedWriter
import java.io.InputStreamReader
import java.io.OutputStreamWriter

val br = BufferedReader(InputStreamReader(System.`in`))
val bw = BufferedWriter(OutputStreamWriter(System.out))

fun main() {

    val board: MutableList<MutableList<Int>> = MutableList(9) { MutableList(9) { 0 } }

    // Board 입력
    for(i in 0 until 9) {
        val currLine = br.readLine().split(" ").map{ it.toInt() }
            for(j in 0 until 9) board[i][j] = currLine[j]
        }

    while(zeroCheck(board)) {
        horizontalCheck(board)
        if(!zeroCheck(board)) break
        verticalCheck(board)
        if(!zeroCheck(board)) break
        areaCheck(board)
    }

    // 출력
    for (row in board) {
        for (value in row) {
            bw.write("$value ")
        }
        bw.write("\n")
    }

    br.close()
    bw.close()
}

// 가로 체크
fun horizontalCheck(Board: MutableList<MutableList<Int>>): MutableList<MutableList<Int>> {

    for(i in 0 until 9) {
        val zeroCheck: MutableList<Boolean> = MutableList(9) { false }
        var cnt = 0
        var zeroIndex = 0
        for(j in 0 until 9) {
            if(Board[i][j] == 0) {
                cnt += 1
                zeroIndex = j
            }
            else { zeroCheck[Board[i][j] - 1] = true }
        }

        if(cnt == 1) {
            val index = zeroCheck.indexOf(false)
            Board[i][zeroIndex] = (index + 1)
        }
    }

    return Board
}

fun zeroCheck(Board: MutableList<MutableList<Int>>): Boolean {
    for(i in 0 until 9) {
        for(j in 0 until 9) {
            if(Board[i][j] == 0) return true
        }
    }
    return false
}

// 세로 체크
fun verticalCheck(Board: MutableList<MutableList<Int>>): MutableList<MutableList<Int>> {

    for(i in 0 until 9) {
        val zeroCheck: MutableList<Boolean> = MutableList(9) { false }
        var cnt = 0
        var zeroIndex = 0
        for(j in 0 until 9) {
            if(Board[j][i] == 0) {
                cnt += 1
                zeroIndex = i
            }
            else { zeroCheck[Board[j][i] - 1] = true }
        }

        if(cnt == 1) {
            val index = zeroCheck.indexOf(false)
            Board[zeroIndex][i] = (index + 1)
        }
    }

    return Board
}

fun areaCheck(Board: MutableList<MutableList<Int>>): MutableList<MutableList<Int>> {
    for(i in 0 until 9 step 3) {
        for(j in 0 until 9 step 3) {
            val zeroCheck: MutableList<Boolean> = MutableList(9) { false }
            var cnt = 0
            var zeroXIndex = 0
            var zeroYIndex = 0

            for(x in i .. i+2) {
                for(y in j .. j+2) {
                    if(Board[x][y] == 0) {
                        cnt += 1
                        zeroXIndex = x
                        zeroYIndex = y
                    }
                    else { zeroCheck[Board[x][y] - 1] = true }
                }
            }

            if(cnt == 1) {
                val index = zeroCheck.indexOf(false)
                Board[zeroXIndex][zeroYIndex] = (index + 1)
            }

        }
    }
    return Board
}

 

import java.io.BufferedReader
import java.io.BufferedWriter
import java.io.InputStreamReader
import java.io.OutputStreamWriter

val br = BufferedReader(InputStreamReader(System.`in`))
val bw = BufferedWriter(OutputStreamWriter(System.out))

val MIN = 0
val MAX = 8

fun main() {

    val board: MutableList<MutableList<Int>> = MutableList(9) { MutableList(9) { 0 } }

    // Board 입력
    for (i in 0 until 9) {
        val currLine = br.readLine().split(" ").map { it.toInt() }
        for (j in 0 until 9) board[i][j] = currLine[j]
    }

    while (checkBoard(board)) {
        for (i in 0 until 9) {
            for (j in 0 until 9) {
                if (board[i][j] == 0) { // 0이 존재?

                    // 가로줄 체크
                    val zeroCheck: MutableList<Boolean> = MutableList(9) { false }
                    for (y in MIN..MAX) {
                        if (board[i][y] != 0) {
                            zeroCheck[board[i][y] - 1] = true
                        }
                    }
                    if (zeroCheck.count { it } == 8) {
                        board[i][j] = zeroCheck.indexOf(false) + 1
                        continue
                    }

                    // 세로줄 체크
                    zeroCheck.fill(false) // zeroCheck를 초기화
                    for (x in MIN..MAX) {
                        if (board[x][j] != 0) {
                            zeroCheck[board[x][j] - 1] = true
                        }
                    }
                    if (zeroCheck.count { it } == 8) {
                        board[i][j] = zeroCheck.indexOf(false) + 1
                        continue
                    }

                    // 구역 체크
                    zeroCheck.fill(false) // zeroCheck를 초기화
                    val xRange = when {
                        i >= 6 -> 6..8
                        i >= 3 -> 3..5
                        else -> 0..2
                    }
                    val yRange = when {
                        j >= 6 -> 6..8
                        j >= 3 -> 3..5
                        else -> 0..2
                    }
                    var cnt = 0
                    var zeroX = 0
                    var zeroY = 0
                    for (x in xRange) {
                        for (y in yRange) {
                            if (board[x][y] == 0) {
                                cnt += 1
                                zeroX = x
                                zeroY = y
                            } else {
                                zeroCheck[board[x][y] - 1] = true
                            }
                        }
                    }
                    if (cnt == 1) board[zeroX][zeroY] = zeroCheck.indexOf(false) + 1
                }
            }
        }
    }

    // 출력
    for (row in board) {
        for (value in row) {
            bw.write("$value ")
        }
        bw.write("\n")
    }

    br.close()
    bw.close()
}

fun checkBoard(Board: MutableList<MutableList<Int>>): Boolean {
    for (i in MIN..MAX) {
        for (j in MIN..MAX) {
            if (Board[i][j] == 0) return true
        }
    }
    return false
}

관련글 더보기