Пиковый опыт: быстро посетите все пики


22

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

1132
2221
1230    # H = 3, W = 4

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

Вызов

Задача состоит в том, чтобы найти самый быстрый путь, чтобы посетить все вершины и вернуться.

Кратчайшая программа выигрывает.

вход

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

Выход

  • Наименьшее время, необходимое для посещения каждой вершины и возврата к исходной точке (целое число)

условия

  • Высота данной области представлена ​​цифрой от 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 by c (строки по столбцам), а затем в игру вступают три различных представления: (1) граф сетки r by 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. В этом случае «кратчайший маршрут» не обязательно тот, который имеет наименьшее количество ходов. Это время с наименьшим общим временем, измеренным в весах ребер.


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

Более длинная, более читаемая форма

(*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 единицу высоты выше или ниже текущей.) Но график сетки позволяет нам легко находить те вершины, которые находятся рядом с любой выбранной вершиной. Это уменьшает количество ребер, которые мы должны рассмотреть, в первом примере (сетка 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 мин).

graph2

Путь от вершины 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.