Numero de campos con valor null en una tabla

viernes, 18 de mayo de 2007

Me surgió el problema de que tenia que contar el numero de campos con valores null en una tabla y se me ocurrió este pequeño truco:


selec
(isnull(cast(campo1 as int) * 0 ,1)) +
(isnull(cast(campo2 as int) * 0 ,1)) +
(isnull(cast(campo3 as int) * 0 ,1)) +
(isnull(cast(campo4 as int) * 0 ,1)) as numeroDeNulls
from miTabla


Esto se pude hacer si los campos son datetime o numéricos, en el caso de cadenas hay que cambiarlos a:

(isnull(len(ltrim(rtrim(campo1)))) * 0 ,1)


Que ademas nos cuenta como nula la cadena vacía ;)

Eternity II, el juego de los 2M$

martes, 8 de mayo de 2007

En el mes de Julio sale a la venta sale un nuevo juego, Eternity II, que puede hacerte ganar mucho dinero o perder el tiempo.

Esta compuesto por un tablero de 16x16 cuadrados de lado y 256 fichas. Cada una de ellas tiene cuadro lados de colores en los que hay dibujada una figura. No se sebe el numero de colores ni de figuras aunque se estima que cada ficha es diferente. Para solucionarlo hay que colocar las 256 fichas en el tablero de manera que las fichas adyacentes contengan en los lados que quedan pegados la misma figura y color. Las fichas pueden rotarse y solo contienen dibujo por una de sus caras.

Existen 56 fichas con un lado gris, cuya posición en el tablero esta restringida a los bordes y 4 fichas con 2 lados grises q forman las esquinas.

Al parecer la solución es única (que me permito dudarlo) y habrá un total de 3 pistas, 2 fichas de las que nos indicaran su posición tras resolver los puzzles de 6x6 y 6x12 y una que ya viene dada.

Podéis encontrar mas información en la pagina web oficial y en algunas otras relacionadas [web oficial] [noticia en microsiervos] [solucion de eternity I]

La aproximación más sencilla para resolver el puzzle parece a simple vista utilizando un ordenador, aunque generar todas las posibles combinaciones de fichas en el tablero podría llevar años con un supercomputador. Así que como primera aproximación al algoritmo de resolución propongo los siguientes pasos:


Generar los posibles laterales del puzzle utilizando un algoritmo de vuelta atrás (backtracking) cuyo esquema general seria el siguiente:


PRODEDURE ResuelveLateral(tablero)
REPEAT
SeleccionarNuevaFichaGiro
IF Valida THEN
AnotarFichaGiro
IF NOT LateralCompleto THEN
ResuelveLateral(tablero_siguiente)
CancelarAnotacion
ELSE
AlmacenarSolucion
END
END
UNTIL (ultimaFichaGiro)
END resuelveLateral


Basado en los ejemplos del libro de la asignatura Análisis y Diseño de Algoritmos (una de mis favoritas): "Técnicas de diseño de algoritmos, Rosa Guerequeta García y Antonio Vallecillo Moreno, Universidad de Málaga"

Una vez generados todos los posibles laterales del puzzle tratar de resolver un cuadrado de pequeñas dimensiones (8x8) formado por la única ficha conocida y todos los posibles laterales, para un cuadrado de 8x8 (que hemos generado previamente).

El algoritmo de resolución de este cuadrado sigue el esquema del anterior pero seria un poco mas complejo.

Una vez calculados todos los posibles cuadrados volveríamos a realizar el algoritmo para el resto de cuadrados (cuadrantes del puzzle), partiendo como base de todas las posibilidades ya generadas.

La división del problema (cuadrado de 16x16) en problemas mas pequeños (cuadrados de 8x8) nos permitiría una resolución distribuida del problema, pudiendo utilizar varios miles ordenadores para resolver el problema, algo parecido al programa SETI@HOME. Aunque con tanto dinero de por medio, habría mas problemas que soluciones.