ไกลแค่ไหนจากภายนอก?


15

ใช้พื้นที่ 2 มิติแบ่งออกเป็นองค์ประกอบตารางหน่วยของแกนที่มีการจัดกึ่งกลางตามระยะเวลาจำนวนเต็ม มีการกล่าวถึงขอบภายในถ้ามันแบ่งเป็นสององค์ประกอบมิฉะนั้นจะเป็นขอบภายนอก

เป้าหมายของคุณคือการหาจำนวนขั้นต่ำขององค์ประกอบที่อยู่ใกล้เคียงซึ่งจะต้องสำรวจให้ถึงขอบด้านนอกโดยเริ่มจากศูนย์กลางของแต่ละองค์ประกอบหรือที่เรียกว่า traversal distanceหรือdistanceสั้น คุณสามารถเคลื่อนที่ผ่านขอบเท่านั้น (เช่นไม่มีการตัดมุม / การเคลื่อนที่ในแนวทแยง) โปรดทราบว่า "องค์ประกอบภายนอก" (องค์ประกอบที่มีขอบภายนอกอย่างน้อยหนึ่ง) ได้รับการพิจารณาว่าจำเป็นต้องสำรวจ0องค์ประกอบที่อยู่ใกล้เคียงเพื่อเข้าถึงขอบด้านนอก ..

อินพุต

อินพุตเป็นรายการของคู่พิกัดจำนวนเต็มที่ไม่เป็นลบซึ่งแสดงถึง (x, y) ของศูนย์กลางขององค์ประกอบทั้งหมด มันจะสันนิษฐานว่าไม่มีองค์ประกอบที่ทับซ้อนกัน (เช่นคู่ x / y ระบุองค์ประกอบ) คุณอาจไม่คิดอะไรเกี่ยวกับลำดับการป้อนองค์ประกอบ

คุณสามารถแปลงต้นกำเนิดของอินพุตให้เป็นตำแหน่งใดก็ได้ (เช่น 0,0 หรือ 1,1 เป็นต้น)

คุณอาจสมมติว่าองค์ประกอบอินพุตทั้งหมดเชื่อมต่อกันหรืออาจกล่าวได้ว่าเป็นไปได้ที่จะเดินทางจากองค์ประกอบหนึ่งไปยังองค์ประกอบอื่น ๆ โดยใช้กฎด้านบน โปรดทราบว่านี่ไม่ได้หมายความว่าการเชื่อมต่อภูมิภาค 2 มิตินั้นง่าย มันอาจมีรูอยู่ข้างใน

ตัวอย่าง: ต่อไปนี้เป็นอินพุตที่ไม่ถูกต้อง

0,0
2,0

ป้อนคำอธิบายรูปภาพที่นี่

ไม่จำเป็นต้องตรวจสอบข้อผิดพลาด

อินพุตอาจมาจากแหล่งใดก็ได้ (ไฟล์ stdio พารามิเตอร์ฟังก์ชัน ฯลฯ )

เอาท์พุต

ผลลัพธ์ควรเป็นรายการของพิกัดที่ระบุแต่ละองค์ประกอบและระยะห่างของจำนวนเต็มที่สอดคล้องกันเพื่อไปที่ขอบ ผลลัพธ์อาจอยู่ในลำดับองค์ประกอบใด ๆ ที่ต้องการ (เช่นคุณไม่ต้องการองค์ประกอบเอาต์พุตในลำดับเดียวกันกับที่ได้รับเป็นอินพุต)

ผลลัพธ์อาจเป็นไปได้กับแหล่งใด ๆ (ไฟล์, stdio, ค่าส่งคืนฟังก์ชั่น, ฯลฯ )

เอาท์พุทใด ๆ ที่ตรงกับพิกัดขององค์ประกอบด้วยระยะทางด้านนอกก็ถือว่าใช้ได้

x,y: distance
...

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

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

ตัวอย่าง

ข้อความตัวอย่างอินพุตอยู่ในรูปแบบx,yหนึ่งองค์ประกอบต่อบรรทัด คุณสามารถปรับแต่งสิ่งนี้เป็นรูปแบบการป้อนข้อมูลที่สะดวก (ดูกฎการจัดรูปแบบอินพุต)

เอาต์พุตข้อความตัวอย่างอยู่ในรูปแบบx,y: distanceโดยมีหนึ่งองค์ประกอบต่อบรรทัด อีกครั้งคุณสามารถปรับแต่งสิ่งนี้เป็นรูปแบบ ouput ที่สะดวกสบาย (ดูกฎของรูปแบบผลลัพธ์)

