A Peak Experience: เยี่ยมชมยอดเขาทั้งหมดได้อย่างรวดเร็ว


22

ฉันกำลังยืนอยู่ที่จุด(0,0)ในแผนที่Hx Wซึ่งมีระดับความสูงเป็นตัวเลขเช่น:

1132
2221
1230    # H = 3, W = 4

3ฉันต้องการที่จะได้สัมผัสกับมุมมองจากทุกยอดซึ่งในกรณีนี้เป็นพื้นที่ที่มีระดับความสูง อย่างไรก็ตามการปีนขึ้นเขาไม่ใช่เรื่องง่ายและฉันก็หมดเวลาด้วย

ท้าทาย

ความท้าทายคือการหาเส้นทางที่เร็วที่สุดในการเยี่ยมชมยอดเขาทั้งหมดและกลับมา

โปรแกรมที่สั้นที่สุดชนะ

อินพุต

  • H, W - ความสูงและความกว้างของแผนที่ (จำนวนเต็ม) (เป็นทางเลือกอาจเป็นรายการ / ทูเปิลหรืออินพุตจำนวนเต็มแยกสองรายการ)
  • แผนที่ที่กำหนดเป็นHชุดWตัวเลข ( 0- 9) ในรูปแบบที่สะดวก (รายการ 2D สตริงคั่นด้วยการขึ้นบรรทัดใหม่ ฯลฯ )

เอาท์พุต

  • ใช้เวลาสั้นที่สุดในการเยี่ยมชมทุกจุดสูงสุดและกลับมาที่จุดเริ่มต้นของคุณ (จำนวนเต็ม)

เงื่อนไข

  • ระดับความสูงของพื้นที่ที่กำหนดจะถูกแสดงโดยหลักมาจากการ09
  • "จุดสูงสุด" ถูกกำหนดโดยพื้นที่ที่มีระดับความสูงสูงสุด
  • เส้นทางทั้งสองจะต้องเริ่มต้นและสิ้นสุดที่(0,0) ด้านซ้ายบนพื้นที่
  • คุณสามารถย้ายไปยังพื้นที่ที่อยู่ติดกับพื้นที่ปัจจุบันของคุณเท่านั้นและคุณไม่สามารถเคลื่อนที่ในแนวทแยงมุมได้
    • ใช้เวลา3 นาทีในการย้ายจากพื้นที่หนึ่งไปยังอีกพื้นที่หนึ่งหากไม่มีการเปลี่ยนแปลงระดับความสูง
    • ใช้เวลา11 นาทีในการปีนขึ้นไป; นั่นคือการย้ายจากพื้นที่หนึ่งไปยังอีกพื้นที่หนึ่งซึ่ง1สูงกว่าหน่วยแน่นอน
    • ใช้เวลา2 นาทีในการปีนลง นั่นคือการย้ายจากพื้นที่หนึ่งไปยังพื้นที่อื่นที่1ต่ำกว่าหน่วย
    • คุณไม่สามารถย้ายไปยังพื้นที่ที่มี1หน่วยมากกว่าหรือสูงกว่าที่คุณอยู่ (คุณไม่สามารถไปจากพื้นที่ที่มีความสูง1ไปยังพื้นที่ใกล้เคียงที่มีระดับความสูงพูดได้3)
  • เส้นทางไปยังจุดสูงสุดทั้งหมดรับประกัน
  • 15จำนวนสูงสุดของยอดเขาเป็น

ตัวอย่าง

อินพุต

4 5
32445
33434
21153
12343

เอาท์พุต

96

คำอธิบาย

3คุณเริ่มต้นที่ด้านบนซ้าย คุณต้องไปที่ทั้งสอง5ที่ตั้งอยู่ที่(0,4)และ(3,3)และกลับมา3ที่(0,0)ในเวลาที่สั้นที่สุด

3  2  4->4->5
V     ^
3->3->4  3  4

2  1  1  5  3

1  2  3  4  3    # 3 + 3 + 11 + 3 + 3 + 11 = 34 minutes to visit 1st peak


3  2  4  4  5
            V
3  3  4  3  4
            V
2  1  1  5  3
         ^  V
1  2  3  4<-3    # 2 + 2 + 3 + 11 + 11 = 29 minutes to visit 2nd


3  2  4  4  5
^            
3  3  4  3  4
^            
2  1  1  5  3
^        V   
1<-2<-3<-4  3    # 2 + 2 + 2 + 2 + 11 + 11 + 3 = 33 minutes to come back

# 34 + 29 + 33 = 96 minutes total is the answer

