교묘하게 만족하는 포인트 세트 식별


14

arborally 만족 지점 세트 포인트들의 2 차원 세트되어, 그 사각형을 포함하거나 터치 적어도 하나의 다른 점 것을 반대 코너로 설정된 두 개의 포인트를 이용하여 형성 될 수있는 임의의 축 정렬 구형. 다음은 Wikipedia와 동등한 정의입니다.

다음 속성이 유지되는 경우 점 집합은 교묘하게 만족한다고합니다. 둘 다 동일한 수평선 또는 수직선에 있지 않은 점 쌍의 경우 첫 두 점에 걸쳐있는 사각형에있는 세 번째 점이 있습니다 ( 내부 또는 경계).

다음 이미지는 사각형이 어떻게 형성되는지 보여줍니다. 이 사각형에는 적어도 하나 이상의 점이 있어야하므로이 점 세트는 만족스럽지 않습니다.

여기에 이미지 설명을 입력하십시오

ASCII 기술에서이 포인트 세트는 다음과 같이 표시 될 수 있습니다.

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

약간의 수정만으로도이를 만족스럽게 만들 수 있습니다.

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

위에서 모든 사각형 (하나만 있음)에 세 개 이상의 점이 있음을 알 수 있습니다.

다음은 arborally 만족되는 더 복잡한 포인트 집합의 또 다른 예입니다.

여기에 이미지 설명을 입력하십시오

두 점에 걸쳐 그려 질 수있는 사각형의 경우 해당 사각형에는 하나 이상의 다른 점이 포함됩니다.

도전

A (I 함께 나타내는 직사각형 격자 점을 감안 O)과 빈 공간 (I 함께 표현되는 .) 출력 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

답변:


7

달팽이 , 29 30 39 바이트

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

사각형의 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 포인트의 좌표를 계산합니다.
빼기의 첫 번째 부분은 모든 사각형을 반환하며 where 절은 점을 자신과 쌍을 이룰 수 없도록합니다.
두 번째 부분은 각 사각형에서 세 번째 점을 검색합니다. 이 점은 하나의 좌표 x 또는 y를 가져야하며 사각형을 정의하는 두 점 중 하나의 좌표와 같습니다. 해당 세 번째 점의 다른 좌표는 사각형을 정의하는 각 점에 대해 해당 좌표에 의해 제한되는 범위에 있어야합니다.
where 절의 마지막 부분은 세 번째 점이 사각형을 정의하는 두 점 중 하나가 아닌지 확인합니다.
모든 사각형에 적어도 세 번째 점이 있으면 빼기의 첫 번째 부분이 두 번째 부분과 같고 쿼리는 아무것도 반환하지 않습니다.


2

MATL , 38 바이트

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

행을로 구분하여 2D 문자 배열을 입력으로 사용합니다 ;. 첫 번째 예는

['......';'....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);}

후행 줄 바꿈이 필요합니다 (줄 바꿈없이 코드는 2 바이트 더 큼). 0 (수 목적으로 만족하지 않음) 또는 1 (수 목적으로 만족 됨)을 출력합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.