Визначте арборально задоволені набори точок


14

Arborally задоволені задане значення є 2D безлічі точок, що для будь-якої осі вирівняно прямокутника , який може бути утворений з використанням двох точок в наборі як протилежні кути, що прямокутник містить або штрихи , щонайменше , один іншу точку. Ось еквівалентне визначення з Вікіпедії:

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

Наступне зображення ілюструє, як утворюються прямокутники. Цей набір точок НЕ задоволений арборально, оскільки цей прямокутник повинен містити принаймні ще одну точку.

введіть тут опис зображення

У мистецтві ASCII цей набір точок може бути представлений як:

......
....O.
......
.O....
......

Невелика модифікація може зробити це арборально задоволеним:

......
....O.
......
.O..O.
......

Вище видно, що всі прямокутники (з яких є лише один) містять щонайменше три точки.

Ось ще один приклад складнішого набору точок, який задовольняється арборально:

введіть тут опис зображення

Для будь-якого прямокутника, який може бути намальований на дві точки, цей прямокутник містить щонайменше одну точку.

Змагання

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

Додаткові правила:

  • Ви можете вибрати символи Oта .замінити їх будь-якою іншою парою символів для друку ASCII. Просто вкажіть, яке відображення символів використовує ваша програма.
  • Сітка завжди буде прямокутної. Доступний новий рядок.

Більше прикладів

Арборально задоволений:

.OOO.
OO...
.O.OO
.O..O
....O

..O..
OOOO.
...O.
.O.O.
...OO

O.O.
..O.
OOOO
.O.O
OO..

...
...
...

...
..O
...

O.....
O.O..O
.....O

OOO.OO

Не задоволений арборальною справою:

..O..
O....
...O.
.O...
....O

..O..
O.OO.
...O.
.O.O.
...OO

O.....
..O...
.....O

1
Тож нам заборонено приймати дані як список координат замість ASCII? Якщо ні, то я не можу вважати вхідним записом як двовимірний список цілих чисел (0 і 1) для відображення точок?
Денкер

Чи може сітка мати 0 площі?
feersum

Відповіді:


7

Равлики , 29 30 39 байт

