WeberDev.com PHP and MySQL Code

LOG IN
BEGINNER GUIDESPHP CLASSESCODE SEARCHARTICLES SEARCHPHP FORUMSPHP MANUALPHP FUNCTIONS LISTWEB SITE TEMPLATES
Start typing to search for PHP and MySQL Code Snippets and Articles Search
Submit a code Example / Snippet Join us on FaceBook
Submit a code Example / Snippet Submit Your Code
Poker Tournaments Poker Tournaments
Poker Guide for Developers Poker Guide for Developers
Search Engine Optimization Monitor SEO Monitor
Web Site UpTime Monitor UpTime Monitor
Your Personal Examples List My Favorite Examples
Your Personal Articles List My Favorite Articles
Edit Account Info Update Your Profile
PHP Code Search
Web Development Forums
Learn MySQL Playing Trivia
PHPBB2 Templates
Web Development Resources
Web Development Content
Internet Security Software
PHPClasses
PHP Editor
PHP Jobs
Vision.To Design
Ajax Tutorials
PHP Programming Help
PHP/MySQL Programming
Webmaster Resources
Webmaster Forum
XML meta language
website builder
פרייסז - הכח לקנות עובר לידיים שלך
Texas Holdem Poker Evangelists

Go Back Add a Comment Send this example to a friend Add this Article to your personal favoritest for easy future access to your favorite Code Examples and Articles. Submit a code example Print this code example.
BACK ADD A COMMENT SEND TO A FRIEND ADD TO MY FAVORITES ADD CODE EXAMPLES PRINT
Title : The su doku solver in PHP
Categories : PHP, Games Click here to Update Your Picture
leaping langoor
Date : Oct 28th 2005
Grade : 4 of 5 (graded 4 times)
Viewed : 7394
File : 4243.zip
Images : No Images for this code example.
Search : More code by leaping langoor
Action : Grade This Code Example
Tools : My Examples List

Submit your own code examples  Submit your own code examples 
 

Finally the all awaited su doku solver in PHP. This is a release after quite a few attempts to convert my c++ logic algorithms to PHP. I ended up with a basic, not so complete script. It is right now a bit messy with all the HTML and Javascript, but never the less, it's there. If you make any updates on it please inform me about it.
Thank you,
leapinglangoor


<?php
/*************************************************************
** su doku solver
** Author: leapinglangoor[ http://leapinglangoor.phenominet.com ]
**
** Description inside
*************************************************************/
?>
<html>
<head>
<title>Sudoku Solver</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
body {
    font-family: Trebuchet MS, Arial, Helvetica, sans-serif;
    font-size: 10pt;
}

a {
    color: #D84519;
}

h1 {
    color: #D84519;
    font-size: 18pt;
    margin-bottom: 20px;
}

h2 {
    color: #306996;
    font-size: 16pt;
}

.indent {
    margin: -20px 0px 0px 20px;
}
.indentn {
    margin: 0px 0px 0px 20px;
}
.minih {
    margin: -20px 0px 0px 0px;
    font-size: 9pt;
    font-style: italic;
}
textarea {
    font-family: Trebuchet MS, Arial, Helvetica, sans-serif;
    font-size: 10pt;
    width: 90px    ;
    height: 180px;
    margin: 5px;
    margin-left: 20px;
}
select {
    font-family: Trebuchet MS, Arial, Helvetica, sans-serif;
    font-size: 10pt;
    width: 450px;
    margin: 5px;
    margin-left: 20px;
}

.h {
    font-size: 24px;
    font-weight: bold;
}

.s {
    font-size: 14px;
    font-weight: bold;
    margin-bottom: 3px;
}

.tag {
    font-style: italic;
    margin-bottom: 15px;
}

.help {
    margin: 18px;
    padding: 6px;
    border: 4px solid;
    border-color: #336699;
    background-color: #DCF0FF;
}

.old {
    margin-left: 20px;
    color: #808080;
}

.new {
    margin-left: 20px;
    font-weight: bold;
}

.del {
    margin-left: 20px;
    text-decoration: line-through;
    color: #D04040;
}

.gr {
    color: #D84519;
    font-size: 8pt;
    margin-left: 30px;
}

.jumpindent {
    margin-left: 30px;
    margin-bottom: 1em;
    background-color: #FFFFDD;
    border: 1px solid #CCCC99;
    padding: 5px;
}
</style>
</head>
<body>

