外部からどのくらい離れていますか?


15

中心が整数間隔で配置された軸に沿った単位正方形要素に分割された2D領域を取ります。エッジは、2つの要素で共有される場合は内部エッジと呼ばれ、それ以外の場合は外部エッジと呼ばれます。

あなたの目標は、として知られている各要素の中心から出発外縁に到達するために横断しなければならない隣接要素の最小数を見つけることであるtraversal distance、またはdistance略しています。エッジのみを横断できます(つまり、コーナーカット/斜め移動はできません)。「外部要素」(少なくとも1つの外部エッジを持つ要素)は0、外部エッジに到達するために隣接する要素を横断する必要があると見なされることに注意してください。

入力

入力は、すべての要素の中心の(x、y)を示す非負の整数ペア座標のリストです。重複する要素はないと想定されます(つまり、x / yペアが要素を一意に識別します)。要素の入力順序について何も想定してはいけません

入力の原点を任意の場所(0、0、1、1など)に変換できます。

すべての入力要素が接続されていると仮定できます。つまり、上記の規則を使用して、任意の要素から他の要素に移動することが可能です。これは、2D領域が単に接続されているという意味ではないことに注意してください。内部に穴がある場合があります。

例:次は無効な入力です。

0,0
2,0

ここに画像の説明を入力してください

エラーチェックは不要です。

入力は、任意のソース(ファイル、stdio、関数パラメーターなど)からのものです。

出力

出力は、各要素を識別する座標のリストと、エッジに到達するために通過した対応する整数距離である必要があります。出力は、任意の要素の順序にすることができます(たとえば、入力として受け取ったのと同じ順序で要素を出力する必要はありません)。

出力は、任意のソース(ファイル、stdio、関数の戻り値など)に対するものです。

要素の座標を外部距離と一致させる出力はすべて問題ありません。たとえば、これらはすべて問題ありません。

x,y: distance
...

[((x,y), distance), ...]

[(x,y,distance), ...]

テキスト入力例の形式はx,y、1行に1つの要素があります。これを便利な入力形式に変更してください(入力形式の規則を参照)。

テキスト例の出力は、x,y: distance行ごとに1つの要素を持つ形式です。繰り返しになりますが、これを便利な出力形式に変更してください(出力形式の規則を参照)。

グラフィカルな図の左下の境界は(0,0)であり、内部の数字は、外側の端に到達するために予想される最小距離を表します。これらの図は純粋にデモンストレーションのみを目的としていることに注意してください。プログラムはこれらを出力する必要はありません。

例1

入力:

1,0
3,0
0,1
1,2
1,1
2,1
4,3
3,1
2,2
2,3
3,2
3,3

出力:

1,0: 0
3,0: 0
0,1: 0
1,2: 0
1,1: 1
2,1: 0
4,3: 0
3,1: 0
2,2: 1
2,3: 0
3,2: 0
3,3: 0

グラフ表示:

ここに画像の説明を入力してください

例2

入力:

4,0
1,1
3,1
4,1
5,1
6,1
0,2
1,2
2,2
3,2
4,2
5,2
6,2
7,2
1,3
2,3
3,3
4,3
5,3
6,3
7,3
8,3
2,4
3,4
4,4
5,4
6,4
3,5
4,5
5,5

出力:

4,0: 0
1,1: 0
3,1: 0
4,1: 1
5,1: 0
6,1: 0
0,2: 0
1,2: 1
2,2: 0
3,2: 1
4,2: 2
5,2: 1
6,2: 1
7,2: 0
1,3: 0
2,3: 1
3,3: 2
4,3: 2
5,3: 2
6,3: 1
7,3: 0
8,3: 0
2,4: 0
3,4: 1
4,4: 1
5,4: 1
6,4: 0
3,5: 0
4,5: 0
5,5: 0

グラフ表示:

ここに画像の説明を入力してください

例3

入力:

4,0
4,1
1,2
3,2
4,2
5,2
6,2
8,2
0,3
1,3
2,3
3,3
4,3
5,3
6,3
7,3
8,3
9,3
1,4
2,4
3,4
4,4
5,4
6,4
7,4
8,4
9,4
2,5
3,5
4,5
5,5
6,5
9,5
10,5
11,5
3,6
4,6
5,6
9,6
10,6
11,6
6,7
7,7
8,7
9,7
10,7
11,7

出力:

