闲人真多啊:Sudoku(数独?)的XQuery解决方案

来源:互联网 发布:linux 三大命令wc grep 编辑:程序博客网 时间:2024/05/02 01:40

 从Haskell作者的blog看来的。如果觉得不够变态的话,可以欣赏一下XQuery后面XSLT写的程序

XQuery的程序:

declare namespace fn = "sudoku";

declare variable  $board as xs:integer+ := (
1,0,0,  3,0,0,  6,0,0,
0,2,0,  5,0,0,  0,0,4,
0,0,9,  0,0,0,  5,2,0,

0,0,0,  9,6,3,  0,0,0,
7,1,6,  0,0,0,  0,0,0,
0,0,0,  0,8,0,  0,4,0,

9,0,0,  0,0,5,  3,0,7,
8,0,0,  4,0,6,  0,0,0,
3,5,0,  0,0,0,  0,0,1);

declare variable  $rowStarts as xs:integer+  := (1, 10, 19, 28, 37, 46, 55, 64,73);

declare variable  $groups as xs:integer+  := (
1,1,1,  2,2,2,  3,3,3,
1,1,1,  2,2,2,  3,3,3,
1,1,1,  2,2,2,  3,3,3,

4,4,4,  5,5,5,  6,6,6,
4,4,4,  5,5,5,  6,6,6,
4,4,4,  5,5,5,  6,6,6,

7,7,7,  8,8,8,  9,9,9,
7,7,7,  8,8,8,  9,9,9,
7,7,7,  8,8,8,  9,9,9
);


declare function fn:getRow ($board as xs:integer+, $index as xs:integer) as xs:integer+ {
let $rowStart := floor(($index - 1) div 9) * 9
return
  $board[position() > $rowStart and position() <= $rowStart + 9]
};


declare  function fn:getCol ($board as xs:integer+, $index as xs:integer)  as xs:integer+ {
let $gap := ($index - 1) mod 9,
    $colIndexes := for $x in $rowStarts return $x + $gap
      return
  $board[position() = $colIndexes]};


declare  function fn:getGroup ($board as xs:integer+, $index as xs:integer)  as xs:integer+ {
let $group :=    $groups[$index]
return
   $board[for $x in position()  return $groups[$x]= $group]
};


declare  function fn:getAllowedValues ($board as xs:integer+, $index as xs:integer)  as xs:integer* {
let $existingValues := (fn:getRow($board,
$index), fn:getCol($board, $index), fn:getGroup($board, $index))
return
for $x in (1 to 9) return
                               if (not($x = $existingValues))
                                 then $x
                           else ()
};


declare  function  fn:tryValues($board as xs:integer+,
                               $emptyCells as xs:integer+,
                               $possibleValues as xs:integer+) as xs:integer* {
let $index as xs:integer := $emptyCells[1],
    $newBoard as xs:integer+ := ($board[position() <$index],
                            $possibleValues[1], $board[position() > $index]),
    $result as xs:integer* := fn:populateValues($newBoard, $emptyCells[position() != 1])
   return
    if (empty($result)) then
     if (count($possibleValues) > 1) then
       fn:tryValues($board, $emptyCells, $possibleValues[position() != 1])
     else
       ()
   else
    $result
};

declare  function  fn:populateValues($board as xs:integer+,
                                    $emptyCells as xs:integer*) as xs:integer*{

if (not(empty($emptyCells)))
       then
  let $index as xs:integer :=$emptyCells[1],
      $possibleValues as xs:integer* := distinct-values(fn:getAllowedValues($board, $index))
    return
      if (count($possibleValues) > 1)
  then
      fn:tryValues($board, $emptyCells, $possibleValues)
  else if (count($possibleValues) = 1)
      then
let $newBoard as xs:integer+ :=($board[position() <
$index], $possibleValues[1], $board[position() > $index])
  return
   fn:populateValues($newBoard, $emptyCells[position() != 1])
    else ()
else
$board
};

declare  function  fn:solveSudoku ($startBoard as xs:integer+) as  xs:integer+{
let $emptyCells as xs:integer* :=for $x in (1 to 81) return if
($startBoard[$x] = 0) then $x else (),
     $endBoard as xs:integer* :=fn:populateValues($startBoard,$emptyCells)
    return
  if (empty($endBoard))
  then
  $startBoard
  else
   $endBoard};


