Vertikale Schnitte bestimmen

23

Geben Sie bei einem gegebenen Bild die [Breite in Pixel eines vollständigen vertikalen Abschnitts] 1 aus (falls vorhanden). Wenn kein vertikaler Schnitt vorhanden ist, wird ausgegeben 0.

Die Eingabe kann als lokale Datei oder als verschachteltes Array erfolgen. Wenn Sie sich für die Eingabe als verschachteltes Array entscheiden, sollten weiße Pixel durch einen Wahrheitswert dargestellt werden, während nichtweiße Pixel durch einen Falsey-Wert dargestellt werden sollten.

1. Die Anzahl der zusammenhängenden weißen Spalten


Das können Sie annehmen

  • Kein Bild wird größer als 1000 quadratische Pixel sein

  • Es wird nicht mehr als einen vollständigen vertikalen Abschnitt pro Bild geben


Beispiele

Eingänge:

Ausgänge:

50
57
0
0

Hier sind die ersten beiden Beispiele, die (in Gelb) hervorgehoben sind, um ihre Abschnitte zu zeigen:

Zach Gates
quelle
Können sich in der Mitte schwarze Inseln befinden, so dass es mehrere vertikale Abschnitte gibt?
Xnor
@xnor: Es wird immer nur einen vollständigen vertikalen Schnitt pro Bild geben. Ich werde das der Spezifikation hinzufügen.
Zach Gates
Mein Code gibt 50 für den ersten Testfall aus, aber korrekte Zahlen für die letzten 3, mit dem vertikalen Slice aus den Spalten 233 bis 282 (= 50 Pixel breit). Können Sie bestätigen, dass 48 die richtige Nummer ist?
David
@ David: Ich sehe das richtige Stück aus den Spalten 232 bis 282 (exklusiv). Ich glaube du hast recht.
Zach Gates
2
Ich glaube nicht, dass irgendjemand Probleme hat, aber es lohnt sich vielleicht ausdrücklich zu erwähnen, dass Sie nach der Anzahl der zusammenhängenden, rein weißen Spalten suchen. Das Beispiel macht es deutlich, aber es ist im Allgemeinen vorzuziehen , sich nicht auf Beispiele oder Testfälle zu verlassen.
MichaelS

Antworten:

36

Gelee, 2 Bytes

PS

Probieren Sie es hier aus!

Wenn ich ein Bild wie folgt kodiere:

0000111111111100000
0000000111111111000
0000000001111100000
0000000011111000000
0001111111111111100
0000001111110000000
0000000111111110000
0000111111111100000

In ein verschachteltes Array wie dieses:

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

Nimmt Pdann das elementweise Produkt aller Zeilenvektoren und Ssummiert alle im Ergebnis enthaltenen, wobei sich die Länge des vertikalen Schnitts ergibt. (Dies funktioniert nur, weil garantiert nur ein zusammenhängendes Segment vorhanden ist.) In unserem Fall lautet die Antwort 3.

Lynn
quelle
21
ಠ_ಠ Dieses Golfniveau überrascht mich.
Addison Crump
Wofür wird ausgegeben, wenn keine zusammenhängenden Slices vorhanden sind? (gültige Eingabe)
Addison Crump
3
psfunktioniert auch in MATL!
David
Dann wird es keine Spalte von allen 1s geben, was bedeutet, dass das Ergebnis von sein Pwird [0,0,0...0], von dem das Sum 0wie erwartet ist.
Lynn
@ David Post es dann? Sie müssen jedoch möglicherweise Xps, wenn das Bild eine einzelne Zeile sein kann (oder fragen Sie das OP, ob es eine Mindestgröße gibt)
Luis Mendo
7

APL, 4 Bytes

+/×⌿

Try it here.

Dies ist meine erste APL-Antwort!

Vielen Dank an @ jimmy23013 und @NBZ für das Speichern von Bytes!

Mama Fun Roll
quelle
Dies ist keine Funktion. (+/×/⍉)funktioniert nicht
Jimmy23013
1
Aber Sie können verwenden (+/×⌿)und das ist 1 Byte kürzer.
Jimmy23013
Speichern Sie weitere 2 Byte, indem Sie die Klammern entfernen. Viele andere APL-Antworten haben nur einen anonymen Funktionszug, der benannt oder in Klammern gesetzt werden muss, um verwendet zu werden:+/×⌿ f←+/×⌿ f picture
Adám
6

Bash + gemeinsame Dienstprogramme, 17

rs -Tc|grep -vc 0

Wenn Sie nicht grepfür die , dann machen Sie es falsch ;-).

Dies verwendet das rsDienstprogramm, um die Transposition durchzuführen. rswird in OSX gebündelt , muss aber unter den meisten Linux-Betriebssystemen mit so etwas wie installiert werden sudo apt-get install rs.

Eingabespalten werden TABgetrennt und Zeilen werden durch Zeilenumbrüche getrennt:

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

Wenn Sie möchten, können Sie die Beispiel-Eingabebilder mit imagemagick und (GNU) sed in dieses Format vorverarbeiten. Z.B:

$ 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
$
Digitales Trauma
quelle
6

