Найбільша площа


9

Це питання схоже на Найбільший квадрат у сітці .

Виклик

Давши матрицю 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 для обробки поточного виходу підсистеми "не все-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)

Дивовижно. Ви можете додати пояснення?
Luis felipe De jesus Munoz

Буду, спершу намагаюся придумати коротше ...
Джонатан Алан

@ 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-1 ..

Пояснення / Недозволений

Наступна допоміжна функція просто створює компенсації, 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

Перевіряє, чи вхід є квадратною матрицею лише тих s==('1'<$s<$s), що мають відповідь, довжина ^ 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│   │ │
├─────┼─────┼─────┼───┼─┤
│     │     │     │   │ │
│     │     │     │   │ │
├─────┼─────┼─────┼───┼─┤
│     │     │     │   │ │
└─────┴─────┴─────┴───┴─┘

Для кожної підматриці я перевіряю, чи складається вона повністю з 1s: (#**/)@,- вирівняти матрицю та зменшити кількість елементів за їх продуктом. Якщо всі предмети дорівнюють 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
#коротше, ніж додавання 1s.
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,
#

У цей момент кожен рядок складається з двох значень, а) лічильника горизонтальної ширини і b) порозрядних і з цього безлічі бітів, взятих з кожного рядка. Перетворіть решту 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ý

@ Zacharý Спасибі Насправді, замість рекурсії я вважаю за краще щось подібне k's f \ x для монадичного f, яке є (x; fx; ffx; ...) до конвергенції, але еквівалента в APL (поки) немає. Якщо це зробити з ⍣≡, це займе багато байтів.
ngn

2

Python 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

Пітон 2 , 116 115 117 109 байт

Подяка @Kirill за те, що я допоміг мені ще більше гольфу та за його розумне та раннє рішення

Редагувати : Гольф на 1 байт, використовуючи лямбда, я не знав, привласнення його до змінної не рахується з кількістю байтів.

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

Edit 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підхід як "занадто довгий напевно", але потім повинен був створити інший спосіб, щоб зробити значення булінгу з матчу. На жаль, у вашому рішенні не вистачає однієї точки - ви не можете простоrange(l) - це пропустить випадок, коли взагалі немає нулів. Наприклад, візьміть 2-й тестовий випадок і зробіть це всі 1 - це повинно стати 16, а не 9.
Кирилл Л.

Блін, я думав про тестування з усіма нулями, але не з усіма (ніколи не згадується в виклику ...). Я спробую щось придумати.
etene

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

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

Дякую, так, марний кортеж з мого боку досить дурний. І зайве findтеж, що тобі було розумно.
etene




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

Нічого, ескалація: о

Менше гольфу:

(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.