<script type="text/javascript">
var puzzles = Array(".....5912\r\n4.3.1..8.\r\n5...726..\r\n.7.95...6\r\n9.8...1.4\r\n6...38.2.\r\n..748...5\r\n.5..6.3.1\r\n2615.....",
                    ".6.1.4.5.\r\n..83.56..\r\n2.......1\r\n8..4.7..6\r\n..6...31.\r\n7..9.1..4\r\n5.......2\r\n..72.69..\r\n.4.5.8.7.",
                    "2...1...4\r\n.3...521.\r\n.4.23....\r\n.5....1..\r\n3.8...5.6\r\n..7....3.\r\n....73.8.\r\n.269...4.\r\n8...6...1",
                    ".....7.3.\r\n2...456..\r\n..923..4.\r\n.......97\r\n3..7.1..4\r\n59.......\r\n.4..239..\r\n..267...3\r\n.6.8.....",
                    ".........\r\n..9.1832.\r\n7.45....1\r\n.6..3....\r\n.2.....4.\r\n....7..5.\r\n3....97.6\r\n.9516.8..\r\n.........");
                   
function samplePuzzle(n) {
    document.forms[0].elements[0].value = puzzles[n];
}
</script>

<h1>Sudoku Solver</h1>
<p class="minih">Copyright 2005 &copy; leapinglangoor(<a href="http://leapinglangoor.phenominet.com/">Math Crap</a>)</p>
<p>This is an attempt at a Sudoku solver, written in PHP. Sudoku puzzles are  9x9 grids of numbers, where the goal is to make every row, column, and 3x3 block inside the grid contain one of each digit. If you are so inclined, you can <a href="http://en.wikipedia.org/wiki/Sudoku">read more about Sudoku puzzles on Wikipedia</a>.</p>
<p>First, it is definitely worth mentioning that <span style="font-weight: bold">this solver is not at all complete!</span> There are many Sudoku puzzles that it cannot complete. This is because the solver works by using a limited number of logic algorithims. While it would be relatively simple to make a Sudoku solver that could solve any puzzle simple by guessing, that is not my goal. The point of this solver is to better understand how Sudoku puzzles work. Currently, there are only a few logic algorithims coded into the solver, so many puzzles will be unsolvable.</p>
<p>Click on a puzzle below to solve it. Alternatively, you can enter your own Sudoku puzzle into the solver. Just type the puzzle, line by line, into the textbox below. Use a period (or any other non-numeric character) to indicate unknown squares.</p>
<form method="post" action="sudoku.php">
<table cellpadding="0" cellspacing="0"><tr>
<td valign="top"><textarea name="puzzle" cols="11" rows="10" id="puzzle"><?php print $_REQUEST['puzzle']; ?></textarea></td>
<td valign="top" style="padding-left: 50px;">
<a href="javascript:samplePuzzle(0);">Easy Puzzle #1</a><br />
<a href="javascript:samplePuzzle(1);">Easy Puzzle #2</a><br />
<a href="javascript:samplePuzzle(2);">Medium Puzzle #1</a><br />
<a href="javascript:samplePuzzle(3);">Medium Puzzle #2</a><br />
<a href="javascript:samplePuzzle(4);">Hard Puzzle #1</a></td>
</table>
<p><input type="submit" name="Submit" value="Solve" /></p>
</form>
<?php
function apply_elimination() {
    global
$matrix, $howmany, $didelim; $changed = false;
   
// * * * * *
    // NUMBER ELIMINATION
    //    In this phase, we go through each square and eliminate the value of that square from the row, column, and 3x3 block
    //    that square shares. For example, if we are given a 2 in square (1, 1) then we rule out 2 as a potential solution for
    //    any of the other squares in the first column, any of the other squares in the first row, and any of the other squares
    //    in the first 3x3 block.
   
   
for ($r = 1; $r < 10; $r++)
    for (
$c = 1; $c < 10; $c++) {
       
$thevalue = $matrix[$r][$c];
        if (!
is_array($thevalue)) {
           
// only eliminate once for each square
           
if (in_array("($r, $c)", $didelim)) continue; array_push($didelim, "($r, $c)");
           
           
$block_startrow = $r - (($r - 1) % 3); $block_startcol = $c - (($c - 1) % 3);
            print
"($r, $c) is a $thevalue, so no other square in row $r, column $c, or block " . (1+(($block_startrow - 1) / 3)*3 + (($block_startcol - 1) / 3)) . " is a $thevalue<br />"; $thiselim = true;
           
           
// eliminate the value from other squares in this row
           
for ($x = 1; $x < 10; $x++)
                if (
is_array($matrix[$x][$c])) {
                   
$location = array_search($thevalue, $matrix[$x][$c]);
                    if (
$location !== false) array_splice($matrix[$x][$c], $location, 1);
                    if (
count($matrix[$x][$c]) == 1) {
                       
$changed = true;
                       
$thenewvalue = $matrix[$x][$c][0];
                       
$matrix[$x][$c] = $thenewvalue;
                        print
"($x, $c) only has one remaining possibility, $thenewvalue <span class=\"gr\">(" . --$howmany . " squares to go)</span><br />";
                        if (
$howmany == 0) return false;
                    }
                }
               
           
// eliminate the value from other squares in this column
           
for ($x = 1; $x < 10; $x++)
                if (
is_array($matrix[$r][$x])) {
                   
$location = array_search($thevalue, $matrix[$r][$x]);
                    if (
$location !== false) array_splice($matrix[$r][$x], $location, 1);
                    if (
count($matrix[$r][$x]) == 1) {
                       
$changed = true;
                       
$thenewvalue = $matrix[$r][$x][0];
                       
$matrix[$r][$x] = $thenewvalue;
                        print
"($r, $x) only has one remaining possibility, $thenewvalue<span class=\"gr\">(" . --$howmany . " squares to go)</span><br />";
                        if (
$howmany == 0) return false;
                    }
                }
           
           
// eliminate the value from other squares in this 3x3 block
           
for ($x = $block_startrow; $x < $block_startrow + 3; $x++)
            for (
$y = $block_startcol; $y < $block_startcol + 3; $y++)
                if (
is_array($matrix[$x][$y])) {
                   
$location = array_search($thevalue, $matrix[$x][$y]);
                    if (
$location !== false) array_splice($matrix[$x][$y], $location, 1);
                    if (
count($matrix[$x][$y]) == 1) {
                       
$changed = true;
                       
$thenewvalue = $matrix[$x][$y][0];
                       
$matrix[$x][$y] = $thenewvalue;
                        print
"($x, $y) only has one remaining possibility, $thenewvalue<span class=\"gr\">(" . --$howmany . " squares to go)</span><br />";
                        if (
$howmany == 0) return false;
                    }
                }
        }
    }
    return
$changed;
}

