+    Ficha Técnica


 +    Mapa Publicaciones


 +    Videos Asociados




Algoritmo
¿Cómo Construir un Sudoko?

Pasos para Configurar una Solución Unica

José Enrique González Cornejo
marzo 2026



       



 Introducción

El presente algoritmo matemático constituye el núcleo conceptual de la aplicación publicada en Internet bajo la denominación Sudoku-U1 .

Dicha aplicación corresponde a un editor y generador de tableros de Sudoku desarrollado conforme a un conjunto de reglas que se han denominado Platinum, cuyo propósito fundamental consiste en garantizar que cada tablero generado posea una única solución.1

En este contexto, el usuario puede construir, simular y resolver tableros generados automáticamente por el sistema, así como trabajar con configuraciones propuestas en otras publicaciones especializadas.

Los sudokus clasificados como de solución única se construyen a partir de una configuración inicial válida. En una primera etapa se completa una matriz global \(M_{9\times 9}\) utilizando valores del conjunto \[ D=\{1,2,3,4,5,6,7,8,9\}, \] cumpliendo estrictamente las condiciones estructurales del rompecabezas.2


 Definiciones

Sea \(M\) una matriz cuadrada de orden \(9\times9\), formada por 81 celdas cuyos elementos se denotan por \(m_{ij}\), con \(i,j \in \{0,1,2,\dots,8\}\). Cada elemento \(m_{ij}\) pertenece al conjunto \(D\) y se dispone en la matriz respetando las restricciones fundamentales del Sudoku clásico.

En términos formales, la matriz \(M\) debe satisfacer simultáneamente las siguientes condiciones:
    i) Cada fila contiene exactamente una vez cada elemento del conjunto \(D\).

    ii) Cada columna contiene exactamente una vez cada elemento del conjunto \(D\).

    iii) La matriz puede particionarse en nueve submatrices de tamaño \(3\times3\), y cada una de ellas contiene también todos los elementos del conjunto \(D\) sin repetición.
Desde el punto de vista computacional, la matriz \(M\) se implementa mediante una tabla HTML identificada por ID="tbl_sudoku", mientras que cada celda posee un identificador de la forma td_i_j, lo que permite manipular los valores directamente mediante el modelo de objetos del documento (DOM). .


Matriz \(M_{9\times9}\) particionada en 9 submatrices de \(3\times3\)


El proceso de llenado de la matriz \(M\) con valores \(m_{ij}\in D\) se realiza verificando, entre otras condiciones, que la suma de los elementos de cada fila y de cada columna sea igual a \(45\), es decir, \[ \sum_{j=0}^{8} m_{ij} = 45 \] Esta propiedad constituye una consecuencia directa de la utilización del conjunto \(D\).3

La configuración matemática del algoritmo empleado para garantizar una solución única se estructura en tres etapas principales, que se describen a continuación.


 1. Generación de la Solución Completa

Generar

En la primera etapa se construye un tablero completamente resuelto mediante un algoritmo basado en el método de backtracking (búsqueda con retroceso). Este método consiste en una exploración sistemática del espacio de soluciones bajo restricciones. El algoritmo asigna valores a cada celda de la matriz y, si en algún punto no existe una opción válida, retrocede al estado anterior y continúa explorando alternativas hasta completar correctamente toda la matriz.

El procedimiento comienza generando permutaciones aleatorias del conjunto \(D\), las cuales se validan progresivamente para construir una matriz que cumpla simultáneamente todas las restricciones del Sudoku.4

