Skip to content

Instantly share code, notes, and snippets.

@DrAzraelTod
Created June 25, 2012 12:12
Show Gist options
  • Save DrAzraelTod/2988245 to your computer and use it in GitHub Desktop.
Save DrAzraelTod/2988245 to your computer and use it in GitHub Desktop.
Ich durfte vor langer Zeit mal einen Tag an Sudokus rumbasteln und versuchen welche zu generieren/lösen, das ist was dabei rausgekommen ist
<html>
<head>
<style type="text/css">
table.sudoku {
border-collapse: collapse;
border-bottom: 1px solid red;
border-right: 1px solid red;
}
table.sudoku td {
width: 20px;
height: 20px;
text-align: center;
}
table.sudoku td.invalid {
background-color: black;
color: white;
}
table.sudoku tr:nth-child(3n+1) {
border-top: 1px solid red;
}
table.sudoku tr td:nth-child(3n+1) {
border-left: 1px solid red;
}
</style>
</head>
<body>
<?php
//header('Content-Type: text/plain');
function get_empty_array() {
$in = array();
for ($i = 0; $i < 9; $i++) {
$in[$i] = array();
for ($j = 0; $j < 9; $j++) {
$in[$i][$j] = ' ';
}
}
return $in;
}
function get_basic_array() {
$in = array(
array(1,2,3,4,5,6,7,8,9),
array(4,5,6,7,8,9,1,2,3),
array(7,8,9,1,2,3,4,5,6),
array(3,4,5,6,7,8,9,1,2),
array(6,7,8,9,1,2,3,4,5),
array(9,1,2,3,4,5,6,7,8),
array(2,3,4,5,6,7,8,9,1),
array(5,6,7,8,9,1,2,3,4),
array(8,9,1,2,3,4,5,6,7),
);
return $in;
}
function generate_by_line_switching($iterations = 1000, $in = null) {
if (!is_array($in)) {
$in = get_basic_array();
}
for ($i = 0; $i < $iterations; $i++) {
$block = rand(0,2);
$line_1 = $block*3+rand(0,2);
$line_2 = $block*3+rand(0,2);
$f = round(rand(0,1));
if ($f > 0) {
$in = switch_col($in, $line_1, $line_2);
} else {
$in = switch_row($in, $line_1, $line_2);
}
}
return $in;
}
function switch_col($in, $l1, $l2) {
foreach ($in as $i => $row) {
$temp = $row[$l1];
$row[$l1] = $row[$l2];
$row[$l2] = $temp;
$in[$i] = $row;
}
return $in;
}
function switch_row($in, $l1, $l2) {
$temp = $in[$l1];
$in[$l1] = $in[$l2];
$in[$l2] = $temp;
return $in;
}
function pretty_output($a, $dont_print = false, &$valid = true) {
$valid = true;
$lines = array();
$ret = '<table class="sudoku"><tr>';
foreach ($a as $i => $col) {
foreach ($col as $j => $row) {
$field_valid = validate_field($a, $i, $j);
$class = $field_valid ? 'valid' : 'invalid';
$valid &= $field_valid;
$lines[$i] .= '<td class="'.$class.'">'.$row.'</td>';
}
}
$ret .= implode($lines, "</tr><tr>");
$ret .= '</table>';
if (!$dont_print) {
echo $ret;
}
return $ret;
}
function validate_field($in, $x, $y) {
if (!validate_row($in, $x)) return false;
if (!validate_col($in, $y)) return false;
if (!validate_block($in, $x, $y)) return false;
return true;
}
function validate_row($in, $x) {
return validate_sth($in[$x]);
}
function validate_sth($numbers) {
$test = array(1,1,1,1,1,1,1,1,1,1);
$i = 0;
foreach ($numbers as $val) {
$i++;
if ($val != ' ') {
if ($test[$val] == 1) {
$test[$val] = 0;
} else {
return false;
}
}
}
return true;
}
function validate_col($in, $y) {
$sth = array();
foreach ($in as $line) {
$sth[] = $line[$y];
}
return validate_sth($sth);
}
function validate_block($in, $x, $y) {
$x1 = $x - ($x % 3);
$y1 = $y - ($y % 3);
$sth = array();
for ($i = 0; $i < 3; $i++) {
for ($j = 0; $j < 3; $j++) {
$sth[] = $in[$x1+$i][$y1+$j];
}
}
debug($sth);
return validate_sth($sth);
}
function validate_sudoku($s) {
foreach ($s as $x => $row) {
foreach ($row as $y => $val) {
if (!validate_field($s, $x, $y)) {
return false;
}
}
}
return true;
}
function debug($obj) {
global $debug;
if ($debug) {
echo '<pre>'.print_r($obj,1)."</pre>\n";
}
}
function get_valid_number($s,$x,$y) {
$test = array(1,2,3,4,5,6,7,8,9);
$found = $s[$x][$y];
while ($found == ' ' && count($test) > 0) {
$c = rand(0,count($test)-1);
$v = $test[$c];
unset($test[$c]);
$test = array_merge($test,array());
$s[$x][$y] = $v;
if (validate_field($s,$x,$y)) {
$found = $v;
}
}
return $found;
}
function generate_by_solving() {
$r = true;
while($r) {
$s = get_empty_array();
$r = false;
for ($i = 0; $i < 81; $i++) {
$x = rand(0,8);
$y = rand(0,8);
$x = $i % 9;
$y = floor($i / 9);
$number = get_valid_number($s,$x,$y);
if ($number === ' ') {
$r = true;
break 1;
}
$s[$x][$y] = $number;
}
}
return $s;
}
$in = get_basic_array();
pretty_output($in);
echo "<br /><br />";
$s = generate_by_line_switching(10, $in);
$s[2][2] = 9;
$valid = true;
pretty_output($s, false, $valid);
echo '<p>Sudoku was '.($valid ? 'valid' : 'invalid').'</p>';
$s = generate_by_solving(10, $in);
pretty_output($s, false, $valid);
echo '<p>Sudoku was '.($valid ? 'valid' : 'invalid').'</p>';
$s = generate_by_line_switching(100, $s);
pretty_output($s, false, $valid);
echo '<p>Sudoku was '.($valid ? 'valid' : 'invalid').'</p>';
?>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment