[Powershell] 用powershell算9X9数独.

This arctical will also be published in English at http://www.cnblogs.com/LarryAtCNBlog/p/4307965.html

数独是一个填字游戏,广为人知的是9X9类型的,下面是一个算法,也就是由每次从可确定的数中推算同行或同列的可能值,如果可能值只为1个,那就可以直接确定该单元格的值,如果可能的值的数量大于或等于2,则做循环和单元格值的假设,推算出答案。由于数独答案不唯一,因此加了一个参数定义返回的答案数量。

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)
)
# 循环每个元素,给没有值的元素加上 1-9 的数组。
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])
        }
    }
}

# 循环每个元素,比较横向和纵向数据,从除去所有可能的值。
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
}

# 循环每个元素,如果可能的值数量变为0,返回true,说明计算错误。
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
}

# 找到元素中可能的值数量最小的那个,返回该元素的位置。
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
                }
            }
        }
    }
}

# 计算数组中有多少个元素已经被确认了值。
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)
        }
    }
}
# 触发
GoCalculate($SudokuMatrix)

# 输出结果
$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-10-28 22:02:52

[Powershell] 用powershell算9X9数独.的相关文章

Exchange 2013 PowerShell创建PowerShell函数

函数是将一些列命令合并到一个可重用的代码块中,然后我们只需要调用这个函数.函数可以被配置为更改或返回一个或多个可以显示在控制台或输出到一个外部文件的对象.你可以将函数的输出传递給一个变量,或其它命令.在这一节中,我们讲学习下如何创建一个PowerShell函数 去创建一个函数,我们需要用到关键字Function,然后紧跟着就是这个函数的名称,然后函数的代码附在大括号{}中.先来看一个示例,这是一个基本的函数,将会在一个列表中显示邮箱的三个属性 function Get-MailboxList {

数据库管理——Powershell——使用Powershell脚本找出消耗最多磁盘空间的文件

原文:数据库管理--Powershell--使用Powershell脚本找出消耗最多磁盘空间的文件 原文译自: http://www.mssqltips.com/sqlservertip/2774/powershell-script-to-find-files-that-are-consuming-the-most-disk-space/?utm_source=dailynewsletter&utm_medium=email&utm_content=headline&utm_cam

Windows cannot find 'C:\Users\....\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShell\Windows PowerShell.lnk'.Make sure you typed the name correctly, and then try again.

Windows cannot find 'C:\Users\....\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShell\Windows PowerShell.lnk'.Make sure you typed the name correctly, and then try again. 解决方法: 在上面提示的位置新建一个快捷方式,目标为%SystemRoot%\system32\WindowsPow

[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 e

[PowerShell] check PowerShell Version

如果你已经开始在日常的工作中大量使用PowerShell自动化重复工作.建议你使用3.0以上的版本. 可以使用如下命令检测你的PS版本 如需要安装PowerShell,可以参看https://technet.microsoft.com/en-us/library/hh847837.aspx

Azure PowerShell (1) PowerShell入门

<Windows Azure Platform 系列文章目录> 2014-09-30:把之前关于Azure PowerShell的内容重新整理了一下. 我们知道,我们可以通过以下三种方式管理Windows Azure: Azure Management Portal,特点是简单直观 Azure REST API,特点是可以通过调用REST API来实现云端的开发 Azure PowerShell,特点是可以批量操作 大家可以想象一下,如何在短时间内需要申请200个虚拟机,使用Azure Man

PowerShell 将powershell脚本转换成exe

#1.脚本 function Convert-PS1ToExe {     param(     [Parameter(Mandatory=$true)]     [ValidateScript({$true})]     [ValidateNotNullOrEmpty()]        [IO.FileInfo]$ScriptFile     )     if( -not $ScriptFile.Exists)     {         Write-Warning "$ScriptFile

第一个PowerShell脚本——PowerShell三分钟(九)

前面把基础知识讲了一遍,现在我们开始写一个最初级的脚本 写脚本的工具有很多,有文本文档,有PowerShell ISE,PowerShell Studio等,这里选用系统自带的PowerShell ISE 这里大家依然要记得以管理员身份运行,否则容易权限不足导致命令运行失败 好,接下来找个最常用的命令,假设我们想查询前一天的Exchange邮件队列,来确定垃圾邮件等信息 那么首先,默认情况下ISE是无法识别Exchange的命令的,所以需要先添加Exchange管理单元 然后输入查询邮件队列的命

[powershell]Use powershell to get file hash / 使用powershell获取文件哈希值

1.首先检查powershell版本: 应该为5.1 低版本升级补丁:https://docs.microsoft.com/en-us/powershell/scripting/install/installing-windows-powershell?view=powershell-6 WIN7SP1:https://www.microsoft.com/en-us/download/details.aspx?id=54616 2.使用方法 1 Get-FileHash .\bilibil_ma