อินพุต

2 7
6787778
5777679

เอาท์พุต

75

9
ยินดีต้อนรับสู่ PPCG และคำถามแรกที่ยอดเยี่ยม! ฉันขอแนะนำให้เปลี่ยนเป็นคำถามเกี่ยวกับการเล่นกอล์ฟเนื่องจากต้องมีเกณฑ์การชนะอย่างมีวัตถุประสงค์เพื่อให้ได้คะแนนคำตอบ
Deusovi

4
ขอบคุณสำหรับคำแนะนำฉันอ่านกฎในศูนย์ช่วยเหลือและแก้ไขคำถาม
cozyconemotel

บางทีความท้าทายของคุณอาจได้รับความนิยมมากขึ้นถ้าชื่อเรื่องนั้นดีขึ้น "การปีนเขาท้าทาย" บางที
DavidC

1
cozyconemotel ฉันแนะนำชื่อที่สั้นกว่าอาจจะน่าสนใจกว่าสำหรับความท้าทายของคุณ โปรดเปลี่ยนกลับเป็นต้นฉบับหากคุณต้องการ (มีผู้ชม 245 ครั้งนับตั้งแต่การส่งของคุณ)
DavidC

@DavidC ฉันเห็นด้วยอย่างยิ่ง ขอบคุณสำหรับการแก้ไข
cozyconemotel

คำตอบ:


5

Mathematica 745 681 ไบต์

แนวคิดพื้นฐานคือการทำกราฟถ่วงน้ำหนักของการเคลื่อนไหวที่เป็นไปได้ น้ำหนักคือเวลาที่ใช้ในการย้ายจากที่หนึ่งไปอีกที่หนึ่ง เส้นทางที่มีน้ำหนักน้อยที่สุดจะเป็นเส้นทางที่รวดเร็วที่สุด

ตัวเลขที่ป้อนเข้าจะถูกวางในอาร์เรย์ r โดย c (แถวเรียงตามแถว) อาร์เรย์สี่เหลี่ยมจากนั้นมีการนำเสนอสามรูปแบบที่แตกต่างกันออกไป: (1) r โดย c กราฟกราฟที่แต่ละจุดยอดสอดคล้องกับเซลล์ในอาร์เรย์ (2) (r c) โดย (r c) เมทริกซ์ adjacency ถ่วงน้ำหนักที่เก็บน้ำหนักให้สอดคล้องกับเวลาที่ใช้ (2, 3, หรือ 11 นาที) เพื่อย้ายจากตำแหน่งหนึ่ง (ในกราฟกริด) ไปยังอีกตำแหน่งหนึ่งและ (3) ตำแหน่งกำกับ กราฟ adjacency ถ่วงน้ำหนักที่สร้างจากเมทริกซ์

กราฟกริดช่วยกำหนดว่าเซลล์ใด (เช่นจุดยอด) ที่สามารถเข้าถึงได้จากจุดสุดยอดแต่ละจุด - "อาจเข้าถึงได้" เพราะเซลล์ข้างเคียงต้องไม่เพียง แต่ถูกต้องซ้ายด้านบนหรือด้านล่างของเซลล์ที่กำหนด ค่าของมันต้องอยู่ในระยะ 1 หน่วยจากเพื่อนบ้าน (เช่น 3 ไม่เชื่อมต่อกับเพื่อนบ้าน 5 หรือ 1) หากจุดยอดaไม่ได้เชื่อมต่อกับจุดสุดยอดbดังนั้นเมทริกซ์เซลล์ adjacency {a, b} และ {b, a} จะมีค่าเป็น∞ ดังนั้นกราฟ adjacency ที่ถ่วงน้ำหนักจะไม่มีขอบจาก a ถึง b หรือจาก b ถึง a

กราฟ adjacency ที่ถ่วงน้ำหนักทำหน้าที่กำหนดระยะทางต่ำสุด ( GraphDistance) และเส้นทางที่สั้นที่สุดระหว่างจุดยอดต่างๆ เส้นทางที่ดีที่สุดจะต้องเริ่มต้นด้วย 1 แตะที่แต่ละจุดสูงสุดและกลับไปที่ 1 ในกรณีนี้ "เส้นทางที่สั้นที่สุด" ไม่จำเป็นต้องเป็นเส้นทางที่มีการเคลื่อนไหวน้อยที่สุด เป็นเครื่องที่มีเวลาโดยรวมที่สั้นที่สุดวัดเป็นค่าน้ำหนักขอบ


แข็งแรงเล่นกอล์ฟ

