Діагоналізація блоку мінімальних витрат


10

Розглянемо двійкові діагональні блок-матриці, які мають основні блоки 1s на головній діагоналі, а 0 - скрізь. Назвемо такі матриці "дійсними" матрицями.

Наприклад, ось кілька дійсних матриць 4x4:

1 0 0 0     1 1 0 0     1 0 0 0     1 0 0 0     1 1 0 0    1 1 1 1
0 1 0 0     1 1 0 0     0 1 1 0     0 1 1 1     1 1 0 0    1 1 1 1
0 0 1 0     0 0 1 0     0 1 1 0     0 1 1 1     0 0 1 1    1 1 1 1
0 0 0 1     0 0 0 1     0 0 0 1     0 1 1 1     0 0 1 1    1 1 1 1

Зауважте, що альтернативним способом опису таких матриць є те, що є ланцюг квадратних блоків 1 зліва-вліво-внизу праворуч, торкаючись кута до кута, а всюди ще 0.

Для порівняння, ось кілька недійсних матриць 4x4:

1 0 1 0     1 0 1 0     1 1 0 0     0 1 1 1     1 1 0 0    0 0 0 0
0 1 1 1     0 1 0 1     1 1 0 0     0 1 1 1     1 1 0 0    0 0 0 0
1 0 0 1     1 0 1 0     0 0 0 0     0 1 1 1     1 1 0 0    0 0 0 0
0 0 1 0     0 1 0 1     0 0 0 1     1 0 0 0     0 0 1 1    0 0 0 0

Вам буде дано nпо nбінарної матриці в якості вхідних даних - яку мінімальну кількість 0бітів вам потрібно задати 1, щоб отримати дійсну матрицю?

Ви можете написати функцію або програму взяття в будь-якому зручному рядку, список або матриці форматі , що представляє собою nпо nматриці 0 і 1 ( до тих пір , як він не препроцесор). Рядки повинні бути чітко розділені певним чином, тому формати, як 1D масив бітів, не допускаються.

Це , тому мета - мінімізувати кількість байтів у вашій програмі.

Приклади

Наприклад, якщо вхід є

0 0 0 0 0
0 0 1 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 1

то відповідь 5, оскільки ви можете встановити п'ять 0біт, 1щоб отримати:

1 0 0 0 0
0 1 1 0 0
0 1 1 0 0
0 0 0 1 0
0 0 0 0 1

і це мінімальна необхідна кількість. Однак, якщо вхід був

0 0 0 0 1
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0

то відповідь - 24, оскільки єдиною дійсною матрицею 5x5, де справа вгорі 1є матриця всіх 1s.

Тестові справи

Тести представлені тут як двовимірний масив цілих чисел.

[[0]] -> 1
[[1]] -> 0
[[0,1],[0,0]] -> 3
[[1,0],[0,0]] -> 1
[[0,0,0],[0,1,0],[0,0,0]] -> 2
[[0,1,0],[0,0,0],[0,1,0]] -> 7
[[0,1,0],[1,0,0],[0,0,1]] -> 2
[[1,1,1],[1,1,1],[1,1,1]] -> 0
[[0,0,0,0],[0,0,1,0],[0,1,0,0],[0,0,0,0]] -> 4
[[0,0,1,0],[0,0,0,0],[0,0,0,0],[0,0,0,1]] -> 8
[[0,0,1,0],[0,0,0,0],[0,0,0,0],[0,0,1,0]] -> 14
[[0,0,1,0],[0,0,0,0],[0,0,0,0],[0,1,0,0]] -> 14
[[0,0,0,0,0],[0,0,0,0,0],[0,1,0,0,0],[0,0,0,0,1],[0,0,0,0,0]] -> 7
[[0,0,0,0,0],[0,0,0,0,0],[1,0,0,0,0],[0,0,0,0,1],[0,0,0,0,0]] -> 11
[[0,0,0,0,0],[0,0,1,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,1]] -> 5
[[0,0,0,0,1],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]] -> 24
[[0,0,0,1,0],[0,0,0,0,1],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]] -> 23
[[0,1,0,0,0],[1,0,0,0,0],[0,0,1,0,0],[0,0,0,0,1],[0,0,0,1,0]] -> 4
[[0,1,1,1,0],[0,1,1,0,1],[0,1,1,1,0],[0,1,0,0,1],[0,0,0,0,0]] -> 14

Примітки

Відповіді:


3

MATL , 46 43 байти

nX^tQt:qZ^!tsb=Z)"@!"@1$l]@n$YdG-Q?6MG>zvX<

Вхід - це 2D масив з крапкою з комою як роздільник рядків. Наприклад, вхід для останнього тестового випадку є

[0,1,1,1,0;0,1,1,0,1;0,1,1,1,0;0,1,0,0,1;0,0,0,0,0]

Спробуйте в Інтернеті! Або перевірити всі тестові випадки (код трохи змінений, щоб прийняти всі дані; результати з’являються через кілька секунд)

Пояснення

Нехай вхід буде матрицею N × N. Код спочатку обчислює всі ( N +1) - пар розмірів блоків, які створюють відповідний розмір матриці. Наприклад, для N = 4 кортежі є 0 0 0 0 4, 0 0 0 1 3, ..., 4 0 0 0 0. Для кожного кортежу він будує блок-діагональну матрицю з тими розмірами блоків. Потім він перевіряє, чи охоплює матриця всі 1записи на вході, і якщо так, то враховує кількість 1записів, яких не було у введенні. Кінцевий результат - мінімум усіх отриманих чисел.

