[Powershell] An algorithm to 9x9 sudoku.

Sudoku is a numbers filling game, most known by people is 9x9 class, the algorithm is using confirmed numbers to get all possible numbers for each cell, if the number if possible numbers for a cell is 1, then the cell value confirmed, if greater or equal than 2, script makes loop and calculates a potential answer. Since answers are not unique, so a parameter is added to specify how many answers to return.

param(
    # 返回几个答案
    [int]$HowManyAnswersYouWanttoGet = 1
)

$SudokuMatrix = @(
    @(0,0,0, 0,0,0, 0,0,3),
    @(0,0,0, 0,0,0, 0,4,0),
    @(0,5,1, 6,0,0, 0,0,0),

    @(0,3,0, 0,0,8, 0,0,2),
    @(9,0,0, 1,6,0, 0,0,0),
    @(0,6,0, 0,5,4, 0,0,0),

    @(5,4,0, 0,0,0, 0,2,0),
    @(0,0,3, 4,0,2, 0,0,0),
    @(0,0,8, 3,0,0, 7,1,0)
)
# Loop each cell, add array [1..9] for each null cell.
for($i = 0; $i -lt 9; $i++){
    for($j = 0; $j -lt 9; $j++){
        if(!$SudokuMatrix[$i][$j]){
            $SudokuMatrix[$i][$j] = 1..9
        }else{
            $SudokuMatrix[$i][$j] = @($SudokuMatrix[$i][$j])
        }
    }
}

# Loop each cell, calculate possible numbers to remove impossible numbers for the cell.
function GoLoop($arr){
    $NewArr = @($null) * 9
    for($i = 0; $i -lt 9; $i++){
        $NewArr[$i] = $arr[$i].PSObject.Copy()
    }
    for($i = 0; $i -lt 9; $i++){
        for($j = 0; $j -lt 9; $j++){
            if($NewArr[$i][$j].Count -ne 1){
                for($k = 0; $k -lt 9; $k++){
                    if($NewArr[$i][$k].Count -eq 1 -and $NewArr[$i][$j].Count -ne 1){
                        $NewArr[$i][$j] = @($NewArr[$i][$j] | ?{$_ -ne $NewArr[$i][$k][0]})
                    }
                    if($NewArr[$k][$j].Count -eq 1 -and $NewArr[$i][$j].Count -ne 1){
                        $NewArr[$i][$j] = @($NewArr[$i][$j] | ?{$_ -ne $NewArr[$k][$j][0]})
                    }
                }
            }
        }
    }
    return $NewArr
}

# Loop each cell, if the possible number of the cell is null, means current calculation is wrong.
function VerifyZero($arr){
    for($i = 0; $i -lt 9; $i++){
        for($j = 0; $j -lt 9; $j++){
            if($arr[$i][$j].Count -eq 0){
                return $i, $j, $true
            }
        }
    }
    return $i, $j, $false
}

# Find the most less of possible numbers for a cell, return the position.
function FindSmallest($arr){
    foreach($k in 2..9){
        for($i = 0; $i -lt 9; $i++){
            for($j = 0; $j -lt 9; $j++){
                if($arr[$i][$j].Count -eq $k){
                    return $i, $j, $k
                }
            }
        }
    }
}

# Calculate how many cells have been confirmed, if it‘s 81, correct answer hit.
function CountConfirmedNumber($arr){
    $NumberConfirmed = 0
    for($i = 0; $i -lt 9; $i++){
        for($j = 0; $j -lt 9; $j++){
            if($arr[$i][$j].Count -eq 1){
                $NumberConfirmed++
            }
        }
    }
    return $NumberConfirmed
}

$AnswerCount = 0
$Results = @()

