Зламати сейф!


10

Натхненний /puzzling/24334/to-catch-a-thief

Вам надається сітка ( сама nпо собі вводиться необов’язково), заповнена s і s (або будь-який інший символ на ваш вибір). Ви прагнете зробити кожну клітинку однаковою (або або ). Ви можете зробити ряд кроків, як визначено нижче (відзначте несхожість із загадковою посиланням SE):nn0101

  • Виберіть клітинку.
  • Кожна комірка в одному рядку та стовпці (крім самої комірки) змінюється на свою протилежність. 0до 1і 1до 0.

Виведіть мінімальну кількість рухів, необхідних для виконання завдання. Якщо нерозв’язане, виведіть що-небудь, крім невід'ємного цілого числа. Найкоротший код виграє.

Зразок даних

1 0 0
0 0 0
0 0 0

-1

1 1 1
1 1 1
1 1 1

0

1 0 1
0 1 0
1 0 1

1

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

2

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

2


3
Що робити, якщо головоломка нерозв’язна? Напр. 1000(Переставляти як квадрат, не важливо, як).
orlp


@orlp Будь-який вихід, який не є числом, зробить.
ghosts_in_the_code

Чи потрібно нам аналізувати вхідні дані чи це може бути будь-який вже заповнений тип даних масиву?
coredump

1
Яке рішення має перший тестовий випадок? Я не отримую цього рішення.
cardboard_box

Відповіді:


4

Матлаб 171 байт

Вхід має бути 2-матричною матрицею, так що ви б назвали це так c([1,1,1,1;0,0,0,0;0,0,0,0;1,1,1,1])(крапкою з комою починається новий рядок). Ця функція просто посилює всі можливі рухи, тому ми отримуємо час виконання O(2^(n^2)).

Як це робиться

Це робиться шляхом вибору всіх можливих способів заповнення іншої матриці однакового розміру одиницями та нулем, це в основному рахується в двійковій частині, де кожен запис матриці представляє певну потужність 2.

Потім виконуємо рухи на тих осередках, які дорівнюють 1, це робиться сумою (мод 2) двох двовимірних згортків з вектором розмірів 1xn і nx1.

Нарешті ми вирішуємо, чи справді ці ходи дали бажаний результат, обчислюючи стандартне відхилення для всіх записів. Стандартне відхилення - це лише нулі, якщо всі записи однакові. І кожного разу, коли ми дійсно знайшли бажаний результат, ми порівнюємо його з кількістю ходів попередніх рішень. Функція повернеться, infякщо задана проблема не вирішена.

Математика?

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

Версія для гольфу:

function M=c(a);n=numel(a);p=a;M=inf;o=ones(1,n);for k=0:2^n-1;p(:)=dec2bin(k,n)-'0';b=mod(conv2(p,o,'s')+conv2(p,o','s'),2);m=sum(p(:));if ~std(b(:)-a(:))&m<M;M=m;end;end

Повна версія (з виведенням фактичних рухів.)

function M = c(a)
n=numel(a);
p=a;
M=inf;                                               %current minimum of number of moves
o=ones(1,n);
for k=0:2^n-1;
    p(:) = dec2bin(k,n)-'0';                         %logical array with 1 where we perform moves
    b=mod(conv2(p,o,'same')+conv2(p,o','same'),2);   %perform the actual moves
    m=sum(p(:));                                     %number of moves;
    if ~std(b(:)-a(:))&m<M                           %check if the result of the moves is valid, and better
        M=m;
        disp('found new minimum:')
        disp(M)                                      %display number of moves of the new best solution (not in the golfed version)
        disp(p)                                      %display the moves of the new best solution                               (not in the golfed version)
    end
end

1

Perl 5, 498 байт

Це приймає 'n' і бажаний результат, і виводить кількість, або 'X', якщо немає.

Наприклад:

perl ./crack.golf.pl 3 000111111

дає 2. Він буде працювати лише тоді, коли n ^ 2 <= 64, значить n <= 8. Хоча це досить повільно, навіть якщо n так низько, як 5. Він будує ^ 3-бітовий масив і попередньо сортує масив 2 ^ (n ^ 2), бо чому б ні ?

Я витратив тут кілька ліній каналів для читабельності :

$n=shift;$y=shift;$p=$n*$n;@m=(0..$n-1);@q=(0..$p-1);@v=(0..2**$p-1);@d=map{0}(@q);@b=map{$r=$_;map{$c=$_;$d[$r*$n+$_]^=1 for(@m);$d[$_*$n+$c]^=1 for(@m);$j=0;$k=1;
map{$j|=$k*$d[$_];$k<<=1;}@q;@d=map{0}(@q);$j;}@m}@m;for$k(sort{$a->[0]<=>$b->[0]}map{$z=0;map{$z+=$_}split(//,sprintf"%b",$_);[$z,$_]}@v){$l=sprintf"%0${p}b",$k->[1];
@m=map{$_}split(//,$l);$s=0;for(@q){$s^=$b[$_]if$m[$_];}$z=0;map{$z+=$_}split(//,sprintf"%b",$_);if($y eq sprintf"%0${p}b",$s){print"$k->[0]\n";exit 0;}}print"X\n";
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.