垂直スライスの決定


23

画像が与えられたら、[完全な垂直断面のピクセル単位の幅] 1(存在する場合)を出力します。垂直断面が存在しない場合は、を出力します0

入力は、ローカルファイルまたはネストされた配列として提供されます。入力をネストされた配列として取得することを選択した場合、白いピクセルは真実の値で表され、非白いピクセルは偽の値で表されます。

1.連続した、すべて白い列の数


あなたはそれを仮定することができます

  • 1000平方ピクセルを超える画像はありません

  • 画像ごとに垂直セクションが1つしかありません


入力:

出力:

50
57
0
0

以下に、セクションを示すために強調表示された(黄色で)最初の2つの例を示します。


真ん中に黒の島があり、複数の垂直セクションがあるようにできますか?
-xnor

@xnor:画像ごとに1つの完全な垂直セクションのみが存在します。これを仕様に追加します。
ザックゲイツ

私のコードは、最初のテストケースで50を出力していますが、最後の3で正しい数値を出力しています。列233から282までの垂直スライス(= 50ピクセル)。48が正しい番号であることを確認できますか?
デビッド

@David:列232から282までの正しいスライスが表示されます(排他的)。私はあなたが正しいと信じています。
ザックゲイツ

2
誰かが問題を抱えているとは思いませんが、連続した、真っ白な列の数を探していることを明示的に言及する価値があります。例から明らかですが、一般に例やテストケースに依存しないことをお勧めします。
MichaelS

回答:


36

ゼリー、2バイト

PS

ここで試してみてください!

画像を次のようにエンコードする場合:

0000111111111100000
0000000111111111000
0000000001111100000
0000000011111000000
0001111111111111100
0000001111110000000
0000000111111110000
0000111111111100000

次のようなネストされた配列に:

[[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],...]

次にP、すべての行ベクトルの要素単位の積をS取得し、結果のすべてを合計して、垂直スライスの長さを求めます。(これは、連続したスライスが1つだけであることが保証されているためにのみ機能します。)この場合、答えは3です。


21
level_ಠこのレベルのゴルフは私を驚かせます。
アディソンクランプ

連続したスライスがない場合の出力は何ですか?(有効な入力)
アディソンクランプ

3
psMATLでも動作します!
デビッド

次に、すべての一切の列は存在しません1の結果を意味し、S Pになります[0,0,0...0]そのうち、Sされええと0、として期待されます。
リン

@Davidそれを投稿しますか?Xpsただし、画像が1行になる可能性がある場合(または、OPに最小サイズがあるかどうかを尋ねる場合)
ルイスメンドー

7

APL、4バイト

+/×⌿

Try it here.

これが私の最初のAPL回答です!

バイトを節約してくれた@ jimmy23013と@NBZに感謝します!


これは機能ではありません。(+/×/⍉)動作しません。
jimmy23013

1
しかし、使用することができ(+/×⌿)、それは1バイト短くなります。
jimmy23013

括弧を削除して、さらに2バイトを保存します。他の多くのAPL回答には、使用するために名前を+/×⌿ f←+/×⌿ f picture
付ける

6

Bash +共通ユーティリティ、17

rs -Tc|grep -vc 0

使用grepしていない場合は、間違っています;-)。

これは、rsユーティリティを使用して転置を行います。 rsOSXバンドルされていますが、ほとんどのLinuxでのようなものをインストールする必要がありsudo apt-get install rsます。

入力列はTAB区切られ、行は改行で区切られます。

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

必要に応じて、imagemagickおよび(GNU)sedを使用して、サンプル入力画像をこの形式に前処理できます。例えば:

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

6

Perl、21 22バイト

修正版

以下のための2が含まれています-lp-l省略することができるが、まだ有効な解決策になるが、それは最後の改行せずに醜いです)

STDINの0行以上に1と0のシーケンスを与えます。使用法がすべての行で一貫している限り、スペース、カンマ、または数字の間に何でも追加できます。

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

これは示されているように機能しますが、置き換えます \xce、リテラルバイト値にて、要求されたスコアを取得します

複数の垂直セクションがある場合、これはすべてのセクション幅の合計を返します。垂直セクションの幅が必要な場合は

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

古いバージョン

私はもともと挑戦を誤解し、垂直線が存在するかどうかに基づいてtrueまたはfalseを与えるプログラムを実装しました。ここのコードと説明はこの古いバージョンのものです

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

ほぼ完全な対称性を得るために左側に1 =〜を追加できれば...最も近いのは

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

説明

$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)

4

Python 2、30バイト

私のお気に入りの組み込み関数の多くをつなげて使用する驚くほどエレガントなソリューションがあります。

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

@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

4

Pyth、5

s*VFQ

ここで試してみてください

これはLynnのアルゴリズムを使用しますが、Pythでベクトル演算をゴルフする方法を示すためだけに投稿することにしました。ここでのトリックはチェーンに「砂糖」構文ヘルパーであるVF折り目はベクトル演算として適用されるように。折り畳まれた演算子はもちろん乗算であり、結果は合計されて最終的な答えが得られます。


4

JavaScript(ES6)、54 45 43バイト

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

@LynnのJellyの回答に基づきますが、の代わりにeveryまたはのsome代わりにゴルフを使用していreduceます。最初のバージョンはblack = 0をエンコードし、2番目のバージョンはblack = 1をエンコードします。

編集:@ edc65のおかげで、さらに2バイト節約しました。


3
使用してみてくださいmap
CalculatorFeline

私の数では45です。43になる可能性があるため、十分に努力しませんでした。
edc6516年

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

1
@ edc65まあ、コンピューティングの2つの困難な問題は、キャッシュの無効化、ネーミング、オフバイワンエラーであることがわかっています...-
ニール

4

J5 6バイト

引数としてブール行列を取ります。

[:+/*/

これが私の最初のJ回答です!(1年半の間間違っていた…)

*/ 列ごとの積

+/ 和

[: cap(プレースホルダーとして機能します +/左引数を取るべきではないため、ます)

オンラインでお試しください!



2

Mathematica 24

Length@Cases[Total@#,0]&

次の形式の配列を取ります。

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

そして、この場合の出力:

1

またはLength[Total@#~Cases~0]&同じバイトカウント
CalculatorFeline

1と0はMathematicaでは真偽でも偽でもありません(もしそれらが割り当てであるなら、おそらく逆になります)。
マーティンエンダー

1

𝔼𝕊𝕄𝕚𝕟、7文字/ 9バイト

⨭МƟïⓜ⨴$

Try it here (Firefox only).

これは@Lynnの素晴らしいアルゴリズムですが、私は独立してそれを見つけました。(私はこれのためにどこかにビルトインがあると思っていましたが、まだ探しています:P)

説明

МƟï入力配列を転置し、ⓜ⨴$各内部ベクトルをその積に変換し、結果の配列を合計します。


1

ジャプト6 4バイト

入力を行の配列として取得します。10で黒です。

y xe
  • ETHのおかげで2バイト節約されました。

試して


説明

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.

y x_×5 でもできると思います。実際、e同様に動作します×のでy xe、4でも:
ETHproductions

週末にそのコメントを逃した、@ ETHproductions-ありがとう:)
シャギー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.