4,0: 0
4,1: 0
1,2: 0
3,2: 0
4,2: 1
5,2: 0
6,2: 0
8,2: 0
0,3: 0
1,3: 1
2,3: 0
3,3: 1
4,3: 2
5,3: 1
6,3: 1
7,3: 0
8,3: 1
9,3: 0
1,4: 0
2,4: 1
3,4: 2
4,4: 2
5,4: 2
6,4: 1
7,4: 0
8,4: 0
9,4: 0
2,5: 0
3,5: 1
4,5: 1
5,5: 1
6,5: 0
9,5: 0
10,5: 0
11,5: 0
3,6: 0
4,6: 0
5,6: 0
9,6: 0
10,6: 1
11,6: 0
6,7: 0
7,7: 0
8,7: 0
9,7: 0
10,7: 0
11,7: 0

グラフ表示:

ここに画像の説明を入力してください

得点

これはコードゴルフです。バイト単位の最短コードが優先されます。標準の抜け穴が適用されます。この問題を解決するために特別に設計されたもの以外のビルトインは許可されます。


[((1,0)、0)、...]として出力できますか?
リルトシアスト

はい@lirtosiast
helloworld922

1
例では、入力を明示的に述べていません。
デールジョンソン

@DaleJohnsonは、x、yペアの各テキスト入力の最初の2列を取得します。少し長くなっているように見えたので、入力だけに別の引用符ボックスを追加しませんでした。引用ボックスを追加して、垂直方向の高さを手動で制限する方法はありますか?
helloworld922

どこから始まる外側の端に到達するために横断する必要がある隣接要素の最小数を見つけますか?そして、テストケースに出力を追加できますか?
ルイスメンドー

回答:


2

MATLAB / Octave、143バイト

function [v,x,y]=d(x,y)R=S=zeros(max(y+3),max(x+3));i=sub2ind(size(S),y+2,x+2);S(i)=1;while nnz(S=imerode(S,strel('disk',1,0)))R+=S;end;v=R(i);

非ゴルフ

function [v,x,y]=d(x,y)
  R=S=zeros(max(y+3),max(x+3));
  i=sub2ind(size(S),y+2,x+2);
  S(i)=1;
  while nnz(S=imerode(S,strel('disk',1,0)))
    R+=S;
  end;
  v=R(i);

説明

ゼロで満たされた適切なサイズのS行列とR行列を作成します。

R=S=zeros(max(y+3),max(x+3));

xy-pairsに対応する線形インデックスを計算します。境界に1つの要素が埋め込まれます。

i=sub2ind(size(S),y+2,x+2);

構造を描きます。

S(i)=1;

S例2の例次に示します。

0   0   0   0   0   0   0   0   0   0   0
0   0   0   0   0   1   0   0   0   0   0
0   0   1   0   1   1   1   1   0   0   0
0   1   1   1   1   1   1   1   1   0   0
0   0   1   1   1   1   1   1   1   1   0
0   0   0   1   1   1   1   1   0   0   0
0   0   0   0   1   1   1   0   0   0   0
0   0   0   0   0   0   0   0   0   0   0

画像収縮によってすべての境界要素を削除します

S=imerode(S,strel('disk',1,0))

半径1の構造化要素ディスクを使用します。

0   1   0
1   1   1
0   1   0

斜めの動きが許可されている場合、代わりに長方形を使用します。

1   1   1
1   1   1
1   1   1

次に、すべての非境界要素の結果をインクリメントします

R+=S;

画像が完全に侵食されるまでループします。

while nnz(S)

xyペアの結果を返します。

v=R(i);

2

Pyth、26バイト

V]MQNf>*4Nl=Nsmfq1.a,dYQN0

例2

使用した出力形式は次のとおりです。

[[4, 3]]
2

つまり、ポイントとそれに続く外部からの距離を含むリスト。

コードは、現在到達しているセットを使用して動作します。各ポイントに対して、そのポイントから正確に距離1離れたすべてのポイントの入力をフィルタリングし、結果のポイント数が開始数の4倍かどうかを確認し、そうでないまで繰り返す。特定のポイントで開始すると、これはそのポイントが外部からどれだけ離れているかを示します。


2

MATL38 37 36 33バイト

1Z?t"tX@<~5Bt!Z~2X53$Y+4=+]3#fqhh

これは、現在のバージョン(15.0.0)の言語/コンパイラーを使用します。

入力形式は、x値を持つ1つの配列とy値を持つ1つの配列です。入力と出力は1ベースです。したがって、テストケースには次の入力があります。

[2 4 1 2 2 3 5 4 3 3 4 4]
[1 1 2 3 2 2 4 2 3 4 3 4]

[5 2 4 5 6 7 1 2 3 4 5 6 7 8 2 3 4 5 6 7 8 9 3 4 5 6 7 4 5 6]
[1 2 2 2 2 2 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 5 5 5 5 5 6 6 6]

[5 5 2 4 5 6 7 9 1 2 3 4 5 6 7 8 9 10 2 3 4 5 6 7 8 9 10 3 4 5 6 7 10 11 12 4 5 6 10 11 12 7 8 9 10 11 12]
[1 2 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 7 7 7 7 7 7 8 8 8 8 8 8]