function
apply_placement() {
    global
$matrix, $howmany; $changed = false;
    print
"<br /><b>Number Placement</b><br />";
   
// * * * * *
    // NUMBER PLACEMENT
    //    In this phase, we go through each row/column/block and try to add the numbers that are missing when we count from 1 to 9.
    //    If any number from 1 to 9 is missing from the row/column/block, and there is only one possibility of where to place it,
    //    add the number.
   
    // check rows
   
for ($r = 1; $r < 10; $r++)
       
// check each number from 1 to 9
       
for ($value = 1; $value < 10; $value++) {
           
$where = array();
           
           
// stop if this number is already somewhere in this row
           
$abort = false;
            for (
$c = 1; $c < 10; $c++)
                if (!
is_array($matrix[$r][$c]) && $matrix[$r][$c] == $value)
                   
$abort = true;
           
            if (!
$abort) {
               
// the number is not in this row, but it does need to be
                // list all of the possible places where the number could appear in this row
               
for ($c = 1; $c < 10; $c++)
                    if (
is_array($matrix[$r][$c]) && in_array($value, $matrix[$r][$c])) array_push($where, array($r, $c));
                   
               
// add the number if there is only one possibility
               
if (count($where) == 1) {
                   
$changed = true;
                    list(
$where_r, $where_c) = array_pop($where);
                   
$matrix[$where_r][$where_c] = $value;
                    print
"($where_r, $where_c) is the only possible place for the $value in row $r<span class=\"gr\">(" . --$howmany . " squares to go)</span><br />";
                    if (
$howmany == 0) return false;
                    print
'<div class="jumpindent">'; apply_elimination(); print '</div>';
                }
            }
        }
       
   
// check columns
   
for ($c = 1; $c < 10; $c++)
       
// check each number from 1 to 9
       
for ($value = 1; $value < 10; $value++) {
           
$where = array();
           
           
// stop if this number is already somewhere in this row
           
$abort = false;
            for (
$r = 1; $r < 10; $r++)
                if (!
is_array($matrix[$r][$c]) && $matrix[$r][$c] == $value)
                   
$abort = true;
           
            if (!
$abort) {
               
// the number is not in this column, but it does need to be
                // list all of the possible places where the number could appear in this column
               
for ($r = 1; $r < 10; $r++)
                    if (
is_array($matrix[$r][$c]) && in_array($value, $matrix[$r][$c])) array_push($where, array($r, $c));
                   
               
// add the number if there is only one possibility
               
if (count($where) == 1) {
                   
$changed = true;
                    list(
$where_r, $where_c) = array_pop($where);
                   
$matrix[$where_r][$where_c] = $value;
                    print
"($where_r, $where_c) is the only possible place for the $value in column $c<span class=\"gr\">(" . --$howmany . " squares to go)</span><br />";
                    if (
$howmany == 0) return false;
                    print
'<div class="jumpindent">'; apply_elimination(); print '</div>';
                }
            }
        }

   
   
// check 3x3 blocks
   
for ($r = 0; $r < 3; $r++)
    for (
$c = 0; $c < 3; $c++)
       
// check each number from 1 to 9
       
for ($value = 1; $value < 10; $value++) {
           
$where = array();
           
           
// stop if this number is already somewhere in this block
           
$abort = false;
            for (
$rr = 1+$r*3; $rr < 4+$r*3; $rr++)
            for (
$cc = 1+$c*3; $cc < 4+$c*3; $cc++)
                if (!
is_array($matrix[$rr][$cc]) && $matrix[$rr][$cc] == $value)
                   
$abort = true;
           
            if (!
$abort) {
               
// the number is not in this 3x3 block, but it does need to be
                // list all of the possible places where the number could appear in this block
               
for ($rr = 1+$r*3; $rr < 4+$r*3; $rr++)
                for (
$cc = 1+$c*3; $cc < 4+$c*3; $cc++)
                    if (
is_array($matrix[$rr][$cc]) && in_array($value, $matrix[$rr][$cc])) array_push($where, array($rr, $cc));
                   
               
// add the number if there is only one possibility
               
if (count($where) == 1) {
                   
$changed = true;
                    list(
$where_r, $where_c) = array_pop($where);
                   
$matrix[$where_r][$where_c] = $value;
                    print
"($where_r, $where_c) is the only possible place for the $value in block " . (1+$r*3 + $c) . "<span class=\"gr\">(" . --$howmany . " squares to go)</span><br />";
                    if (
$howmany == 0) return false;
                    print
'<div class="jumpindent">'; apply_elimination(); print '</div>';
                   
                } else {
                   
$whererows = array(); $wherecols = array();
                    foreach (
$where as $w) {
                        list(
$temp_r, $temp_c) = $w;
                       
array_push($whererows, $temp_r); array_push($wherecols, $temp_c);
                    }
                   
$urows = array_unique($whererows); $ucols = array_unique($wherecols);
                   
                   
// are all the possibilities for this value in this block in the same row?
                   
if (count($urows) == 1) {
                       
$therow = array_pop($urows);
                       
$othercols = array_diff(range(1, 9), $ucols);
                        foreach (
$othercols as $thecol) {
                            if (
is_array($matrix[$therow][$thecol])) {
                               
$location = array_search($value, $matrix[$therow][$thecol]);
                                if (
$location !== false) {
                                   
$changed = true;
                                   
array_splice($matrix[$therow][$thecol], $location, 1);
                                    print
"($therow, $thecol) is not a $value because the $value in that row must be in block " . (1+$r*3 + $c) . "<br />";
                                }
                               
                                if (
count($matrix[$therow][$thecol]) == 1) {
                                   
$changed = true;
                                   
$thenewvalue = $matrix[$therow][$thecol][0];
                                   
$matrix[$therow][$thecol] = $thenewvalue;
                                    print
"($therow, $thecol) only has one remaining possibility, $thenewvalue <span class=\"gr\">(" . --$howmany . " squares to go)</span><br />";
                                    if (
$howmany == 0) return false;
                                    print
'<div class="jumpindent">'; apply_elimination(); print '</div>';
                                }
                            }
                        }
                    }
                   
                   
// are all the possibilities for this value in this block in the same column?
                   
if (count($ucols) == 1) {                       
                       
$thecol = array_pop($ucols);
                       
$otherrows = array_diff(range(1, 9), $urows);
                        foreach (
$otherrows as $therow) {
                            if (
is_array($matrix[$therow][$thecol])) {
                               
$location = array_search($value, $matrix[$therow][$thecol]);
                                if (
$location !== false) {
                                   
$changed = true;
                                   
array_splice($matrix[$therow][$thecol], $location, 1);
                                    print
"($therow, $thecol) is not a $value because the $value in that column must be in block " . (1+$r*3 + $c) . "<br />";
                                }
                               
                                if (
count($matrix[$therow][$thecol]) == 1) {
                                   
$changed = true;
                                   
$thenewvalue = $matrix[$therow][$thecol][0];
                                   
$matrix[$therow][$thecol] = $thenewvalue;
                                    print
"($therow, $thecol) only has one remaining possibility, $thenewvalue <span class=\"gr\">(" . --$howmany . " squares to go)</span><br />";
                                    if (
$howmany == 0) return false;
                                    print
'<div class="jumpindent">'; apply_elimination(); print '</div>';
                                }
                            }
                        }
                    }
                }
            }
        }
   
    return
$changed;           
}

