หาโพลีนีโม!


11

ไม่นะ! นีโมปลาตัวตลกของเราหายไปในมหาสมุทร ASCII และพ่อของเขามาร์ลินกำลังพยายามตามหาเขา

งานของคุณคือนำ Marlin ไป Nemo อย่างปลอดภัย แต่ระวังเรามีบรูซบ้าคลั่งให้อาหารที่หลวมดังนั้นหลีกเลี่ยงเขาได้ดีกว่า!

รายละเอียด

คุณจะได้รับตาราง ASCII a-zทะเลเป็นรูปสี่เหลี่ยมผืนผ้าที่มีตัวอักษรตัวพิมพ์เล็กเท่านั้น ทะเลแห่งนี้จะมีnemo, marlinและbruceภายในนั้นในรูปแบบของ polyomino อย่างต่อเนื่องเสมอเริ่มต้นจากด้านบนมือถือมากที่สุดในคอลัมน์แรกของ polyomino ตัวอย่างเช่นจาก tetrominos ที่เป็นไปได้ทั้งหมดรายการที่ถูกต้องจะแสดงรายการในตัวอย่างด้านล่าง

แต่แบบฟอร์มเหล่านี้ไม่ถูกต้องและจะไม่ปรากฏในอินพุต:

omen

ne
mo

nem
o

o
m
en

nem
 o

n
eo
m

ในที่สุดงานของคุณคือการหาเส้นทางจากmarlinแผ่นกระเบื้อง polyomino ไปยังแผ่นกระเบื้อง polyomino เพื่อnemoให้แน่ใจว่าเซลล์ใด ๆ ในเส้นทางของคุณไม่ได้อยู่ติดกับbruceแผ่นกระเบื้อง polyomino ส่งออกของคุณควรเปลี่ยนทุกตัวอักษรที่ไม่ได้เป็นส่วนหนึ่งของmarlinกระเบื้องnemoกระเบื้องและเส้นทางเชื่อมต่อพวกเขาทั้งที่มีตัวละครจากช่วง ASCII พิมพ์ (รวมทั้งพื้นที่) a-zที่นอกเหนือจากตัวพิมพ์เล็ก

ตัวอย่าง

หากมหาสมุทรอินพุตเป็นดังต่อไปนี้:

oxknvvolacycxg
xmliuzsxpdzkpw
warukpyhcldlgu
tucpzymenmoyhk
qnvtbsalyfrlyn
cicjrucejhiaeb
bzqfnfwqtrzqbp
ywvjanjdtzcoyh
xsjeyemojwtyhi
mcefvugvqabqtt
oihfadeihvzakk
pjuicqduvnwscv

(โดยมี 3 polyominos เป็น:

...n..........
.mli..........
.ar...........
..............
....b.........
....ruce......
..............
.....n........
.....emo......
..............
..............
..............

)

จากนั้นโซลูชันที่ถูกต้องอาจมีลักษณะดังนี้:

...n..........
.mli..........
.ar...........
.u............
.n............
.i............
.z............
.wvjan........
.....emo......
..............
..............
..............

ตัวอย่างด้านล่างมีตัวอย่างอีกสองสามตัวอย่าง:

หมายเหตุ

  • ตารางจะเป็นรูปสี่เหลี่ยมผืนผ้าที่สมบูรณ์แบบและจะมีเพียงกระเบื้อง polyomino หนึ่งnemo, และmarlinbruce
  • เส้นทางของคุณไม่ควรผ่านbruceหรือใด ๆ ของเซลล์ 4 เซลล์ที่ติดกัน (ขึ้นลงซ้ายและขวา) ของเซลล์ใด ๆ ในbruceแผ่นกระเบื้อง
  • จะรับประกันเสมอว่าจะมีอย่างน้อยหนึ่งเส้นทางที่ถูกต้องจากไปmarlinnemo
  • ไม่มีความต้องการของเส้นทางที่สั้นที่สุดที่นี่เพื่อไปถั่ว!
  • แม้ว่าคุณไม่จำเป็นต้องค้นหาเส้นทางที่สั้นที่สุดเซลล์ใด ๆ ในเส้นทาง (เส้นทางที่ไม่รวมมาร์ลินหรือนีโม) ไม่สามารถอยู่ติดกับเซลล์อื่นมากกว่าสองเซลล์ในเส้นทาง
  • เส้นทางไม่ควรผ่านmarlinหรือnemoเรียงต่อกันเนื่องจากจะทำให้ปลาตัวเล็กสับสนในการเลือกทิศทาง
  • ตามปกติคุณอาจเขียนโปรแกรมหรือฟังก์ชั่นรับอินพุตผ่าน STDIN (หรือเทียบเท่าที่ใกล้เคียงที่สุด) อาร์กิวเมนต์บรรทัดคำสั่งหรือพารามิเตอร์ฟังก์ชันและสร้างเอาต์พุตผ่าน STDOUT (หรือเทียบเท่าที่ใกล้เคียงที่สุด), ส่งคืนค่าหรือฟังก์ชัน
  • ถ้าใส่หลายคู่สายเป็นไปไม่ได้แล้วคุณอาจคิดว่าตารางจะเข้าร่วมโดยตัวละครแทน| \nคุณอาจใช้อินพุตเป็นอาร์เรย์ของแถวกริด