オンラインでお試しください!

説明

行列は、最初は入力位置に1が、それ以外の場合は0で構築されます。次に、「北、東、南、西」マスク([0 1 0; 1 0 1; 0 1 0])を使用して畳み込みが適用され、各位置での結果が4と比較されます。4の結果は、その位置が他のポイントに囲まれ、 to-exterior少なくとも1。結果(各ポイントに対して0または1)が元のマトリックスに追加されます。これらの位置には2が含まれるようになりました(プロセスの終了時に、マトリックスは1ずつ減少します)。

畳み込みプロセスが繰り返されます。次の反復では、畳み込みの入力は2でしきい値処理された累積行列です。つまり、2より小さい値は0に設定されます。畳み込みの結果は、少なくとも2つの距離を持つポイントを示します(すべての隣接ポイントの距離は1になります)。

繰り返し回数は、便宜上、入力行列の列数として選択されます。これで十分です(実際、反復の最大必要数は最小行列次元の半分です)。最後の反復は役に立たないかもしれませんが、害はありません(すべてのポイントに0を追加するだけです)。

プロセスの終了時に、値kの位置は外部との距離がk -1 であるため、結果から1が減算されます。すべての位置の座標と値が抽出されて表示されます。

           % take x and y implicitly
1          % push 1
Z?         % build sparse matrix from that x, y indices with 1 as value
t          % duplicate
"          % for each column of that matrix
  t        %   duplicate
  X@       %   push iteration index
  <~       %   true for matrix entries that are >= iteration index
  5B       %   5 in binary: row vector [1 0 1]
  t!       %   duplicate and transpose into a column vector
  Z~       %   element-wise XOR with broadcast: gives desired mask,
           %   [0 1 0; 1 0 1; 0 1 0]
  2X53$Y+  %   2D convolution. Output has same size as input
  4=       %   compare with 4: are all neighbouring positions occupied?
  +        %   add to accumulated matrix from previous iteration
]          % end for each
3#f        % extract row index, column index and value for nonzero
           % entries. In this case all entries are nonzero
q          % subtract 1 to value to yield distance to exterior
hh         % concatenate vertically twice
           % display implicitly 

1

Python 3、180 166 160バイト

def f(l,d=0):
 l=set(l);
 if l:i={(a,b)for a,b in l if all([x in l for x in[(a+1,b),(a-1,b),(a,b+1),(a,b-1)]])};return{(c,d)for c in l-i}|f(i,d+1)
 return set()

座標の隣人が4人未満の場合は、「外側」になければならないことがわかっています。したがって、外部セルを繰り返しストリップし、この場合、反復の回数/再帰の深さと等しい距離をそれらに割り当てることができます。

間違いなく改善の余地があると思います-隣接する隣人をチェックする最良の方法は何ですか?

編集:ペアのリストをタプルとして受け入れることを許可する必要があります。


0

PHP、316バイト

<?preg_match_all("#^(\d+),(\d+)#m",$_GET[i],$t);foreach($t[1]as$k=>$v)$a[$v][$t[2][$k]]=0;function w($x,$y){global$a;return isset($a[$x][$y])?$a[$x][$y]:-1;};for(;$z++<max($t[2]);$o=$s,$s="")foreach($a as$x=>$b)foreach($b as$y=>$c)$s.="\n$x,$y: ".$a[$x][$y]=1+min(w($x+1,$y),w($x-1,$y),w($x,$y-1),w($x,$y+1));echo$o;

オンライン版

壊す

preg_match_all("#^(\d+),(\d+)#m",$_GET[i],$t); 
foreach($t[1]as$k=>$v) 
$a[$v][$t[2][$k]]=0;  # make a 2 D array
function w($x,$y){global$a;return isset($a[$x][$y])?$a[$x][$y]:-1;};# check the neighbours
for(;$z++<max($t[2]);$o=$s,$s="") # stored the last loop string first run make possible to 1 and so on
foreach($a as$x=>$b) # x values
foreach($b as$y=>$c) # y values
$s.="\n$x,$y: ".$a[$x][$y]=1+min(w($x+1,$y),w($x-1,$y),w($x,$y-1),w($x,$y+1)); # concanate array item x+y+value
echo$o; #Output

アスキー文字として視覚化

ksort($a); 
foreach($a as$x=>$b){
for($y=0;$y<=max($t[2]);$y++)
echo isset($a[$x][$y])?$a[$x][$y]:" ";
#The better way would be make a SVG and use the text element and use a factor
#echo '<text x="'.($x*$factor).'" y="'.($y*$factor).'">'.$a[$x][$y].'</text>';
echo"\n";}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.