function
apply_locked_pairing() {
    global
$matrix, $howmany; $changed = false;
    print
"<br /><b>Locked Pairing</b><br />";
   
// * * * * *
    // LOCKED PAIRING
    //    If X squares in a row/column/block all share an identical set of X possibilities, exclude these possibilities
    //    from the other squares in the same row/column/block.
   
    // check rows
   
for ($r = 1; $r < 10; $r++) {
       
// compile an array of the possibilities for each square in this row
       
$rowpossibilities = array();
        for (
$c = 1; $c < 10; $c++)
            if (
is_array($matrix[$r][$c])) $rowpossibilities[ serialize($matrix[$r][$c]) ]++;
           
        foreach (
$rowpossibilities as $tp_serialize => $tp_count) {
           
$tp_array = unserialize($tp_serialize);
            if (
$tp_count > 1 && $tp_count == count($tp_array)) {               
                for (
$c = 1; $c < 10; $c++)
                    if (
is_array($matrix[$r][$c]) && $matrix[$r][$c] !== $tp_array) {
                        foreach (
$tp_array as $tp) {
                           
$location = array_search($tp, $matrix[$r][$c]);
                            if (
$location !== false) {
                               
$changed = true;
                               
array_splice($matrix[$r][$c], $location, 1);
                                print
"($r, $c) is not $tp because the $tp in row $r is locked in a $tp_count-square pairing<br />";
                            }
                        }
                       
                        if (
count($matrix[$r][$c]) == 1) {
                           
$changed = true;
                           
$thenewvalue = $matrix[$r][$c][0];
                           
$matrix[$r][$c] = $thenewvalue;
                            print
"($r, $c) only has one remainig possibility, $thenewvalue <span class=\"gr\">(" . --$howmany . " squares to go)</span><br />";
                            if (
$howmany == 0) return false;
                            print
'<div class="jumpindent">'; apply_elimination(); print '</div>';
                        }
                    }
            }
        }
    }
   
   
// check columns
   
for ($c = 1; $c < 10; $c++) {
       
// compile an array of the possibilities for each square in this column
       
$columnpossibilities = array();
        for (
$r = 1; $r < 10; $r++)
            if (
is_array($matrix[$r][$c])) $columnpossibilities[ serialize($matrix[$r][$c]) ]++;
           
        foreach (
$columnpossibilities as $tp_serialize => $tp_count) {
           
$tp_array = unserialize($tp_serialize);
            if (
$tp_count > 1 && $tp_count == count($tp_array)) {               
                for (
$r = 1; $r < 10; $r++)
                    if (
is_array($matrix[$r][$c]) && $matrix[$r][$c] !== $tp_array) {
                        foreach (
$tp_array as $tp) {
                           
$location = array_search($tp, $matrix[$r][$c]);
                            if (
$location !== false) {
                               
$changed = true;
                               
array_splice($matrix[$r][$c], $location, 1);
                                print
"($r, $c) is not $tp because the $tp in column $c is locked in a $tp_count-square pairing<br />";
                            }
                        }
                       
                        if (
count($matrix[$r][$c]) == 1) {
                           
$changed = true;
                           
$thenewvalue = $matrix[$r][$c][0];
                           
$matrix[$r][$c] = $thenewvalue;
                            print
"($r, $c) only has one remaining possibility, $thenewvalue <span class=\"gr\">(" . --$howmany . " squares to go)</span><br />";
                            if (
$howmany == 0) return false;
                            print
'<div class="jumpindent">'; apply_elimination(); print '</div>';
                        }
                    }
            }
        }
    }

   
// check 3x3 blocks
   
for ($r = 0; $r < 3; $r++)
    for (
$c = 0; $c < 3; $c++) {
       
// compile an array of the possibilities for each square in this 3x3 block
       
$blockpossibilities = array();
        for (
$rr = 1+$r*3; $rr < 4+$r*3; $rr++)
        for (
$cc = 1+$c*3; $cc < 4+$c*3; $cc++)
            if (
is_array($matrix[$rr][$cc])) $blockpossibilities[ serialize($matrix[$rr][$cc]) ]++;
           
        foreach (
$blockpossibilities as $tp_serialize => $tp_count) {
           
$tp_array = unserialize($tp_serialize);
            if (
$tp_count > 1 && $tp_count == count($tp_array)) {               
                for (
$rr = 1+$r*3; $rr < 4+$r*3; $rr++)
                for (
$cc = 1+$c*3; $cc < 4+$c*3; $cc++)
                    if (
is_array($matrix[$rr][$cc]) && $matrix[$rr][$cc] !== $tp_array) {
                        foreach (
$tp_array as $tp) {
                           
$location = array_search($tp, $matrix[$rr][$cc]);
                            if (
$location !== false) {
                               
$changed = true;
                               
array_splice($matrix[$rr][$cc], $location, 1);
                                print
"($rr, $cc) is not $tp because the $tp in block " . (1+$r*3 + $c) . " is locked in a $tp_count-square pairing<br />";
                            }
                        }
                       
                        if (
count($matrix[$rr][$cc]) == 1) {
                           
$changed = true;
                           
$thenewvalue = $matrix[$rr][$cc][0];
                           
$matrix[$rr][$cc] = $thenewvalue;
                            print
"($rr, $cc) only has one remaining possibility, $thenewvalue <span class=\"gr\">(" . --$howmany . " squares to go)</span><br />";
                            if (
$howmany == 0) return false;
                            print
'<div class="jumpindent">'; apply_elimination(); print '</div>';
                        }
                    }
            }
        }
    }
   
    return
$changed;           
}

