logoApuntes agrupados: Sudokus


Sudokus (sudokus): Se encontraron 7 apuntes:

  1. SVG: crear sudokus
  2. Resolviendo sencillos sudokus
  3. SVG interactivo: sudokus
  4. Resolver sudokus
  5. 1001 sudokus
  6. Sudokus de colores
  7. Sudo-Captcha: Sudoku y Captcha


Titulo: SVG: crear sudokus


emoticón de Caricatos Publicado el día 01 de enero de 2013
id=109

sudoku Simplemente haremos un recuadro con nueve (9) filas y nueve (9) columnas, resaltando recuadros agrupados en tres (3) filas y tres (3) columnas. Los parámetros adicionales son la anchura de cada casilla y los valores iniciales donde cualquier valor distinto del rango de números aceptados [1..9] corresponderá a una casilla vacía. En la imagen asociada a este párrafo tenemos un ejemplo; y si miramos su código podemos afirmar que sería muy fácil implementar otras opciones como los colores del mismo.

Para conseguir entonces distintos sudokus, vamos a facilitar un formulario con la inicialización del mismo como parámetro:

:

Como podemos ver, con este apunte solo generamos el recuadro con sus casillas y los valores que nosotros pongamos. Investigaremos en su resolución.






Titulo: Resolviendo sencillos sudokus


emoticón de Caricatos Publicado el día 18 de enero de 2013
id=111

Cuando publicamos el apunte SVG: crear sudokus, pensamos como podríamos resolverlo; pero debíamos dar unos pasos previos que nos servirán de introducción. La lógica de este juego consiste en rellenar las casillas vacías con un número que no se repita en la misma fila, ni en la misma columna, ni en el mismo sector.

La lógica que se nos ha ocurrido es la de buscar los posibles candidatos, detectando los números existentes en cada fila, columna y sector.

Dando un vistazo rápido a la primera casilla, vemos que la fila tiene los números: 2, 8 y 7; la columna tiene: 8, 1, 4 y 5; y el sector: 8, 3 y 6. Juntándolo todo tenemos: 1, 2, 3, 4, 5, 6, 7 y 8. O sea qué el único candidato es el número 9; y si sólo tenemos un candidato, podemos usarlo sin riesgo de cometer errores.

Sin pensar en autómatas, podemos hacerlo manualmente editando a mano la cadena de texto que mostramos en el control del formulario asociado (se puede probar si se desea, sin olvidarse luego de "").

: |

Pero también hemos pensado en automatizar esa resolución, así que hemos creado un pequeño recuadro informativo y luego le daremos uso, en principio estudiando el sudoku, y luego intentándo resolverlo.

Aquí los progresos

Con el sistema descrito, hemos podido resolver tan solo dos (2) casillas, aunque si hubiéramos usado la misma lógica con los números del sudoku del apunte anteriormente citado el resultado hubiera sido distinto (si tiene su navegador javascript habilitado, pulse sobre la miniatura para cambiarlo).

Reflexiones

Volviendo al resultado del , vemos que la casilla de la segunda fila y primera columna debe ser un siete (7), así que tendremos que mejorar nuestro algoritmo...






Titulo: SVG interactivo: sudokus


emoticón de Caricatos Publicado el día 09 de febrero de 2013
id=115

Veremos como podemos resolver un sudoku introduciendo los números por teclado. No intentaremos resolverlo con código, ya que nuestra intención es otra: la interacción.

Podemos escoger entre los sudokus en miniatura, o incluír cada número pulsando sobre cada casilla. En este caso no hacemos ninguna verificación.

Puede seleccionar una miniatura
sudoku alternativo sudoku alternativo sudoku alternativo sudoku alternativo

Algunos de los ejemplos los hemos visto ya en anteriores apuntes.

Eventos

Para responder a un evento hay que asociarlo de la misma forma que con cualquier elemento html. Hemos asignado un identificador "id" a cada casilla de forma que la primera tiene id="casilla_0_0" y la última : id="casilla_8_8"; y dentro de cada casilla tenemos un elemento "text" (texto) con similar identificador, reemplazando "casilla_" por "txt_":

function tag(id)	{return document.getElementById(id);}
function poner_evento(elemento, evento, f)	{
	if (document.addEventListener)
		elemento.addEventListener(evento, f, true);
	else
		if (document.attachEvent)
			elemento.attachEvent("on" + evento, f);
		else
			elemento["on" + evento] = f;
}
// De la inicialización de la página, nos interesan estas pocas líneas.
for (i = 0; i < 9; i++)	for (j = 0; j < 9; j++)	{
	tag("txt_" + i + "_" + j).appendChild(document.createTextNode(""));
	poner_evento(tag("casilla_" + i + "_" + j), "click", entrada);
}

