Определение вертикальных срезов


23

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

Входные данные могут быть предоставлены в виде локального файла или вложенного массива. Если вы решите принимать ввод как вложенный массив, белые пиксели должны быть представлены истинным значением, тогда как небелые пиксели должны быть представлены значением фальси.

1. количество смежных, полностью белых столбцов


Вы можете предположить, что

  • изображение не будет больше 1000 квадратных пикселей

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


Примеры

Входы:

Выходы:

50
57
0
0

Вот первые два примера, выделенные (желтым цветом), чтобы показать их разделы:


Могут ли быть острова черного цвета посередине, чтобы было несколько вертикальных участков?
xnor

@xnor: для каждого изображения будет только один полный вертикальный разрез. Я добавлю это к спецификации.
Зак Гейтс

Мой код выводит 50 для первого контрольного примера, но правильные числа для последних 3 с вертикальным срезом от столбцов 233 до 282 (= 50 пикселей в поперечнике). Можете ли вы подтвердить, что 48 является правильным номером?
Дэвид

@ Давид: я вижу правильный срез из столбцов 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
Level_ಠ Этот уровень гольфа поражает меня.
Эддисон Крамп

Что выводится, когда нет смежных срезов? (действительный ввод)
Эддисон Крамп

3
psработает и в MATL!
Дэвид

Тогда не будет никакой столбец всех 1с, то есть результат Pбудет [0,0,0...0], из которых Sит 0, как и ожидалось.
Линн

@ Давид Опубликуете это тогда? Возможно, вам понадобится Xps, если изображение может быть одной строкой (или спросить у ОП, есть ли минимальный размер)
Луис Мендо

7

APL, 4 байта

+/×⌿

Try it here.

Это мой первый ответ APL!

Спасибо @ jimmy23013 и @NBZ за сохранение байтов!


Это не функция. (+/×/⍉)не работает
jimmy23013

1
Но вы можете использовать, (+/×⌿)и это на 1 байт короче.
jimmy23013

Сохраните еще 2 байта, удалив скобки. У многих других ответов APL есть только анонимный +/×⌿ f←+/×⌿ f picture
набор

6

Баш + коммунальные услуги, 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's 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! (был неправ в течение 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).

Это отличный алгоритм @ Линн, но я нашел его независимо. (Я думал, что для этого где-то есть встроенная функция, все еще смотрящая: 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.