function
apply_hidden_pairing() {
    global
$matrix, $howmany; $changed = false;
    print
"<br /><b>Hidden Pairing</b><br />";
   
// * * * * *
    // HIDDEN PAIRING
    //    If X possibilities exist in only X squares in a row/column/block, exclude any other possibilities from these X squares.
   
    // check rows
   
for ($r = 1; $r < 10; $r++) {
       
// compile an array of each number and its locations in this row
       
$location = array();
        for (
$c = 1; $c < 10; $c++)
            if (
is_array($matrix[$r][$c]))
                foreach (
$matrix[$r][$c] as $value) {
                    if (!
$location[$value]) $location[$value] = array();
                   
array_push($location[$value], "($r, $c)");
                }
       
       
        foreach (
$location as $tp_number => $tp_locations)
        foreach (
$location as $tp_number2 => $tp_locations2) {
            if (
$tp_number >= $tp_number2) continue;
           
$combined = array_count_values(array_merge($tp_locations, $tp_locations2));
            if (
count(array_unique($combined)) == 1 && array_shift($combined) == 2) {
               
$int = array_intersect($location[$tp_number], $location[$tp_number2]);
                if (
count($int) == 2) {
                    print
"hidden pair in row $r: $tp_number and $tp_number2<br>";
                    foreach (
$location[$tp_number] as $square) {
                       
$square_r = substr($square, 1, 1); $square_c = substr($square, 4, 1);
                        if (
$matrix[$square_r][$square_c] !== array($tp_number, $tp_number2)) {
                        print
"($square_r, $square_c) is either $tp_number or $tp_number2 because these numbers are locked in a 2-square pairing<br />";
                       
$matrix[$square_r][$square_c] = array($tp_number, $tp_number2); }
                    }
                }
            }
        }
    }
   
   
// check columns
   
for ($c = 1; $c < 10; $c++) {
       
// compile an array of each number and its locations in this column
       
$location = array();
        for (
$r = 1; $r < 10; $r++)
            if (
is_array($matrix[$r][$c]))
                foreach (
$matrix[$r][$c] as $value) {
                    if (!
$location[$value]) $location[$value] = array();
                   
array_push($location[$value], "($r, $c)");
                }
       
       
        foreach (
$location as $tp_number => $tp_locations)
        foreach (
$location as $tp_number2 => $tp_locations2) {
            if (
$tp_number >= $tp_number2) continue;
           
$combined = array_count_values(array_merge($tp_locations, $tp_locations2));
            if (
count(array_unique($combined)) == 1 && array_shift($combined) == 2) {
               
$int = array_intersect($location[$tp_number], $location[$tp_number2]);
                if (
count($int) == 2) {
                    print
"hidden pair in column $c: $tp_number and $tp_number2<br>";
                    foreach (
$location[$tp_number] as $square) {
                       
$square_r = substr($square, 1, 1); $square_c = substr($square, 4, 1);
                        if (
$matrix[$square_r][$square_c] !== array($tp_number, $tp_number2)) {
                        print
"($square_r, $square_c) is either $tp_number or $tp_number2 because these numbers are locked in a 2-square pairing<br />";
                       
$matrix[$square_r][$square_c] = array($tp_number, $tp_number2); }
                    }
                }
            }
        }
    }
   
    return
$changed;
}