Podemos resumir en estas pocas líneas que a cada casilla le asociamos al evento "click" (onclick) la función "entrada()" que mostramos a continuación:

function entrada() {
	id = this.id;
	coleta = id.substr(8);
	xy = coleta.split("_");
	n_actual = tag("txt_" + coleta).firstChild.data;
	n = prompt("nuevo valor para la casilla [" + xy + "] : ", n_actual)[0];
	if ("123456789".indexOf(n) != -1)	{
		sudoku = document.forms.form_sudoku.inicio.value;
		valores = sudoku.split("");
		posi = parseInt(xy[0]) * 9 + parseInt(xy[1]);
		valores[posi] = n;
		document.forms.form_sudoku.inicio.value = valores.join("");
		tag("txt_" + coleta).replaceChild(document.createTextNode(n), tag("txt_" + coleta).firstChild);
	}
}

Sobre este último código, solo reseñaremos que tanto la lectura como escritura de nodos de texto se hace de la misma manera que hemos hecho hasta el momento.






Titulo: Resolver sudokus


emoticón de Caricatos Publicado el día 01 de mayo de 2013
id=120

Para poder resolver sudokus sencillos hemos buscado los números candidatos, discriminando los existentes en el recuadro (grupo de casillas adyacentes mostradas del mismo color), fila y columna de la casilla en cuestión. Pero en el apunte donde teníamos esa implementación: Resolviendo sencillos sudokus, si necesitábamos modificar alguna casilla, teníamos que encontrar el lugar mediante la cadena de números del campo inicio de un formulario. Hemos resuelto ese inconveniente dándole interactividad a nuestro sudoku, permitiendo modificar su valor pinchando sobre la casilla que quisiéramos modificar. Podemos verlo en este otro apunte: SVG interactivo: sudokus.

Con lo que teníamos tan solo se podían resolver sudokus muy sencillos, así que necesitabamos algo más.

Marcado y recuperación

Al intentar resolver algún sudoku algo más complejos, podemos tener dudas entre algunas posibles soluciones y puede haber algún error al elegirla. Para esos casos nos parece muy útil guardar el estado antes de realizar la elección; en el caso de habernos equivocado, simplemente podemos recuperar ese estado guardado.

Este sistema podemos implementarlo con un par de botones y el siguiente código:

marcas = [];

function poner_marca()	{
	marcas.push(document.forms.form_sudo.inicio.value);
}

function quitar_marca()	{
	if (marcas.length == 0)
		alert("no hay marcas")
	else	{
		sudo = marcas.pop();
		document.forms.form_sudo.inicio.value = sudo;
		entrar_sudoku(sudo);
	}
}

Y "entrar_sudoku()", que utilizaremos más veces:

function entrar_sudoku(cadena) {
	enes = cadena.split("");
	for (var i = 0; i < 9; i++)	for (var j = 0; j < 9; j++)	{
		n = enes.shift();
		poner = ("123456789".indexOf(n) == -1) ? " ": n;
		tag("txt_" + i + "_" + j).replaceChild(document.createTextNode(poner),
			tag("txt_" + i + "_" + j).firstChild);
	}
}

Ahora podemos resolver más fácilmente un sudoku de forma manual, pero aún hay más.

Detectar errores

Si introducimos algún número repetido, podemos creer que estamos resolviendo bien nuestro sudoku, así que aún nos falta implementar si el estado actual de un sudoku es correcto. Para ello tenemos que poder detectar números repetidos en filas, columnas y recuadros (3 filas x 3 columnas).

Para filas y columnas, el código es tan sencillo como comparar cada número encontrado con los anteriormente encontrados, pero para las zonas es algo más complejos. A continuación, la implementación:

