Determinación de cortes verticales

23

Dada una imagen, genera el [ancho en píxeles de una sección vertical completa] 1 (si existe). Si no existe una sección vertical, salida 0.

La entrada se puede proporcionar como un archivo local o una matriz anidada. Si elige tomar la entrada como una matriz anidada, los píxeles blancos se deben representar con un valor verdadero, mientras que los píxeles no blancos se deben representar con un valor falso.

1. el número de columnas contiguas totalmente blancas


Puedes asumir que

  • ninguna imagen será mayor de 1000 píxeles cuadrados

  • no habrá más de una sección vertical completa por imagen


Ejemplos

Entradas:

Salidas:

50
57
0
0

Estos son los dos primeros ejemplos, resaltados (en amarillo) para mostrar sus secciones:

Puertas de Zach
fuente
¿Puede haber islas de negro en el medio para que haya múltiples secciones verticales?
xnor
@xnor: Solo habrá una sección vertical completa por imagen. Agregaré eso a la especificación.
Zach Gates
Mi código genera 50 para el primer caso de prueba, pero los números correctos para los últimos 3, con el corte vertical de las columnas 233 a 282 (= 50 píxeles de ancho). ¿Puedes confirmar que 48 es el número correcto?
David
@David: veo el corte correcto de las columnas 232 a 282 (exclusivo). Creo que tienes razon.
Zach Gates
2
No creo que nadie esté teniendo problemas, pero vale la pena mencionar explícitamente que está buscando la cantidad de columnas contiguas totalmente blancas. Está claro en el ejemplo, pero generalmente se prefiere no confiar en ejemplos o casos de prueba.
MichaelS

Respuestas:

36

Jalea, 2 bytes

PS

Pruébalo aquí!

Si codifico una imagen así:

0000111111111100000
0000000111111111000
0000000001111100000
0000000011111000000
0001111111111111100
0000001111110000000
0000000111111110000
0000111111111100000

En una matriz anidada como esta:

[[0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0],[0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0],...]

Luego Ptoma el producto basado en elementos de todos los vectores de fila, y Ssuma todos los del resultado, produciendo la longitud del corte vertical. (Esto funciona solo porque se garantiza que solo habrá una porción contigua). En nuestro caso, la respuesta es 3.

Lynn
fuente
21
ಠ_ಠ Este nivel de golf me sorprende.
Addison Crump
¿Cuál es la salida para cuando no hay cortes contiguos? (entrada válida)
Addison Crump
3
ps¡también funciona en MATL!
David
Entonces no habrá una columna de todos los 1s, lo que significa que el resultado Pserá [0,0,0...0], de los cuales el Sum es 0, como se esperaba.
Lynn
@David ¿Publicarlo entonces? Sin Xpsembargo, es posible que necesite si la imagen puede ser una sola fila (o pregunte al OP si hay un tamaño mínimo)
Luis Mendo
7

APL, 4 bytes

+/×⌿

Try it here.

Esta es mi primera respuesta APL!

¡Gracias a @ jimmy23013 y @NBZ por guardar bytes!

Mama Fun Roll
fuente
Esto no es una función. (+/×/⍉)no funciona
jimmy23013
1
Pero puedes usar (+/×⌿)y eso es 1 byte más corto.
jimmy23013
Ahorre otros 2 bytes eliminando los paréntesis. Muchas otras respuestas APL tienen solo un tren de funciones anónimo que debe ser nombrado o entre paréntesis para ser utilizado:+/×⌿ f←+/×⌿ f picture
Adám
6

Bash + utilidades comunes, 17

rs -Tc|grep -vc 0

Si no se está usando greppara el , entonces usted está haciendo mal ;-).

Esto usa la rsutilidad para hacer transposición. rsestá incluido en OSX , pero necesitará instalarse en la mayoría de Linux con algo así sudo apt-get install rs.

Las columnas de entrada están TABseparadas, y las filas están separadas por una nueva línea:

