Arboral olarak memnun nokta kümelerini tanımlayın


14

Bir arborally tatmin noktası belirlendi noktaları 2B grubu olduğu şekilde, dikdörtgen içeren ya da dokunur en az bir başka nokta şekilde, karşıt köşeleri olarak ayarlandı iki nokta kullanılarak oluşturulabilir bir eksen hizalı dikdörtgen için. İşte Wikipedia'dan eşdeğer bir tanım:

Aşağıdaki özellik geçerliyse bir nokta kümesinin arboral olarak tatmin olduğu söylenir: her ikisi de aynı yatay veya dikey çizgide bulunmayan herhangi bir nokta çifti için, ilk iki noktanın kapsadığı dikdörtgenin içinde yer alan üçüncü bir nokta vardır ( içeride veya sınırda).

Aşağıdaki görüntü dikdörtgenlerin nasıl oluştuğunu göstermektedir. Bu dikdörtgenin en az bir nokta daha içermesi gerektiğinden, bu nokta kümesi tamamen tatmin edici DEĞİLDİR.

resim açıklamasını buraya girin

ASCII sanatında, bu nokta seti şu şekilde temsil edilebilir:

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

Küçük bir değişiklik bunu keyfi olarak tatmin edebilir:

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

Yukarıda, tüm dikdörtgenlerin (sadece bir tanesi vardır) en az üç nokta içerdiğini görebilirsiniz.

İşte, daha karmaşık bir nokta kümesinin, keyfi olarak tatmin edilen başka bir örneği:

resim açıklamasını buraya girin

İki noktayı kapsayan çizilebilecek herhangi bir dikdörtgen için, bu dikdörtgen en az bir başka nokta içerir.

Meydan okuma

Bir (I ile temsil noktalarının dikdörtgen bir ızgara verilen O) ve boş alanını (I olan temsil eder .), çıkış truthy bu arborally yerine getirildiği takdirde değer ya da bir Falsey değerin değilse. Bu kod golfü.

Ek kurallar:

  • Karakterleri seçebilir Ove .yazdırılabilir ASCII karakter çiftleriyle yer değiştirebilirsin. Programınızın hangi karakter eşlemesini kullandığını belirtmeniz yeterlidir.
  • Izgara her zaman dikdörtgen olacaktır. Sondaki satırsonuna izin verilir.

Daha fazla örnek

Arboral olarak memnunum:

.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

Tamamen Memnun Değil:

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

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

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

1
Yani girdiyi ASCII yerine koordinatlar listesi olarak almamıza izin yok mu? Değilse, noktaları temsil etmek için girdiyi 2B Tamsayılar listesi (0 ve 1) olarak alabilir miyim?
Denker

Izgarada 0 alan olabilir mi?
feersum

Yanıtlar:


7

Salyangoz , 29 30 39 bayt

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

Dikdörtgenin 2 tarafını izleyerek ve ardından O'nun bulunduğu bazı karelerin olup olmadığını kontrol ederek, kardinal yönlerin 2'sindeki kareden düz bir çizgide hareket etmenin, dikdörtgenin bir tarafına çarpmasına neden olacağı şekilde çalışır.

Giriş "tatmin edici şekilde" sağlanmışsa maksimum 1 değerini ve ızgaranın alanını yazdırır; aksi takdirde 0.


3

Oracle SQL 11.2, 364344 bayt

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, bir dize olarak ızgaradır
: w, ızgaranın genişliğidir

Hiçbir satırı doğrulukla döndürmez, ölçütlerle uyuşmayan dikdörtgenleri yanlış olarak döndürür

Un-golfed

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

Görünüm v, her bir O noktasının koordinatlarını hesaplar.
Eksi ilk bölümü tüm dikdörtgenleri döndürür; burada yan tümce, bir noktanın kendisiyle eşleştirilememesini sağlar.
İkinci bölüm her bir dikdörtgenin üçüncü noktasını arar. Bu noktanın, dikdörtgeni tanımlayan iki noktadan biri için x veya y koordinatlarına eşit olması gerekir. Üçüncü noktanın diğer koordinatının, dikdörtgeni tanımlayan her bir nokta için bu koordinatla sınırlanan aralıkta olması gerekir.
Where yan tümcesinin son kısmı, üçüncü noktanın dikdörtgeni tanımlayan iki noktadan biri olmamasını sağlar.
Tüm dikdörtgenlerin en az üçüncü bir noktası varsa, eksi ilk kısmı ikinci kısma eşittir ve sorgu hiçbir şey döndürmez.


2

MATL , 38 bayt

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

Bu, satır olarak ayrılmış satırlar olarak giriş olarak bir 2D karakter dizisi kullanır ;. İlk örnek

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

Bu formattaki test senaryolarının geri kalanı aşağıdaki gibidir.

  • Arboral olarak memnunum:

    ['.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']
    
  • Arboral olarak tatmin olmamış:

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

Çevrimiçi deneyin! Ayrıca tüm test senaryolarını bir kerede doğrulayabilirsiniz .

açıklama

Kod önce Ogirişteki karakterlerin koordinatlarını alır . Daha sonra iki iç içe döngü kullanır. Dış döngü her bir P noktasını (koordinatlarının 2 parçası) alır, tüm noktalarla karşılaştırır ve iki koordinatta P'den farklı noktaları tutar. Bunlar, P ile bir dikdörtgen oluşturabilecek noktalardır.

İç döngü her T noktasını R'den alır ve P ve T tarafından tanımlanan dikdörtgenin en az 3 nokta içerip içermediğini kontrol eder. Bunu yapmak için P'yi tüm noktalardan çıkarır; yani, koordinatların başlangıç ​​noktasını P'ye taşır. Koordinatlarının her birinin T'nin ilgili koordinatına bölünmesiyle bir nokta dikdörtgenin içinde ise kapalı aralıktadır [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'yi daha çok sevdim, neden geri değiştirdin? :(
Denker

@DenkerAffe :-) Gerçek ismime geri döndüm. Diğeri eğlenceliydi, ancak geçici olarak tasarlandı
Luis Mendo

1
Bu gerçek hayat adam değil, burada biraz daha eğlenmeye ihtiyacımız var! :)
Denker

@DenkerAffe Gelecekte bu isme veya başka bir isme geri dönebilirim. Denim Soul'a ne dersin? :-D
Luis Mendo

1
... ve 30 gün beklemelisin (sanırım)
Stewie Griffin

2

PHP, 1123 bayt , 851 bayt , 657 bayt

(acemi 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;

açıklama (yorumlanmış kod):

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

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

İzin verilen sondaki satırsonu gerektirir (satırsonu olmadan kod iki bayt daha büyük olur). Çıkışlar 0 (tam olarak memnun değil) veya 1 (tam olarak memnun).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.