function chequear_sudoku()	{
	repes = [];
	sin_errores = true;
	cadena = tag("form_sudo").elements.inicio.value;
	if (cadena.length > 81)
		cadena = cadena.substr(0, 81)
	else
		while (cadena.length < 81)
			cadena += "0";

	for (i = 0; i < 9; i++)
		arr_sudoku[i] = cadena.substr(i * 9, 9);

	// buscamos repes en filas...
	for (i = 0; i < 9; i++)	{
		n = arr_sudoku[i].charAt(0);
		repes[i] = (n == 0) ? []:[n];
		for (j = 1; j < 9; j++)	{
			m = arr_sudoku[i].charAt(j);
			if (in_array(m, repes[i]))
				sin_errores = false;
			else	if (m != 0)
				repes[i].push(m);
		}
	}

	// Ahora buscamos repes en columnas...
	if (sin_errores)
	for (i = 0; i < 9; i++)	{
		n = arr_sudoku[0].charAt(i);
		repes[i] = (n == 0) ? []:[n];
		for (j = 1; j < 9; j++)	{
			m = arr_sudoku[j].charAt(i);
			if (in_array(m, repes[i]))
				sin_errores = false;
			else	if (m != 0)
				repes[i].push(m);
		}
	}

	// Y por último, buscamos repes en zonas...
	if (sin_errores)	{
		for (i = 0; i < 9; i++)	{
			posi = 27 * parseInt(i / 3) + (3 * (i % 3));
			n = cadena.charAt(posi);
			repes[i] = (n == 0) ? []:[n];
		}
		for (j = 1; j < 9; j++)	for (i = 0; i < 9; i++)	{
			posi = (27 * parseInt(i / 3) + (3 * (i % 3))) + (9 * parseInt(j / 3) + (j % 3));
			m = cadena.charAt(posi);
				if (in_array(m, repes[i]))
					sin_errores = false;
				else	if (m != 0)
					repes[i].push(m);
		}
	}
	return sin_errores;
}

Tan solo nos queda mostrar como resolvemos el sudoku, pero al ser un código extenso, enlazaremos con él: script.resolver_sudokus.

Funcionamiento

A continuación el resultado de nuestra implementación.

:
:

:

:
Aquí los progresos (Primeros pasos)
Puede seleccionar una miniatura

Aunque ya resolvemos nuestro pasatiempo favorito, nos queda más que decir en próximos apuntes. Esperamos que haya gustado.






Titulo: 1001 sudokus


emoticón de Caricatos Publicado el día 28 de mayo de 2013
id=121

sudoku alternativo Empezamos con un sencillo ejemplo cuya miniatura hemos adjuntado a este párrafo de muy fácil resolución, y hemos terminado con una extensa lista de diferentes dificultades; pero hubiéramos podido obtener una lista mucho más amplia basándonos en ese primer ejemplo y simples modificaciones que iremos explicando.

La lista de sudokus que acabamos de citar puede encontrarse en el siguiente enlace: sudokus.txt, donde encontraremos una definición de un array del lenguaje php que podemos incrustar en cualquier fichero php con una sencilla instrucción include:

include("sudokus.txt");

Pero para poder usarlo en nuestras páginas lo hemos incluído en un fichero php que convierte ese arreglo php en un fichero xml válido mediante el siguiente código:

<?php
include("sudokus.txt");
header("Content-type: text/xml");
echo <<< xml
<?xml version="1.0" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="sudokus.xsl" ?>

<sudokus>

xml;
while (count($sudokus) > 0)	{
	$s = array_shift($sudokus);
	$n = $s["sudoku"];
	echo "<sudoku>$n</sudoku>\n";
}
echo "</sudokus>";
?>

Ese listado es el que usaremos en los distintos apuntes que dedicamos a este juego, pero seguiremos con nuestro asunto principal.

Invertir el sudoku

Hemos visto que podemos referir o definir a un sudoku con una lista de 81 números, donde el 0 se corresponde con la casilla vacía, y con cualquier lenguaje de programación es muy sencillo invertir esa lista... usaremos por ejemplo javascript, que no tiene definida esa función para cadenas de texto (String), pero sí para arrays (reverse()). El código podría ser asi:

String.prototype.inverso = function()	{
	return this.split("").reverse().join("");
}
sudoku = "014500032369001004000000010007604090690087020020300000100800070000000008802400603";
ukodus = sudoku.inverso();
// ukodus = "306004208800000000070008001000003020020780096090406700010000000400100963230005410"

Ya hemos visto como con pocas líneas de código de un sudoku obtenemos otro. Per aún hay mucho más.

Otras sencillas modificaciones

Cuando queremos tratar filas y columnas, tenemos que convertir nuestra lista de números en una tabla. Hasta ahora hemos usado el siguiente código con el que convertíamos nuestra lista grande en un lista de pequeñas listas:

s = [];
for (i = 0; i < 9; i++)
	s[i] = cadena.substr(i * 9, 9);

Vamos a plantear otra forma de obtener el mismo resultado:

s = ["", "", "", "", "", "", "", "", ""];
for (i = 0; i < 81; i++)
	s[parseInt(i / 9)] += cadena.charAt(i);