<script>
/*Construcción tabla de matriz M con ID por celdas/*
let table=document.getElementById("tbl_sudoku")
   for(let i=0;i<9;i++)
   {
   let tr=document.createElement("tr")
   for(let j=0;j<9;j++)
   {
   let td=document.createElement("td")
   td.id="td_" + i + "_" + j
   if(i%3==0) td.style.borderTop="3px solid black"
   if(j%3==0) td.style.borderLeft="3px solid black"
   if(i==8) td.style.borderBottom="3px solid black"
   if(j==8) td.style.borderRight="3px solid black"
   td.innerHTML=" "
   tr.appendChild(td)
   }
   table.appendChild(tr)
   }
</script>


Luego, el llenado de las celdas de la matriz \( M \) con los valores \(m_{ij} \in D\), donde i,j ={0,1,2,..,8} son índices se verifica que la sumatoria de cada fila y cada columna es igual a \(45\) (i.e.\(\sum m_{ij}=45 \) para cualquier fila o columna fija de los números de \(D\) 3).

En la localización de valores durante el proceso de llenado de \( M \), se aplican las reglas de no repetición de un número ni en sus filas, ni en sus columnas y tampoco un número puede repetirse en su subcuadrante. Justamente este procedimiento restringido y aleatorio, es el que marca la diferencia con el método Montecarlo.

La configuración del método matemático empleado para garantizar una solución única consta de tres etapas, que estarán representadas por tres botones en la aplicación desarrollada como explicación de la construcción del Sudoko.



 2. Generación del Planteamiento

Puzzle

Una vez obtenida una solución completa válida, se procede a generar el planteamiento del Sudoku mediante la eliminación controlada de valores. Este proceso puede interpretarse como una aplicación inversa del algoritmo de construcción: se eliminan valores uno por uno, verificando en cada paso que el tablero resultante continúe teniendo una única solución.

Si la eliminación de un valor produce múltiples soluciones posibles, dicho valor se restituye y el algoritmo continúa con otra celda. De esta forma se obtiene un tablero incompleto que conserva la propiedad fundamental de unicidad.

Desde una perspectiva matemática, este procedimiento puede interpretarse como la exploración de un árbol de decisiones, en el cual cada eliminación representa una bifurcación y el algoritmo verifica continuamente la estabilidad estructural del sistema.

<script>
/*Barajando D/*
function barajar(arr)
{
   for(let i=arr.length-1;i>0;i--)
   {    let j=Math.floor(Math.random()*(i+1))
   let tmp=arr[i]
   arr[i]=arr[j]
   arr[j]=tmp
   }
   return arr
}

function randomRow()
   {
   let base=[1,2,3,4,5,6,7,8,9]
   return barajar(base.slice())
   }


Entonces, se establecen las funciones que validarán las reglas del Sudocko por columnas y localizando las filas en la matriz \(M \) .Se generan los valores por celda mediante una arreglo (array) \(mm \), declarado como variable global.
function columnasValidas(M,row)
{
   let r=M.length
   for(let c=0;c<9;c++)
   {
   for(let i=0;i    {
    if(M[i][c]==row[c])
    {
    return false
    }
   }
  }
  return true
}


function generarMatriz()
{
   let M=[]
   while(M.length<9)
   {
   let row=randomRow()
   if(columnasValidas(M,row))
   {
   M.push(row)
   }
   }
return M
}

var mm=new Array()
function configura_Arreglos(M)
{    for(let r=0;r<9;r++)
   {
   mm[r]=M[r].join(", ")
   }
}

Cada fila y columna de esta matriz \(M \) generada suma 45, asi mismo cada uno de estos arreglos tiene los valores de \(D\) sin repetir valores.

Luego, invocando las funciones anteriores se comienza el llenado de la matriz \(M \). Se localizan valores en la celdas utilizando las referencias ID con DOM Javascript.

function localiza_valores_matriz()
{
/*Se recomienda almacenar los valores por celda en una tabla paralela oculta/*
   for(let i=0;i<9;i++)
   {    var auxiliar=mm[i];
   cadena=auxiliar.split(",")
      for(let j=0;j<9;j++)
      {
 var sCelda=document.getElementById("td_"+i+"_"+j);
 sCelda.innerHTML=cadena[j];
      }
   }
}


A efecto de armar el Puzzle, i.e. la segunda etapa del algoritmo, opera una serie de funciones:

function esValido(grid,r,c,n)
{
/*Verifica en el tablero que cada valor \(n\) en fila \(r\) y columna \(r\)*
   for(let i=0;i<9;i++)
   {
   if(grid[r][i]==n) return false
   if(grid[i][c]==n) return false
   }
   
   let br=Math.floor(r/3)*3
   let bc=Math.floor(c/3)*3
   
   for(let i=0;i<3;i++)
   for(let j=0;j<3;j++)
   if(grid[br+i][bc+j]==n) return false

  return true
}


function contarSoluciones(grid,limit=2)
{
/*Verifica que la sólución sea única/*
/*Cuenta soluciones/*

   let soluciones=0
   function resolver()
   {
   for(let r=0;r<9;r++)
    for(let c=0;c<9;c++)
    {
    if(grid[r][c]==0)
    {
    for(let n=1;n<=9;n++)
    {
    if(esValido(grid,r,c,n))
    {
    grid[r][c]=n
    resolver()
    grid[r][c]=0
    }
   }
   return
   }
   }
   soluciones++
   }
   resolver()
   return soluciones
}

function leerSudokuDOM()
   {
   let g=[]
   for(let i=0;i<9;i++)
   {
   g[i]=[]
   for(let j=0;j<9;j++)
   {
   let v=document.getElementById("td_"+i+"_"+j).innerHTML
   g[i][j]=(v=="" || v==" ") ? 0 : parseInt(v)
   }
   }
return g
}

function generarPuzzleUnico()
{
/*Borrar celdas manteniendo solución única/*
   if(Verifica()==false){return}
   let grid=leerSudokuDOM()
   let celdas=[]
   for(let i=0;i<9;i++)
   for(let j=0;j<9;j++)
   celdas.push([i,j])
   barajar(celdas)
   for(let k=0;k    {
   let r=celdas[k][0]
   let c=celdas[k][1]
   let backup=grid[r][c]
   grid[r][c]=0
   let copia=JSON.parse(JSON.stringify(grid))
   let sol=contarSoluciones(copia,2)
   if(sol!=1)
   {
    grid[r][c]=backup
   }
   }
   actualizarDOM(grid)
}

function actualizarDOM(grid)
{
   for(let i=0;i<9;i++)
   for(let j=0;j<9;j++)
   {
   let td=document.getElementById("td_"+i+"_"+j)
   if(grid[i][j]==0)
   {td.innerHTML="";}
   else
   {
   td.innerHTML=grid[i][j]
   td.style.backgroundColor="#e2e2e2";
   }
   }
}

   async function Generar_Sudoko_Completo()
   {
   /* Limpiar(), función complemetaria*/
   let M=generarMatriz()
   
   configura_Arreglos(M)
   await localiza_valores_matriz()
   }

   async function Mostrar_Valores()
{
   let table1=document.getElementById("tbl_sudoku")
   for(let i=0;i<9;i++)
   {
      for(let j=0;j<9;j++)
      {
    if(table1.rows[i].cells[j].style.backgroundColor=="white")
   {
   /* table1.rows[i].cells[j].innerHTML=tabla2.rows[i].cells[j].innerHTML*
   /* tabla2 tabla auxiliar oculta que almacena valores en el Paso 1*
   }
  }
  }
}




 3. Recuperación de la Solución

Solucionar

Finalmente, cuando el usuario visualiza el tablero incompleto, la solución permanece almacenada en una estructura auxiliar generada en la etapa inicial. Al activar el botón correspondiente, el algoritmo recupera dichos valores y completa automáticamente las celdas restantes, garantizando la coherencia lógica del resultado.

En consecuencia, el algoritmo descrito no sólo permite generar tableros válidos, sino también garantizar formalmente la existencia de una única solución, lo que constituye una propiedad esencial en los sudokus clasificados como de tipo Platinum.



 Notas Adjuntas