0   0   0   0   1   1   1   1   1   1   1   1   1   1   0   0   0   0   0   
0   0   0   0   0   0   0   1   1   1   1   1   1   1   1   1   0   0   0   
0   0   0   0   0   0   0   0   0   1   1   1   1   1   0   0   0   0   0   
0   0   0   0   0   0   0   0   1   1   1   1   1   0   0   0   0   0   0   
0   0   0   1   1   1   1   1   1   1   1   1   1   1   1   1   1   0   0   
0   0   0   0   0   0   1   1   1   1   1   1   0   0   0   0   0   0   0   
0   0   0   0   0   0   0   1   1   1   1   1   1   1   1   0   0   0   0   
0   0   0   0   1   1   1   1   1   1   1   1   1   1   0   0   0   0   0

Si lo desea, puede preprocesar las imágenes de entrada de ejemplo en este formato con imagemagick y (GNU) sed. P.ej:

$ for img in "AmXiR.jpg" "vb2Yt.jpg" "1V7QD.jpg" "MqcDJ.jpg" ; do
>     convert -depth 1 "$img" xpm:- | \
>     sed -nr '/pixels/{:l;n;/}/q;s/^"(.*)",?$/\1/;y/ ./01/;s/./&\t/g;p;bl}' | \
>     rs -Tc|grep -vc 0
> done
50
57
0
0
$
Trauma digital
fuente
6

Perl, 21 22 bytes

Versión fija

Incluye +2 para -lp( -lse puede omitir y seguiría siendo una solución válida, pero es feo sin la nueva línea final)

Proporcione secuencias de 1 y 0 en 0 o más líneas en STDIN. Puede agregar espacios o comas o lo que sea entre los dígitos si lo desea, siempre que el uso sea coherente en todas las líneas.