นี่คือรหัสกอล์ฟเพื่อให้รายการที่สั้นที่สุดเป็นไบต์ชนะ


เส้นทางผ่านมาร์ลิน (หรือนีโม) ได้หรือไม่? การแก้ปัญหาข้างต้นจะยังคงถูกต้องหากkข้างต้นlมาร์ลินสามารถมองเห็นได้? (ทำให้เส้นทางจาก n ใน marlin ไปยัง nemo)
KSab

@KSab ฉันไม่บอกว่ามันจะทำให้สับสนมาร์ลิน :)
เครื่องมือเพิ่มประสิทธิภาพ

คำตอบ:


4

Matlab 560

560 ไบต์เมื่อลบช่องว่างที่ไม่จำเป็นออกทั้งหมดเครื่องหมายอัฒภาคและความคิดเห็นทั้งหมด สามารถตีกอล์ฟได้มากกว่านี้ แต่ตอนนี้ฉันเหนื่อยแล้ว (บางทีพรุ่งนี้ ... ) ราตรีสวัสดิ์ทุกคน

PS: ฉันคิดว่าเส้นทางต้องมีการเชื่อมต่อ 4 ย่าน ('+')

function c(A)
Z = [0,1,0;1,1,1;0,1,0];
Br = q('bruce');
Bn = conv2(Br,ones(3),'s')>0;
Ne = q('nemo');
Ma = q('marlin');
%construct path marlin to nemo
U=Ma>0;M=A*Inf;
M(U)=0;
for k=1:2*sum(size(A))%upper bound for path length
    %expand
    V=imdilate(U,Z);
    V(Bn)=0;
    M(V-U==1)=k;
    U=V;
    %disp(M)
end
%go back from nemo to marlin
Pr=reshape(1:numel(A),size(A));
[i,j]=find(Ne);
m=M(i(1),j(1));%value
P=A*0;%path image
P(i(1),j(1))=1;
for k=m:-1:1
    %find neighbour of (i(1),j(1)) with value m-1
    U=imdilate(P,Z);
    F = M==k;
    G = F&U;
    mask = Pr == min(Pr(F & U));
    P(mask)=1; 
end
A(~P & ~Ma & ~Ne)='.';
disp(A)



    function M = q(s)%find string in matrix, A ascii, M mask
        M = A*0;
        m=numel(s);
        N = M+1;%all neighbours
        for k=1:m;
            M(A==s(k) & N)=k;%only set the ones that were in the neighbourhood of last
            L=M==k;
            N=imdilate(L,Z);
        end
        for k=m:-1:2
            %set all that are not neighbour to next higher highest to zero
            L=M==k;
            N=imdilate(L,Z);
            M(M==k-1 & ~N)=0;
        end
    end


end

ฟังก์ชั่นการโทร: (ไม่จำเป็นต้องขึ้นบรรทัดใหม่)

c(['oxknvvolacycxg',
'xmliuzsxpdzkpw',
'warukpyhcldlgu',
'tucpzymenmoyhk',
'qnvtbsalyfrlyn',
'cicjrucejhiaeb',
'bzqfnfwqtrzqbp',
'ywvjanjdtzcoyh',
'xsjeyemojwtyhi',
'mcefvugvqabqtt',
'oihfadeihvzakk',
'pjuicqduvnwscv']);

เอาท์พุท:

