En Yüksek Deneyim: Tüm Zirveleri Hızla Ziyaret Edin


22

Örneğin rakımın rakamlarla gösterildiği (0,0)bir Hx Wharitasında duruyorum, örneğin:

1132
2221
1230    # H = 3, W = 4

Her zirveden manzarayı deneyimlemek isterim ki bu durumda rakımlı alanlar 3. Ancak, tepelere tırmanmak kolay bir iş değildir ve zamanım da azalıyor.

Meydan okuma

Buradaki zorluk, tüm zirveleri ziyaret etmenin ve geri dönmenin en hızlı yolunu bulmak.

En kısa program kazanır.

Giriş

  • H, W - haritanın yüksekliği ve genişliği (Tamsayılar) (isteğe bağlı, bir liste / grup veya iki ayrı tamsayı girişi olabilir)
  • Olarak verilen harita, Hsetleri W(basamak 0- 9) uygun herhangi bir formatta, (2B listesinde, string, satırbaşıyla vb ayrılmış)

Çıktı

  • Her zirveyi ziyaret etmek ve başlangıç ​​noktanıza dönmek için alınan en kısa süre (Tam sayı)

Koşullar

  • Belirli bir bölgenin yüksekliği bir basamakla ile temsil edilir 0için 9.
  • "Zirve", en yüksek rakımlı alan tarafından tanımlanır.
  • Yol hem sol üst (0,0) alanda başlamalı ve hem de bitmelidir .
  • Sadece bulunduğunuz bölgeye bitişik bölgelere gidebilir ve çapraz olarak hareket etmeyebilirsiniz.
    • Yükseklikte değişiklik olmazsa bir bölgeden diğerine geçmek 3 dakika sürer .
    • Tırmanmak 11 dakika sürer ; yani, bir alandan tam olarak 1daha yüksek olan başka bir alana geçme .
    • Aşağı inmek 2 dakika sürer ; yani, bir alandan tam olarak 1ünite daha düşük olan başka bir bölgeye geçmek .
    • 1Birimden daha yüksek veya bulunduğunuz yerden daha düşük olan alanlara geçemezsiniz . (Rakımlı bir bölgeden rakımlı 1olan bitişik bir bölgeye gidemezsiniz , örneğin 3)
  • Tüm zirvelere giden bir yol garantilidir
  • Maksimum tepe sayısı 15.

Numuneler

Giriş

4 5
32445
33434
21153
12343

Çıktı

96

açıklama

Sol üst kısımdan başlıyorsunuz 3. İki ziyaret etmek 5yer almaktadır s (0,4)ve (3,3)ve geri gelmek 3de (0,0)mümkün olan en kısa sürede.

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

Giriş

2 7
6787778
5777679

Çıktı

75

9
PPCG'ye hoş geldiniz ve harika bir ilk soru! Cevap kodları almak için nesnel bir kriter olması gerektiğinden, bunu kod golf sorusuna değiştirmenizi şiddetle tavsiye ederim.
Deusovi

4
Tavsiye için teşekkür ederim, yardım merkezindeki kuralları okudum ve şu soruyu
düzelttim

Belki de başlığınız iyileştirildiyse meydan okumanız daha fazla isabet alacaktır. Belki de "Dağa tırmanma mücadelesi".
DavidC

1
cosyconemotel, mücadeleniz için daha kısa, belki de daha çekici bir başlık önerdim. İsterseniz orijinal haline getirmek için çekinmeyin. (Gönderiminizden bu yana 245 kez izlendi.)
DavidC

@DavidC Kesinlikle katılıyorum. Düzenleme için teşekkürler.
cosyconemotel

Yanıtlar:


5

Mathematica 745 681 bayt

Temel fikir, olası hareketlerin ağırlıklı bir grafiğini yapmaktır. Ağırlıklar bir yerden diğerine geçmenin zamanıdır. En az ağırlığa sahip olan yol en hızlı olacaktır.

Girdi haneleri r r'ye c (sütunlar halinde satırlar) dikdörtgen dizisine yerleştirilir ve sonra üç farklı gösterimler devreye girer: (1) her köşenin dizideki bir hücreye karşılık geldiği, r r'ye göre c ızgara grafiği, (2) (rc ) ( rc) bir konumdan (ızgara grafiğindeki) bir konumdan diğerine hareket etmek için geçen süreye (2, 3 veya 11 dakika) karşılık gelen ağırlıkları tutan ağırlıklı bitişik matris ile ve (3) yönlendirilmiş matristen oluşturulan ağırlıklı bitişik grafik.

