Determinando fatias verticais

23

Dada uma imagem, imprima a [largura em pixels de uma seção vertical completa] 1 (se houver). Se não houver seção vertical, produza 0.

A entrada pode ser fornecida como um arquivo local ou uma matriz aninhada. Se você optar por receber a entrada como uma matriz aninhada, os pixels brancos devem ser representados por um valor verdadeiro, enquanto os pixels não brancos devem ser representados por um valor falsey.

1. o número de colunas contíguas totalmente brancas


Você pode assumir que

  • nenhuma imagem será maior que 1000 pixels quadrados

  • não haverá mais de uma seção vertical completa por imagem


Exemplos

Entradas:

Saídas:

50
57
0
0

Aqui estão os dois primeiros exemplos, destacados (em amarelo) para mostrar suas seções:

Zach Gates
fonte
Pode haver ilhas de preto no meio para que haja várias seções verticais?
Xnor
@xnor: sempre haverá uma seção vertical completa por imagem. Vou adicionar isso à especificação.
Zach Gates
Meu código está produzindo 50 para o primeiro caso de teste, mas números corretos para os últimos 3, com a fatia vertical das colunas 233 a 282 (= 50 pixels de largura). Você pode confirmar que 48 é o número correto?
David
@ David: Eu vejo a fatia correta das colunas 232 a 282 (exclusiva). Eu acredito que você está certo.
Zach Gates
2
Não acho que alguém esteja tendo problemas, mas pode valer a pena mencionar explicitamente que você está procurando o número de colunas contíguas e totalmente brancas. É claro a partir do exemplo, mas geralmente é preferível não confiar em exemplos ou casos de teste.
MichaelS

Respostas:

36

Gelatina, 2 bytes

PS

Experimente aqui!

Se eu codificar uma imagem assim:

0000111111111100000
0000000111111111000
0000000001111100000
0000000011111000000
0001111111111111100
0000001111110000000
0000000111111110000
0000111111111100000

Em uma matriz aninhada 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],...]

Em seguida, Ppega o produto em termos de elementos de todos os vetores de linha e Ssoma todos os resultados no resultado, produzindo o comprimento da fatia vertical. (Isso funciona apenas porque é garantido que haja apenas uma fatia contígua.) No nosso caso, a resposta é 3.

Lynn
fonte
21
Level_ಠ Esse nível de golfe me surpreende.
Addison Crump
Qual é o resultado para quando não há fatias contíguas? (entrada válida)
Addison Crump
3
pstrabalha em MATL também!
David
Então não haverá coluna de todos os 1s, significando o resultado de Pwill [0,0,0...0], da qual o Sum é 0, como esperado.
Lynn
@ David Post, então? Você pode precisar Xps, no entanto, se a imagem pode ser uma única linha (ou pedir o OP se há um tamanho mínimo)
Luis Mendo
7

APL, 4 bytes

+/×⌿

Try it here.

Esta é a minha primeira resposta APL!

Obrigado a @ jimmy23013 e @NBZ por salvar bytes!

Mama Fun Roll
fonte
Isto não é uma função. (+/×/⍉)não funciona
#
1
Mas você pode usar (+/×⌿)e isso é 1 byte menor.
#
Salve outros 2 bytes removendo os parênteses. Muitas outras respostas da APL têm apenas um trem de funções anônimas que devem ser nomeadas ou entre parênteses para serem usadas:+/×⌿ f←+/×⌿ f picture
Adám
6

Bash + utilitários comuns, 17

rs -Tc|grep -vc 0

Se você não está usando greppara , está fazendo errado ;-).

Isso usa o rsutilitário para fazer a transposição. rsestá incluído no OSX , mas precisará ser instalado na maioria dos Linux com algo parecido sudo apt-get install rs.

As colunas de entrada são TABseparadas e as linhas são separadas por nova linha:

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

Se desejar, você pode pré-processar as imagens de entrada de exemplo neste formato com imagemagick e (GNU) sed. Por exemplo:

$ 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
fonte
6

Perl, 21 22 bytes

Versão fixa