...n..........
.mli..........
.ar...........
..c...........
..v...........
..c...........
..q...........
..vjan........
.....emo......
..............
..............
..............

มันทำงานอย่างไร

แยกชื่อ

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

การค้นหาเส้นทาง

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

 2 1 1  0  1  2  3  4  5  6  7  8  9 10
 1 0 0  0  1  2  3  4  5  6  7  8  9 10
 1 0 0  1  2  3  4  5  6  7  8  9 10 11
 2 1 1  _  _  _  5  6  7  8  9 10 11 12
 3 2 2  _  _  _  _  _  _  9 10 11 12 13
 4 3 3  _  _  _  _  _  _ 10 11 12 13 14
 5 4 4  _  _  _  _  _  _ 11 12 13 14 15
 6 5 5  6  7  8  9 10 11 12 13 14 15 16
 7 6 6  7  8  9 10 11 12 13 14 15 16 17
 8 7 7  8  9 10 11 12 13 14 15 16 17 18
 9 8 8  9 10 11 12 13 14 15 16 17 18 19
10 9 9 10 11 12 13 14 15 16 17 18 19 20

ตอนนี้เริ่มที่nemoพิกเซลและลดตัวนับระยะทางในแต่ละขั้นตอนและเพิ่มเพื่อนบ้านด้วยระยะทางที่ต่ำกว่าถัดไป (ตามแผนที่ระยะทางที่เราคำนวณก่อนหน้านี้) ไปยังเส้นทางของเรา


3

Python 2 - 658

ไม่มีประสิทธิภาพมากทั้งในเวลาและหน่วยความจำ ฟังก์ชั่นในการระบุรูปแบบคือฟังก์ชั่นวนซ้ำ S และฟังก์ชั่นเพื่อค้นหาเส้นทางคือ C ซึ่งโดยพื้นฐานแล้วเป็นการใช้งานที่ไม่มีประสิทธิภาพอย่างน่ากลัว A *

G=input().split('\n')
R=range
S=lambda g,x,y,s,B:[[(x,y)]+r for a,b in[(-1,0),(0,-1),(0,1),(1,0)]for r in S(g,x+a,y+b,s[1:],B)if B(x,y)and s[0]==g[y][x]]if s else[[]]
C=lambda l,N,B:[i for i in l if i[-1]in N]or C([i+[(i[-1][0]+c,i[-1][1]+d)]for i in l for c,d in [(-1,0),(0,-1),(0,1),(1,0)]if all(1<abs(i[-1][0]+c-a)or 1<abs(i[-1][1]+d-b)for a,b in B)],N,B)
X,Y=len(G[0]),len(G)
N,M,B=[filter(list,[S(G,s,t,e,lambda a,b:0<=a<X and 0<=b<Y and Y*(a-s)+b-t>=0)for s in R(X)for t in R(Y)])[0][0]for e in["nemo","marlin","bruce"]]
print'\n'.join(''.join(G[y][x]if(x,y)in N+M+min([C([[k]],N,B)[0]for k in M],key=lambda i:len(i))else'.'for x in R(X))for y in R(Y))

สำหรับการทดสอบใช้อันนี้น้อยมาก golfed (ซึ่งคำนวณเส้นทางครั้งเดียวแทนทุกกระเบื้อง)

G=input().split('\n')
R=range
S=lambda g,x,y,s,B:[[(x,y)]+r for a,b in[(-1,0),(0,-1),(0,1),(1,0)]for r in S(g,x+a,y+b,s[1:],B)if B(x,y)and s[0]==g[y][x]]if s else[[]]
C=lambda l,N,B:[i for i in l if i[-1]in N]or C([i+[(i[-1][0]+c,i[-1][1]+d)]for i in l for c,d in [(-1,0),(0,-1),(0,1),(1,0)]if all(1<abs(i[-1][0]+c-a)or 1<abs(i[-1][1]+d-b)for a,b in B)],N,B)
X,Y=len(G[0]),len(G)
N,M,B=[filter(list,[S(G,s,t,e,lambda a,b:0<=a<X and 0<=b<Y and Y*(a-s)+b-t>=0)for s in R(X)for t in R(Y)])[0][0]for e in["nemo","marlin","bruce"]]
s=N+M+min([C([[k]],N,B)[0]for k in M],key=lambda i:len(i))
print'\n'.join(''.join(G[y][x]if(x,y)in s else'.'for x in R(X))for y in R(Y))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.