Самая большая площадь


9

Этот вопрос похож на Biggest Square в сетке .

Вызов

Учитывая матрицу 1и 0в строковом формате "xxxx,xxxxx,xxxx,xx.."или формате массива ["xxxx","xxxx","xxxx",...], Вы создадите функцию, которая определяет область самой большой квадратной подматрицы, которая содержит все 1.

Квадратная подматрица имеет одинаковую ширину и высоту, и ваша функция должна возвращать область самой большой подматрицы, которая содержит только 1.

Например:

Учитывая "10100,10111,11111,10010", это выглядит как следующая матрица:

1 0 1 0 0

1 0 1 1 1

1 1 1 1 1

1 0 0 1 0

Вы можете видеть выделенную жирным шрифтом 1самую большую квадратную подматрицу размером 2x2, поэтому ваша программа должна вернуть область, которая равна 4.

правила

  • Подматрица должна быть одинаковой ширины и высоты
  • Подматрица должна содержать только значения 1
  • Ваша функция должна вернуть область наибольшей подматрицы
  • Если подматрица не найдена, вернуть 1
  • Вы можете рассчитать площадь подматрицы, посчитав количество 1в подматрице

Контрольные примеры

Вход: "10100,10111,11111,10010" Выход: 4

Вход: "0111,1111,1111,1111" Выход: 9

Входной "0111,1101,0111" Выход: 1


Это Таким образом, самый короткий ответ в байтах побеждает.


3
Почему формат строки?
Стьюи Гриффин

3
Можем ли мы принять входные данные в виде двоичной (числовой) матрицы?
Стьюи Гриффин

5
Для [0] все еще требуется вывод 1?
l4m2

6
Задумайтесь, зачем возвращать 1, если подматрицы all-1 не найдено, разве 0 не имеет смысла? (В противном случае это просто особый случай)
Джонатан Аллан

2
Я полагаю, что оба ответчика не будут против, если вы измените спецификации, и я настоятельно рекомендую сделать это, потому что нет смысла возвращать 1, и это не делает представления более интересными.
მოიმო

Ответы:


2

Желе , 18 байт

+2 для обработки выходных данных подсписка no-all-1

ẆZṡ¥"L€$ẎȦÐfL€Ṁ²»1

Попробуйте онлайн! Или посмотрите набор тестов

Как?

ẆZṡ¥"L€$ẎȦÐfL€Ṁ²»1 - Link: list of lists of 1s and 0s
Ẇ                  - all slices (lists of "rows") call these S = [s1,s2,...]
       $           - last two links as a monad:
     L€            -   length of each (number of rows in each slice) call these X = [x1, x2, ...]
    "              -   zip with (i.e. [f(s1,x1),f(s2,x2),...]):
   ¥               -     last two links as a dyad:
 Z                 -       transpose (get the columns of the current slice)
  ṡ                -       all slices of length xi (i.e. squares of he slice)
        Ẏ          - tighten (to get a list of the square sub-matrices)
          Ðf       - filter keep if:
         Ȧ         -   any & all (all non-zero when flattened?)
            L€     - length of €ach (the side length)
              Ṁ    - maximum
               ²   - square (the maximal area)
                »1 - maximum of that and 1 (to coerce a 0 found area to 1)

Потрясающие. Можете ли вы добавить некоторые объяснения?
Луис Фелипе Де Иисус Муньос

Я буду, я пытаюсь думать о короче в первую очередь ...
Джонатан Аллан

@ Mr.Xcoder Я обновил, чтобы справиться с требованием на данный момент
Джонатан Аллан

5

Haskell , 113 121 118 117 байт

