Це L-опукла?


14

Фон

Полімін називається L-опуклий , якщо це можливо подорожувати з будь-якої плитки будь-якої іншої плитки з допомогою L-подібною траєкторією, тобто шлях , який йде в кардинальних напрямах і змінює напрямок більш ніж один раз. Наприклад, поліоміно з 1фігури

0 0 1 1 1 0

1 1 1 1 0 0

1 1 0 0 0 0

не є L-опуклим, оскільки обидві L-подібні доріжки знизу вліво 1праворуч 1містять 0:

0>0>1>1>1 0
^       ^
1 1 1 1 0 0
^       ^
1>1>0>0>0 0

Однак полиомино 1s на цій фігурі є L-опуклим:

0 1 1 1 0 0

1 1 1 1 1 1

0 1 1 0 0 0

Вхідні дані

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

Вихідні дані

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

Правила та підрахунок балів

Ви можете написати або повну програму, або функцію. Виграє найменший байт, а стандартні лазівки заборонені.

Випробування

Ці тестові випадки повинні працювати також, якщо ви обертаєте або відображаєте масиви або додаєте рядки 0s до будь-яких меж.

False instances
01
10

111
101
111

1101
1111
1110

1100
1000
0011

01100
11110
01110
00110

011000
011110
001111

True instances
1

01
11

010
111
010

001
011
111

11100
11110
01100
01000

011000
011000
111100
111111
001000

Дуже приємний виклик, мені сподобалось =)
недолік

Про введення: це дозволена строка з обмеженим рядком , якщо нашій мові не вистачає масивів ?
edc65

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

Відповіді:


6

Равлики , 45 24

