| Bytes | Lang | Time | Link |
|---|---|---|---|
| 002 | Japt x | 170811T120818Z | Shaggy |
| 006 | J | 160302T013219Z | Adá |
| 043 | JavaScript ES6 | 160301T010306Z | Neil |
| 022 | Perl | 160229T233315Z | Ton Hosp |
| 004 | APL | 160301T063051Z | Mama Fun |
| 005 | Pyth | 160301T140213Z | FryAmThe |
| 030 | Python 2 | 160301T064444Z | Logic Kn |
| 079 | 𝔼𝕊𝕄𝕚𝕟 | 160301T054501Z | Mama Fun |
| 007 | CJam | 160301T005253Z | Luis Men |
| 017 | Bash + common utilities | 160229T234223Z | Digital |
| 024 | Mathematica | 160229T234040Z | Tally |
| 002 | Jelly | 160229T230832Z | lynn |
Japt -x, 6 4 2 bytes
Takes input as an array of rows, with 1 being white and 0 being black.
ye
- 2 bytes saved thanks to ETH.
ye :Implicit input of 2D array
y :Transpose and map each row
e : All truthy (i.e., 1)
:Implicit output of sum of resulting array
J, 5 6 bytes
Takes Boolean matrix as argument.
[:+/*/
This is my first J answer! (was wrong for 1½ years…)
*/ columnwise product
+/ sum
[: cap (serves as placeholder since +/ should not take a left argument)
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
Based on @Lynn's Jelly answer, though since golfed by using every or some instead of reduce. The first version encodes black = 0 while the second encodes black = 1.
Edit: Saved 2 further bytes thanks to @edc65.
Perl, 21 22 bytes
Fixed version
Includes +2 for -lp (-l can be omitted and would still be a valid solution, but it's ugly without the final newline)
Give sequences of 1's and 0's on 0 or more lines on STDIN. You can add spaces or commas or whatever between the digits if you want as long as the usage is.consistent on all lines.
$a|=~$_}{$_=$a=~y;\xce;
This works as shown, but replace \xce by the literal byte value to get the claimed score
If there are multiple vertical sections this returns the sum of all section widths. If you want the width of a vertical section use
$a|=~$_}{$a=~/\xce+/;$_="@+"-"@-"
Old version
I originally misunderstood the challenge and implemented a program that gives true or false based on if a vertical line exists at all. Code and explanation here are for this old version
$a|=~$_}{$_|=~$a=~1
If only I could add 1=~ at the left for almost perfect symmetry... I suppose the closest would be
1=>$a|=~$_}{$_|=~$a=~1
Explanation
$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)
APL, 4 bytes
+/×⌿
This is my first APL answer!
Thanks to @jimmy23013 and @NBZ for saving bytes!
Pyth, 5
s*VFQ
This uses Lynn's algorithm, but I decided to post it just to show how to golf vector operations in Pyth. The trick here is to chain the "sugar" syntax helpers V and F so that the fold is applied as a vector operation. The operator that is folded is of course multiplication, and then the result is summed to get the final answer.
Python 2, 30 bytes
There is a surprisingly elegant solution using many of my favourite built-in functions chained together.
lambda c:sum(map(all,zip(*c)))
Using the test image from @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
𝔼𝕊𝕄𝕚𝕟, 7 chars / 9 bytes
⨭МƟïⓜ⨴$
This is @Lynn's great algorithm, but I found it independently. (I thought there was a builtin for this somewhere, still looking :P)
Explanation
МƟï transposes the input array, ⓜ⨴$ turns each inner vector into its product, and ⨭ sums the resulting array.
CJam, 7 bytes
q~:.*:+
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
Bash + common utilities, 17
rs -Tc|grep -vc 0
If you're not using grep for image-processing, then you're doing it wrong ;-).
This uses the rs utility to do transposition. rs is bundled in OSX, but will need installing in most linux with something like sudo apt-get install rs.
Input columns are TAB separated, and rows are newline separated:
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
If you like, you can preprocess the example input images into this format with imagemagick and (GNU) sed. E.g:
$ 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
$
Mathematica 24
Length@Cases[Total@#,0]&
Takes an array in the following form:
{{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}}
And in this case outputs:
1
Jelly, 2 bytes
PS
If I encode an image like so:
0000111111111100000
0000000111111111000
0000000001111100000
0000000011111000000
0001111111111111100
0000001111110000000
0000000111111110000
0000111111111100000
Into a nested array like this:
[[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],...]
Then P takes the element-wise product of all of the row vectors, and S sums all of the ones in the result, yielding the length of the vertical slice. (This works only because there’s guaranteed to be only one contiguous slice.) In our case, the answer is 3.