Esta pregunta se basa en el rompecabezas de colocación de números Towers (también conocido como Skyscrapers), que puedes jugar en línea . Su objetivo es tomar una solución al rompecabezas y determinar las pistas: el número de torres visibles a lo largo de cada fila y columna. Este es el código de golf, por lo que gana menos bytes.
Cómo funcionan las torres
La solución a un rompecabezas Torres es un cuadrado latino - una n*n
cuadrícula en la que cada fila y columna contiene una permutación de los números 1
a través n
. Un ejemplo para n=5
es:
4 3 5 2 1
5 4 1 3 2
1 5 2 4 3
2 1 3 5 4
3 2 4 1 5
Cada fila y columna está etiquetada con una pista en cada extremo como:
2 3 1 4 5
v v v v v
2 > 4 3 5 2 1 < 3
1 > 5 4 1 3 2 < 4
2 > 1 5 2 4 3 < 3
3 > 2 1 3 5 4 < 2
3 > 3 2 4 1 5 < 1
^ ^ ^ ^ ^
2 2 2 2 1
Cada pista es un número de 1
a n
que te dice cuántas torres "ver" mirando a lo largo de la fila / columna de esa dirección, si los números son tratados como torres con esa altura. Cada torre bloquea torres más cortas detrás de ella. En otras palabras, las torres que puedes ver son las que son más altas que cualquier torre antes que ellas.
Por ejemplo, veamos la primera fila.
2 > 4 3 5 2 1 < 3
Tiene una pista de 2
la izquierda porque puedes ver el 4
y el 5
. Los 4
bloques de la 3
de la vista y la 5
bloquea todo lo demás. Desde la derecha, se puede ver 3
torres: 1
, 2
, y 5
.
Requisitos del programa
Escriba un programa o función que tome en la cuadrícula de números y produzca o imprima las pistas, yendo en sentido horario desde la parte superior izquierda.
Entrada
Un n*n
cuadrado latino con 2<=n<=9
.
El formato es flexible. Puede usar cualquier estructura de datos que represente una cuadrícula o lista que contenga números o caracteres de dígitos. Es posible que necesite un separador entre las filas o ningún separador en absoluto. Algunas posibilidades son una lista, una lista de listas, una matriz, una cadena separada por tokens como
43521 54132 15243 21354 32415,
o una cadena sin espacios.
No te dan n
como parte de la entrada.
Salida
Devuelve o imprime las pistas comenzando desde la parte superior izquierda y en sentido horario. Entonces, primero las pistas superiores leen hacia la derecha, luego las pistas correctas leen hacia abajo, luego las pistas inferiores leen hacia la izquierda, las pistas izquierdas leen hacia arriba.
Esto sería 23145 34321 12222 33212
para el ejemplo anterior.
2 3 1 4 5
v v v v v
2 > 4 3 5 2 1 < 3
1 > 5 4 1 3 2 < 4
2 > 1 5 2 4 3 < 3
3 > 2 1 3 5 4 < 2
3 > 3 2 4 1 5 < 1
^ ^ ^ ^ ^
2 2 2 2 1
Al igual que para la entrada, puede usar una lista, cadena o cualquier estructura ordenada. Los cuatro "grupos" se pueden separar o no, en una estructura anidada o plana. Pero, el formato debe ser el mismo para cada grupo.
Ejemplos de casos de prueba:
(Su formato de entrada / salida no tiene que ser el mismo que estos).
>> [[1 2] [2 1]]
[2 1]
[1 2]
[2 1]
[1 2]
>> [[3 1 2] [2 3 1] [1 2 3]]
[1 2 2]
[2 2 1]
[1 2 3]
[3 2 1]
>> [[4 3 5 2 1] [5 4 1 3 2] [1 5 2 4 3] [2 1 3 5 4] [3 2 4 1 5]]
[2 3 1 4 5]
[3 4 3 2 1]
[1 2 2 2 2]
[3 3 2 1 2]
>> [[2 6 4 1 3 7 5 8 9] [7 2 9 6 8 3 1 4 5] [5 9 7 4 6 1 8 2 3] [6 1 8 5 7 2 9 3 4] [1 5 3 9 2 6 4 7 8] [3 7 5 2 4 8 6 9 1] [8 3 1 7 9 4 2 5 6] [9 4 2 8 1 5 3 6 7] [4 8 6 3 5 9 7 1 2]]
[4 2 2 3 3 3 3 2 1]
[1 3 3 2 2 2 2 3 3]
[4 3 2 1 2 3 3 2 2]
[3 1 2 4 3 3 2 2 5]
Para su conveniencia, estos son los mismos casos de prueba en un formato de cadena plana.
>> 1221
21
12
21
12
>> 312231123
122
221
123
321
>> 4352154132152432135432415
23145
34321
12222
33212
>> 264137589729683145597461823618572934153926478375248691831794256942815367486359712
422333321
133222233
432123322
312433225
≢¨∪¨↓⌈\(⍉⍪⌽⍪⍉∘⌽∘⊖⍪⊖)
Python 2, 115 bytes
Hay una gran cantidad de listas cambiando allí.
Toma la entrada como una lista anidada (por ejemplo, llamar con
T([[4,3,5,2,1],[5,4,1,3,2],[1,5,2,4,3],[2,1,3,5,4],[3,2,4,1,5]])
). La salida es una sola lista plana.Sin golf:
Alternativa 115:
No tengo idea de por qué esto funciona con una comprensión de lista, pero arroja una
NameError
con una comprensión establecida ...Un poco demasiado, pero si alguien está interesado, sí, ¡es posible que esto se reduzca a una lambda!
Pyth , 25 bytes
Puerto Pyth obligatorio.
Ingrese la lista a través de STDIN, por ejemplo
[[4, 3, 5, 2, 1], [5, 4, 1, 3, 2], [1, 5, 2, 4, 3], [2, 1, 3, 5, 4], [3, 2, 4, 1, 5]]
.Pruébelo en línea ... es lo que diría, pero desafortunadamente, por razones de seguridad, el intérprete en línea no permite el uso de eval en paréntesis anidados. Intente con el código de solución alternativa
JcQ5V4=J_CJ~Yml{meS<dhkUd_J)Y
e ingrese como una lista aplanada como[4, 3, 5, 2, 1, 5, 4, 1, 3, 2, 1, 5, 2, 4, 3, 2, 1, 3, 5, 4, 3, 2, 4, 1, 5]
.(Gracias a @isaacg que ayudó a jugar golf unos pocos bytes)
fuente
<
y>
son los operadores de corte unilateral, por lo que:d0hk
se pueden convertir<dhk
.U
en las entradas de colección es lo mismoUl
, por lo queUld
se puede convertir enUd
.CJam,
2927 bytesEntrada como
Salida como
Cómo funciona
La idea básica es hacer que el código funcione a lo largo de las filas y rotar la cuadrícula en sentido antihorario 4 veces. Para contar las torres, estoy elevando cada torre hasta donde no haga una "diferencia visual" (es decir, no la cambie si es visible, ni la levante a la misma altura de la torre frente a ), y luego estoy contando distintas alturas.
fuente
APL, 44
Probado aquí.
fuente
J, 35 caracteres
Ejemplo:
Pruébalo aquí.
fuente
Haskell, 113
fuente
Mathematica,
230,120,116,113110 bytesUso:
fuente
a[[y]][[x]]
esa[[y,x]]
. Y el usoArray
puede ser más corto queTable
.JavaScript
335264256213Evalúe en la consola de JavaScript del navegador (usé Firefox 34.0, parece que no funciona en Chrome 39 ??) Pruebe con:
Aquí está la encarnación actual del código no protegido: es cada vez más difícil de seguir:
Intencionalmente no miré ninguna de las otras respuestas, quería ver si podía resolver algo por mí mismo. Mi enfoque consistía en aplanar las matrices de entrada a una matriz unidimensional y precalcular las compensaciones a las filas desde las cuatro direcciones. Luego usé shift right para probar si la siguiente torre era falsa y si lo era, luego incremente el contador para cada fila.
Espero que haya muchas maneras de mejorar esto, tal vez no calcular previamente los desplazamientos, sino usar algún tipo de desbordamiento / módulo en la matriz de entrada 1D. Y quizás combinar mis bucles, ser más funcional, deduplicar.
¡Cualquier sugerencia sera apreciada!
Actualización n. ° 1 : ¡Progreso, tenemos la tecnología! Pude deshacerme de las compensaciones precalculadas y hacerlas en línea con operadores ternarios unidos. También pude deshacerme de mi declaración if y convertir los bucles for en whiles.
Actualización n. ° 2 : Esto es bastante frustrante; No hay fiesta de pizza para mí. Pensé que funcionar y usar la recursión reduciría muchos bytes, ¡pero mis primeros intentos terminaron siendo mayores en hasta 100 caracteres! En su desesperación, utilicé las funciones de flecha de grasa ES6 para reducirlo realmente. Luego decidí reemplazar los operadores booleanos por aritméticos y eliminar parens, punto y coma y espacios donde pude. Incluso dejé de declarar mis variables y contaminé el espacio de nombres global con mis símbolos locales. Sucio sucio. Después de todo ese esfuerzo, superé mi puntaje de Actualización n. ° 1 con la friolera de 8 caracteres, hasta 256. ¡Blargh!
Si aplicara las mismas optimizaciones despiadadas y trucos ES6 a mi función de Actualización n. ° 1, superaría esta puntuación por una milla. Puedo hacer una Actualización # 3 solo para ver cómo se vería.
Actualización n. ° 3 : Resulta que el enfoque recursivo de la flecha gorda tenía mucha más vida, solo necesitaba trabajar con la entrada bidimensional directamente en lugar de aplanarla y mejorar el aprovechamiento de los ámbitos de cierre. Reescribí los cálculos de compensación de la matriz interna dos veces y obtuve el mismo puntaje, por lo que este enfoque puede estar cerca de ser explotado.
fuente
Java, solo
352350325 bytes ...Entrada como
43521 54132 15243 21354 32415
Salida como:
23145343211222233212
Sangrado:
¡Algún consejo sería de gran aprecio!
fuente
for
buclesfor(;i<n;i++)
afor(;++i<n;)
e inicializari
a-1
. Luego, utilízalos para hacer cosas. También puedes hacer lo mismo con el otro bucle.a[i].charAt(j)-'0'
lugar de un análisis explícito. Esto tampoco requiere delimitadores en la entrada (hace que el formato de entrada se parezca más al formato de salida).for
bucles, siempre puede introducir algo útil en la parte de "incremento de bucle". Esto hace que el código sea más oscuro y elimina un punto y coma. Por ejemplo:for(j=n;j-->0;System.out.print(c))
.Python 2 - 204 bytes
Este es probablemente un golf realmente pobre. Pensé que el problema era interesante, así que decidí abordarlo sin buscar la solución de nadie más. Mientras escribo esta oración, todavía tengo que mirar las respuestas a esta pregunta. No me sorprendería que alguien más haya hecho un programa Python más corto;)
Ejemplo de E / S
Opcionalmente, puede incluir espacios en blanco en la entrada. Casi en cualquier lugar, sinceramente. Mientras puedas
eval()
, funcionará.Explicación
La única parte interesante de este programa es la primera línea. Define una función
f(l)
que le dice cuántas torres se pueden ver en una fila, y el resto del programa simplemente aplica esa función a cada posición posible.Cuando se le llama, encuentra la longitud
l
y la guarda en una variablen
. Luego crea una nueva variablek
con esta comprensión de lista bastante monstruosa:No es tan malo cuando lo descompones. Desde entonces
n==len(l)
, todo antes de loif
justo represental
. Sin embargo, usandoif
podemos eliminar algunos elementos de la lista. Construimos una lista con([0]+list(l))
, que es solo "l
con un0
agregado al principio" (ignore la llamada alist()
, eso solo está allí porque a vecesl
es un generador y debemos asegurarnos de que en realidad sea una lista aquí).l[c]
solo se coloca en la lista final si es mayor que([0]+list(l))[c]
. Esto hace dos cosas:l[c]
conviertec+1
. Estamos comparando efectivamente cada elemento con el elemento a la izquierda del mismo. Si es mayor, es visible. De lo contrario, se oculta y se elimina de la lista.[0]+
sentido y sólo se comparól[c]
al[c-1]
, Python sería comparar la primera torre a la última (que puede indexar en una lista desde el extremo con-1
,-2
, etc.), por lo que si la última torre era más alto que el primero obtendríamos el resultado incorrecto.Cuando todo está dicho y hecho,
l
contiene un número de torres yk
contiene cada una de ellas que no es más corta que su vecino inmediato a la izquierda. Si ninguno de ellos fuera (por ejemplo, paraf([1,2,3,4,5])
), entoncesl == k
. Sabemos que no queda nada que hacer y regresarn
(la longitud de la lista). Sil != k
, eso significa que al menos una de las torres fue retirada esta vez y puede haber más por hacer. Entonces volvemosf(k)
. Dios, amo la recursión. Curiosamente,f
siempre recurre un nivel más profundo de lo estrictamente "necesario". Cuando se genera la lista que se devolverá, la función no tiene forma de saberlo al principio.Cuando comencé a escribir esta explicación, este programa tenía 223 bytes de longitud. Al explicar las cosas, me di cuenta de que había formas de salvar personajes, ¡así que me alegro de haber escrito esto! El mayor ejemplo es que
f(l)
se implementó originalmente como un bucle infinito que se rompió cuando se realizó el cálculo, antes de darme cuenta de que la recursión funcionaría. Simplemente demuestra que la primera solución que piensas no siempre será la mejor. :)fuente
Matlab,
(123)(119)usado así:
C #, hasta 354 ...
Enfoque diferente al utilizado por TheBestOne.
fuente
\n
lugar de líneas nuevas, simplemente las reemplacé por espacios, por lo que el código se ejecuta de inmediato cuando alguien lo copia. Y me permití eliminar el últimoend
(que cierra la función, que no es necesaria) que guarda 4 caracteres adicionales, espero queend
, gracias :)