function
apply_fish_cycles() {
    global
$matrix, $howmany; $changed = false;
    print
"<br /><b>&quot;X-Wings&quot;</b><br />";
   
// * * * * *
    // FISH CYCLES
    //    If X possibilities exist in only X squares in a row/column/block, exclude any other possibilities from these X squares.
   
    // check rows
   
$location = array();
    for (
$r = 1; $r < 10; $r++)
    for (
$c = 1; $c < 10; $c++)
        if (
is_array($matrix[$r][$c]))
            foreach (
$matrix[$r][$c] as $value) {
                if (!
$location[$r][$value]) $location[$r][$value] = array();
               
array_push($location[$r][$value], $c);
            }
    for (
$r = 1; $r < 10; $r++) {
        for (
$value = 1; $value < 10; $value++) {
            if (
$location[$r][$value] && count($location[$r][$value]) == 2) {
                for (
$rr = 1; $rr < 10; $rr++) {
                    if (
$r >= $rr) continue;
                    if (!
$location[$rr][$value]) continue;
                   
$i = array_intersect($location[$r][$value], $location[$rr][$value]);
                    if (
count($i) == 2 && count($location[$rr][$value]) == 2) {
                        print
"$value appears in the same columns in rows $r and $rr<br />";
                        for (
$x = 1; $x < 10; $x++) {
                            if (
$x == $r || $x == $rr) continue;
                            if (
is_array($matrix[$x][ $location[$r][$value][0] ])) {
                               
$pos = array_search($value, $matrix[$x][ $location[$r][$value][0] ]);
                                if (
$pos !== false) {
                                   
$changed = true;
                                   
array_splice($matrix[$x][ $location[$r][$value][0] ], $pos, 1);
                                    print
"($x, {$location[$r][$value][0]}) is not $value because the $value in that column is in either ($r, {$location[$r][$value][0]}) or ($rr, {$location[$r][$value][0]})<br />";
                                }
                            }
                        }
                        for (
$x = 1; $x < 10; $x++) {
                            if (
$x == $r || $x == $rr) continue;
                            if (
is_array($matrix[$x][ $location[$r][$value][1] ])) {
                               
$pos = array_search($value, $matrix[$x][ $location[$r][$value][1] ]);
                                if (
$pos !== false) {
                                   
$changed = true;
                                   
array_splice($matrix[$x][ $location[$r][$value][1] ], $pos, 1);
                                    print
"($x, {$location[$r][$value][1]}) is not $value because he $value in that column is in either ($r, {$location[$r][$value][1]}) or ($rr, {$location[$r][$value][1]})<br />";
                                }
                            }
                        }
                    }
                }
            }
        }
    }
   
   
// check columns
   
$location = array();
    for (
$r = 1; $r < 10; $r++)
    for (
$c = 1; $c < 10; $c++)
        if (
is_array($matrix[$r][$c]))
            foreach (
$matrix[$r][$c] as $value) {
                if (!
$location[$c][$value]) $location[$c][$value] = array();
               
array_push($location[$c][$value], $r);
            }
    for (
$c = 1; $c < 10; $c++) {
        for (
$value = 1; $value < 10; $value++) {
            if (
$location[$c][$value] && count($location[$c][$value]) == 2) {
                for (
$cc = 1; $cc < 10; $cc++) {
                    if (
$c >= $cc) continue;
                    if (!
$location[$cc][$value]) continue;
                   
$i = array_intersect($location[$c][$value], $location[$cc][$value]);
                    if (
count($i) == 2 && count($location[$cc][$value]) == 2) {
                        print
"$value appears in the same rows in columns $c and $cc<br />";
                        for (
$x = 1; $x < 10; $x++) {
                            if (
$x == $c || $x == $cc) continue;
                            if (
is_array($matrix[ $location[$c][$value][0] ][$x])) {
                               
$pos = array_search($value, $matrix[ $location[$c][$value][0] ][$x]);
                                if (
$pos !== false) {
                                   
$changed = true;
                                   
array_splice($matrix[ $location[$c][$value][0] ][$x], $pos, 1);
                                    print
"({$location[$c][$value][0]}, $x) is not $value because the $value in that row is in either ({$location[$c][$value][0]}, $c) or ({$location[$c][$value][0]}, $cc)<br />";
                                }
                            }
                        }
                        for (
$x = 1; $x < 10; $x++) {
                            if (
$x == $c || $x == $cc) continue;
                            if (
is_array($matrix[ $location[$c][$value][1] ][$x])) {
                               
$pos = array_search($value, $matrix[ $location[$c][$value][1] ][$x]);
                                if (
$pos !== false) {
                                   
$changed = true;
                                   
array_splice($matrix[ $location[$c][$value][1] ][$x], $pos, 1);
                                    print
"({$location[$c][$value][1]}, $x) is not $value because the $value in that row is in either ({$location[$c][$value][1]}, $c) or ({$location[$c][$value][1]}, $cc)<br />";
                                }
                            }
                        }
                    }
                }
            }
        }
    }
   
    return
$changed;
}

