/* * File: nQueens.kt * Purpose: Solves the n-queens puzzle. * Compilation: kotlinc nQueens.kt * Execution: kotlin NQueensKt n * where n is a positive integer * Author: San Skulrattanakulchai */ import kotlin.math.abs fun main(args: Array) { fun swap(a: IntArray, i: Int, j: Int) { val tmp = a[i] a[i] = a[j] a[j] = tmp } fun queen(size: Int) { val board = Array(size) { CharArray(size) { ' ' } } val pi = IntArray(size) { it } fun printBoard() { val line = "${"+---".repeat(size)}+\n" val sb = StringBuilder() for (i in 0 until size) { sb.append(line) for (j in 0 until size) sb.append("| ${board[i][j]} ") sb.append("|\n") } sb.append(line) print(sb) } fun isCompat(i: Int, j: Int): Boolean { fun isAttacking(x1: Int, y1: Int, x2: Int, y2: Int) = x1 == x2 || y1 == y2 || abs(x1-x2) == abs(y1-y2) for (k in 0 until i) { if (isAttacking(k, pi[k], i, j)) return false } return true } fun perm(i: Int): Boolean { if (i == size) { println("Here is one possible answer.") for (j in 0 until size) board[j][pi[j]] = 'Q' printBoard() return true } else { for (j in i until size) { if (isCompat(i, pi[j])) { swap(pi, i, j) if (perm(i+1)) return true swap(pi, i, j) } } return false } } val randGen = java.util.Random() for (i in size downTo 1) swap(pi, i-1, randGen.nextInt(i)) if (!perm(0)) println("There is no answer.") } queen(args[0].toInt()) }