declare  function  fn:drawResult ($board as xs:integer+) as  element(){
       <html>
               <head>
                       <title>Sudoku - XSLT</title>
                       <style>
                         table {{ border-collapse: collapse;
                                 border: 1px solid black; }}
                         td {{ padding: 10px; }}
                         .norm {{ border-left: 1px solid #CCC;
                                 border-top: 1px solid #CCC;}}
                         .csep {{ border-left: 1px solid black; }}
                         .rsep {{ border-top: 1px solid black; }}
                       </style>
               </head>
               <body>
         {fn:drawBoard($board)}
               </body>
       </html>
};

declare  function  fn:drawBoard ($board as xs:integer+) as  element(){
       <table>
           { for $i in 1 to 9
             return
                               <tr>
{for $j at $p in 1 to 9
let $pos := (($i - 1) * 9) + $j
  return
<td class="{if ($p mod 3 = 1) then 'csep' else ('norm')}
{if ($i mod 3 = 1) then 'rsep' else ('norm')}">
       {$board[$pos]}
  </td>
}
                               </tr>
         }
       </table>
};


fn:drawResult(fn:solveSudoku($board))


<xsl:stylesheet version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:saxon="http://saxon.sf.net/"
xmlns:fn="sudoku">

<xsl:param name="board" select="(
1,0,0,  3,0,0,  6,0,0,
0,2,0,  5,0,0,  0,0,4,
0,0,9,  0,0,0,  5,2,0,

0,0,0,  9,6,3,  0,0,0,
7,1,6,  0,0,0,  0,0,0,
0,0,0,  0,8,0,  0,4,0,

9,0,0,  0,0,5,  3,0,7,
8,0,0,  4,0,6,  0,0,0,
3,5,0,  0,0,0,  0,0,1
)" as="xs:integer+"/>

<xsl:param name="verbose" select="false()" as="xs:boolean"/>

<xsl:variable name="rowStarts" select="(1, 10, 19, 28, 37, 46, 55, 64, 73)" as="xs:integer+"/>
<xsl:variable name="topLeftGroup"     select="(1, 2, 3,     10, 11, 12,  19, 20, 21)" as="xs:integer+"/>
<xsl:variable name="topGroup"         select="(4, 5, 6,     13, 14, 15,  22, 23, 24)" as="xs:integer+"/>
<xsl:variable name="topRightGroup"    select="(7, 8, 9,     16, 17, 18,  25, 26, 27)" as="xs:integer+"/>
<xsl:variable name="midLeftGroup"     select="(28, 29, 30,  37, 38, 39,  46, 47, 48)" as="xs:integer+"/>
<xsl:variable name="center"           select="(31, 32, 33,  40, 41, 42,  49, 50, 51)" as="xs:integer+"/>
<xsl:variable name="midRightGroup"    select="(34, 35, 36,  43, 44, 45,  52, 53, 54)" as="xs:integer+"/>
<xsl:variable name="bottomLeftGroup"  select="(55, 56, 57,  64, 65, 66,  73, 74, 75)" as="xs:integer+"/>
<xsl:variable name="bottomGroup"      select="(58, 59, 60,  67, 68, 69,  76, 77, 78)" as="xs:integer+"/>
<xsl:variable name="bottomRightGroup" select="(61, 62, 63,  70, 71, 72,  79, 80, 81)" as="xs:integer+"/>

<xsl:function name="fn:getRowStart" as="xs:integer+" saxon:memo-function="yes">
<xsl:param name="index" as="xs:integer+"/>
<xsl:sequence select="xs:integer(floor(($index - 1) div 9) * 9) + 1"/>
</xsl:function>

<xsl:function name="fn:getRowNumber" as="xs:integer+" saxon:memo-function="yes">
<xsl:param name="index" as="xs:integer+"/>
<xsl:sequence select="(($index - 1) idiv 9) + 1"/>
</xsl:function>

<xsl:function name="fn:getColNumber" as="xs:integer+" saxon:memo-function="yes">
<xsl:param name="index" as="xs:integer+"/>
<xsl:sequence select="(($index - 1) mod 9) + 1"/>
</xsl:function>

<xsl:function name="fn:getRow" as="xs:integer+">
<xsl:param name="board" as="xs:integer+"/>
<xsl:param name="index" as="xs:integer+"/>
<xsl:sequence select="subsequence($board, fn:getRowStart($index), 9)"/>
</xsl:function>

<xsl:function name="fn:getCol" as="xs:integer+">
<xsl:param name="board" as="xs:integer+"/>
<xsl:param name="index" as="xs:integer+"/>
<xsl:variable name="gap" select="($index - 1) mod 9" as="xs:integer"/>
<xsl:variable name="colIndexes" select="for $x in $rowStarts return $x + $gap" as="xs:integer+"/>
<xsl:sequence select="for $x in $colIndexes return $board[$x]"/>
</xsl:function>

<xsl:function name="fn:getGroup" as="xs:integer+">
<xsl:param name="board" as="xs:integer+"/>
<xsl:param name="index" as="xs:integer+"/>
<xsl:choose>
  <xsl:when test="$index = $topLeftGroup">
   <xsl:sequence select="for $x in $topLeftGroup return $board[$x]"/>
  </xsl:when>
  <xsl:when test="$index = $topGroup">
   <xsl:sequence select="for $x in $topGroup return $board[$x]"/>
  </xsl:when>
  <xsl:when test="$index = $topRightGroup">
   <xsl:sequence select="for $x in $topRightGroup return $board[$x]"/>
  </xsl:when>
  <xsl:when test="$index = $midLeftGroup">
   <xsl:sequence select="for $x in $midLeftGroup return $board[$x]"/>
  </xsl:when>
  <xsl:when test="$index = $center">
   <xsl:sequence select="for $x in $center return $board[$x]"/>
  </xsl:when>
  <xsl:when test="$index = $midRightGroup">
   <xsl:sequence select="for $x in $midRightGroup return $board[$x]"/>
  </xsl:when>
  <xsl:when test="$index = $bottomLeftGroup">
   <xsl:sequence select="for $x in $bottomLeftGroup return $board[$x]"/>
  </xsl:when>
  <xsl:when test="$index = $bottomGroup">
   <xsl:sequence select="for $x in $bottomGroup return $board[$x]"/>
  </xsl:when>
  <xsl:when test="$index = $bottomRightGroup">
   <xsl:sequence select="for $x in $bottomRightGroup return $board[$x]"/>
  </xsl:when>
</xsl:choose>
</xsl:function>

<xsl:function name="fn:getOtherValuesInTriple" as="xs:integer+" saxon:memo-function="yes">
<xsl:param name="num" as="xs:integer"/>
<xsl:sequence select="(xs:integer(((($num -1) idiv 3) * 3) + 1) to xs:integer(((($num - 1) idiv 3) * 3) + 3))[. != $num]"/>
</xsl:function>

<xsl:function name="fn:getRowFriends" as="xs:integer+">
<xsl:param name="board" as="xs:integer+"/>
<xsl:param name="index" as="xs:integer+"/>
<xsl:sequence select="for $x in fn:getOtherValuesInTriple($index) return $board[$x]"/>
</xsl:function>

<xsl:function name="fn:getColFriends" as="xs:integer+">
<xsl:param name="board" as="xs:integer+"/>
<xsl:param name="index" as="xs:integer+"/>
<xsl:sequence select="for $x in fn:getOtherValuesInTriple(fn:getRowNumber($index))
            return
             $board[(($x * 9) - 8) + (($index - 1) mod 9)]"/>
</xsl:function>

<xsl:function name="fn:reducePossibleValues" as="xs:integer*">
<xsl:param name="board" as="xs:integer+"/>
<xsl:param name="index" as="xs:integer+"/>
<xsl:param name="possibleValues" as="xs:integer+"/>

<xsl:variable name="rowFriends" select="fn:getRowFriends($board, $index)" as="xs:integer+"/>
<xsl:variable name="colFriends" select="fn:getColFriends($board, $index)" as="xs:integer+"/>

<xsl:variable name="otherRow1" select="fn:getRow($board, 9 * fn:getOtherValuesInTriple(fn:getRowNumber($index))[1])" as="xs:integer+"/>
<xsl:variable name="otherRow2" select="fn:getRow($board, 9 * fn:getOtherValuesInTriple(fn:getRowNumber($index))[2])" as="xs:integer+"/>

<xsl:variable name="otherCol1" select="fn:getCol($board, fn:getOtherValuesInTriple($index)[1])" as="xs:integer+"/>
<xsl:variable name="otherCol2" select="fn:getCol($board, fn:getOtherValuesInTriple($index)[2])" as="xs:integer+"/>

<xsl:variable name="reducedValues" as="xs:integer*">
  <xsl:for-each select="$possibleValues">
   <xsl:if test=". = $otherCol1 and . = $otherCol2">
    <xsl:choose>
     <xsl:when test="not($colFriends = 0)">
      <xsl:sequence select="."/>
     </xsl:when>
     <xsl:when test="$colFriends != 0">
      <xsl:choose>
       <xsl:when test="$colFriends[1] = 0">
        <xsl:if test=". = $otherRow1">
         <xsl:sequence select="."/>
        </xsl:if>
       </xsl:when>
       <xsl:when test="$colFriends[2] = 0">
        <xsl:if test=". = $otherRow2">
         <xsl:sequence select="."/>
        </xsl:if>
       </xsl:when>
      </xsl:choose>
     </xsl:when>
    </xsl:choose>
   </xsl:if>
  
   <xsl:if test=". = $otherRow1 and . = $otherRow2">
    <xsl:choose>
     <xsl:when test="not($rowFriends = 0)">
      <xsl:sequence select="."/>
     </xsl:when>
     <xsl:when test="$rowFriends != 0">
      <xsl:choose>
       <xsl:when test="$rowFriends[1] = 0">
        <xsl:if test=". = $otherCol1">
         <xsl:sequence select="."/>
        </xsl:if>
       </xsl:when>
       <xsl:when test="$rowFriends[2] = 0">
        <xsl:if test=". = $otherCol2">
         <xsl:sequence select="."/>
        </xsl:if>
       </xsl:when>
      </xsl:choose>
     </xsl:when>
    </xsl:choose>
   </xsl:if>
  </xsl:for-each>
</xsl:variable>

<xsl:sequence select="if (count($reducedValues) = 1) then $reducedValues else $possibleValues"/>

</xsl:function>

<xsl:function name="fn:getAllowedValues" as="xs:integer*">
<xsl:param name="board" as="xs:integer+"/>
<xsl:param name="index" as="xs:integer+"/>

<xsl:variable name="possibleValues" select="(1 to 9)[not(. = (fn:getRow($board, $index), fn:getCol($board, $index), fn:getGroup($board, $index)))]" as="xs:integer*"/>

<xsl:choose>
  <xsl:when test="count($possibleValues) > 1">
      <xsl:variable name="reducedValues" select="fn:reducePossibleValues($board, $index, $possibleValues)" as="xs:integer*"/>
  
   <xsl:sequence select="$reducedValues"/>
  </xsl:when>
  <xsl:otherwise>
   <xsl:sequence select="$possibleValues"/>
  </xsl:otherwise>
</xsl:choose>

</xsl:function>

<xsl:function name="fn:tryValues" as="xs:integer*">
<xsl:param name="board" as="xs:integer+"/>
<xsl:param name="emptyCells" as="xs:integer+"/>
<xsl:param name="possibleValues" as="xs:integer+"/>

<xsl:variable name="index" select="$emptyCells[1]" as="xs:integer"/>

<xsl:variable name="newBoard" select="(subsequence($board, 1, $index - 1), $possibleValues[1], subsequence($board, $index + 1))" as="xs:integer+"/>

<xsl:if test="$verbose">
  <xsl:message>
   <xsl:value-of select="concat('Trying ', $possibleValues[1], ' out of a possible ', string-join(for $i in $possibleValues return xs:string($i), ' '), ' at index ', $index)"/>
  </xsl:message>
</xsl:if>

<xsl:variable name="result" select="fn:populateValues($newBoard, subsequence($emptyCells, 2))" as="xs:integer*"/>

<xsl:sequence select="if (empty($result)) then
                               if (count($possibleValues) > 1) then
                                 fn:tryValues($board, $emptyCells, subsequence($possibleValues, 2))
                               else
                                 ()
                             else
                               $result"/>
</xsl:function>

<xsl:function name="fn:populateValues" as="xs:integer*">
<xsl:param name="board" as="xs:integer+"/>
<xsl:param name="emptyCells" as="xs:integer*"/>

<xsl:choose>
  <xsl:when test="empty($emptyCells)">
   <xsl:message>Done!</xsl:message>
   <xsl:sequence select="$board"/>
  </xsl:when>
  <xsl:otherwise>
   <xsl:variable name="index" select="$emptyCells[1]" as="xs:integer"/>
   <xsl:variable name="possibleValues" select="fn:getAllowedValues($board, $index)" as="xs:integer*"/>
   <xsl:choose>
    <xsl:when test="count($possibleValues) = 0">
     <xsl:if test="$verbose">
      <xsl:message>! Cannot go any further !</xsl:message>
     </xsl:if>
     <xsl:sequence select="()"/>
    </xsl:when>
    <xsl:when test="count($possibleValues) > 1">
     <xsl:sequence select="fn:tryValues($board, $emptyCells, $possibleValues)"/>
    </xsl:when>
    <xsl:when test="count($possibleValues) = 1">
     <xsl:variable name="newBoard" select="(subsequence($board, 1, $index - 1), $possibleValues[1], subsequence($board, $index + 1))" as="xs:integer+"/>

     <xsl:if test="$verbose">
      <xsl:message>
       <xsl:value-of>
        <xsl:text>Only one value </xsl:text>
        <xsl:value-of select="$possibleValues[1]"/>
        <xsl:text> for index </xsl:text>
        <xsl:value-of select="$index"/>
       </xsl:value-of>
      </xsl:message>
     </xsl:if>

     <xsl:sequence select="fn:populateValues($newBoard, subsequence($emptyCells, 2))"/>
    </xsl:when>
   </xsl:choose>
  </xsl:otherwise>
</xsl:choose>
</xsl:function>

<xsl:function name="fn:populateSingleValueCells" as="xs:integer+">
<xsl:param name="board" as="xs:integer+"/>
<xsl:param name="emptyCellsXML" as="element()*"/>

<xsl:for-each select="1 to 81">
  <xsl:variable name="pos" select="." as="xs:integer"/>
  <xsl:choose>
   <xsl:when test="$emptyCellsXML[@index = $pos]/@possibleValues = 1">
    <xsl:sequence select="$emptyCellsXML[@index = $pos]/@values"/>
   </xsl:when>
   <xsl:otherwise>
    <xsl:sequence select="$board[$pos]"/>
   </xsl:otherwise>
  </xsl:choose>
</xsl:for-each>

</xsl:function>

<xsl:function name="fn:populateSingleValueCells" as="xs:integer+">
<xsl:param name="board" as="xs:integer+"/>

<xsl:variable name="emptyCells" select="for $x in (1 to 81) return $x[$board[$x] = 0]" as="xs:integer*"/>

<xsl:variable name="emptyCellsXML" as="element()*">
  <xsl:for-each select="$emptyCells">
   <xsl:variable name="allowedValues" select="fn:getAllowedValues($board, .)" as="xs:integer*"/>
   <cell index="{.}" possibleValues="{count($allowedValues)}" values="{$allowedValues}"/>
  </xsl:for-each>
</xsl:variable>

<xsl:choose>
  <xsl:when test="$emptyCellsXML/@possibleValues = 1">
   <xsl:variable name="newBoard" select="fn:populateSingleValueCells($board, $emptyCellsXML)" as="xs:integer+"/>
   <xsl:sequence select="fn:populateSingleValueCells($newBoard)"/>
  </xsl:when>
  <xsl:otherwise>
   <xsl:sequence select="$board"/>
  </xsl:otherwise>
</xsl:choose>

</xsl:function>

<xsl:function name="fn:solveSudoku" as="xs:integer+">
<xsl:param name="startBoard" as="xs:integer+"/>

<xsl:variable name="board" select="fn:populateSingleValueCells($startBoard)" as="xs:integer+"/>

<xsl:variable name="emptyCells" select="for $x in (1 to 81) return $x[$board[$x] = 0]" as="xs:integer*"/>

<xsl:variable name="emptyCellsXML" as="element()*">
  <xsl:for-each select="$emptyCells">
   <xsl:variable name="allowedValues" select="fn:getAllowedValues($board, .)" as="xs:integer*"/>
   <cell index="{.}" possibleValues="{count($allowedValues)}" values="{$allowedValues}"/>
  </xsl:for-each>
</xsl:variable>

<xsl:variable name="emptyCellsOrdered" as="xs:integer*">
  <xsl:for-each select="$emptyCellsXML">
   <xsl:sort select="@possibleValues" data-type="number" order="ascending"/>
   <xsl:sequence select="@index"/>
  </xsl:for-each>
</xsl:variable>

<xsl:variable name="endBoard" select="fn:populateValues($board, $emptyCells)" as="xs:integer*"/>

<xsl:choose>
  <xsl:when test="empty($endBoard)">
   <xsl:message>! Invalid board - The starting board is not correct</xsl:message>
   <xsl:sequence select="$startBoard"/>
  </xsl:when>
  <xsl:otherwise>
   <xsl:sequence select="$endBoard"/>
  </xsl:otherwise>
</xsl:choose>
</xsl:function>

<xsl:template match="/tt" name="maintt">
<div>
  <xsl:variable name="emptyCellsXML" as="element()*">
   <xsl:for-each select="for $x in (1 to 81) return $x[$board[$x] = 0]">
    <cell index="{.}" possibleValues="{count(fn:getAllowedValues($board, .))}" values="{fn:getAllowedValues($board, .)}"/>
   </xsl:for-each>
  </xsl:variable>

  <xsl:for-each select="$emptyCellsXML">
   <xsl:sort select="@possibleValues" data-type="number" order="ascending"/>
   <xsl:copy-of select="."/>
  </xsl:for-each>
</div>
</xsl:template>

<xsl:template match="/" name="main">
<xsl:call-template name="drawResult">
  <xsl:with-param name="board" select="fn:solveSudoku($board)"/>
</xsl:call-template>
</xsl:template>

<xsl:template name="drawResult">
<xsl:param name="board" as="xs:integer+"/>
<html>
  <head>
   <title>Sudoku - XSLT</title>
   <style>
    table { border-collapse: collapse;
    border: 1px solid black; }
    td { padding: 10px; }
    .norm { border-left: 1px solid #CCC;
      border-top: 1px solid #CCC;}
    .csep { border-left: 1px solid black; }
    .rsep { border-top: 1px solid black; }
   </style>
  </head>
  <body>
   <xsl:call-template name="drawBoard">
    <xsl:with-param name="board" select="$board"/>
   </xsl:call-template>
  </body>
</html>
</xsl:template>

<xsl:template name="drawBoard">
<xsl:param name="board" as="xs:integer+"/>
<table>
  <xsl:for-each select="1 to 9">
   <xsl:variable name="i" select="."/>
   <tr>
    <xsl:for-each select="1 to 9">
     <xsl:variable name="pos" select="(($i - 1) * 9) + ."/>
     <td class="{if (position() mod 3 = 1) then 'csep' else ('norm')} {if ($i mod 3 = 1) then 'rsep' else ('norm')}">
      <xsl:value-of select="$board[$pos]"/>
     </td>
    </xsl:for-each>
   </tr>
  </xsl:for-each>
</table>
</xsl:template>

<xsl:template name="drawBasicBoard">
<xsl:param name="board" as="xs:integer+"/>
<xsl:for-each select="1 to 9">
  <xsl:variable name="i" select="."/>

  <xsl:for-each select="1 to 9">
   <xsl:variable name="pos" select="(($i - 1) * 9) + ."/>
   <xsl:value-of select="$board[$pos]"/>
   <xsl:value-of select="if ($pos mod 3 = 0) then ',   ' else ', '"/>
  </xsl:for-each>

  <xsl:value-of select="if ($i mod 3 = 0) then '


' else '
'"/>
</xsl:for-each>
</xsl:template>

<!-- Easy board, 32 existing numbers -->
<xsl:variable name="testBoard1" select="(
0,2,0,  0,0,0,  0,3,6,
0,0,7,  4,0,0,  0,9,0,
0,0,5,  6,0,0,  0,4,8,

0,0,0,  9,3,0,  0,1,2,
2,9,0,  0,0,0,  0,7,5,
1,5,0,  0,8,2,  0,0,0,

6,7,0,  0,0,9,  1,0,0,
0,3,0,  0,0,7,  6,0,0,
4,8,0,  0,0,0,  0,2,0
)" as="xs:integer+"/>

<!-- Hard board, 24 existing numbers -->
<xsl:variable name="testBoard2" select="(
1,0,0,  5,6,0,  0,0,0,
9,0,0,  0,0,0,  2,0,8,
0,0,0,  0,0,0,  7,0,0,

0,8,0,  9,0,7,  0,0,2,
2,0,0,  0,0,0,  0,0,1,
6,0,0,  3,0,2,  0,4,0,

0,0,5,  0,0,0,  0,0,0,
4,0,3,  0,0,0,  0,0,9,
0,0,0,  0,4,1,  0,0,6
)" as="xs:integer+"/>