function
display() {
    global
$matrix, $given;
    print
'<table border="0" cellpadding="0" cellspacing="2">';
    for (
$r = 1; $r < 10; $r++) {
        print
'<tr>';
        for (
$c = 1; $c < 10; $c++) {
           
// shade and bold the boxes with the givens
           
$styleextra = ($given[$r][$c] ? ' background-color: #DDDDFF; font-weight: bold;' : '');
           
           
// provide extra space so the 3x3 regions are easier to see
           
$styleextra .= ($r == 4 || $r == 7 ? ' margin-top: 8px;' : '');
           
$styleextra .= ($c == 4 || $c == 7 ? ' margin-left: 8px;' : '');
           
           
$display = (is_array($matrix[$r][$c]) ? '<acronym title="' . join($matrix[$r][$c], ' or ') . '">(?)</acronym>' : $matrix[$r][$c]);
            print
'<td><div style="width: 30px; height: 25px; border: 1px solid #BBBBDD; text-align: center; font-size: 10pt; padding-top: 5px;' . $styleextra . '">' . $display . '</a></div></td>';
        }
        print
'</tr>';
    }
    print
'</table>';
}

if (
$_REQUEST['puzzle']) {
   
// load
   
$matrix = array(); $given = array(); $didelim = array(); $howmany = 81; $row = 0;
   
$rows = explode("\r\n", $_REQUEST['puzzle']);
    foreach (
$rows as $r) {
       
$row++; $colcount strlen($r);
        for (
$col = 0; $col < $colcount; $col++) {
           
$t = substr($r, $col, 1);
            if (!
in_array($t, range(1, 9))) {
               
$matrix[$row][($col+1)] = range(1, 9);
            } else {
$matrix[$row][($col+1)] = $t; $given[$row][($col+1)] = true; $howmany--; }
        }
    }
   
   
// solve
   
$starttime = microtime(1);
   
ob_start();
   
    print
"<br /><b>Number Elimination</b><br />";
   
apply_elimination();
    do {
       
$c1 = apply_placement(); if ($howmany == 0) break;
       
$c2 = apply_locked_pairing(); if ($howmany == 0) break;
       
$c3 = apply_hidden_pairing(); if ($howmany == 0) break;
       
$c4 = apply_fish_cycles(); if ($howmany == 0) break;
       
$changes = $c1 || $c2 || $c3 || $c4;
    } while (
$changes == true);
   
$endtime = microtime(1);
   
$timetaken = $endtime - $starttime;
   
   
// display
   
print '<br/>' . ($howmany == 0 ? 'Solved in ' : 'Partially solved, still ' . $howmany  . ' squares to go after ') . number_format($timetaken * 1000) . ' ms<br />';
   
display();
}
?>
</body>
</html>



