Визначення вертикальних зрізів


23

Давши зображення, виведіть [ширину в пікселях повного вертикального перерізу] 1 (якщо така існує). Якщо немає вертикального перерізу, виведіть 0.

Вхід може бути наданий у вигляді локального файлу або вкладеного масиву. Якщо ви вирішили взяти введення як вкладений масив, білі пікселі повинні бути представлені триєдкою величиною, тоді як небілі пікселі повинні бути представлені значенням фальси.

1. кількість суміжних, повністю білих стовпців


Ви можете припустити, що

  • жодне зображення не перевищує 1000 квадратних пікселів

  • не буде більше одного повного вертикального перерізу на зображення


Приклади

Вхідні дані:

Виходи:

50
57
0
0

Ось перші два приклади, виділені (жовтим кольором) для показу їх розділів:


Чи можуть бути посередині чорні острови, щоб було кілька вертикальних ділянок?
xnor

@xnor: На одному зображенні буде лише один повний вертикальний розріз. Я додам це до специфікації.
Зак Гейтс

Мій код виводить 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підсумовує всі результати, отримуючи довжину вертикального зрізу. (Це працює лише тому, що там гарантується лише один суміжний шматочок.) У нашому випадку відповідь така 3.


21
ಠ_ಠ Цей рівень гольфу вражає мене.
Аддісон Кримп

Який вихід, коли немає суміжних зрізів? (дійсний вклад)
Addison Crump

3
psпрацює і в MATL!
Девід

Тоді не буде стовпця всіх 1s, тобто результат Pбуде [0,0,0...0], з якого Sum 0, як очікувалося.
Лінн

@David Опублікувати його тоді? Вам може знадобитися Xps, якщо зображення може бути одним рядком (або запитайте ОП, чи є мінімальний розмір)
Луїс Мендо

7

APL, 4 байти

+/×⌿

Try it here.

Це моя перша відповідь APL!

Дякуємо @ jimmy23013 та @NBZ за збереження байтів!


Це не функція. (+/×/⍉)не працює.
jimmy23013

1
Але ви можете використовувати, (+/×⌿)і це на 1 байт коротше.
jimmy23013

Збережіть ще 2 байти, видаливши дужки. Багато інших відповідей на APL мають лише анонімний функціональний потяг, який повинен бути названий або в скобках скористатися:+/×⌿ f←+/×⌿ f picture
Adám

6

Bash + загальні комунальні послуги, 17

rs -Tc|grep -vc 0

Якщо ви не використовуєте grepдля , то ви робите це неправильно ;-).

Це використовує rsутиліту для переміщення. rsв комплекті в OSX , але потрібно установка в більшості 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може бути пропущено і все-таки буде правильним рішенням, але це некрасиво без остаточного нового рядка)

Наведіть послідовності 1 і 0 на 0 або більше рядків на STDIN. Ви можете додати пробіли, коми або будь-що між цифрами, якщо хочете, якщо використання є.послідовним у всіх рядках.

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

Це працює, як показано, але замінити \xceна буквальне значення байта, щоб отримати заявлений бал

Якщо є кілька вертикальних ділянок, це повертає суму всіх ширин секцій. Якщо ви хочете ширину в використанні вертикального перетину

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

Стара версія

Я спочатку неправильно зрозумів виклик і реалізував програму, яка дає правду чи хибність на основі, якщо вертикальна лінія взагалі існує. Код та пояснення тут для цієї старої версії

$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

Піта, 5

s*VFQ

Спробуйте тут

Для цього використовується алгоритм Лінна, але я вирішив опублікувати його лише для того, щоб показати, як здійснювати векторні операції з гольфу в Pyth. Хитрість тут полягає в ланцюжок «цукровий» синтаксичні хелпери Vі Fтак , що складка застосовуються як операція вектора. Оператор, який складений, звичайно, множує, і тоді результат підсумовується, щоб отримати остаточну відповідь.


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. Перша версія кодує чорний = 0, а друга кодує чорний = 1.

Редагувати: збережено ще 2 байти завдяки @ edc65.


3
Спробуйте скористатисяmap
CalculatorFeline

В моєму рахунку це 45. І ти не дуже старався, бо це могло бути 43.
edc65

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

1
@ edc65 Ну, ви знаєте, дві важкі проблеми обчислень - це недійсність кешу, іменування та помилки по одному ...
Ніл

4

J , 5 6 байт

В якості аргументу береться булева матриця.

[:+/*/

Це моя перша J відповідь! (помилявся півтора року…)

*/ стовпчик продукту

+/ сума

[: cap (служить заповнювачем, оскільки +/не повинен брати аргумент зліва)

Спробуйте в Інтернеті!



2

Математика 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).

Це чудовий алгоритм @ Лінна, але я знайшов його самостійно. (Я думав, що для цього десь є вбудований, і досі шукаю: P)

Пояснення

МƟïтранспонує вхідний масив, ⓜ⨴$перетворює кожен внутрішній вектор у свій добуток і підсумовує отриманий масив.


1

Japt , 6 4 байти

Вводить введення як масив рядків, з 1білим та0 чорним кольором.

y xe
  • 2 байти збережено завдяки ETH .

Перевірте це


Пояснення

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 - дякую :)
Shaggy
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.