o=Sequence;v[a_<->b_,z_]:=(m_~u~q_:={Quotient[m-1,q[[2]]]+1,1+Mod[m-1, q[[2]]]};j=z[[o@@u[a,i=Dimensions@z]]];k=z[[o@@u[b,i]]];Which[j==k,{{a,b}->3,{b,a}->3},j==k-1,{{a,b}->11,{b,a}->2},j==k+1,{{a,b}->2,{b,a}->11},2<4,{{a,b}->∞, {b, a}->∞}]);w@e_:=Module[{d,x,l,y},x=Map[ToExpression,Characters/@Drop[StringSplit@e,2],{2}];d_~l~c_:=d[[2]](c[[1]]-1)+c[[2]];g_~y~p_:=(Min[Plus@@(GraphDistance[g,#,#2]&@@@#)&/@(Partition[#,2,1]&/@({1,o@@#,1}&/@Permutations@p))]);y[WeightedAdjacencyGraph[ReplacePart[ConstantArray[∞,{t=Times@@(d=Dimensions@x),t}],Flatten[#~v~x &/@Union@Flatten[EdgeList[GridGraph@Reverse@d,#<->_]&/@Range@(Times@@d),1],1]]], l[Dimensions@x, #] & /@ Position[x, Max@x]]

แบบฟอร์มที่ยาวและอ่านได้มากขึ้น

(*determines a weight (number of minutes) to go from vertex a to b and from b to a*)
weight[a_ <-> b_, dat_]:= 
  Module[{cellA,cellB,dim,valA,valB,vertexToCell},

  (*Convert graph vertex index to cell location*)
  vertexToCell[m_,dimen_]:={Quotient[m-1,dim[[2]]]+1,1+Mod[m-1,dimen[[2]]]};
     dim=Dimensions[dat];
     cellA = vertexToCell[a,dim];
     cellB = vertexToCell[b,dim];
     valA=dat[[Sequence@@cellA]];
     valB=dat[[Sequence@@cellB]];
     Which[
       valA==valB,{{a,b}-> 3,{b,a}-> 3},
       valA==valB-1,{{a,b}-> 11,{b,a}-> 2},
       valA==valB+1,{{a,b}-> 2,{b,a}-> 11},
       2<4,{{a,b}->∞,{b,a}->∞}]];

(* weights[] determines the edge weights (times to get from one position to the next), makes a graph and infers the shortest distance 
from vertex 1 to each peak and back.  It tries out all permutations of peaks and 
selects the shortest one. Finally, it returns the length (in minutes) of the shortest trip. *)

weights[str_]:=
  Module[{d,dat,neighbors,cellToVertex,peaks,z,gd},
  dat=Map[ToExpression,Characters/@Drop[StringSplit[str],2],{2}];
  cellToVertex[dim_,cell_]:=dim[[2]] (cell[[1]]-1)+cell[[2]];
  peaks[dat_]:= cellToVertex[Dimensions[dat],#]&/@Position[dat,peak =Max[dat]];

     (* to which cells should each cell be compared? neighbors[] is a function defined within weights[]. It returns a graph, g, from which graph distances will be derived in the function gd[] *)
  neighbors[dim_]:=
  Union@Flatten[EdgeList[GridGraph[Reverse@dim],#<->_]&/@Range@(Times@@dim),1];
    d=Dimensions[dat];
    m=ReplacePart[ConstantArray[∞,{t=Times@@d,t}], 
     (*substitutions=*)
    Flatten[weight[#,dat]&/@neighbors[d],1]];
    g=WeightedAdjacencyGraph[m,VertexLabels->"Name",ImageSize->Full,GraphLayout->"SpringEmbedding"];

    (* finds shortest path.  gd[] is also defined within weights[] *)
  gd[g3_,ps_]:=
    Module[{lists,pairs},
    pairs=Partition[#,2,1]&/@({1,Sequence@@#,1}&/@Permutations@ps);
    Min[Plus@@(GraphDistance[g3,#,#2]&@@@#)&/@pairs]]; 

  gd[g,peaks[dat]]]

การทดสอบ

weights["4 5
 32445
 33434
 21153
 12343"]

96


weights@"2 7
 6787778
 5777679"

75


weights@"3 4
 1132
 2221
 1230"

51


คำอธิบาย

นึกถึงบรรทัด 2-5 ของอินพุตต่อไปนี้

"4 5
 32445
 33434
 21153
 12343"

ในฐานะตัวแทนของอาร์เรย์ที่มี 4 แถวและ 5 คอลัมน์:

gridgraph

โดยจุดยอดแต่ละจุดตรงกับตัวเลขจากแถวลำดับอินพุต: 3 คือจุดยอด 1, 2 อยู่ที่จุดสุดยอด 2, 4 คือจุดยอด 3, อีก 4 ที่จุดยอด 4, 5 ที่จุดยอด 5, ฯลฯ กราฟตารางเป็นเพียงคร่าวๆ การประมาณกราฟที่เราตั้งเป้าไว้ มันไม่ได้บอกทาง นอกจากนี้ขอบบางส่วนจะไม่สามารถใช้งานได้ (โปรดจำไว้ว่า: เราไม่สามารถย้ายจากตำแหน่งหนึ่งไปอีกตำแหน่งหนึ่งที่มีความสูงมากกว่า 1 หน่วยเหนือหรือใต้ตำแหน่งปัจจุบัน) แต่กราฟกริดช่วยให้เราค้นหาจุดยอดเหล่านั้นที่อยู่ถัดจากจุดยอดที่เลือก สิ่งนี้ช่วยลดจำนวนของขอบที่เราต้องพิจารณาในตัวอย่างแรก (a 4 คูณ 5 grid) จาก 400 (20 * 20) ถึง 62 (31 * 2 คือจำนวนของขอบในกราฟกริด) ในตัวอย่างเดียวกันมีเพียง 48 ของขอบที่ทำงาน 14 ไม่ใช่

เมทริกซ์ adjacency แบบถ่วงน้ำหนัก 20 ต่อไปนี้แสดงระยะห่างระหว่างจุดยอดคู่ทั้งหมดจากกราฟกริด

รหัสคีย์ที่ตัดสินใจว่าจะกำหนดหมายเลขใดให้อยู่ด้านล่าง

Which[
      valA==valB,{{a,b}-> 3,{b,a}-> 3},
      valA==valB-1,{{a,b}-> 11,{b,a}-> 2},
      valA==valB+1,{{a,b}-> 2,{b,a}-> 11},
      2<4,{{a,b}->∞,{b,a}->∞}]

เซลล์ {1,2} - ในการจัดทำดัชนีเดียว - ประกอบด้วยค่า 2 เนื่องจากการย้ายจากจุดยอด 1 ไปจนถึงจุดสุดยอด 2 เป็นจุดตกต่ำ เซลล์ {2,1} มี 11 เนื่องจากการย้ายจากจุดสุดยอด 2 ถึงจุดสุดยอด 1 ขึ้นไป 3 ในเซลล์ {1,6} และ {6,1} มีความหมายว่าการเคลื่อนไหวไม่ขึ้นหรือลง เซลล์ {1,1} มี∞เนื่องจากไม่ได้เชื่อมต่อกับตัวเอง

น้ำหนัก

กราฟต่อไปนี้แสดงโครงสร้างพื้นฐานของอินพุตข้างต้น ลูกศรสีแสดงเส้นทางที่ดีที่สุดจากจุดสุดยอด 1 ถึงจุดสูงสุด (ที่ 5 และ 14) และกลับไปที่ 1 ลูกศรสีน้ำเงินสอดคล้องกับการเคลื่อนไหวในระดับเดียวกัน (3 นาที) ลูกศรสีแดงหมายถึงการขึ้น (11 นาที) และลูกศรสีเขียวหมายถึงการขึ้น (2 นาที)

กราฟ 2

เส้นทางจากจุดสุดยอด 1 (เซลล์ {1,1} ไปยังจุดสูงสุดสองจุดและกลับไปสู่จุดสุดยอด 1:

3 + 3 + 11 + 3 + 3 + 11 + 2 + 2 + 3 + 11 + 11 + 2 + 2 + 2 + 2 + 11 + 11 + 3

96


0

Pyth, 92 ไบต์

hSms@Lu.dm,bhS,@Gb+@G,hbH@G,HebG[FQ.dm,(Fb?|tsaMCb>.aJ-F@LQb1.n4@[3hT2)J*QQC.<B+]hSQd1.p.M@Q

รูปแบบการป้อนเป็น Dict {(0, 0): 3, (0, 1): 2, (0, 2): 4, …}ทำแผนที่พิกัดให้สูง: สิ่งนี้จะค้นหาเส้นทางที่เร็วที่สุดระหว่างคู่คะแนนทั้งหมดโดยใช้อัลกอริทึม Floyd – Warshallจากนั้นลดเวลารวมของรอบที่ต้องการให้น้อยลงกว่าการเปลี่ยนลำดับของยอดเขาทั้งหมด

ลองออนไลน์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.