Query2Report : Generating Html, Pdf and Csv Reports from SQL Query
Categories : PHP, PHP, HTML, PDF, Excel
Boolean Keyword Interpreter
Categories : PHP, Algorithms, Search Engines
Finds files on your site, uses UNIX find command.
Categories : Complete Programs, Filesystem, PHP
.htpassword manager for apache
Categories : PHP, PHP Classes, Authentication, Apache
How to Create a Shoutbox Using PHP & MySQL
Categories : PHP, MySQL, Web Applications, Beginner Guides, HTML and PHP
Sessions and -enable-trans-sid
Categories : PHP, PHP Configuration, PHP Options and Info, Sessions
Freshmeat.net XML-RPC - This class is meant to query Freshmeat for information about registered projects.
Categories : PHP, PHP Classes, XML, Web Services
A class for sending email; it has support for To:, Cc:, Bcc: and Reply-To: headers. It requires that you have sendmail installed.
Categories : Email, PHP Classes, PHP
day and week grid with clickable fields on/off and possibility to insert in DB
Categories : PHP, Java Script, CSS
Identify and log search engine access (spiders, robots, etc.) to a page.
Categories : HTTP, Environment Variables, PHP, MySQL, Databases
Image Cache
Categories : Graphics, PHP Classes, PHP
How to get the exit code and result of an exec() command.
Categories : PHP, Network
Validating a URL with preg_match
Categories : PHP, Regexps, Beginner Guides, Data Validation
Gets the browser and OS from the $_SERVER['http_user_agent'] variable in PHP
Categories : PHP, HTTP, Regexps
GoTemplate
Categories : PHP, Complete Programs, Templates