x!s=[0..length x-s]
t#d=take t.drop d
f x=last$1:[s*s|s<-min(x!0)$x!!0!0,i<-x!!0!s,j<-x!s,all(>'0')$s#i=<<(s#j)x,s>0]

Попробуйте онлайн!

-3 байта благодаря Лайкони !

-1 байт благодаря Линн !

+8 байтов за нелепое требование возврата 1, если нет подматрицы all-1s.

Объяснение / Ungolfed

Следующая вспомогательная функция просто создает смещения, xпозволяющие уменьшить их на s:

x!s=[0..length x-s]

x#yудалит yэлементы из списка и затем возьмет x:

t#d=take t.drop d

Функция fперебирает все возможные размеры для подматриц по порядку, генерирует каждую подматрицу соответствующего размера, проверяет, содержит ли она только '1's, и сохраняет размер. Таким образом, решение будет последней записью в списке:

--          v prepend a 1 for no all-1s submatrices
f x= last $ 1 : [ s*s
                -- all possible sizes are given by the minimum side-length
                | s <- min(x!0)$x!!0!0
                -- the horizontal offsets are [0..length(x!!0) - s]
                , i <- x!!0!s
                -- the vertical offsets are [0..length x - s]
                , j <- x!s
                -- test whether all are '1's
                , all(>'0') $
                -- from each row: drop first i elements and take s (concatenates them to a single string)
                              s#i =<<
                -- drop the first j rows and take s from the remaining
                                      (s#j) x
                -- exclude size 0...........................................
                , s>0
                ]

4

Haskell , 99 97 байт

b s@((_:_):_)=maximum$sum[length s^2|s==('1'<$s<$s)]:map b[init s,tail s,init<$>s,tail<$>s]
b _=1

Проверяет, является ли input квадратной матрицей, состоящей из единиц с s==('1'<$s<$s), если она есть, answer является длина ^ 2, иначе 0. Затем рекурсивно обрезает первый / последний столбец / строку и принимает максимальное значение, которое находит где угодно.

Попробуйте онлайн!



3

J , 33 27 байт

-6 байт благодаря FrownyFrog!

[:>./@,,~@#\(#**/)@,;._3"$]

Попробуйте онлайн!

Объяснение:

Я буду использовать первый тестовый пример в моем объяснении:

    ] a =. 3 5$1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1

Я генерирую все возможные квадратные подматрицы размером от 1 до количества строк ввода.

,~@#\создает список пар для размеров подматриц, ,.соединяя длину последовательных префиксов #\ввода:

   ,~@#\ a
1 1
2 2
3 3

Затем я использую их, чтобы разрезать x u ;. _3 yвходные данные на подматрицы. У меня уже есть x(список размеров); yправильный аргумент ](вход).

 ((,~@#\)<;._3"$]) a
┌─────┬─────┬─────┬───┬─┐
│1    │0    │1    │0  │0│
│     │     │     │   │ │
│     │     │     │   │ │
├─────┼─────┼─────┼───┼─┤
│1    │0    │1    │1  │1│
│     │     │     │   │ │
├─────┼─────┼─────┼───┼─┤
│1    │1    │1    │1  │1│
└─────┴─────┴─────┴───┴─┘

┌─────┬─────┬─────┬───┬─┐
│1 0  │0 1  │1 0  │0 0│ │
│1 0  │0 1  │1 1  │1 1│ │
│     │     │     │   │ │
├─────┼─────┼─────┼───┼─┤
│1 0  │0 1  │1 1  │1 1│ │
│1 1  │1 1  │1 1  │1 1│ │
├─────┼─────┼─────┼───┼─┤
│     │     │     │   │ │
└─────┴─────┴─────┴───┴─┘

┌─────┬─────┬─────┬───┬─┐
│1 0 1│0 1 0│1 0 0│   │ │
│1 0 1│0 1 1│1 1 1│   │ │
│1 1 1│1 1 1│1 1 1│   │ │
├─────┼─────┼─────┼───┼─┤
│     │     │     │   │ │
│     │     │     │   │ │
├─────┼─────┼─────┼───┼─┤
│     │     │     │   │ │
└─────┴─────┴─────┴───┴─┘

Для каждой подматрицы я проверяю, состоит ли она целиком из 1: (#**/)@,- выровнять матрицу и подсчитать количество элементов по их продукту. Если все элементы равны 1 с, результатом будет их сумма, в противном случае - 0:

   (#**/)@, 3 3$1 0 0 1 1 1 1 1 1
0
   (#**/)@, 2 2$1 1 1 1
4 

   ((,~@#\)(+/**/)@,;._3"$]) a
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1

0 0 0 0 0
0 0 4 4 0
0 0 0 0 0

0 0 0 0 0
0 0 0 0 0
0 0 0 0 0

Наконец, я выравниваю список результатов для каждой подматрицы и нахожу максимум:

>./@,

   ([:>./@,,~@#\(+/**/)@,;._3"$]) a
4

1
,~@#\и "1 2->"$
FrownyFrog

@FrownyFrog Спасибо! Я не знал о"$
Гален Иванов

1
#короче, чем сложение 1 с.
FrownyFrog

@ FrownyFrog Хм, это действительно так. Хорошо, спасибо!
Гален Иванов


2

Сетчатка , 143 байта

%`$
,;#
+%(`(\d\d.+;#)#*
$1¶$&¶$&#
\G\d(\d+,)|\G((;#+¶|,)\d)\d+
$1$2
)r`((11)|\d\d)(\d*,;?#*)\G
$#2$3
1,
#
Lv$`(#+).*;\1
$.($.1*$1
N`
-1G`
^$
1

Попробуйте онлайн! Ссылка включает в себя тестовые случаи. Принимает ввод как разделенные запятыми строки. Объяснение:

%`$
,;#

Добавьте a, ,чтобы завершить последнюю строку, a, ;чтобы отделить строки от #s и a #в качестве счетчика.

+%(`
)

Повторяйте блок до тех пор, пока больше не произойдет подстановок (потому что каждая строка теперь имеет только одну цифру).

(\d\d.+;#)#*
$1¶$&¶$&#

Тройной строкой, установив счетчик на 1 в первой строке и увеличивая его в последней строке.

\G\d(\d+,)|\G((;#+¶|,)\d)\d+
$1$2

В первой строке удалите первую цифру каждой строки, а во второй строке удалите все цифры, кроме первой.

r`((11)|\d\d)(\d*,;?#*)\G
$#2$3

В третьей строке поразрядно и первые две цифры вместе.

1,
#

В этот момент каждая строка состоит из двух значений: а) счетчика горизонтальной ширины и б) побитового числа и того количества битов, взятых из каждой строки. Преобразуйте все оставшиеся 1s в #s, чтобы их можно было сравнить со счетчиком.

Lv$`(#+).*;\1
$.($.1*$1

Найдите любые последовательности битов (по вертикали), которые соответствуют счетчику (по горизонтали), соответствующие квадратам 1s в исходном входе, и возведите в квадрат длину.

N`

Сортировать численно.

-1G`

Возьми самый большой.

^$
1

Особый случай нулевой матрицы.


2

JavaScript, 92 байта

a=>(g=w=>a.match(Array(w).fill(`1{${w}}`).join(`..{${W-w}}`))?w*w:g(w-1))(W=a.indexOf`,`)||1


2

APL (Dyalog Classic) , 21 20 байт

×⍨{1∊⍵:1+∇2×/2×⌿⍵⋄0}

Попробуйте онлайн!


Рекурсия! Ницца!
Захари

@ Zacharý Спасибо. На самом деле, вместо рекурсии я бы предпочел что-то вроде k's f \ x для монады f, которая (x; fx; ffx; ...) до сходимости, но в APL (пока) нет эквивалента. Выполнение этого с ⍣≡ занимает слишком много байтов.
НГН,

2

Питон 2 , 117 109 байт

Благодарю @etene за указание на неэффективность, которая стоила мне дополнительного байта.

lambda s:max(i*i for i in range(len(s))if re.search(("."*(s.find(',')-i+1)).join(["1"*i]*i),s))or 1
import re

Попробуйте онлайн!

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

В моих вычислениях, выполнение этого с анонимной лямбдой чуть короче определенной функции или полной программы. or 1Часть , в конце концов , необходимо только обрабатывать странный край случай, когда мы должны выход , 1если нет в них вход.


2

Python 2 , 116 115 117 109 байт

Благодарю @Kirill за помощь в игре в гольф и за умное и раннее решение

Изменить : Гольф 1 байт с использованием лямбда, я не знал, присвоение его переменной не учитывается в счетчик байтов.

Редактировать 2 : Кирилл указал, что мое решение не работает для случаев, когда вход содержит только 1s, я должен был исправить это и потерял два драгоценных байта ...

Редактировать 3 : больше игры в гольф благодаря Кириллу

Принимает строку через запятую, возвращает целое число.

lambda g:max(i*i for i in range(len(g))if re.search(("."*(g.find(",")+1-i)).join(["1"*i]*i),g))or 1
import re

Попробуйте онлайн!

Я независимо нашел ответ, близкий к ответу Кирилла, то есть основанный на регулярных выражениях, за исключением того, что я использую re.search и adef .

Он использует регулярное выражение, построенное во время каждого цикла, чтобы соответствовать постепенно увеличивающемуся квадрату и возвращает наибольшее или 1.


1
Хорошо, я как-то автоматически отбросил ifподход как «слишком длинный наверняка», но затем мне пришлось придумать какой-то другой способ сделать значение bool из матча. К сожалению, ваше решение пропускает один пункт - вы не можете иметь просто range(l)- оно упустит случай, когда нет нулей вообще. Например, возьмите 2-й контрольный пример и сделайте все 1 с - должно быть 16, а не 9.
Кирилл Л.

Блин, я думал о тестировании со всеми нулями, но не со всеми (никогда не упоминалось в тесте ...). Я постараюсь что-то придумать.
Этене

@KirillL. кстати, ты быстр! Я все еще работал над своим ответом, когда вы опубликовали свой, и был немного расстроен (и горд!), Когда увидел, что наши подходы похожи ... уровень здесь впечатляет.
Этене

1
Гольф еще несколько байтов, избавившись от дубликатов find. Теперь, когда наши коды больше не идентичны, я предлагаю, по крайней мере, исправить очевидные ошибки друг друга - в вашем случае дополнительный байт получается при использовании кортежа ("1"*i,)вместо списка.
Кирилл Л.

Спасибо, да, бесполезный кортеж довольно глуп с моей стороны. И дополнительно find, это было умно с вашей стороны.
Этене




1

Clojure, 193 байта

#(apply max(for [f[(fn[a b](take-while seq(iterate a b)))]R(f next %)R(f butlast R)n[(count R)]c(for[i(range(-(count(first R))n -1)):when(apply = 1(for[r R c(subvec r i(+ i n))]c))](* n n))]c))

Ух, все обострилось: o

Менее гольф:

(def f #(for [rows (->> %    (iterate next)    (take-while seq)) ; row-postfixes
              rows (->> rows (iterate butlast) (take-while seq)) ; row-suffixes
              n    [(count rows)]
              c    (for[i(range(-(count(first rows))n -1)):when(every? pos?(for [row rows col(subvec row i(+ i n))]col))](* n n))] ; rectangular subsections
          c))
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.