# sudoku.msh
# (c) 2006 Adam Barr
# show the whole board
function show_board {
foreach ($y in (0..8)) {
foreach ($x in (0..8)) {
write-host -nonewline $board[$y][$x]
write-host -nonewline " "
}
write-host
}
write-host $(count_filled)
}
# count how many cells have a digit in them
function count_filled {
$count = 0
$board | foreach-object { $count += ($_ -like "[1-9]").Length }
return $count
}
# initialize the board to empty
$board = @()
get-content -TotalCount 9 $args[0] |
foreach-object {
$arr = [char[]]$_
if ($arr.Length -ne 9) {
write-host "Invalid input" $arr
exit
}
$board += ,$arr
}
# board now is an array of 9 elements,
# each element is an array of 9 chars
$rawui = $host.ui.rawui
write-host
show_board
write-host
$curcoord = $rawui.CursorPosition
# fill $groups with the boxes, rows, and columns
# each entry in $groups will be an array of 9 elements,
# each element is an array with 2 elements, the y and x coordinates
foreach ($y in (0,3,6)) {
foreach ($x in (0,3,6)) {
$box = @()
foreach ($y1 in (0..2)) {
foreach ($x1 in (0..2)) {
$box += ,(($y+$y1),($x+$x1))
}
}
$groups += ,$box
}
}
foreach ($b in (0..8)) {
$row = @()
$col = @()
foreach ($a in (0..8)) {
$row += ,($a,$b)
$col += ,($b,$a)
}
$groups += ,$row
$groups += ,$col
}
# now solve it
$last_count = count_filled
while (count_filled -lt 81) {
foreach ($g in $groups) {
foreach ($digit in (1..9)) {
$d = [char][string]$digit
$conflicts = new-object int[] 9
$conflicts = (0..8) | foreach { $false }
# fills in the $conflicts array for character $d
in $g
:nloop
foreach ($n in (0..8)) {
$yx = $g[$n]
# cell occupied?
if ($board[$yx[0]][$yx[1]] -like
"[1-9]") {
$conflicts[$n] = $true
continue nloop
}
# row conflict?
foreach ($c in (0..8)) {
if ($board[$yx[0]][$c] -eq
$d) {
$conflicts[$n]
= $true
continue
nloop
}
}
# column conflict?
foreach ($r in (0..8)) {
if ($board[$r][$yx[1]] -eq
$d) {
$conflicts[$n]
= $true
continue
nloop
}
}
# box conflict?
$yfloor = $yx[0] - ($yx[0] % 3)
$xfloor = $yx[1] - ($yx[1] % 3)
foreach ($y in ($yfloor..($yfloor+2)))
{
foreach ($x in ($xfloor..($xfloor+2)))
{
if ($board[$y][$x]
-eq $d) {
$conflicts[$n]
= $true
continue nloop
}
}
}
}
if (($conflicts -eq $false).Length -eq 1) {
$index = [array]::IndexOf($conflicts,$false)
$thisy = $g[$index][0]
$thisx = $g[$index][1]
$board[$thisy][$thisx] = $d
$coord =
new-object
System.Management.Automation.Host.Coordinates `
($curcoord.X+($thisx*2)),($curcoord.Y+$thisy-11)
$rawui.CursorPosition = $coord
write-host $d
$coord.X = $curcoord.X
$coord.Y = $curcoord.Y - 2
$rawui.CursorPosition = $coord
write-host $(count_filled)
}
}
}
$new_count = count_filled
if ($new_count -eq $last_count) {
break;
}
$last_count = $new_count
}