WeberDev.com PHP and MySQL Code

LOG IN
BEGINNER GUIDES  |  PHP CLASSES  |  CODE SEARCH  |  ARTICLES SEARCH  |  PHP FORUMS  |  PHP MANUAL  |  PHP FUNCTIONS LIST  |  WEB SITE TEMPLATES
Start typing to search for PHP and MySQL Code Snippets and Articles Search
Submit a code Example / Snippet Submit Your Code
Search Engine Optimization Monitor SEO Monitor
Web Site UpTime Monitor UpTime Monitor
WeberDev's Monthly code contest PHP Code Contest
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 Index
Web Development Resources
Web Development Content
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
Mobile Dev World

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 : 6214
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 
 

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
A database abstraction layer for the PHP 3.0 ODBC module. It supports persistent connections, fetching rows into arrays, prepare/execute (variable binding) and has a new and improved error interface.
Categories : Databases, PHP, Complete Programs
A simple script to count and report hits and the last modification time of an HTML page. Requires MySQL support (other DBs should work too, except possibly mSQL).
Categories : HTTP, MySQL, PHP, Databases
Scripts to build APACHE - PHP and SQL 7.0
Categories : PHP, Databases, MS SQL Server
DbObject - A PHP wrapper for working with various databases
Categories : Databases, PHP, PHP Classes
The Ajax Tree view class fetches data from a db for the requested parent category id. The data is then stored in an array and converted into JSON (Javascript Object Notation) format. This format is then used by JavaScript for populating tree view.
Categories : PHP, PHP Classes, Java Script, AJAX, Databases
create a grid out of <INPUT TYPE=TEXT> then saving to a database. Uses a 'multi-dimension array', but not really as the array is just one big array with the index of "[$i][$j]". Have a look at the code and you'll see what I mean.
Categories : PHP, MySQL, Arrays, Databases
Securing Web Forms with Simple PHP-CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart)
Categories : PHP, Security, GD image library, Sessions
How to access MS Excel spread sheets from PHP
Categories : PHP, Excel, ODBC, Databases
Password reminder
Categories : PHP, PHP Classes, Databases, MySQL, Mail
Website Engine
Categories : PHP, HTML and PHP, Templates
How to strip non-alpha characters from a string
Categories : Regexps, PHP
PHP Nested Menu Example - Shows how to make a single level nested menu
Categories : PHP, Navigation
ovrimos_close -- Closes the connection to ovrimos
Categories : PHP, PHP Functions, OvrimosSQL
Using PHP im HTML image tags
Categories : PHP, HTML and PHP, Graphics, Beginner Guides