Sudoku calculator.

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]

Umm, pretty cool.

[editline]03:56PM[/editline]

Why don’t you make a cool little gui that you can input the Sudoko into and click solve.

I love Sudoku.

I suck as artist :P.

Look, it doesn’t find all possible solutions. If the sudoku is really hard to solve it will return false on solving.

I did 2 functions that solve 2 different ways. If someone knows anyone more, just tell me.

EDIT: Is the first post that I have got useful ranks and no dumb ranks!!! I feel useful xD.
(Waiting for someone to rate dumb :P)

Wouldn’t be too hard to do. Just make some kind of panel that is selectable and you can input a single number into, then create a DPanelList with a size that represents 9 by 9 of these panels, and the rest should happen by itself. Then just know which square is which, and calculate a final representation.

Something like my Befunge interpreter would look nice.

OMG What the fuck is that? Visual programming LOL. It’s awesome.
I will try do that for input sudokus.

I was just showing you what the interface looks like so you can get an idea of the sort of thing that would look nice for this. But since you asked, it is a befunge interpreter.