&
!{\1t\1!{o\1,nf\1,!.!~

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


О БОЖЕ МІЙ!! Чи є онлайн-перекладач, де ми могли б пограти з цим?
недолік

1
@flawr Ви можете створити його з джерела зі вихідним кодом тут .
Олексій А.

6

Матлаб, 182 байт

Ідея: Повторіть для кожного 1в поліоміно матриці:

  • Створіть нову матрицю лише із заданим, 1але рештою нульовим.
  • для кожного 1з цієї нової матриці (повторюйте, поки нічого більше не зміниться)
    • додати 1як сусідів у напрямку x, якщо 1в поліномі є сусіди
  • для кожного 1з цієї нової матриці (повторюйте, поки нічого більше не зміниться)
    • додати 1як сусідів у напрямку x, якщо 1в поліномі є сусіди

Тепер 1у новій матриці слід охопити всі 1поліноміоматриці, до яких можна дістатись із заданої вихідної точки, спочатку рухаючись у напрямку x, а потім у напрямку y. Тепер ми можемо повторити той самий процес, але спочатку переходимо в напрямку y, а потім у напрямку x. Тепер кожна 1поліоміно матриця повинна бути досягнута одночасно або обидва рази. Якщо ні, то ми знайшли положення в матриці многочленів, яке неможливо дістати з будь-якого іншого положення по- Lшляху.

Гольф:

function r=f(a);[i,j,b]=find(a);N=nnz(i);r=1;for k=1:N;K=1:3;for l=1:2;c=b;b=a*0;b(i(k),j(k))=1;for z=1:2*N; b=conv2(b+0,K,'s')&a;if z==N;K=K';end;end;end;r=r*all(b(:)|c(:)>=a(:));end

З коментарями:

function r=codegolf_L_convex(a);
%a=[0,1;1,1];
[i,j,b]=find(a);%b just needs to be initialized, does not really mattter
N=nnz(i);%number of ones in the matrix
r=1;%return value
for k=1:N;%go throu all '1' in the matrix
    %expand that pixel in x dir:
    K=1:3;%convolution kernel (just three positive values needed)
    for l=1:2;%first horizontal->vertical then vertical->horizontal
        c=b;%backup for considering both runs
        b=a*0;
        b(i(k),j(k))=1; %set the seed
        for z=1:2*N;     
            b=conv2(b+0,K,'s')&a; %expand the seed horizontally (or vertically for the second half) but only within the polyomino
            if z==N;
                K=K'; %change horizontal/vertical 
            end;
        end;
    end;
    r=r*all(b(:)|c(:)>=a(:));%check whether we can really reach every point
end

Сценарій тестових випадків:

disp('all false -------------');
a=[0,1;1,0];
f(a)
a=[1,1,1;1,0,1;1,1,1];
f(a)
a=[1,1,0,1;1,1,1,1;1,1,1,0];
f(a)
a=[1,1,0,0;1,0,0,0;0,0,1,1];
f(a)
a=[0,1,1,0,0;1,1,1,1,0;0,1,1,1,0;0,0,1,1,0];
f(a)
a=[0,1,1,0,0,0;0,1,1,1,1,0;0,0,1,1,1,1];
f(a)
 disp('all true +++++++++++++');
a=[1];
f(a)
a=[0,1;1,1];
f(a)
a=[0,1,0;1,1,1;0,1,0];
f(a)
a=[0,0,1;0,1,1;1,1,1];
f(a)
a=[1,1,1,0,0;1,1,1,1,0;0,1,1,0,0;0,1,0,0,0];
f(a)
a=[0,1,1,0,0,0;0,1,1,0,0,0;1,1,1,1,0,0;1,1,1,1,1,1;0,0,1,0,0,0];
f(a)

2

Javascript ES6, 290 байт

Гаразд, можливо, він не виграє жодної нагороди за стислість, але він використовує новий підхід. Про те, як це працює, див.

Доказ цього методу можна знайти в: Стільникові автомати та дискретні складні системи .

L=a=>[1,0,1].every($=>(a=a[0].map((_,col)=>a.map(row=>row[col]))).map(r=>($?r.reverse():r).join``).every((r,i,b)=>r.replace(/^(0*)(1*)(0*)$|(.+)/,(_,s,m,o,e)=>(c=e)?'':!m||b[i-1]&&+b[i-1][s.length]?1:b.every((r,j)=>j<i||(c=c||!+r[l=s.length])?r.search(`0{${l}}.*0{${o.length}}`)+1:1)||'')))

Безголівки:

function L(a) {
  /* Runs three times and ensure all pass validation
   * 1: horizontally reversed
   * 2: 90 degrees rotated
   * 3: original
   *
   *     | 1:  | 2:  | 3:
   * =====================
   * 001 | 100 | 111 | 001
   * 011 | 110 | 011 | 011
   * 111 | 111 | 001 | 111
   *
   * By finding maximal rectangles with corners on all NW and NE corners
   * (separately) of a HV-convex polyomino and ensuring it doesn't enter the
   * boundaries labelled ABCD for the rectangle X below:
   *
   *   A  |         |  B
   * -----===========-----
   *      |    X    |
   * -----===========-----
   *   C  |         |  D
   *
   * The first iteration tests the NE corners and horizontal convexity.
   * The second iteration test vertical convexity.
   * The third iteration tests the NW corners.
   *
   * If all pass then the polyomino is L-convex.
   */
  return [1,0,1].every(function($){
    return (a=a[0].map((_,col)=>{
      // Transpose rows with columns
      return a.map(row=>row[col])
    })).map(row=>{
      // Join rows as strings and on odd iterations reverse them
      return ($ ? row.reverse() : row).join``
    }).every(function(row, i, b) {
      if (i == 0) console.log(b.join('\n'));
      return row.replace(/^(0*)(1*)(0*)$|(.+)/, function(_, start, middle, end, invalid) {
        // Non H-convex polyomino (0 between 1s)
        if (invalid) return '';
        // Is not a NW corner (character above is 1)
        if (!middle || b[i-1] && +b[i-1][start.length]) return 1;
        c=1;
        return b.every(function(row, j) {
          // Above or below maximal rectangle from corner
          if (j < i || !(c=c&&+row[l=start.length])) {
            // Area before and after maximal rectangle doesn't contain 1
            return row.search(`0{${l}}.*0{${end.length}}`)+1
          }
          return 1;
        }) || '';
      });
    });
  });
}

1
Ха, ця стаття - це те, де я отримав натхнення для цього виклику!
Згарб

@ Zgarb Стаття була чудовою і одна з небагатьох, яку я могла знайти, що мала сенс для того, хто не орієнтований на математику.
Джордж Рейт

2

Математика, 129 127 байт

3>GraphDiameter@Graph[#,#<->#2&@@@Select[#~Tuples~2,!FreeQ[#-#2&@@#,0]&]]&@Position[#,1]&&{#,Thread@#}~FreeQ~{___,1,0..,1,___}&

Пояснення:

По-перше, якщо в одному рядку або стовпці є 0між двома 1s, масив не є L-опуклим, тому що ми не можемо з'єднати два 1s.

Виключивши цей випадок, кожні два 1s в одному рядку чи стовпчику можна з'єднати прямим шляхом. Ми можемо створити графік, вершинами якого є позиції 1s в масиві, а ребра - пари 1s в одному рядку або стовпці. Тоді масив L-опуклий тоді і тільки тоді, якщо діаметр графіка менше 3.


1
Чи можете ви дати пояснення, як це працює? Я не збираюся порушувати безглуздість, яку ніхто не міг зрозуміти =)
недолік

Як це розпізнає перший та четвертий помилкові екземпляри (відключені)?
Згарб

1
@ Zgarb Якщо графік відключений, його діаметр - нескінченність.
алефальфа

2

JavaScript (ES6) 174

Дивлячись на сітку порожніх або заповнених комірок, для будь-якої пари заповнених комірок я перевіряю горизонтальні шляхи до іншого стовпчика комірок (їх може бути 1, якщо комірки в одному рядку, інакше або 2) та вертикальні шляхи до інший рядок комірок (їх також може бути 1 або 2). Якщо я знаходжу порожню клітинку в обох вертикальних контурах або обох горизонтальних контурах, між ними не може бути шляху у формі L.

(Мені було важко намагатися викласти це пояснення - я сподіваюся, що це було зрозуміло)

Випробуйте запуск фрагмента нижче в будь-якому веб-переглядачі, сумісному з EcmaScript 6

F=p=>!p.some((n,y)=>n.some((q,x)=>q&&p.some((o,u)=>o.some((q,t)=>{for(f=0,i=y;q&i<=u;i++)f|=!p[i][x]|2*!p[i][t];if(f<3)for(f=0,j=x;q&j<=t;j++)f|=!n[j]|2*!o[j];return f>2}))))

// TEST
console.log=(...x)=>O.innerHTML+=x+'\n'

tko = [
 [[0,1],[1,0]]
,[[1,1,1],[1,0,1],[1,1,1]]
,[[1,1,0,1],[1,1,1,1],[1,1,1,0]]
,[[1,1,0,0],[1,0,0,0],[0,0,1,1]]
,[[0,1,1,0,0],[1,1,1,1,0],[0,1,1,1,0],[0,0,1,1,0]]
,[[0,1,1,0,0,0],[0,1,1,1,1,0],[0,0,1,1,1,1]]
]
tko.forEach(t=>(console.log(t.join`\n`+`\nFalse? ${F(t)}\n`)));
tok = [
 [[1]]
,[[0,1],[1,1]]
,[[0,1,0],[1,1,1],[0,1,0]]
,[[0,0,1],[0,1,1],[1,1,1]]
,[[1,1,1,0,0],[1,1,1,1,0],[0,1,1,0,0],[0,1,0,0,0]]
,[[0,1,1,0,0,0],[0,1,1,0,0,0],[1,1,1,1,0,0],[1,1,1,1,1,1],[0,0,1,0,0,0]]
]  
tok.forEach(t=>(console.log(t.join`\n`+`\nTrue? ${F(t)}\n`)));

// LESS GOLFED

U=p=>
  !p.some((n,y)=>  
    n.some((q,x)=> 
      q && p.some((o,u)=>  
        o.some((q,t)=>{
          for(f=0,i=y; q&i<=u; i++)f|=!p[i][x]|2*!p[i][t]
          if (f<3)
            for(f=0,j=x; q&j<=t; j++)f|=!n[j]|2*!o[j]
          return f>2
        })
      )
    )
  )
<pre id=O></pre>

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