En un mundo ficticio en 2D, un conjunto de instrucciones de impresión en 2D para un objeto se puede representar mediante una lista de enteros de la siguiente manera:
1 4 2 1 1 2 5 3 4
Cada número representa la altura del objeto en ese punto en particular. La lista anterior se traduce en el siguiente objeto cuando se imprime:
#
# # #
# ###
## ####
#########
Luego lo llenamos con la mayor cantidad de agua posible, lo que resulta en esto:
#
#~~~~#~#
#~~~~###
##~~####
#########
Definimos la capacidad del objeto para ser las unidades de agua que el objeto puede contener cuando está completamente lleno; en este caso, 11.
Estrictamente hablando, una unidad de agua ( ~
) puede existir en una ubicación si y solo está rodeada por dos bloques sólidos ( #
) en la misma fila.
Reto
Tome una lista de enteros positivos como entrada (en cualquier formato) y genere la capacidad del objeto impreso cuando la lista se usa como instrucciones.
Puede suponer que la lista contiene al menos un elemento y todos los elementos están entre 1 y 255.
Casos de prueba
+-----------------+--------+
| Input | Output |
+-----------------+--------+
| 1 | 0 |
| 1 3 255 1 | 0 |
| 6 2 1 1 2 6 | 18 |
| 2 1 3 1 5 1 7 1 | 7 |
| 2 1 3 1 7 1 7 1 | 9 |
| 5 2 1 3 1 2 5 | 16 |
| 80 80 67 71 | 4 |
+-----------------+--------+
Respuestas:
Haskell, 54 bytes
Las expresiones
scanl1 max l
yscanr1 max l
calculan el máximo de lectura de la lista hacia adelante y hacia atrás, es decir, el perfil del agua más la tierra si el agua fluye en una dirección.Orig:
Izquierda:
Correcto:
Entonces, el perfil de la imagen general es el mínimo de estos, que corresponde a donde el agua no se escapa en ninguna dirección.
Mínimo:
Finalmente, la cantidad de agua es la suma de esta lista, que contiene agua y tierra, menos la suma de la lista original, que contiene solo tierra.
fuente
Jalea, 10 bytes
Si bien APL requiere varios paréntesis y J símbolos de dos caracteres, el algoritmo es hermoso en Jelly.
Probarlo aquí .
fuente
MATL , 14
Mi respuesta de Matlab traducida a MATL. Algoritmo de xnor.
Explicación
Y>
:cummax()
(la entrada se empuja implícitamente en la pila)G
: entrada de empuje (nuevamente)P
:flip()
Y>
:cummax()
P
:flip()
2$X<
:min([],[])
(mínimo de dos argumentos)G
: entrada de empuje (nuevamente)-
:-
s
:sum()
fuente
Dyalog APL, 17 bytes
Este es un tren monádico que toma la matriz de entrada a la derecha.
El algoritmo es prácticamente el mismo que el de xnor, aunque lo encontré de forma independiente. Busca el máximo en ambas direcciones (hacia atrás invirtiendo la matriz, escaneando e invirtiendo nuevamente), y encuentra el mínimo vectorizado de esos. Luego resta la matriz original y las sumas.
La otra forma de hacerlo sería dividir la matriz en cada ubicación, pero eso es más largo.
Probarlo aquí .
fuente
+/⊢-⍨⌈\⌊⌈\⍢⌽
.Matlab, 47
También usando el algoritmo de xnor.
fuente
MATLAB,
116113109106 BytesEsto funciona almacenando el punto más alto a la izquierda, y mientras recorre cada punto siguiente, encuentra el punto más alto a la derecha. Si el punto actual es menor que ambos puntos altos, entonces agrega la diferencia mínima al volumen acumulado.
Código sin golf:
La primera vez que he intentado jugar al golf, MATLAB no parece ser el mejor para hacerlo ...
fuente
ES6, 101 bytes
Otro puerto del algoritmo de @xnor.
fuente
Python 2 , 68 bytes
Pruébalo en línea!
fuente
Pip
-l
, 19 bytesToma los números de entrada como argumentos de línea de comandos. O bien, agregue la
-r
bandera para tomarlos como líneas de stdin: ¡ Pruébelo en línea!Explicación
A diferencia de todas las otras respuestas, en Pip en realidad fue más corto construir (una versión modificada de) el arte ASCII y contar las unidades de agua.
Comenzamos con
g
la lista de argumentos.0Xg
produce una lista de cadenas de n ceros para cada n eng
.ZD1
luego comprime estas cadenas juntas, usando1
para llenar cualquier espacio en la lista anidada rectangular resultante:ST
Convierte esta lista en una cadena. La-l
bandera especifica que las listas tienen el siguiente formato: cada lista anidada se une sin un separador, y en el nivel superior el separador es una nueva línea. Entonces obtenemos esta cadena multilínea, esencialmente, el diagrama del objeto, pero al revés:Luego encontramos todas las coincidencias de la expresión regular
`0.*0`
. Esto coincide con las dos paredes exteriores y todo lo que hay entre ellas en cada línea.J
une estas cadenas en una sola cadena grande y la$+
suma, dando el número de1
s, que es igual a la cantidad de agua que puede contener el objeto.fuente