Пиковий досвід: Швидко відвідайте всі вершини


22

Я стою в точці (0,0)на карті Hx, Wде висота представлена ​​цифрами, наприклад:

1132
2221
1230    # H = 3, W = 4

Я хотів би випробувати погляди з кожної вершини, що в даному випадку - це райони з висотою 3. Однак сходження на горби - завдання не з легких, і у мене теж не вистачає часу.

Виклик

Завдання полягає в тому, щоб знайти найшвидший шлях для відвідування всіх вершин і повернутися назад.

Найкоротша програма виграє.

Вхідні дані

  • H, W - висота та ширина карти (Цілі числа) (необов’язково, може бути список / кортеж або два окремі цілі входи)
  • Карта, подана у вигляді Hнаборів Wцифр ( 0- 9), у будь-якому зручному форматі (2D-список, рядок, розділений новими рядками тощо)

Вихідні дані

  • Найменший час, який потрібно взяти для відвідування кожної вершини та повернутися до початкової точки (Integer)

Умови

  • Висота даної області представлена ​​цифрою від 0до 9.
  • "Пік" визначається площею з найбільшою висотою.
  • Шлях повинен починатися і закінчуватися в лівій верхній (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, і чудове перше запитання! Я настійно рекомендую змінити це на питання з кодовим гольфом, оскільки для отримання відповідей повинен бути об'єктивний критерій виграшу.
Деусови

4
Дякую за рекомендацію, я прочитав правила у довідковому центрі та відредагував питання
cozyconemotel

Можливо, ваш виклик отримав би більше звернень, якби назва була вдосконалена. Можливо, "виклик гірського альпінізму".
DavidC

1
cozyconemotel, я запропонував для вашого виклику коротший, можливо, привабливіший заголовок. Будь ласка, не соромтесь повернути його до оригіналу, якщо бажаєте. (З моменту подання заявки було 245 переглядів.)
DavidC

@DavidC Я повністю згоден. Дякую за редагування
cozyconemotel

Відповіді:


5

Mathematica 745 681 байт

Основна ідея - скласти зважений графік можливих рухів. Ваги - це час, необхідний для переміщення з одного місця на інше. Шлях з найменшою вагою буде найшвидшим.

Вхідні цифри розміщуються у прямокутному масиві r на c (рядки за стовпцями), після чого вступають у дію три різні зображення: (1) сітка графіка r за c, де кожна вершина відповідає комірці в масиві, (2) (r c) за (r c) зваженою матрицею суміжності, яка утримує ваги, що відповідають часу, необхідному (2, 3 або 11 хвилин) для переміщення з одного місця (у графічній сітці) в інше, та (3) спрямованого , зважений графік суміжності, побудований з матриці.

Графік сітки допомагає визначити, які комірки (тобто які вершини) можливо досяжні з кожної вершини - "можливо досяжні", оскільки сусідня комірка повинна бути не лише правою, лівою, над або нижче даної комірки. Це значення також має бути в межах 1 одиниці відстані від сусіда (наприклад, 3 не підключається до сусіднього 5 або 1). Якщо вершина aне підключена до вершини, bто комірки матриці суміжності {a, b} і {b, a} матимуть значення ∞. Відповідно, зважений графік суміжності не матиме краю від a до b, а також від b до a.

Зважений графік суміжності служить для визначення мінімальної відстані ( 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 стовпців:

сітка

де кожній вершині відповідає цифра з вхідного масиву: 3 знаходиться у вершині 1, 2 - у вершині 2, 4 - у вершині 3, ще 4 - у вершині 4, 5 - у вершині 5 тощо. Графік сітки лише приблизний наближення графа, до якого ми прагнемо. Він непрямий. Крім того, деякі краї будуть недоступними. (Пам'ятайте: ми не можемо переходити з позиції в іншу, яка більше ніж на 1 одиницю висоти над або нижче поточної.) Але графік сітки дозволить нам легко знайти ті вершини, які знаходяться поруч із будь-якою обраною вершиною. Це зменшує кількість ребер, які нам потрібно врахувати у першому прикладі (сітка 4 на 5) з 400 (20 * 20) до 62 (31 * 2 - кількість ребер у графіку сітки). У цьому ж прикладі функціонують лише 48 ребер; 14 - ні.

Наступна зважена матриця примикання 20 на 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

Вхідний формат є диктує відображення координат на висоти: {(0, 0): 3, (0, 1): 2, (0, 2): 4, …}. Це знаходить найшвидший шлях між усіма парами точок за допомогою алгоритму Флойда – Варшала , а потім мінімізує загальний час потрібного циклу за всі перестановки піків.

Спробуйте в Інтернеті

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.