Izgara grafiği, hangi hücrelerin (yani hangi köşelerin) her köşe noktasından muhtemelen ulaşılabilir olduğunu - "muhtemelen ulaşılabilir" olduğunu belirlemeye yardımcı olur, çünkü komşu bir hücre verilen bir hücrenin sadece sağ, sol, üstünde veya altında olmamalıdır. Değeri de komşuya 1 birim mesafede olmalıdır (örneğin, bir 3 komşu 5 veya 1'e bağlanmaz). Köşe tepe noktasına abağlı değilse b, bitişik matris hücreleri {a, b} ve {b, a}, ∞ değerine sahip olacaktır. Buna göre, ağırlıklı bitiş grafiği, a'dan b'ye ya da b'den a'ya bir kenara sahip değildir.

Ağırlıklı bitişik grafik, GraphDistanceherhangi bir tepe noktası arasındaki minimum mesafeyi ( ) ve en kısa rotayı belirlemeye yarar . En uygun yol 1 ile başlamalı, her bir tepe noktasına dokunmalı ve 1'e geri dönmelidir. Bu durumda, "en kısa yol" mutlaka en az hareket yapan yol değildir. Kenar ağırlıkları ile ölçülen en kısa toplam süreye sahip olanıdır.


golfed

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]]

Daha uzun, daha okunabilir form

(*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]]]

Testler

weights["4 5
 32445
 33434
 21153
 12343"]

96.


weights@"2 7
 6787778
 5777679"

75.


weights@"3 4
 1132
 2221
 1230"

51.


açıklama

Aşağıdaki girişin 2-5 satırlarını düşünün

"4 5
 32445
 33434
 21153
 12343"

4 satırlı ve 5 sütunlu bir diziyi temsil eden:

gridgraph

her köşe giriş dizisinden bir basamağa karşılık gelir: 3 köşe 1'de, 2 köşe 2'de, 4 köşe 3'te, köşe 4, 5'de köşe 5, vb. 4'tür. Izgara grafiği sadece kaba hedeflediğimiz grafiğin yaklaştırılması. Bu yönlendirilmemiş. Ayrıca, bazı kenarlar kullanılamayacak. (Unutmayın: Bir konumdan diğerine 1 veya daha yüksek birimin üstünde olan bir konumdan diğerine geçemeyiz.) Ancak ızgara grafiği, seçilen herhangi bir tepe noktasının yanındaki köşeleri kolayca bulalım. Bu, ilk örnekte (4'e 5'lik bir ızgara), göz önünde bulundurmamız gereken kenar sayısını 400 (20 x 20) 'den 62'ye (31 * 2, ızgara grafiğindeki kenar sayısıdır) azaltır. Aynı örnekte, kenarların sadece 48'i çalışır durumda; 14 değil.

Aşağıdaki 20 x 20 ağırlıklı bitişik matris, ızgara grafiğindeki tüm köşe çiftleri arasındaki mesafeyi temsil eder.

Hangi numaraya atanacağına karar veren anahtar kodu aşağıdadır.

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}->∞}]

Hücre {1,2} - bir indekslemede - 2 değerini içerir çünkü köşe 1'den köşe 2'ye geçiş yokuş aşağıdır. Hücre {2,1} 11 içerir çünkü köşe 2'den köşe 1'e geçiş yokuş yukarıdır. {1,6} ve {6,1} hücrelerinde bulunan 3'ler hareketin ne aşağı ne de aşağı olduğunu gösterir. {1,1} hücresi, ∞ içerir çünkü kendisine bağlı değildir.

ağırlıklar

Aşağıdaki grafik yukarıdaki girişin altında yatan yapıyı göstermektedir. Renkli oklar, tepe 1'den tepe noktalarına (5 ve 14'te) ve 1'e geri dönüş için en uygun yolu gösterir. Mavi oklar, aynı seviyedeki (3 dakika) hareketlere karşılık gelir; kırmızı oklar yükselme (11 dak.) ve yeşil oklar iniş (2 dak) gösterir.

grafik2

Köşe 1'den ({1,1} hücresinden iki tepe noktasına ve köşe 1'e geri giden yol:

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

96


0

Pyth, 92 bayt

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

Giriş biçimi zirvelere koordinatları haritalama dict geçerli: {(0, 0): 3, (0, 1): 2, (0, 2): 4, …}. Bu, Floyd-Warshall algoritmasını kullanarak tüm nokta çiftleri arasındaki en hızlı yolları bulur ve daha sonra, tepe noktalarının tüm permütasyonları boyunca istenen döngünün toplam süresini en aza indirir.

Çevrimiçi deneyin

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.