Xác định bộ điểm hài lòng


14

Một điểm đặt arborally hài lòng là một tập hợp 2D điểm như vậy mà, đối với bất kỳ hình chữ nhật trục thẳng hàng có thể được hình thành bằng hai điểm trong tập như góc đối diện, mà hình chữ nhật chứa hoặc chạm ít nhất một điểm khác. Đây là một định nghĩa tương đương từ Wikipedia:

Một tập hợp điểm được cho là thỏa mãn nếu thuộc tính sau: đối với bất kỳ cặp điểm nào không nằm trên cùng một đường ngang hoặc dọc, tồn tại điểm thứ ba nằm trong hình chữ nhật được kéo dài bởi hai điểm đầu tiên ( hoặc bên trong hoặc trên ranh giới).

Hình ảnh sau đây minh họa cách hình chữ nhật được hình thành. Bộ điểm này KHÔNG được thỏa mãn vì hình chữ nhật này cần chứa ít nhất một điểm nữa.

nhập mô tả hình ảnh ở đây

Trong nghệ thuật ASCII, tập hợp điểm này có thể được biểu diễn dưới dạng:

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

Một sửa đổi nhỏ có thể làm cho điều này được thỏa mãn:

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

Ở trên, bạn có thể thấy rằng tất cả các hình chữ nhật (trong đó chỉ có một) chứa ít nhất ba điểm.

Đây là một ví dụ khác về tập hợp điểm phức tạp hơn được thỏa mãn:

nhập mô tả hình ảnh ở đây

Đối với bất kỳ hình chữ nhật nào có thể được vẽ kéo dài hai điểm, hình chữ nhật đó chứa ít nhất một điểm khác.

Các thách thức

Cho một lưới hình chữ nhật điểm (mà tôi đại diện với O) và khoảng trống (mà tôi đại diện với .), sản lượng một truthy giá trị nếu nó arborally được thỏa mãn, hoặc một falsey giá trị nếu nó không phải là. Đây là môn đánh gôn.

Quy tắc bổ sung:

  • Bạn có thể chọn để có các ký tự O.hoán đổi với bất kỳ cặp ký tự ASCII có thể in nào khác. Đơn giản chỉ cần xác định ánh xạ ký tự chương trình của bạn sử dụng.
  • Lưới sẽ luôn là hình chữ nhật. Một dòng mới được cho phép.

Thêm ví dụ

Hài lòng về mặt trồng trọt:

.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

Không hài lòng về mặt trồng trọt:

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

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

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

1
Vì vậy, chúng tôi không được phép lấy đầu vào làm danh sách tọa độ thay vì ASCII? Nếu không tôi có thể lấy đầu vào làm danh sách Số nguyên 2D (0 và 1) để thể hiện các điểm không?
Denker

Lưới có thể có 0 diện tích không?
frageum

Câu trả lời:


7

Ốc sên , 29 30 39 byte

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

Nó hoạt động bằng cách vạch ra 2 cạnh của hình chữ nhật, sau đó kiểm tra xem có hình vuông nào chứa chữ O sao cho đi theo đường thẳng từ hình vuông theo 2 hướng của hồng y sẽ dẫn đến việc chạm vào một cạnh của hình chữ nhật.

In tối đa 1 và diện tích của lưới nếu đầu vào "được thỏa mãn"; mặt khác 0


3

Oracle SQL 11.2, 364 344 byte

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 là lưới dưới dạng chuỗi
: w là chiều rộng của lưới

Trả về không có dòng nào là trung thực, trả về các hình chữ nhật không khớp với tiêu chí là sai

Không chơi gôn

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));

Khung nhìn v tính tọa độ của từng điểm O.
Phần đầu tiên của dấu trừ trả về tất cả các hình chữ nhật, mệnh đề where bảo đảm rằng một điểm không thể được ghép với chính nó.
Phần thứ hai tìm kiếm một điểm thứ ba trong mỗi hình chữ nhật. Điểm đó cần phải có một tọa độ, x hoặc y, bằng với tọa độ đó cho một trong hai điểm xác định hình chữ nhật. Tọa độ khác của điểm thứ ba đó cần nằm trong phạm vi giới hạn bởi tọa độ đó cho mỗi điểm xác định hình chữ nhật.
Phần cuối cùng của mệnh đề where bảo đảm rằng điểm thứ ba không phải là một trong hai điểm xác định hình chữ nhật.
Nếu tất cả các hình chữ nhật có ít nhất một điểm thứ ba thì phần đầu tiên của dấu trừ bằng phần thứ hai và truy vấn không trả về gì.


2

MATL , 38 byte

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

Điều này sử dụng một mảng char 2D làm đầu vào, với các hàng được phân tách bằng ;. Vì vậy, ví dụ đầu tiên là

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

Phần còn lại của các trường hợp thử nghiệm trong định dạng này như sau.

  • Hài lòng về mặt trồng trọt:

    ['.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']
    
  • Không hài lòng về mặt thực tế:

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

Hãy thử trực tuyến! Bạn cũng có thể xác minh tất cả các trường hợp thử nghiệm cùng một lúc .

Giải trình

Mã đầu tiên có tọa độ của các ký tự O trong đầu vào. Sau đó, nó sử dụng hai vòng lặp lồng nhau. Vòng lặp bên ngoài chọn từng điểm P (2-tuple tọa độ của nó), so sánh với tất cả các điểm và giữ các điểm khác với P trong hai tọa độ. Đó là những điểm có thể tạo thành một hình chữ nhật với P. Gọi chúng là R.

Vòng lặp bên trong chọn từng điểm T từ R và kiểm tra xem hình chữ nhật được xác định bởi P và T có bao gồm ít nhất 3 điểm không. Để làm điều đó, nó trừ P từ tất cả các điểm; nghĩa là, di chuyển gốc tọa độ sang P. Một điểm nằm trong hình chữ nhật nếu mỗi tọa độ của nó chia cho tọa độ tương ứng của T nằm trong khoảng đóng [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

Tôi thích Don Muesli hơn, tại sao bạn lại thay đổi nó? :(
Denker

@DenkerAffe :-) Chà, tôi đã trở lại tên thật của mình. Cái kia thì vui, nhưng nó chỉ là tạm thời
Luis Mendo

1
Đây không phải là người đàn ông ngoài đời thực, chúng ta cần thêm một số niềm vui ở đây! :)
Denker

@DenkerAffe Tôi có thể quay lại tên đó hoặc một số tên khác trong tương lai. Làm thế nào về linh hồn denim? :-D
Luis Mendo

1
... Và bạn cũng phải đợi 30 ngày nữa (tôi nghĩ vậy)
Stewie Griffin

2

PHP, 1123 byte , 851 byte , 657 byte

(người mới dùng 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;

giải thích (mã nhận xét):

<?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 byte

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);}

Yêu cầu theo dõi dòng mới, được phép (không có dòng mới, mã sẽ lớn hơn hai byte). Đầu ra 0 (không hài lòng về mặt thực tế) hoặc 1 (hài lòng theo cách riêng).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.