$a|=~$_}{$_=$a=~y;\xce;

Esto funciona como se muestra, pero se reemplaza \xcepor el valor del byte literal para obtener la puntuación reclamada

Si hay varias secciones verticales, esto devuelve la suma de todos los anchos de sección. Si desea el ancho de una sección vertical use

$a|=~$_}{$a=~/\xce+/;$_="@+"-"@-"

Versión antigua

Originalmente entendí mal el desafío e implementé un programa que da verdadero o falso en función de si existe una línea vertical. El código y la explicación aquí son para esta versión anterior

$a|=~$_}{$_|=~$a=~1

Si solo pudiera agregar 1 = ~ a la izquierda para una simetría casi perfecta ... supongo que lo más cercano sería

1=>$a|=~$_}{$_|=~$a=~1

Explicación

$a|=~$_     The bitwise operators in perl (&, |, ^, ~) also work on strings by 
            working on the sequence of byte values. The digits "0" and "1" happen
            to have the same ASCII value differing only in the last bit which is
            0 for "0" and 1 for "1". So I would really like to do an "&" here.
            Unfortunately "&" of two different length strings shortens the result
            to the shortest of the strings and my accumulator starts as an empty 
            string. The "|" of two strings however extends to the longest string.
            So instead I will apply De Morgan's law and use "|" on the
            complemented byte string 
}{          Standard perl golf trick. "-p code" transforms to (simplified)
            "while (<>) { code; print }". So if code is "code1 } { code2" this
            becomes "while (<>) { code1 } {code2; print }". So you can use code1
            for the loop operation, use code2 for the final calculation and get a
            free print by assigning to $_
$_|=~$a=~1  I would like to match the accumulator with the bit complement of "1",
            but $a=~~1 doesn't work because the 1 is not a string but a number.
            $a=~~"1" would work but is too long. Next up is complementing $a back
            and matching with 1, so $_=~$a=~1. That also doesn't work since the
            first =~ will be interpreted as a string match insteads of equals
            followed by complement. Easily solved by writing it as $_= ~a=~1. But
            if I am going to give up a byte I can at least have some fun with it.
            Using $_|= also makes the parse work and has the advantage that the
            failure case will give 0 instead of an empty string, which looks
            nicer. It also makes the code look very symmetric. I can also bring
            out the symmetry more by putting 1=> in front (which evaluates 1
            before the assignment and then immediately discards it)
Ton Hospel
fuente
4

Python 2, 30 bytes

Hay una solución sorprendentemente elegante que utiliza muchas de mis funciones integradas favoritas encadenadas.

lambda c:sum(map(all,zip(*c)))

Usando la imagen de prueba de @Lynn:

>>> image = [[0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]]
>>> func = lambda c:sum(map(all,zip(*c)))
>>> func(image)
3
Caballero Lógico
fuente
4

Pyth, 5

s*VFQ

Pruébalo aquí

Esto usa el algoritmo de Lynn, pero decidí publicarlo solo para mostrar cómo hacer operaciones de vectores de golf en Pyth. El truco aquí es encadenar los ayudantes de sintaxis de "azúcar" Vy Fpara que el pliegue se aplique como una operación vectorial. El operador que está plegado es, por supuesto, la multiplicación, y luego el resultado se suma para obtener la respuesta final.

FryAmTheEggman
fuente
4

JavaScript (ES6), 54 45 43 bytes

a=>a[s=0].map((_,i)=>s+=a.every(b=>b[i]))|s
a=>a[s=0].map((_,i)=>s+=!a.some(b=>b[i]))|s

Basado en la respuesta de @ Lynn's Jelly, aunque desde el golf usando everyo en somelugar de reduce. La primera versión codifica negro = 0 mientras que la segunda codifica negro = 1.

Editar: Guardado 2 bytes más gracias a @ edc65.

Neil
fuente
3
Intente usarmap
CalculatorFeline
Es 45 en mi cuenta. Y no lo intentaste lo suficiente porque podría ser 43.
edc65
a => a [s = 0] .map ((_, i) => s + =! a.some (b => b [i])) | s
edc65
1
@ edc65 Bueno, ya sabes que los dos problemas difíciles de la informática son la invalidación de caché, los nombres y los errores fuera de uno ...
Neil
4

J , 5 6 bytes

Toma la matriz booleana como argumento.

[:+/*/

Esta es mi primera respuesta J! (estuvo mal durante 1 año y medio ...)

*/ producto en columnas

+/ suma

[: cap (sirve como marcador de posición ya +/que no debe tomar un argumento izquierdo)

Pruébalo en línea!

Adán
fuente
3

CJam, 7 bytes

q~:.*:+

Pruébalo en línea!

q~      e# read input and evaluate: push nested array
:.*     e# fold vectorized product over nested array: element-wise product of rows
:+      e# fold addition over array: compute its sum
Luis Mendo
fuente
2

Mathematica 24

Length@Cases[Total@#,0]&

Toma una matriz de la siguiente forma:

{{1, 0, 0, 0, 1, 0},
{1, 0, 0, 1, 1, 1},
{1, 1, 0, 0, 0, 0},
{1, 1, 0, 0, 1, 1},
{1, 0, 0, 1, 1, 1}}

Y en este caso salidas:

1
Cuenta
fuente
O el Length[Total@#~Cases~0]&mismo recuento de bytes
CalculatorFeline
1 y 0 no son verdaderas o falsas en Mathematica (y si fueran la tarea probablemente sería al revés).
Martin Ender
1

𝔼𝕊𝕄𝕚𝕟, 7 caracteres / 9 bytes

⨭МƟïⓜ⨴$

Try it here (Firefox only).

Este es el gran algoritmo de @ Lynn, pero lo encontré de forma independiente. (Pensé que había un lugar para esto en alguna parte, aún buscando: P)

Explicación

МƟïtranspone la matriz de entrada, ⓜ⨴$convierte cada vector interno en su producto y suma la matriz resultante.

Mama Fun Roll
fuente
1

Japt , 6 4 bytes

Toma la entrada como un conjunto de filas, 1siendo blanco y 0negro.

y xe
  • 2 bytes guardados gracias a ETH .

Pruébalo


Explicación

y xe
          :Implicit input of array U.
y         :Transpose.
   e      :Map over each sub-array, checking if every element is truthy.
  x       :Reduce by summing, converting booleans to 1 or 0.
          :Implicit output of resulting integer.
Lanudo
fuente
Creo que puedes hacerlo y x_×por 5. En realidad, efunciona tan bien ×, así que y xepor 4 :-)
ETHproductions
Se perdió ese comentario durante el fin de semana, @ETHproductions - gracias :)
Shaggy