!{t\Oo\.+c\.,\O!{t\O{w!(.,~}2

Він працює, відшукуючи дві сторони прямокутника, а потім перевіряючи, чи є якийсь квадрат, що містить O, такий, що пересування по прямій площі від квадрата в 2 кардинальних напрямках призведе до удару в сторону прямокутника.

Друкує максимум 1 та площу сітки, якщо вхід "виконаний арборально"; інакше 0.


3

Oracle SQL 11.2, 364 344 байт

WITH v AS(SELECT MOD(LEVEL-1,:w)x,FLOOR((LEVEL-1)/:w)y FROM DUAL WHERE'O'=SUBSTR(:g,LEVEL,1)CONNECT BY LEVEL<=LENGTH(:g))SELECT a.*,b.*FROM v a,v b WHERE b.x>a.x AND b.y>a.y MINUS SELECT a.*,b.*FROM v a,v b,v c WHERE((c.x IN(a.x,b.x)AND c.y>=a.y AND c.y<=b.y)OR(c.y IN(a.y,b.y)AND c.x>=a.x AND c.x<=b.x))AND(c.x,c.y)NOT IN((a.x,a.y),(b.x,b.y));

: g - сітка як рядок
: w - ширина сітки

Не повертається жодна лінія як тривожна, поверніть прямокутники, які не відповідають критеріям, як хибні

Без гольфу

WITH v AS
(
  SELECT MOD(LEVEL-1,:w)x,FLOOR((LEVEL-1)/:w)y,SUBSTR(:g,LEVEL,1)p 
  FROM   DUAL 
  WHERE  'O'=SUBSTR(:g,LEVEL,1)
  CONNECT BY LEVEL<=LENGTH(:g)
)
SELECT a.*,b.*FROM v a,v b
WHERE b.x>a.x AND b.y>a.y
MINUS
SELECT a.*,b.*FROM v a,v b,v c
WHERE((c.x IN(a.x,b.x) AND c.y>=a.y AND c.y<=b.y) OR (c.y IN(a.y,b.y) AND c.x>=a.x AND c.x<=b.x))
  AND(c.x,c.y)NOT IN((a.x,a.y),(b.x,b.y));

Вид v обчислює координати кожної точки O.
Перша частина мінусу повертає всі прямокутники, де застереження гарантує, що крапка не може бути сполучена з самим собою.
Друга частина шукає третю точку в кожному прямокутнику. Ця точка повинна мати одну координату, х або у, рівну цій координаті для однієї з двох точок, що визначають прямокутник. Інша координата цієї третьої точки повинна бути в діапазоні, обмеженому цією координатою для кожної точки, що визначає прямокутник.
Остання частина пункту де гарантує, що третя точка не є однією з двох точок, що визначають прямокутник.
Якщо всі прямокутники мають принаймні третю точку, то перша частина мінусу дорівнює другій частині, і запит нічого не повертає.


2

MATL , 38 байт

Ti2\2#fh!XJ"J@-XKtAZ)"@K-@/Eq|1>~As2>*

Для цього використовується двовимірний масив знаків як вхідний текст, рядки розділені між собою ;. Тож перший приклад

['......';'....O.';'......';'.O..O.';'......']

Решта тестів у такому форматі наведені нижче.

  • Арборально задоволений:

    ['.OOO.';'OO...';'.O.OO';'.O..O';'....O']
    ['..O..';'OOOO.';'...O.';'.O.O.';'...OO']
    ['O.O.';'..O.';'OOOO';'.O.O';'OO..']
    ['...';'...';'...']
    ['...';'..O';'...']
    ['O.....';'O.O..O';'.....O']
    ['OOO.OO']
    
  • Не задоволений арборальним:

    ['..O..';'O....','...O.';'.O...';'....O']
    ['..O..';'O.OO.';'...O.';'.O.O.';'...OO']
    ['O.....';'..O...';'.....O']
    

Спробуйте в Інтернеті! Ви також можете перевірити всі тестові випадки одночасно .

Пояснення

Код спочатку отримує координати символів Oна вводі. Потім він використовує дві вкладені петлі. Зовнішня петля підбирає кожну точку P (2-кортеж її координат), порівнює з усіма точками і зберігає точки, які відрізняються від P у двох координатах. Це ті точки, ніж вони можуть утворювати прямокутник з P. Назвіть їх набір Р.

Внутрішня петля вибирає кожну точку T з R і перевіряє, чи містить прямокутник, визначений P і T, принаймні 3 точки. Для цього він віднімає P від ​​усіх точок; тобто пересуває початок координат до P. Точка знаходиться у прямокутнику, якщо кожна його координата, поділена на відповідну координату Т, знаходиться в замкнутому інтервалі [0, 1].

T          % push "true"
i          % take input 2D array
2\         % modulo 2: gives 1 for 'O', 0 for '.'
2#f        % row and column coordinates of ones. Gives two column arrays
h!         % concatenate horizontally. Transpose. Each point is a column
XJ         % copy to clipboard J
"          % for each column
  J        %   push all points
  @-       %   subtract current point (move to origin)
  XK       %   copy to clipboard K
  tA       %   logical index of points whose two coordinates are non-zero
  Z)       %   keep only those points. Each is a column
  "        %   for each column (point)
    @K-    %     push that point. Subtract all others
    @/     %     divide by current point
    Eq|1>~ %     true if in the interval [0,1]
    A      %     true if that happens for the two coordinates
    s      %     sum: find out how many points fulfill that
    2>     %     true if that number is at least 3
    *      %     multiply (logical and). (There's an initial true value at the bottom)
           %   end
           % end
           % implicit display

Мені більше подобався Дон Мюслі, чому ти змінив його назад? :(
Денкер

@DenkerAffe :-) Ну, я повернувся до свого справжнього імені. Інший був веселим, але був призначений як тимчасовий
Луїс Мендо

1
Це не людина з реального життя, нам тут потрібно ще весело! :)
Денкер

@DenkerAffe У майбутньому я можу повернутися до цього імені або до якогось іншого. Як щодо джинсової душі? :-D
Луїс Мендо

1
... і вам також доведеться почекати 30 днів (я думаю)
Стюі Гріффін

2

PHP, 1123 байт , 851 байт , 657 байт

(новачок php)

<?php
$B=array_map("str_split",array_map("trim",file('F')));$a=[];$b=-1;foreach($B as $c=>$C){foreach($C as $d=>$Z){if($Z=='O'){$a[++$b][]=$c;$a[$b][]=$d;}}}$e=array();foreach($a as $f=>$l){foreach($a as $g=>$m){$h=$l[0];$i=$l[1];$j=$m[0];$k=$m[1];if($h!=$j&&$i!=$k&&!(in_array([$g,$f],$e,1)))$e[]=[$f,$g];}}$A=array();foreach($e as $E){$n=$E[0];$o=$E[1];$q=$a[$n][0];$s=$a[$n][1];$r=$a[$o][0];$t=$a[$o][1];$u=($q<$r)?$q:$r;$v=($s<$t)?$s:$t;$w=($q>$r)?$q:$r;$X=($s>$t)?$s:$t;$Y=0;foreach($a as $p){$x=$p[0];$y=$p[1];if($x>=$u&&$x<=$w&&$y>=$v&&$y<=$X){$Y=($x==$q&&$y==$s)||($x==$r&&$y==$t)?0:1;}if($Y==1)break;}if($Y==1)$A[]=1;}echo count($A)==count($e)?1:0;

пояснення (коментований код):

<?php
//read the file
$lines=array_map("str_split",array_map("trim",file('F'))); // grid in file 'F'

//saving coords
$coords=[]; // new array
$iCoord=-1;
foreach($lines as $rowIndex=>$line) {
    foreach($line as $colIndex=>$value) {
        if ($value=='O'){
            $coords[++$iCoord][]=$rowIndex;//0 is x
            $coords[$iCoord][]=$colIndex;  //1 is y
        }
    }
}

/* for each point, draw as many rectangles as other points
 * without creating 'mirror' rectangles
 */ 
$rectangles=array();

foreach ($coords as $point1Index=>$point1) {
     //draw
     foreach ($coords as $point2Index=>$point2) {
            $point1X=$point1[0];
            $point1Y=$point1[1];
            $point2X=$point2[0];
            $point2Y=$point2[1];
            //if not on the same line or on the same column, ...
            if ($point1X!=$point2X &&   // same line
                $point1Y!=$point2Y &&   // same column
                !(in_array([$point2Index,$point1Index],$rectangles,true)) //... and if no 'mirror one' already
             ) $rectangles[]=[$point1Index,$point2Index]; //create a new rectangle
     }
 }

//now that we have rectangles and coords
//try and put a third point into each
$tests=array();
foreach ($rectangles as $rectangle) {
    $pointA=$rectangle[0];    // points of the rectangle
    $pointB=$rectangle[1];    // __________"____________
    $xA=$coords[$pointA][0];
    $yA=$coords[$pointA][1];
    $xB=$coords[$pointB][0];
    $yB=$coords[$pointB][1];
    $minX=($xA<$xB)?$xA:$xB;
    $minY=($yA<$yB)?$yA:$yB;
    $maxX=($xA>$xB)?$xA:$xB;
    $maxY=($yA>$yB)?$yA:$yB;

    $arborally=false;
    foreach ($coords as $point) {
        $x=$point[0];
        $y=$point[1];
        if ($x>=$minX &&
            $x<=$maxX &&
            $y>=$minY &&
            $y<=$maxY) {
                $arborally=($x==$xA&&$y==$yA) || ($x==$xB&&$y==$yB)?0:1; //same point (pointA or pointB)
        }     
        if ($arborally==true) break;//1 found, check next rectangle
    }
    if ($arborally==true) $tests[]=1;//array of successes

}

echo count($tests)==count($rectangles)?1:0; //if as many successes than rectangles...

?>

1

C, 289 байт

a[99][99],x,X,y,Y,z,Z,i,c;main(k){for(;x=getchar(),x+1;x-10||(y=0,i++))a[y++][i]=x;for(;X<i;X++)for(x=0;a[x][X]-10;x++)for(Y=X+1;Y<i;Y++)for(y=0;a[y][Y]-10;y++)if(x-y&&!(a[x][X]-79||a[y][Y]-79)){c=0;for(Z=X;Z<=Y;Z++)for(z=x<y?x:y;z<=(x>y?x:y);)a[z++][Z]-79||c++;c-2||(k=0);}putchar(k+48);}

Потрібен останній рядок, що дозволено (без нового рядка код буде на два байти більшим). Виходи 0 (не виконано арборально) або 1 (арборально задоволено).

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