ตัวเลขกราฟิกมีขอบเขตซ้ายล่างเป็น (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

@lirtosiast ใช่
helloworld922

1
ในตัวอย่างของคุณคุณไม่ได้ระบุอินพุตอย่างชัดเจน
Dale Johnson

@DaleJohnson ใช้สองคอลัมน์แรกของแต่ละการป้อนข้อความสำหรับคู่ x, y ฉันไม่ได้เพิ่มกล่องคำพูดแยกต่างหากสำหรับอินพุตเพียงอย่างเดียวเพราะมันดูจะยาวไปหน่อย มีวิธีเพิ่มกล่องคำพูดและจำกัดความสูงในแนวตั้งด้วยตนเองหรือไม่
helloworld922

ค้นหาจำนวนองค์ประกอบขั้นต่ำที่อยู่ใกล้เคียงซึ่งจะต้องเคลื่อนที่ไปถึงขอบด้านนอกเริ่มจากที่ใด และคุณสามารถเพิ่มเอาต์พุตใน caes ทดสอบได้หรือไม่?
Luis Mendo

คำตอบ:


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

Ungolfed

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 ource และR esult ที่มีขนาดเหมาะสมเต็มไปด้วยเลขศูนย์

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

คำนวณดัชนีเชิงเส้นที่สอดคล้องกับxy-pairs โดยมีหนึ่งองค์ประกอบภายในที่ขอบ

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

MATL , 38 37 36 33 ไบต์

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

ใช้เวอร์ชันปัจจุบัน (15.0.0)ของภาษา / คอมไพเลอร์

รูปแบบอินพุตคือ: หนึ่งอาร์เรย์ที่มีค่าxและหนึ่งอาร์เรย์ที่มีค่าy อินพุตและเอาต์พุตเป็นพื้นฐาน 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 หมายถึงตำแหน่งนั้นล้อมรอบด้วยจุดอื่น ๆ และมีระยะห่าง - ด้านนอกอย่างน้อย 1 ผลลัพธ์ (0 หรือ 1 สำหรับแต่ละจุด) ถูกเพิ่มเข้ากับเมทริกซ์ดั้งเดิม ตำแหน่งเหล่านั้นในขณะนี้มี 2 (ในตอนท้ายของกระบวนการเมทริกซ์จะลดลง 1)

กระบวนการวนซ้ำนั้นวนซ้ำ สำหรับการวนซ้ำครั้งถัดไปอินพุทของการโน้มน้าวคือเมทริกซ์สะสมที่มีค่าเท่ากับ 2; นั่นคือค่าที่ต่ำกว่า 2 ถูกตั้งค่าเป็น 0 ผลลัพธ์ของการบิดบ่งชี้ว่าจุดใดมีระยะห่างอย่างน้อย 2 (เพื่อนบ้านทั้งหมดมีระยะทาง 1)

จำนวนของการวนซ้ำถูกเลือกเพื่อความสะดวกเนื่องจากจำนวนคอลัมน์ของเมทริกซ์อินพุต นี่เพียงพอแล้ว (ในความเป็นจริงจำนวนการทำซ้ำที่ต้องการสูงสุดคือครึ่งหนึ่งของมิติเมทริกซ์ขั้นต่ำ) การทำซ้ำครั้งล่าสุดอาจไร้ประโยชน์ แต่ไม่ทำอันตราย (เพียงเพิ่ม 0 เข้าไปในทุกจุด)

ในตอนท้ายของกระบวนการ 1 จะถูกลบออกจากผลลัพธ์เนื่องจากตำแหน่งที่มีค่าkมีระยะทางk -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 bytes

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

เรารู้ว่าถ้าผู้ประสานงานมีเพื่อนบ้านน้อยกว่าสี่คนมันจะต้องอยู่ใน "ภายนอก" ดังนั้นเราสามารถลอกเซลล์ภายนอกออกซ้ำ ๆ และกำหนดระยะทางเท่ากับจำนวนการวนซ้ำ / ความลึกของการเรียกซ้ำในกรณีนี้

คิดว่ามีที่ว่างสำหรับการปรับปรุง - วิธีที่ดีที่สุดในการตรวจสอบเพื่อนบ้านคืออะไร

แก้ไข: ฉันควรได้รับอนุญาตให้ยอมรับรายการคู่เป็น tuples


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

เห็นภาพเป็น Ascii chars

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.