<!-- Extremely Hard board -->
<xsl:variable name="testBoard3" select="(
4,0,6,  7,8,0,  2,0,0,
0,5,7,  0,0,0,  0,0,0,
8,0,0,  0,0,0,  4,0,0,

0,0,0,  0,5,0,  0,9,0,
9,1,2,  0,0,0,  0,0,0,
0,4,0,  0,1,0,  0,0,3,

0,0,4,  3,0,0,  0,2,0,
7,0,3,  0,0,6,  0,0,0,
0,0,0,  5,0,7,  6,0,8
)" as="xs:integer+"/>

<!-- Fiendish board -->
<xsl:variable name="testBoard4" select="(
0,0,0,  0,0,5,  0,0,0,
0,0,0,  0,2,0,  9,0,0,
0,8,4,  9,0,0,  7,0,0,

2,0,0,  0,9,0,  4,0,0,
0,3,0,  6,0,2,  0,8,0,
0,0,7,  0,3,0,  0,0,6,

0,0,2,  0,0,9,  8,1,0,
0,0,6,  0,4,0,  0,0,0,
0,0,0,  5,0,0,  0,0,0
)" as="xs:integer+"/>

<!-- Fiendish 2 board -->
<xsl:variable name="testBoard5" select="(
0,0,0,  0,0,5,  1,0,0,
0,3,5,  0,0,0,  0,4,0,
8,0,0,  4,0,0,  0,2,0,

