package top.r394realms.ltdmanagertest

fun main() {
    val startTime = System.currentTimeMillis()

    // 生成1~9的所有排列并检查是否是幻方
    val numbers = arrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9)
    val magicSquares = mutableListOf<Array<Array<Int>>>()
    val used = BooleanArray(9)
    val current = Array(3) { Array(3) { 0 } }

    fun backtrack(index: Int) {
        if (index == 9) {
            if (isMagicSquare(current)) {
                // 深拷贝当前矩阵
                val copy = Array(3) { i -> Array(3) { j -> current[i][j] } }
                magicSquares.add(copy)
            }
            return
        }

        for (i in numbers.indices) {
            if (!used[i]) {
                used[i] = true
                current[index / 3][index % 3] = numbers[i]
                backtrack(index + 1)
                used[i] = false
            }
        }
    }

    backtrack(0)

    // 去重（排除旋转和镜像对称的重复解）
    val uniqueSquares = removeDuplicates(magicSquares)

    println("找到 ${uniqueSquares.size} 个独特的3阶幻方：")
    println("=".repeat(30))

    uniqueSquares.forEachIndexed { idx, square ->
        println("幻方 ${idx + 1}:")
        printMagicSquare(square)
        println("-".repeat(20))
    }

    val endTime = System.currentTimeMillis()
    println("总排列数: ${factorial(9)}")
    println("有效幻方数: ${magicSquares.size}")
    println("独特幻方数: ${uniqueSquares.size}")
    println("运行时间: ${endTime - startTime}ms")
}

fun isMagicSquare(square: Array<Array<Int>>): Boolean {
    // 检查所有行、列、对角线之和是否为15
    return (square[0][0] + square[0][1] + square[0][2] == 15) &&
            (square[1][0] + square[1][1] + square[1][2] == 15) &&
            (square[2][0] + square[2][1] + square[2][2] == 15) &&

            (square[0][0] + square[1][0] + square[2][0] == 15) &&
            (square[0][1] + square[1][1] + square[2][1] == 15) &&
            (square[0][2] + square[1][2] + square[2][2] == 15) &&

            (square[0][0] + square[1][1] + square[2][2] == 15) &&
            (square[0][2] + square[1][1] + square[2][0] == 15)
}

fun removeDuplicates(squares: List<Array<Array<Int>>>): List<Array<Array<Int>>> {
    val unique = mutableListOf<Array<Array<Int>>>()
    val seen = mutableSetOf<String>()

    for (square in squares) {
        // 获取所有旋转和镜像变换
        val transformations = getAllTransformations(square)
        var isNew = true

        for (transform in transformations) {
            val key = transformToString(transform)
            if (key in seen) {
                isNew = false
                break
            }
        }

        if (isNew) {
            val key = transformToString(square)
            seen.add(key)
            unique.add(square)
        }
    }

    return unique
}

fun getAllTransformations(square: Array<Array<Int>>): List<Array<Array<Int>>> {
    val transformations = mutableListOf<Array<Array<Int>>>()
    var current = square

    // 4个旋转方向
    repeat(4) {
        transformations.add(current)
        // 添加镜像
        transformations.add(mirrorHorizontal(current))
        transformations.add(mirrorVertical(current))
        transformations.add(mirrorDiagonal(current))

        current = rotate90(current)
    }

    return transformations.distinctBy { transformToString(it) }
}

fun rotate90(square: Array<Array<Int>>): Array<Array<Int>> {
    val result = Array(3) { Array(3) { 0 } }
    for (i in 0..2) {
        for (j in 0..2) {
            result[j][2 - i] = square[i][j]
        }
    }
    return result
}

fun mirrorHorizontal(square: Array<Array<Int>>): Array<Array<Int>> {
    val result = Array(3) { Array(3) { 0 } }
    for (i in 0..2) {
        for (j in 0..2) {
            result[i][2 - j] = square[i][j]
        }
    }
    return result
}

fun mirrorVertical(square: Array<Array<Int>>): Array<Array<Int>> {
    val result = Array(3) { Array(3) { 0 } }
    for (i in 0..2) {
        for (j in 0..2) {
            result[2 - i][j] = square[i][j]
        }
    }
    return result
}

fun mirrorDiagonal(square: Array<Array<Int>>): Array<Array<Int>> {
    val result = Array(3) { Array(3) { 0 } }
    for (i in 0..2) {
        for (j in 0..2) {
            result[j][i] = square[i][j]
        }
    }
    return result
}

fun transformToString(square: Array<Array<Int>>): String {
    return square.joinToString("") { row -> row.joinToString("") }
}

fun printMagicSquare(square: Array<Array<Int>>) {
    for (row in square) {
        println(row.joinToString(" ") { "%d".format(it) })
    }
}

fun factorial(n: Long): Long {
    return if (n <= 1) 1
    else n * factorial(n - 1)
}