确定乔木满意的点集


14

一个arborally满意点集是2D点集,使得对于可在所述一组作为相对的角通过两个点来形成,该矩形包含或触摸至少一个其它点的任何轴对齐矩形。这是维基百科的等效定义:

如果具有以下属性,则可以说是满足点集要求的点:对于不都位于同一条水平线或垂直线上的任何一对点,都存在第三个点,该点位于前两个点所跨的矩形中(在边界内或边界上)。

下图说明了矩形的形成方式。不能任意满足此点集,因为此矩形还需要再包含至少一个点。

在此处输入图片说明

在ASCII技术中,此点集可以表示为:

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

稍作修改就可以使它满足:

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

在上方,您可以看到所有矩形(其中只有一个)至少包含三个点。

这是乔木满足的更复杂点集的另一个示例:

在此处输入图片说明

对于可以跨越两个点绘制的任何矩形,该矩形至少包含一个其他点。

挑战

给定的点的矩形网格(其余与代表O)和空的空间(我所代表与.),输出一个truthy值,如果它是arborally满足,或falsey值,如果它不是。这是代码高尔夫球。

附加规则:

  • 您可以选择使用这些字符,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?如果不是,我可以将输入作为2D整数列表(0和1)来表示点吗?
Denker

网格可以有0个区域吗?
feersum '16

Answers:


7

蜗牛,29 30 39字节

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

它的工作方式是找出矩形的2个边,然后检查是否有一个包含O的正方形,这样从2个基本方向的正方形沿直线行进会导致碰到矩形的边。

如果输入是“树状满足”,则输出最大值1和网格区域;否则为0。


3

甲骨文的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点的坐标。
负号的第一部分返回所有矩形,where子句确保不能将一个点与其自身配对。
第二部分在每个矩形中搜索第三个点。该点必须具有一个坐标x或y,该坐标等于定义矩形的两个点之一的坐标。对于定义矩形的每个点,该第三点的另一个坐标必须在该坐标所限制的范围内。
where子句的最后一部分确保了第三点不是定义矩形的两个点之一。
如果所有矩形都至少具有第三点,则负号的第一部分等于第二部分,并且查询不返回任何内容。


2

MATL,38字节

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

这使用2D char数组作为输入,行之间用分隔;。所以第一个例子是

['......';'....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形成矩形的点。将它们称为集合R。

内循环从R中选取每个点T,并检查P和T定义的矩形是否至少包含3个点。为此,它从所有点中减去P。也就是说,将坐标的原点移动到P。如果将每个点的坐标除以T的对应坐标,则该点位于矩形中[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

我更喜欢Don Muesli,您为什么又改回去?:(
Denker

@DenkerAffe :-)好吧,我回到了真实姓名。另一个很有趣,但是它只是临时的
Luis Mendo

1
这不是现实生活中的人,我们在这里需要更多乐趣!:)
Denker

@DenkerAffe我将来可能会使用该名称或其他名称。牛仔灵魂怎么样?:-D
Luis Mendo

1
...而且您也必须等待30天(我想)
Stewie Griffin

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(不满足乔木)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.