[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] Sudoku - A solution in XSLT 2


Subject: Re: [xsl] Sudoku - A solution in XSLT 2
From: andrew welch <andrew.j.welch@xxxxxxxxx>
Date: Thu, 16 Feb 2006 14:18:42 +0000

> which means that fn:getGroup can be simplified to
>
> <xsl:function name="fn:getGroup" as="xs:integer+">
>         <xsl:param name="board" as="xs:integer+"/>
>         <xsl:param name="index" as="xs:integer"/>
>         <xsl:variable name="group" select="$groups[$index]"/>
>         <xsl:sequence select="$board[for $x in position()  return
$groups[$x]= $group]"/>
> </xsl:function>
>
>
> where $groups is a global variable
>
> <xsl:variable name="groups" select="(
> 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
> )" as="xs:integer+"/>

This is a great idea :) seems so obvious now....

Also, if you process the center cells first you reduce the processing
time considerably (by around a second in my simple tests).

Replace the solveSoduko function with this one (and implement Davids
suggestions):

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

	<!-- First process the center cells, then do the rest of the board -->
	<xsl:variable name="centerCells" select="for $x in 1 to 81 return
$x[$groups[$x] = 5]" as="xs:integer+"/>
	<xsl:variable name="theRest" select="for $x in 1 to 81 return
$x[$groups[$x] != 5]" as="xs:integer+"/>

	<xsl:variable name="emptyCells" select="for $x in (centerCells,
$theRest) return if ($startBoard[$x] = 0) then $x else ()"
as="xs:integer*"/>

	<xsl:variable name="endBoard" select="fn:populateValues($startBoard,
$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>

cheers
andrew


Current Thread