Hi everyone. I finished my sudoku calculator. I firstly made it on c++, then I translated to lua, so the organisation is so shity. And some functions are in Spanish xD.
But EH, it works!
Example of usage:
[lua]
local sud = StringToSudoku(“103456789456789123789123456000000000000000000000000000000000000000000000000000000”)
PrintSudoku(sud)
print("
")
sud:ResolverPorDescarte() – solve descarting.
PrintSudoku(sud)
[/lua]
Output:
103456789
456789123
789123456
000000000
000000000
000000000
000000000
000000000
000000000
123456789
456789123
789123456
000000000
000000000
000000000
000000000
000000000
000000000
0 Represent blank spaces.
In the example, the script just found the “2” at the first row, second column.
Useful functions:
· StringToSudoku(str) returns a sudoku table.
· Sudoku:tostring() returns a string representating the sudoku.
· Sudoku:ResolverPorDescarte() solves A BLANK in the sudoku descarting blanks that can contain only a unique value. Returns true if success.
· Sudoku:ResolverPorSolucion() solves A BLANK in the sudoku finding the unique possible position of a value into a square. Returns true if success.
· Sudoku:EstaResuelto() returns if sudoku is already finished. If is not valid (see Valido()) it will return false.
· Sudoku:Valido() returns false if sudoku have any invalid entry, like a value twice in the same row, column, or square.
An example of how to solve the entire sudoku:
[lua]
– strsud must be a string containing the sudoku.
local sud = StringToSudoku(strsud)
local ThereIsSolution = true
while(not sud:EstaResuelto() and ThereIsSolution ) do
ThereIsSolution = sud:ResolverPorDescarte()
if not ThereIsSolution then
ThereIsSolution = sud:ResolverPorSolucion()
end
end
PrintSudoku(sud) – or save your sudoku in a string with sud:tostring()
[/lua]
[lua]
local Celda = {}
Celda._index = Celda
Celda.valor = 0;
Celda.Set = function(self,v) self.valor = v end
Celda.Get = function(self) if not self then error(“no hay self”,2) end return self.valor end
Celda.Valido = function(self) return (self.valor > -1 and self.valor < 10) end
Celda.Colocar = function(self,ant,pos) self.siguiente = pos self.anterior = ant end
Celda.Vacio = function(self) return self.valor == 0 end
Celda.eq = function(self,c)
if type© == “table” and c._index == Celda then
return self:Get() == c:Get()
end
return self:Get() == c
end
Celda.neq = function(self,c) return not self.eq© end
Celda.asg = function(self,i) if type(i) == “table” and i._index == Celda then self:Set(i:Get()) return end self:Set(i) end
Celda.tostring = function(self) return tostring(self.valor) end
function NewCelda()
return table.Copy(Celda)
end
local Fila = {}
Fila._index = Fila
Fila._new = function(self)
self.celdas = {} self.celdas[0] = NewCelda() self.celdas[1] = NewCelda() self.celdas[2] = NewCelda() self.celdas[3] = NewCelda() self.celdas[4] = NewCelda() self.celdas[5] = NewCelda() self.celdas[6] = NewCelda() self.celdas[7] = NewCelda() self.celdas[8] = NewCelda()
self.celdas[0]:Colocar(self.celdas[8],self.celdas[1])
self.celdas[8]:Colocar(self.celdas[7],self.celdas[0])
for i = 1,7 do
self.celdas*:Colocar(self.celdas[i-1],self.celdas[i+1])
end
end
Fila.GetCelda = function(self,v)
if not v then error(“No hay v!!”,2) end
if (v > -1 and v < 9) then
return self.celdas[v]
end
return self.celdas[0]
end
Fila.Valido = function(self) for i = 0,8 do for j = 0,8 do if j ~= i and self.celdas* == self.celdas[j] and self.celdas* ~= 0 then return false end end end return true end
Fila.PosibleValor = function(self,v)
for i = 0,8 do
if (self.celdas*:eq(v)) then
return false
end
end
return true
end
Fila.nd = function(self,i) return not self:PosibleValor(i) end
Fila.Colocar = function(self,ant,pos) self.anterior = ant self.siguiente = pos end
Fila.tostring = function(self)
local result = “”
for i = 0,8 do
result = result…self:GetCelda(i):tostring()
end
return result
end
Fila.asg = function(self,f) for i = 0,8 do self:GetCelda(i):eq (f:GetCelda(i)) end end
function NewFila()
local result = table.Copy(Fila)
result:_new()
return result
end
local Sudoku = {}
Sudoku._new = function(self)
self.filas = {} self.filas[0] = NewFila() self.filas[1] = NewFila() self.filas[2] = NewFila() self.filas[3] = NewFila() self.filas[4] = NewFila() self.filas[5] = NewFila() self.filas[6] = NewFila() self.filas[7] = NewFila() self.filas[8] = NewFila()
self.filas[0]:Colocar(self.filas[8],self.filas[1])
self.filas[8]:Colocar(self.filas[7],self.filas[0])
for i = 1,7 do
self.filas*:Colocar(self.filas[i-1],self.filas[i+1])
end
end
Sudoku.GetFila = function(self,v)
if (v > -1 and v < 9) then
return self.filas[v]
end
return self.filas[0]
end
Sudoku.GetColumna = function(self,v)
if not v then error(“No hay v!!”,2) end
if (v < 0 or v > 8) then
return filas[0]
end
local resultado = NewFila()
for i = 0,8 do
resultado:GetCelda(i):asg (self.filas*:GetCelda(v));
end
return resultado;
end
Sudoku.GetCuadro = function(self,v)
resultado = NewFila()
for i = 0,8 do
resultado:GetCelda(i):asg(self:GetFila(self:PosicionDesdeCuadro(v,i)[1]):GetCelda(self:PosicionDesdeCuadro(v,i)[0]))
end
return resultado
end
Sudoku.FilaRelativa = function(self,x,y) return y end
Sudoku.ColumnaRelativa = function(self,x,y) return x end
Sudoku.CuadroRelativo = function(self,x,y) return math.floor(y/3)*3 + math.floor(x/3) end
Sudoku.PosicionDesdeFila = function (self,fila,numero) local result = {} result[1] = fila result[0] = numero return result end
Sudoku.PosicionDesdeColumna = function(self,columna,numero) local result = {} result[0] = columna result[1] = numero return result end
Sudoku.PosicionDesdeCuadro = function(self,cuadro,numero) local result = {} result[1] = math.floor(cuadro/3)*3 + math.floor(numero/3) result[0] = math.fmod(cuadro,3)*3 + math.fmod(numero,3) return result end
Sudoku.Valido = function(self)
for i = 0,8 do
if (not (self:GetFila(i):Valido()) or not (self:GetColumna(i):Valido()) or not (self:GetCuadro(i):Valido())) then
return false
end
end
return true
end
Sudoku.PosibleValor = function(self,x,y,valor)
return self:GetFila(self:FilaRelativa(x,y)):PosibleValor(valor)
and self:GetColumna(self:ColumnaRelativa(x,y)):PosibleValor(valor)
and self:GetCuadro(self:CuadroRelativo(x,y)):PosibleValor(valor)
end
Sudoku.HuecoPosible = function(self,cuadro,valor)
local resultado = {}
resultado[0] = -1 resultado[1] = -1;
local posibilidades = 0;
if (not self:Valido()) then
return resultado;
end
local caja = self:GetCuadro(cuadro)
for i = 0,8 do
if (self:PosibleValor(self:PosicionDesdeCuadro(cuadro,i)[0],self:PosicionDesdeCuadro(cuadro,i)[1],valor)) then
resultado[0] = self:PosicionDesdeCuadro(cuadro,i)[0];
resultado[1] = self:PosicionDesdeCuadro(cuadro,i)[1];
posibilidades = posibilidades + 1
end
end
if (posibilidades == 1) then
return resultado;
end
resultado[0] = -1 resultado[1] = -1;
return resultado;
end
Sudoku.ResolverPorDescarte = function(self)
local posibilidades, ult = 0,0
if (not self:Valido()) then
return false
end
for i = 0,8 do
for j = 0,8 do
if (self:GetFila(i):GetCelda(j):Vacio()) then
posibilidades = 0;
ult = 0;
for x = 1,9 do
if (self:PosibleValor(j,i,x)) then
posibilidades = posibilidades + 1;
ult = x;
end
end
if (posibilidades == 1) then
self:GetFila(i):GetCelda(j):Set(ult);
return true;
end
end
end
end
return false;
end
Sudoku.ResolverPorSolucion = function(self)
if (not self:Valido()) then
return false;
end
local resueltos = 0;
for cuadro = 0,8 do
for valor = 1,8 do
if (self:HuecoPosible(cuadro,valor)[0] ~= -1) then
self:GetFila(self:HuecoPosible(cuadro,valor)[1]):GetCelda(self:HuecoPosible(cuadro,valor)[0]):Set(valor);
resueltos = resueltos + 1
return true;
end
end
end
return false
end
Sudoku.EstaResuelto = function(self)
if not (self:Valido()) then
return false
end
for i = 0,8 do
for x = 0,8 do
if (self:GetFila(i):GetCelda(x):Vacio()) then
return false
end
end
end
return true
end
Sudoku.tostring = function(self)
if not self then error(“no hay self”,2) end
local result = “”
for i = 0,8 do
result = result…self:GetFila(i):tostring()…"
"
end
return result
end
function NewSudoku()
local result = table.Copy(Sudoku)
result:_new()
return result
end
function StringToSudoku(str)
local result = NewSudoku()
if (string.len(str) == 81) then
for i = 0,8 do
for j = 0,8 do
result:GetFila(i):GetCelda(j):asg(tonumber(string.sub(str,(i9+j)+1,(i9+j)+1)))
end
end
end
return result;
end
function PrintSudoku(sud)
print(sud:tostring());
end
[/lua]