9,0,0,  0,3,0,  5,0,0,
0,0,0,  2,0,8,  0,0,0,
0,0,7,  0,9,0,  0,0,8,

0,5,0,  0,0,9,  0,0,2,
0,4,0,  0,0,0,  9,8,0,
0,0,1,  7,0,0,  0,0,0
)" as="xs:integer+"/>

<xsl:variable name="testBoard_Fiendish_060323" select="(
5,3,0,  0,9,0,  0,0,6,
0,0,0,  1,5,0,  0,0,3,
0,0,2,  0,0,0,  8,0,0,

0,0,0,  0,0,0,  0,8,0,
1,7,0,  0,4,0,  0,2,9,
0,9,0,  0,0,0,  0,0,0,

0,0,6,  0,0,0,  3,0,0,
4,0,0,  0,1,2,  0,0,0,
3,0,0,  0,6,0,  0,5,4
)" as="xs:integer+"/>

<!-- Fiendish 060403-->
<xsl:variable name="testBoard38" select="(
5,0,0, 0,0,1, 0,0,2,
0,6,0, 0,7,0, 0,0,0,
0,0,0, 6,0,0, 8,0,0,

0,0,3, 0,0,5, 0,0,8,
0,9,0, 0,1,0, 0,2,0,
2,0,0, 3,0,0, 7,0,0,

0,0,1, 0,0,2, 0,0,0,
0,0,0, 0,6,0, 0,9,0,
8,0,0, 7,0,0, 0,0,5
)" as="xs:integer+"/>

<!-- Failing board, an erroneous 9 has been added at index 1 -->
<xsl:variable name="testBoard_Fail" select="(
9,2,0,  0,0,0,  0,3,6,
0,0,7,  4,0,0,  0,9,0,
0,0,5,  6,0,0,  0,4,8,

0,0,0,  9,3,0,  0,1,2,
2,9,0,  0,0,0,  0,7,5,
1,5,0,  0,8,2,  0,0,0,

6,7,0,  0,0,9,  1,0,0,
0,3,0,  0,0,7,  6,0,0,
4,8,0,  0,0,0,  0,2,0
)" as="xs:integer+"/>

</xsl:stylesheet>

原创粉丝点击