El videojuego Minecraft se trata de colocar y eliminar diferentes tipos de bloques en la red de enteros 3D que conforma el mundo virtual. Cada punto de la red puede contener exactamente un bloque o estar vacío (un bloque " aéreo " oficialmente). En este desafío, solo nos ocuparemos de un plano vertical 2D del mundo 3D y un tipo de bloque: obsidiana .
Cuando la obsidiana forma el contorno de un rectángulo vacío en un plano vertical, se puede crear un portal inferior . El rectángulo vacío puede ser de cualquier tamaño desde 2 unidades de ancho por 3 unidades de alto hasta 22 unidades de ancho por 22 unidades de alto. Las esquinas del rectángulo no necesitan estar bordeadas en obsidiana, solo los lados.
Por ejemplo, supongamos que X
es obsidiana y .
es vacío: (los números son solo para fines de identificación y también están vacíos).
...................................
..XXXX....XXXX....XXXXXXXXX........
..X..X...X....X..X.........X..XXXX.
..X.1X...X.2..X..X...3...X.X..X....
..X..X...X....XXXX.........X..X.6X.
..XXXX....XXXX...XXXXXXXXXXX..X..X.
.............X.4.X....X.5.X...XXXX.
.............X...X....X...X........
..............XXX......XXX.........
...................................
Esta cuadrícula contiene 3 portales válidos:
- El Portal 1 es de 2 por 3 unidades, totalmente vacío y bordeado en obsidiana. Por lo tanto, es válido.
- Portal 2 es de 4 por 3, totalmente vacío y bordeado en obsidiana. Por lo tanto, es válido.
- Portal 3 no está totalmente vacío. Por lo tanto, no es válido.
- Portal 4 es 3 por 3, totalmente vacío y bordeado en obsidiana. Por lo tanto, es válido.
- Portal 5 es de 3 por 2 unidades, que es demasiado pequeño. Por lo tanto, no es válido.
- Al portal 6 le falta una parte de la frontera. Por lo tanto, no es válido.
Desafío
Escriba un programa o función que tome en estas representaciones de cadenas de cuadrículas de obsidiana y vacío, e imprima o devuelva el número de portales inferiores válidos presentes.
- La entrada puede ser de stdin o archivo o argumento de función.
Puede suponer que la entrada siempre está bien formada, es decir, una cuadrícula de texto perfectamente rectangular, de al menos 1 carácter de ancho y alto, que solo contiene
X
y.
. Opcionalmente, puede suponer que hay una nueva línea final después de la última fila.Si lo desea, puede usar cualquiera de los dos caracteres ASCII imprimibles distintos en lugar de
X
y.
.La obsidiana puede estar en los bordes de la cuadrícula. Cualquier cosa más allá de las fronteras se considera vacía.
Ejemplo de entrada: la salida debe ser 4
:
................................................................
...................................XXXXXXXXXXXXXXXXXXXXXXXXX....
..XXXX....XXXX....XXXXXXXXX........X.......................X....
..X..X...X....X..X.........X..XXXX.X.......................X....
..X..X...X....X..X.......X.X..X....X.......................X....
..X..X...X....XXXX.........X..X..X..XXXXXXXXXXXXXXXXXXXXXXXX....
..XXXX....XXXX...XXXXXXXXXXX..X..X.X......................X..XXX
.............X...X....X...X...XXXX.X......................X..X..
.............X...X....X...X........X......................X..X..
..............XXX......XXX........XXXXXXXXXXXXXXXXXXXXXXXX...X..
..................................XX.........................XXX
Puntuación
El envío con la menor cantidad de bytes gana.
Respuestas:
Perl, 81
86Usando más de una expresión regular.
La expresión regular para un ancho específico de un portal es mucho más simple que una genérica:
X{$m}..{$n}(X\.{$m}X.{$n}){3,22}.X{$m}
dóndem
está el ancho del portal y cuáln
estotal width - 1 - m
. La expresión regular se debe poner en una aserción directa de ancho cero(?=...)
porque las coincidencias pueden superponerse. Luego itero 21 veces sobre esta configuración de expresión regular$n
y$.
."@-"
evalúa la posición de inicio de la última coincidencia (/.\n/
) que resulta ser el ancho total: 1.$.
se usa como la otra variable a la que se inicializa1
cuando se usa con-p0
.fuente
.
de las celdas vacías (para que no tenga que escapar de él).Regex (sabor .NET),
182181145132126114104100989796 bytesReconocimiento de patrones de arte 2D ASCII? Suena como un trabajo para expresiones regulares! (No lo hace)
Sé que esto va a desatar discusiones interminables sobre si las presentaciones de expresiones regulares son programas válidos o no, pero dudo que esto supere a APL o CJam de todos modos, por lo que no veo ningún daño. (Una vez dicho esto, se hacen pasar nuestra prueba recalcitrante para "¿Qué es un lenguaje de programación?" .)
Esto toma la entrada como la cadena que debe coincidir, y el resultado es el número de coincidencias encontradas. Se usa
_
en lugar de.
, porque tendría que escapar de este último. También requiere una nueva línea final.Puede probarlo en vivo en RegexHero o RegexStorm ). Los partidos serán las filas superiores de obsidiana de los portales. Si puede encontrar un caso de prueba donde falla, ¡hágamelo saber!
¿Qué es esta hechicería?
La siguiente explicación supone una comprensión básica de los grupos de equilibrio de .NET . La esencia es que las capturas son pilas en .NET regex: cada nueva captura para el mismo nombre se inserta en la pila, pero también hay sintaxis para capturar capturas de esas pilas nuevamente, así como sintaxis para capturar capturas desde una pila y capturas de inserción en otro al mismo tiempo. Para una imagen más completa, puede echar un vistazo a mi respuesta en Stack Overflow que debe cubrir todos los detalles.
La idea básica es hacer coincidir un patrón como:
Dónde
n
está entre 2 y 22 (inclusive). Lo complicado es hacer que todos losn
sy todosm
sean iguales. Como los caracteres reales no serán los mismos, no podemos usar una referencia inversa.Tenga en cuenta que la expresión regular tiene que incluir nuevas líneas, que escribiré como
\n
en el siguiente.C #, 185 bytes
Aquí hay una función completa de C #, solo para hacer de esta una entrada válida. Es hora de que escriba un "intérprete" de línea de comandos para expresiones regulares .NET ...
fuente
^
(o cualquier carácter no utilizado) para(?!)
.Python, 219 bytes
Mejor que Java, pero vaya, los quintuples bucles anidados duelen. El
for/in
podría ser ligeramente compresible usando%s
sustitución, pero no ahorraría mucho.Expandido:
fuente
Java, 304 bytes
Esto es mucho más largo que una expresión regular. Simplemente itera sobre cada cuadrado posible en la entrada. Si es un portal válido, incrementa un contador en 1. Luego devuelve el contador. Esto probablemente se pueda jugar mucho más. Cualquier sugerencia es bienvenida.
Sangrado:
Programa completo:
fuente