#!/usr/local/bin/perl -w $file = $ARGV[0]; unless ($file){ $file="sudoku.in"; } $c=0; open IN, "< $file" or die "Cannot open $file: $!"; while (){ chomp; @data = split "", $_; $j=0; for $i (@data){ $d[$c][$j]=$i; print "$i"; if ($i =~ /\d/) { $sol[$c][$j]=$i; } $j++; last if ($j==9); } print "\n"; $c++; last if ($c==9); } close IN; $c--; top: $countant=$count=9*9*9; $iter=0; $supo=0; print "-"x20; init(); while ($count!=81){ $iter++; selec_xy(); selec_box(); $count=0; for $i (0..8){ for $j (0..8){ $ok=0; for $k (1..9){ $ok+=$set[$i][$j][$k]; if ($set[$i][$j][$k]==1){ $kk = $k; } } if ($ok==1){ $sol[$i][$j]=$kk; tacha($i,$j,$kk); } $count+= $ok; } } print "$count posibilidades\n"; report(); if ($count<9*9){ goto top; } if ($count==$countant && $iter>2){ $iter = 0; for $i (0..8){ for $j (0..8){ $ok=0; for $k (1..9){ $ok += $set[$i][$j][$k]; } if ($ok==2){ $random = rand(); for $k (1..9){ # reverse? if ($random >.5) { $k = 9-$k+1; } if ($set[$i][$j][$k]==1){ if (!defined $guess[$i][$j]){ $sol[$i][$j]=$k; tacha($i,$j,$k); $guess[$i][$j]++; $supo++; goto bottom; }elsif ($guess[$i][$j]<2 && $supo%2==1) { $sol[$i][$j]=$k; tacha($i,$j,$k); $guess[$i][$j]++; goto bottom; } } } } } } } bottom: $countant=$count; print "$supo Suposiciones\n"; } sub selec_xy{ for $k (1..9){ for $i (0..8){ $kount=0; for $j (0..8){ $kount += $set[$i][$j][$k]; if ($set[$i][$j][$k]==1){ $jj = $j; } } if ($kount==1){ $sol[$i][$jj]=$k; tacha($i,$jj,$k); } } for $j (0..8){ $kount=0; for $i (0..8){ $kount += $set[$i][$j][$k]; if ($set[$i][$j][$k]==1){ $ii = $i; } } if ($kount==1){ $sol[$ii][$j]=$k; tacha($ii,$j,$k); } } } } sub selec_box{ for $k (1..9){ $kount=0; for $l (0..2){ for $m (0..2){ $kount += $set[$l][$m][$k]; if ($set[$l][$m][$k]==1) { $ll=$l; $mm=$m; } } } if ($kount==1){ $sol[$ll][$mm]=$k; tacha($ll,$mm,$k); } $kount=0; for $l (0..2){ for $m (3..5){ $kount += $set[$l][$m][$k]; if ($set[$l][$m][$k]==1) { $ll=$l; $mm=$m; } } } if ($kount==1){ $sol[$ll][$mm]=$k; tacha($ll,$mm,$k); } $kount=0; for $l (0..2){ for $m (6..8){ $kount += $set[$l][$m][$k]; if ($set[$l][$m][$k]==1) { $ll=$l; $mm=$m; } } } if ($kount==1){ $sol[$ll][$mm]=$k; tacha($ll,$mm,$k); } $kount=0; for $l (3..5){ for $m (0..2){ $kount += $set[$l][$m][$k]; if ($set[$l][$m][$k]==1) { $ll=$l; $mm=$m; } } } if ($kount==1){ $sol[$ll][$mm]=$k; tacha($ll,$mm,$k); } $kount=0; for $l (3..5){ for $m (3..5){ $kount += $set[$l][$m][$k]; if ($set[$l][$m][$k]==1) { $ll=$l; $mm=$m; } } } if ($kount==1){ $sol[$ll][$mm]=$k; tacha($ll,$mm,$k); } $kount=0; for $l (3..5){ for $m (6..8){ $kount += $set[$l][$m][$k]; if ($set[$l][$m][$k]==1) { $ll=$l; $mm=$m; } } } if ($kount==1){ $sol[$ll][$mm]=$k; tacha($ll,$mm,$k); } $kount=0; for $l (6..8){ for $m (0..2){ $kount += $set[$l][$m][$k]; if ($set[$l][$m][$k]==1) { $ll=$l; $mm=$m; } } } if ($kount==1){ $sol[$ll][$mm]=$k; tacha($ll,$mm,$k); } $kount=0; for $l (6..8){ for $m (3..5){ $kount += $set[$l][$m][$k]; if ($set[$l][$m][$k]==1) { $ll=$l; $mm=$m; } } } if ($kount==1){ $sol[$ll][$mm]=$k; tacha($ll,$mm,$k); } $kount=0; for $l (6..8){ for $m (6..8){ $kount += $set[$l][$m][$k]; if ($set[$l][$m][$k]==1) { $ll=$l; $mm=$m; } } } if ($kount==1){ $sol[$ll][$mm]=$k; tacha($ll,$mm,$k); } } } sub init{ for $i (0..8){ for $j (0..8){ for $k (1..9){ $set[$i][$j][$k]=1; } } } for $i (0..8){ for $j (0..8){ if ($d[$i][$j] !~ /\d/){ $sol[$i][$j]=undef; } if (defined $sol[$i][$j]){ # unless (defined $guess[$i][$j]){ tacha($i,$j,$sol[$i][$j]); # } } } } } sub report { print "\n"; for $i (0..8){ for $j (0..8){ for $k (1..9){ if ($set[$i][$j][$k]==1){ print $k; } } print " "; } print "\n"; } print "\n"; } sub tacha{ my ($i,$j,$z) = @_; my ($k,$l); for $k (0..8){ $set[$i][$k][$z]=0; $set[$k][$j][$z]=0; } for $k (1..9){ $set[$i][$j][$k]=0; } if ($i<=2){ if ($j<=2){ for $k (0..2){ for $l (0..2){ $set[$k][$l][$z]=0; } } }elsif ($j>2 && $j<=5){ for $k (0..2){ for $l (3..5){ $set[$k][$l][$z]=0; } } }elsif ($j>5 && $j<=8){ for $k (0..2){ for $l (6..8){ $set[$k][$l][$z]=0; } } } }elsif ($i>2 && $i<=5){ if ($j<=2){ for $k (3..5){ for $l (0..2){ $set[$k][$l][$z]=0; } } }elsif ($j>2 && $j<=5){ for $k (3..5){ for $l (3..5){ $set[$k][$l][$z]=0; } } }elsif ($j>5 && $j<=8){ for $k (3..5){ for $l (6..8){ $set[$k][$l][$z]=0; } } } }elsif ($i>5 && $i<=8){ if ($j<=2){ for $k (6..8){ for $l (0..2){ $set[$k][$l][$z]=0; } } }elsif ($j>2 && $j<=5){ for $k (6..8){ for $l (3..5){ $set[$k][$l][$z]=0; } } }elsif ($j>5 && $j<=8){ for $k (6..8){ for $l (6..8){ $set[$k][$l][$z]=0; } } } } $set[$i][$j][$z]=1; } __END__ Ejemplo de fichero sudoku.in --25---4- 9----86-- -6--4---- -1-----98 3---8---4 48-----3- ----3--1- --17----6 -2---97--