Inclui +2 para -lp( -lpode ser omitido e ainda seria uma solução válida, mas é feio sem a nova linha final)

Dê sequências de 1 e 0 em 0 ou mais linhas em STDIN. Você pode adicionar espaços, vírgulas ou qualquer outro elemento entre os dígitos, se desejar, desde que o uso seja consistente em todas as linhas.

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

Isso funciona como mostrado, mas substitua \xcepelo valor literal do byte para obter a pontuação reivindicada

Se houver várias seções verticais, isso retornará a soma de todas as larguras de seção. Se você deseja a largura de uma seção vertical, use

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

Versão antiga

Originalmente, não entendi o desafio e implementei um programa que fornece verdadeiro ou falso com base em se uma linha vertical existe. Código e explicação aqui são para esta versão antiga

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

Se ao menos eu pudesse adicionar 1 = ~ à esquerda para simetria quase perfeita ... Suponho que o mais próximo seria

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

Explicação

$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
fonte
4

Python 2, 30 bytes

Existe uma solução surpreendentemente elegante usando muitas das minhas funções internas favoritas encadeadas.

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

Usando a imagem de teste 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
Cavaleiro Lógico
fonte
4

Pitão, 5

s*VFQ

Experimente aqui

Isso usa o algoritmo de Lynn, mas eu decidi publicá-lo apenas para mostrar como jogar operações de vetores em Pyth. O truque aqui é encadear os auxiliares da sintaxe "açúcar" Ve, Fassim, a dobra é aplicada como uma operação vetorial. O operador dobrado é, obviamente, a multiplicação e, em seguida, o resultado é somado para obter a resposta final.

FryAmTheEggman
fonte
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

Baseado na resposta de @ Lynn's Jelly, embora desde que jogou golfe usando everyou em somevez de reduce. A primeira versão codifica preto = 0 enquanto a segunda codifica preto = 1.

Editar: salvou mais 2 bytes graças a @ edc65.

Neil
fonte
3
Tente usarmap
CalculatorFeline
São 45 na minha contagem. E você não se esforçou o suficiente porque poderia ser 43.
edc65
a => a [s = 0] .map ((_, i) => s + =! a.some (b => b [i])) | s
edc65
1
@ edc65 Bem, você sabe que os dois problemas difíceis da computação são invalidação de cache, nomeação e erros off-by-one ...
Neil
4

J , 5 6 bytes

Pega a matriz booleana como argumento.

[:+/*/

Esta é a minha primeira resposta J! (esteve errado por 1 ano e meio ...)

*/ produto em colunas

+/ soma

[: cap (serve como marcador de posição, pois +/não deve ser um argumento à esquerda)

Experimente online!

Adão
fonte
3

CJam, 7 bytes

q~:.*:+

Experimente online!

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
fonte
2

Mathematica 24

Length@Cases[Total@#,0]&

Toma uma matriz no seguinte formato:

{{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}}

E, neste caso, gera:

1
Tally
fonte
Ou Length[Total@#~Cases~0]&mas mesmo contagem de bytes
CalculatorFeline
1 e 0 não são verdadeiros ou falsos no Mathematica (e se eles fossem a tarefa provavelmente seria o contrário).
Martin Ender
1

, 7 caracteres / 9 bytes

⨭МƟïⓜ⨴$

Try it here (Firefox only).

Esse é o grande algoritmo de @ Lynn, mas eu o encontrei de forma independente. (Eu pensei que havia um builtin para isso em algum lugar, ainda procurando: P)

Explicação

МƟïtranspõe a matriz de entrada, ⓜ⨴$transforma cada vetor interno em seu produto e soma a matriz resultante.

Mama Fun Roll
fonte
1

Japonês , 6 4 bytes

Recebe entrada como uma matriz de linhas, 1sendo branca e 0preta.

y xe
  • 2 bytes salvos graças ao ETH .

Teste-o


Explicação

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.
Shaggy
fonte
Eu acho que você pode fazer y x_×para 5. Na verdade, efunciona bem como ×, de modo que y xepara 4 :-)
ETHproductions
Perdidas que o comentário no fim de semana, @ETHproductions - graças :)
Shaggy