Perl, 21 22 Bytes

Feste Version

Beinhaltet +2 für -lp( -lkann weggelassen werden und wäre immer noch eine gültige Lösung, aber es ist hässlich ohne die letzte Zeile)

Geben Sie Folgen von Einsen und Nullen in 0 oder mehr Zeilen in STDIN ein. Sie können Leerzeichen oder Kommas oder was auch immer zwischen den Ziffern hinzufügen, wenn Sie möchten, solange die Verwendung in allen Zeilen konsistent ist.

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

Dies funktioniert wie gezeigt, wird jedoch \xcedurch den Literal-Byte-Wert ersetzt, um die beanspruchte Punktzahl zu erhalten

Wenn mehrere vertikale Abschnitte vorhanden sind, wird die Summe aller Abschnittsbreiten zurückgegeben. Wenn Sie die Breite eines vertikalen Abschnitts verwenden möchten

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

Alte Version

Ursprünglich habe ich die Herausforderung missverstanden und ein Programm implementiert, das basierend darauf, ob überhaupt eine vertikale Linie existiert, wahr oder falsch ergibt. Code und Erklärung hier beziehen sich auf diese alte Version

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

Wenn ich für fast perfekte Symmetrie nur 1 = ~ links addieren könnte ... Ich nehme an, das nächste wäre

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

Erläuterung

$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)
Tonne Hospel
quelle
4

Python 2, 30 Bytes

Es gibt eine überraschend elegante Lösung, bei der viele meiner bevorzugten integrierten Funktionen miteinander verkettet sind.

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

Verwenden des Testbilds von @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
Logik-Ritter
quelle
4

Pyth, 5

s*VFQ

Probieren Sie es hier aus

Dies verwendet Lynns Algorithmus, aber ich habe mich dazu entschlossen, ihn zu veröffentlichen, um zu zeigen, wie man Vektoroperationen in Pyth spielt. Der Trick dabei ist, die "Zucker" -Syntaxhelfer zu verketten Vund Fdie Falte als Vektoroperation anzuwenden. Der Operator, der gefoldet wird, ist natürlich Multiplikation, und dann wird das Ergebnis summiert, um die endgültige Antwort zu erhalten.

FryAmTheEggman
quelle
4

JavaScript (ES6), 54 45 43 Byte

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

Basierend auf @ Lynns Jelly Antwort, obwohl golfed da durch die Verwendung everyoder somestatt reduce. Die erste Version codiert Schwarz = 0, während die zweite Schwarz = 1 codiert.

Edit: 2 weitere Bytes dank @ edc65 gespeichert.

Neil
quelle
3
Versuchen Sie es mitmap
CalculatorFeline
Es ist 45 in meiner Zählung. Und Sie haben nicht hart genug versucht, weil es 43 sein könnte.
edc65
a => a [s = 0] .map ((_, i) => s + =! a.some (b => b [i])) | s
edc65
1
@ edc65 Nun, Sie wissen, dass die beiden Hauptprobleme beim Rechnen die Ungültigkeit des Caches, die Benennung und einzelne Fehler sind ...
Neil,
4

J , 5 6 Bytes

Nimmt die Boolesche Matrix als Argument.

[:+/*/

Dies ist meine erste Antwort! (war 1½ Jahre falsch…)

*/ kolonnenweises Produkt

+/ Summe

[: cap (dient als Platzhalter, da +/kein linkes Argument verwendet werden sollte)

Probieren Sie es online!

Adam
quelle
3

CJam, 7 Bytes

q~:.*:+

Probieren Sie es 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
quelle
2

Mathematica 24

Length@Cases[Total@#,0]&

Nimmt ein Array in der folgenden Form an:

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

Und in diesem Fall gibt Folgendes aus:

1
Übereinstimmen
quelle
Oder Length[Total@#~Cases~0]&aber die gleiche Anzahl von Bytes
CalculatorFeline
1 und 0 sind in Mathematica nicht wahr oder falsch (und wenn sie es wären, wäre die Zuordnung wahrscheinlich umgekehrt).
Martin Ender
1

𝔼𝕊𝕄𝕚𝕟, 7 Zeichen / 9 Bytes

⨭МƟïⓜ⨴$

Try it here (Firefox only).

Das ist @Lynns großartiger Algorithmus, aber ich habe ihn unabhängig gefunden. (Ich dachte, es gibt irgendwo eine eingebaute Funktion, die immer noch sucht: P)

Erläuterung

МƟï transponiert das Eingangsarray, ⓜ⨴$ wandelt jeden inneren Vektor in sein Produkt um und summiert das resultierende Array.

Mama Fun Roll
quelle
1

Japt , 6 4 Bytes

Nimmt Eingaben als Array von Zeilen auf, 1wobei weiß und0 Schwarz angezeigt werden.

y xe
  • 2 Bytes gespart dank ETH .

Probier es aus


Erläuterung

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.
Zottelig
quelle
Ich denke, Sie können y x_×für 5 tun . Eigentlich efunktioniert so gut ×, so y xefür 4 :-)
ETHproductions
Verpasste diesen Kommentar über das Wochenende, @ETHproductions - danke :)
Shaggy