function GoCalculate($arr){
    $NewArray = GoLoop($arr)
    # verify no zero option!
    $ZeroPosition = VerifyZero($NewArray)
    if($ZeroPosition[2]){
        # Write-Host "0 option found: [$($ZeroPosition[0])][$($ZeroPosition[1])]"
        return
    }
    # confirm current numbers
    if((CountConfirmedNumber($NewArray)) -eq 81){
        $Script:AnswerCount++
        Write-Host "An answer captured, ID: $AnswerCount" -ForegroundColor Green
        # Write-Host "81 numbers confirmed."
        $Script:Results += $null
        $Script:Results[-1] = $NewArray
        return
    }
    # find the nearest(to [0][0]) and smallest(2 to 9) option element.
    $Smallest = FindSmallest($NewArray)
    $OptionsStack = @($NewArray[$Smallest[0]][$Smallest[1]])
    # Write-Host "Row: $($Smallest[0]); Col: $($Smallest[1]); Option: $($OptionsStack -join ‘ ‘)"
    foreach($Option in $OptionsStack){
        # Write-Host "Set [$($Smallest[0])][$($Smallest[1])] to: $Option"
        $NewArray[$Smallest[0]][$Smallest[1]] = @($Option)
        if($AnswerCount -lt $HowManyAnswersYouWanttoGet){
            GoCalculate($NewArray)
        }
    }
}
# Trigger
GoCalculate($SudokuMatrix)

# Output answers
$Results | %{
    if($_ -eq $null){return}
    Write-Host "Answer:" -ForegroundColor Yellow
    for($i = 0; $i -lt 9; $i++){
        for($j = 0; $j -lt 9; $j++){
            Write-Host "$($_[$i][$j][0]) " -NoNewline -ForegroundColor yellow
        }
        Write-Host "`n"
    }
}
时间: 2024-11-03 21:52:33

[Powershell] An algorithm to 9x9 sudoku.的相关文章

LeetCode Medium: 36. Valid Sudoku

一.题目 Determine if a 9x9 Sudoku board is valid. Only the filled cells need to be validated according to the following rules: Each row must contain the digits 1-9 without repetition. Each column must contain the digits 1-9 without repetition. Each of t

[Swift]LeetCode36. 有效的数独 | Valid Sudoku

Determine if a 9x9 Sudoku board is valid. Only the filled cells need to be validated according to the following rules: Each row must contain the digits 1-9 without repetition. Each column must contain the digits 1-9 without repetition. Each of the 9 

Samples for Parallel Programming with the .NET Framework

The .NET Framework 4 includes significant advancements for developers writing parallel and concurrent applications, including Parallel LINQ (PLINQ), the Task Parallel Library (TPL), new thread-safe collections, and a variety of new coordination and s

LeetCode-数组下标的使用

26. Remove Duplicates from Sorted Array 从已排序的数组中移除重复元素 https://leetcode.com/problems/remove-duplicates-from-sorted-array/ 题目:给定已排序数组nums,移除重复项,使每个元素只出现一次,并返回新的长度. 思路:使用快慢指针来记录每次遍历的索引,最开始时两个指针都指向第一个数字,如果两个指针指的数字相同,则快指针向前走一步,如果不同,则两个指针都向前走一步.这样当快指针走完整个

[Powershell] 用powershell算9X9数独.

This arctical will also be published in English at http://www.cnblogs.com/LarryAtCNBlog/p/4307965.html 数独是一个填字游戏,广为人知的是9X9类型的,下面是一个算法,也就是由每次从可确定的数中推算同行或同列的可能值,如果可能值只为1个,那就可以直接确定该单元格的值,如果可能的值的数量大于或等于2,则做循环和单元格值的假设,推算出答案.由于数独答案不唯一,因此加了一个参数定义返回的答案数量. pa

ACdream 1195 Sudoku Checker (暴力)

Sudoku Checker Time Limit: 2000/1000MS (Java/Others)Memory Limit: 128000/64000KB (Java/Others) SubmitStatus Problem Description Sudoku is a popular single player game. The objective is to fill a 9x9 matrix with digits so that each column, each row, a

HDU 1426 Sudoku Killer(dfs 解数独)

传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1426 Sudoku Killer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 9804    Accepted Submission(s): 2944 Problem Description 自从2006年3月10日至11日的首届数独世界

POJ Sudoku 数独填数 DFS

题目链接:Sudoku Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 18105   Accepted: 8772   Special Judge Description Sudoku is a very simple task. A square table with 9 rows and 9 columns is divided to 9 smaller squares 3x3 as shown on the Fig

POJ 3047 Sudoku DLX精确覆盖

DLX精确覆盖.....模版题 Sudoku Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8336   Accepted: 2945 Description In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example, . 2 7 3 8 . . 1 . . 1 . .