nX^      % Implicit input  an N×N matrix. Get N
t        % Duplicate N
Qt:q     % Vector [0 1 ... N]
Z^       % Cartesian power. Gives 2D array
!ts      % Transpose, duplicate, sum of each column
b=       % Logical vector that equals true if the sum is N
Z)       % Filter columns according to that. Only keep columns that sum to N. Each 
         % column is the size of one block
"        % For each column
  @      %   Push that column
  "      %   For each entry of that column
    @    %     Push that entry
    1$l  %     Square matrix with that size, filled with 1
  ]      %   End
  @n     %   Column size. This is the number of blocks in the block-diagonal matrix
  $Yd    %   Build block-diagonal matrix from those blocks
  G-Q    %   Subtract input matrix element-wise, and add 1
  ?      %   If all entries are nonzero (this means each that entry that is 1 in the
         %   block-diagonal matrix is also 1 in the input matrix)
    6M   %   Push block-diagonal matrix again
    G>   %   For each entry, gives 1 if it exceeds the corresponding entry of the
         %   input, that is, if the block-diagonal matrix is 1 and the input is 0
    z    %   Number of 1 entries
    v    %   Concatenate vertically with previous values
    X<   %   Take minimum so far
         %   Implicit end
         % Implicit end
         % Implicit display

3

Пітон з нумером, 102

from numpy import*
lambda M:sum(diff([k for k in range(len(M)+1)if(M|M.T)[:k,k:].any()-1])**2)-M.sum()

Ефективний алгоритм. Знаходить «точки шиї» по діагоналі, які можуть відокремлювати блоки. У них усі 0 і вгорі, і вправо, а також внизу та зліва. Мінімальні блоки - це між точками шиї.

??000
??000
00???
00???
00???

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


2

Pyth, 45 байт

-hSlMf@I.DRlQx1sQTms.b^+LsYN2d+0._ds.pM./lQss

Завдання складне, тому воно досить довге.

Спробуйте в Інтернеті: Демонстрація або Тестовий набір

Пояснення:

s.pM./lQобчислює всі цілі розділи len(matrix). ms.b^+LsYN2d+0._dперетворює їх у пари координат. Наприклад розділ [1, 2, 2]з 5перетворюється в [[0,0], [1,1], [1,2], [2,1], [2,2], [3,3], [3,4], [4,3], [4,4].

f@I.DRlQx1sQTпотім фільтри для розділів, які повністю перекривають матрицю ( .DRlQx1sQобчислює всі пари координат активних комірок у матриці).

-hSlM...ss підраховує осередки кожного решти розділів, вибирає одну з найменшими осередками та віднімає вже активні комірки.


0

Матриці , 180 байт (неконкурентовані)

Matricks - це новий esolang, який я створив зовсім недавно, щоб вирішити проблеми з матрицею (наприклад, ця), маючи лише два типи даних: floats та matricies. Він ще не повністю представлений, і все ще має багато відсутніх операцій (мені довелося додати певну функціональність для цього завдання). У всякому разі, ось код:

il=1:j3;:bdx;;;s1::L;j1;;
b{q:1;mgr:c;|gc:r;|(r=c)|(gr-1:c;|gr:c+1;)&(rec)|(gr+1:c;|gr:c-1;)&(cer):l:L;};z:(l-1)/2;B1;s1::g1:;-1;ig1:;=0:j2;:j1;;
s1::d{q:1;};;kg1:;-g:;;
kg:;*-1+1;

Пояснення

Перша частина il=1:j3;:...;перевіряє, чи масив розміру 1. Якщо він є, він переходить до останнього рядка kg:;*-1+1;, що є простою 0 <-> 1функцією.

В іншому випадку це продовжується з рештою коду. bdx;;;встановлює комірку 0,0на поточну суму і s1::L;j1;створює лічильник у комірці в рядку нижче.

Наступний рядок трохи складніше. Це цикл, який запускається nразів, nбудучи розміром матриці. Я буду використовувати приклад 3-го тесту. Коли ми вперше переходимо до другого рядка, матриця виглядає приблизно так:

1 0 1
2 0 0

Спочатку ми переходимо до розуміння матриці {q:1;m...;}. Це робить діагональ і намагається максимально очистити 0, що потребує заповнення. Все це здійснюється за допомогою простих булевих операторів. Потім додаємо його до поточної матриці, надаючи це:

    V--data we want to keep
1 1 1 0 1 <-|
1 1 2 0 0 <-- old matrix

Потім ми вирізаємо стару матрицю за допомогою z:(l-1)/2;та обертаємо всю матрицю вліво за допомогою B1;. Це дає нам матрицю, готову до наступної ітерації, виглядає так:

1 1 1
2 1 1

Нарешті, ми декрементуємо лічильник, перевіряємо його та продовжуємо ig1:;=0:j2;:j1;;

Як тільки цикл виривається, ми знаходимо нову суму і встановлюємо старе місце лічильника s1::d{q:1;};;. Нарешті, ми беремо різницю і повертаємось kg1:;-g:;;. kвстановлює значення поточного масиву, а друк неявний.

...

Як бачите, Матрікс досить багатослівний, і не дуже гарна мова для гольфу. Але чорт, я хотів це показати.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.