También tres líneas de código, tal vez un poco más complejas pero con el mismo resultado final. Si nos fijamos en la última línea encontramos que el índice del bucle lo dividimos para obtener el valor de la línea del sudoku, pero qué pasaría si en vez de obtener el resultado de la división entera, nos quedamos con el resto (su módulo)...

s = ["", "", "", "", "", "", "", "", ""];
for (i = 0; i < 81; i++)
	s[i % 9] += cadena.charAt(i);

... el resultado que obtenemos, en términos matemáticos es la matriz traspuesta.

Si a cada una de esas listas menores se aplica el método "inverso()" que hemos definido al principio del apunte, obtendremos el efecto reflejo horizontal. Si a la matriz traspuesta le aplicamos el reflejo horizontal, el efecto resultante es el de rotación de 90º. Por cierto, la inversión de de los 81 números sería una rotación de 180º.

Intercambio de filas y columnas

Si intercambiamos las dos primeras filas de cualquier sudoku válido, sigue siendo un sudoku válido. Igualmente seguirá siendo válido con la misma operación entre la segunda y tercera, o cualquier combinación agrupando las filas de tres en tres (no valdría por ejemplo con la tercera y cuarta. También sería válido si intercambiásemos cualquiera de los grupos de tres filas; por ejemplo, intercambiar las tres primeras por las tres últimas.

Todo lo que se puede aplicar en las filas, se puede aplicar con las columnas...

Breve recuento

En principio con los efectos de reflejo horizontal y rotación de 90º hacia la derecha; si hacemos esa rotación tres veces se convierte en rotación hacia la izquierda. También podemos obtener el reflejo vertical en tres pasos: rotar a la derecha, realizar el reflejo horizontal y rotar a la izquierda (Una simplificación con respecto a código podría ser rotando solo una vez y luego invertir la lista).

Con las rotaciones y reflejos obtenemos ocho (8) variantes del sudoku original, pero tan sólo intercambiando dos filas cualesquiera válidas para intercambiar (recordemos lo comentado sobre las agrupaciones de filas y columnas), duplicamos la cifra resultante, o sea solo manipulando las tres primeras filas ya tenemos cuarenta y ocho (48) variantes. Nos quedan muchas combinaciones más que justifican el título de este apunte.

Viendo los resultados

Vamos a intentar usar algunos controles para probar lo expuesto.

:
Controles Básicos: | Rotaciones: | Reflejos:
Intercambios de columnas:
| |
Intercambios de filas:
| |
Intercambios de columnas agrupadas:
Intercambios de filas agrupadas:
|

Hemos añadido un botón para comprobar que aunque realicemos infinitas modificaciones al sudoku inicial, el resultado será otro sudoku válido.






Titulo: Sudokus de colores


emoticón de Caricatos Publicado el día 05 de junio de 2013
id=122

¡Lo que faltaba...! Sudokus de colores...

Si asociamos a cada número de un sudoku un color cualquiera, todos distintos; podríamos omitir mostrar esos números, pero mostraríamos un sudoku; tan solo tenemos que saber cuales son los emparejamientos número <=> color.

Para cada variación de emparejamientos también tendremos nuevos sudokus que se suman a los 1001 sudokus que ya expusimos con anterioridad.

A la dificultad para resolverlo manualmente debemos añadir la dificultad de seleccionar los colores a ingresar, que resolveremos con unas casillas adicionales que al pulsarlas (click) quedan como color activo que cambiará al que tenga donde pulsemos del sudoku.

Elegir los colores

De la paleta de colores web, elegiremos colores que tengan una propia definición para que sea de fácil uso. La lista de colores que hemos usado la vemos a continuación:

Para pasar los colores como parámetros como se ve en las miniaturas, si nos interesase usar un color no definido tendría que estar en formato "#RRGGBB", pero "escapado", o sea en vez de usar el carácter "#" poner "%23". Un ejemplo tenemos en la miniatura del sudoku que hay al principio de este apunte, donde en vez de usar la definición del rojo (red), hemos usado su valor rgb: "#ff0000", pero en el enlace hemos puesto "%23ff0000".

Para adaptar este sistema de colores, hemos tenido que retocar un poco algunos códigos; para muestra mostraremos como ha quedado la función para mostrar el sudoku de colores:

var paleta = ["red", "blue", "green", "yellow", "aqua", "lime", "pink", "darkorange", "magenta"];
function entrar_sudoku(cadena) {
	casillas = cadena.split("");
	for (i = 0; i < 9; i++)	for (j = 0; j < 9; j++)	{
		n = casillas.shift();
		poner = ("123456789".indexOf(n));
		if (poner == -1)
			tag("casilla_" + i + "_" + j).style.fill =
				(((parseInt(i / 3) + parseInt(j / 3)) % 2) == 0) ? "white":"#abcabc"
		else
			tag("casilla_" + i + "_" + j).style.fill = paleta[poner];
	}
}

A continuación ponemos el sistema de colores en funcionamiento:

:
Controles Colores: => 1 => 2 => 3 => 4 => 5 => 6 => 7 => 8 => 9 | Color activo:
Básicos: | Rotaciones: | Reflejos:
Intercambios de columnas:
| |
Intercambios de filas:
| |
Intercambios de columnas agrupadas:
Intercambios de filas agrupadas:
| |
Puede seleccionar una miniatura

yo Para poner un sudoku manualmente (listado de números), se puede pulsar sobre la etiqueta sudoku al comienzo del formulario. Espero que haya gustado.






Titulo: Sudo-Captcha: Sudoku y Captcha


emoticón de Caricatos Publicado el día 11 de octubre de 2013
id=125

Debemos evitar los mensajes basura en los formularios, ya que si queremos tener una copia en nuestro correo, posiblemente el gestor los eliminará (considerándolos spam); y si no quisiéramos esa copia (en sistemas de comentarios, por ejemplo), llenarían nuestras páginas de publicidad de dudosa importancia... es más, posiblemente sean delictivos. Por esa razón se han creado los códigos de seguridad tipo captcha, de los que presentamos esta variante.

Sudoku

ejemplo en vertical ejemplo en horizontal Hemos hablado bastante sobre los sudokus en anteriores apuntes, pero el que presentamos es totalmente distinto, en vez de usar una cuadrícula de nueve casillas horizontales por otras nueve casillas verticales (9 x 9), solo usaremos una fila o columna o zona.

ejemplo en horizontal Por las imágenes que estamos mostrando podemos deducir que mostramos sudokus de colores. Al tratarse de la novena parte de un sudoku normal el tamaño de las casillas puede ser del tamaño que se quiera, por ejemplo si nos decidimos por la imagen horizontal, no importa que sea muy grande (como nuestro ejemplo); en cambio, si nos interesa la orientación vertical, seguramente deberemos minimizar ese tamaño.

Al no tener los habituales números en su interior podemos despreocuparnos del tamaño de éstos, dejando el tamaño que tenga el propio sistema para el elemento que controla la edición del resultado.

Captcha

Los sistemas de seguridad tipo Captcha tienen sus pros y sus contras. Es evidente que evita que cualquier robot malicioso pueda dejar basura en nuestros formularios, pero los más sencillos pueden ser vulnerables y los más complejos, en ocasiones distorsionan tanto el contenido, que aún los humanos los encuentran difíciles de comprender, y por tal motivo pueden desistir de hacer ese comentario que realmente es lo que pretendemos al integrar el formulario en nuestra página.

Para este diario hemos creado otro sistema de seguridad por lo que no lo cambiaremos aún que consiste en escribir en el recuadro para el código de seguridad una palabre resaltada de un párrafo. Existen otras variantes, y se podrían hacer más... esperemos ganar esta batalla contra el spam...

La implementación

Si nos fijamos a la derecha de esta página, en la sección "Otras páginas del dominio", encontraremos un enlace a la que podemos considerar la página oficial, o mejor la página donde presentamos y explicamos en que consiste el Sudo-Captcha. En esa página encontramos enlaces a ficheros necesarios para la implementación y el resto de códigos necesarios, pero hemos creado fichero comprimido con esos ficheros: sudo.captcha.zip. Tan solo nos queda descomprimir ese fichero en una carpeta de nuestro sistema que originalmente es "sudo-captcha", pero de usar otro nombre editar la primera linea de los ficheros que debemos incluir en nuestro sistema con el nombre de esa carpeta.

Seguiremos desarrollando este captcha y veremos si se nos ocurre algo mejor...



Zona de comentarios

Esto grupo aún no tiene comentarios.

Evaluación

Valoración de esta página: (grupo.sudokus) valor

Valoración evaluar evaluar evaluar evaluar evaluar evaluar evaluar evaluar evaluar evaluar

Respuesta: Zona de mensajes (proceso de evaluación)

Copyright © 2002-2018 www.pepemolina.com
RSS rss | Ver Mapa del sitio