Biorąc pod uwagę macierz składającą się z dodatnich liczb całkowitych, wyprowadzaj ścieżkę z najniższą sumą podczas przechodzenia od lewego górnego elementu do prawego dolnego rogu. Możesz poruszać się pionowo, poziomo i po przekątnej. Pamiętaj, że można przesuwać zarówno w górę / w dół, w prawo / w lewo i po przekątnej na wszystkie strony.
Przykład:
1* 9 7 3 10 2 2
10 4* 1* 1* 1* 7 8
3 6 3 8 9 5* 7
8 10 2 5 2 1* 4
5 1 1 3 6 7 9*
Ścieżka dająca najniższą sumę jest oznaczona gwiazdkami i daje następującą sumę: 1 + 4 + 1 + 1 + 1 + 5 + 1 + 9 = 23 .
Przypadki testowe:
1 1 1
1 1 1
Output: 3
7 9 6 6 4
6 5 9 1 6
10 7 10 4 3
4 2 2 3 7
9 2 7 9 4
Output: 28
2 42 6 4 1
3 33 1 1 1
4 21 7 59 1
1 7 6 49 1
1 9 2 39 1
Output: 27 (2+3+4+7+7+1+1+1+1)
5 6 7 4 4
12 12 25 25 25
9 4 25 9 5
7 4 25 1 12
4 4 4 4 4
Output: 34 (5+12+4+4+4+1+4)
1 1 1 1
9 9 9 1
1 9 9 9
1 9 9 9
1 1 1 1
Output: 15
2 55 5 3 1 1 4 1
2 56 1 99 99 99 99 5
3 57 5 2 2 2 99 1
3 58 4 2 8 1 99 2
4 65 66 67 68 3 99 3
2 5 4 3 3 4 99 5
75 76 77 78 79 80 81 2
5 4 5 1 1 3 3 2
Output: 67 (2+2+3+3+4+5+4+3+3+3+1+2+2+1+3+1+1+4+5+1+2+3+5+2+2)
To jest golf golfowy, więc wygrywa najkrótszy kod w każdym języku.
code-golf
number
graph-theory
optimization
matrix
Stewie Griffin
źródło
źródło
Odpowiedzi:
JavaScript,
442 412 408358 bajtówTo moje pierwsze zgłoszenie PPCG. Informacje zwrotne będą mile widziane.
To pobiera tablicę wielowymiarową jako dane wejściowe.
Wyjaśnienie
Zasadniczo, przeglądaj wszystkie komórki w kółko, dostosowując najniższy znany koszt, aby dostać się do każdego z sąsiadów. Ostatecznie siatka osiągnie stan, w którym całkowity koszt dotarcia do prawego dolnego rogu jest najniższym kosztem do osiągnięcia.
Próbny
Edycja: Specjalne podziękowania dla @ETHproductions za pomoc w goleniu dziesiątek smacznych bajtów.
Więcej dzięki @Stewie Griffin za wskazówki, które przewróciły 50 bajtów.
źródło
}
który powinien zaoszczędzić kilka bajtów. Nie musisz także deklarować zmiennych; Myślę, że usunięcievar
s powinno zaoszczędzić ci łącznie 24 bajty więcej.m[v][t]
jako zmienną:t=x+X;v=y+Y;k=m[v][t]
będzie jeszcze krótsze ...?Python 3 + numpy + scipy ,
239222186 bajtówWypróbuj online!
źródło
Pakiet Octave + Image Processing,
175162157151142139 139 bajtówZaoszczędzono 14 bajtów dzięki @Luis Mendo i 1 bajt dzięki @notjagan
Korzysta z pakietu przetwarzania obrazu, ponieważ dlaczego nie? Czy to nie tak wszyscy rozwiązują problemy z grafem?
Wypróbuj online!
Eksplodował
Wyjaśnienie
Biorąc pod uwagę tablicę wag:
Zainicjuj tablicę kosztów, aby koszt dotarcia do każdego elementu wynosił Nieskończoność, z wyjątkiem punktu początkowego (lewy górny element), którego koszt jest równy jego wadze.
Jest to iteracja 0. Dla każdej kolejnej iteracji koszt dotarcia do komórki jest ustawiony na minimum:
Po pierwszej iteracji koszt ścieżki do elementu (2,2) (przy użyciu indeksowania 1) wyniesie
Pełna tablica kosztów po pierwszej iteracji wyglądałaby następująco:
Po iteracji
k
każdy element będzie najniższym kosztem dotarcia do tego elementu od samego początku, wykonując co najmniejk
kilka kroków. Na przykład element w (3,3) można osiągnąć w 2 krokach (iteracjach) za koszt 22:Ale podczas czwartej iteracji znajduje się ścieżka 4 kroków o koszcie 20:
Ponieważ żadna ścieżka przez macierz MXN nie może być dłuższa niż liczba elementów w macierzy (jako bardzo luźna górna granica), po
m*n
iteracjach każdy element będzie zawierał koszt najkrótszej ścieżki, aby dotrzeć do tego elementu od samego początku.źródło
while
i~
.while
celufor
i był jeszcze w stanie wykorzystać końcówkę. Dzięki!JavaScript, 197 bajtów
Upiększać:
źródło
Mathematica 279 bajtów
Podstawową ideą jest stworzenie wykresu z wierzchołkami odpowiadającymi wpisom macierzy i skierowanymi krawędziami między dowolnymi dwoma wierzchołkami oddzielonymi od siebie
ChessboardDistance
większą niż zero, ale mniejszą lub równą 1. Nawiasem mówiąc, tak się składa, że jest znany jako wykres Kinga , ponieważ odpowiada ważne ruchy króla na szachownicy.FindShortestPath
jest następnie używany do uzyskania minimalnej ścieżki. DziałaEdgeWeight
, nieVertexWeight
, więc istnieje dodatkowy kod do zdefiniowaniaEdgeWeight
jako wpis macierzy odpowiadający celowi każdej ukierunkowanej krawędzi.Kod:
Zauważ, że
znak jest symbolem transpozycji. Wklei się w Mathematica bez zmian.Stosowanie:
Wynik:
Jeśli ustawisz,
g=Graph[...,GraphLayout->{"GridEmbedding","Dimension"->d},VertexLabels->Thread[s->m]
ap=FindShortestPath[...
następnie poniższa grafika wyświetli rozwiązanie (górna część matrycy odpowiada dolnej części wykresu):źródło
Haskell, 228 bajtów
Pozycje są listami dwóch elementów, ponieważ są one łatwe do wygenerowania
sequence
i tak samo łatwe do dopasowania, jak 2-krotki.Zacznij od
-1,-1
i policz koszt każdego pola docelowego kroków.Alternatywne dwa pierwsze wiersze: zacznij o
0,0
, policz pola wyjściowe, zakończ współrzędnymi równymi wymiarom macierzy (czyli w prawo od celu, który należy dodać do listy legalnych miejsc docelowych) - dokładnie tej samej długości, ale wolniej:Użycie przyrostka dla
map
nie oszczędza tutaj bajtów, ale zastępuję go, gdy tylko nie kosztuje, ponieważ może być lepszy tylko przy większej liczbie zastosowań, a czasem także przy innych restrukturyzacjach, które golą kolejną parę nawiasów.Do poprawy: Redundantne
filter
s. Scalanie / w-podszewka jefilter(flip elem$(s$(\x->[0..x])#m)\\p)
zimport Data.List
na\\
koszty 3 bajtów.Również szkoda, że
(fromEnumTo 0)
2 bajty są dłuższe niż(\x->[0..x])
.sum$concat c
jest sumą kosztu wszystkich pól, a tym samym zwięźle wyrażoną górną granicą kosztu ścieżki, która jest podawana, abyminimum
uniknąć pustej listy (mój moduł sprawdzania typu już ustalił całą rzecz do pracy naInteger
s, więc nie zakoduj na stałe maksimum , hehe). Bez względu na to, w jaki sposób ograniczam kroki w oparciu o poprzednio wykonane (co znacznie przyspieszyłoby algorytm, ale także koszt bajtów), nie mogę uniknąć ślepych zaułków, które sprawiają, że ten powrót jest konieczny.Jednym z pomysłów na filtrowanie było
((not.e n).zipWith(-)(head r))
wyodrębnienien=s[[-1..1],[-1..1]]
, które wymaga dodania,[-1,-1]
do początkowej ścieżki. Algorytm unika następnie przejścia tam, gdzie mógł już być w poprzednim kroku, co sprawia, że stąpanie po polu krawędzi prostopadle do tej krawędzi jest ślepym zaułkiem.Innym było
((>=0).sum.z(*)d)
wyodrębnieniez=zipWith
, które wprowadza nowy argumentd
do funkcji rekurencyjnej, który jest podany tak jak(z(-)p q)
w rekurencji i[1,1]
w pierwszym przypadku. Algorytm unika kolejnych kroków z ujemnym iloczynem skalarnym (d
będącym poprzednim krokiem), co oznacza brak ostrych obrotów o 45 °. To wciąż znacznie zawęża możliwości i pozwala uniknąć trywialnego ślepego zaułka, ale wciąż istnieją ścieżki, które kończą się w już odwiedzonych polach (i być może „ucieczka”, która byłaby jednak ostrym zakrętem).źródło
Python 2,
356320 bajtówWypróbuj tutaj!
-36 bajtów dzięki notjagan !
Pobiera listę list jako dane wejściowe i generuje najniższy koszt podczas nawigacji po matrycy od lewego górnego rogu do prawego dolnego rogu.
Wyjaśnienie
Znajdź każdą możliwą trasę od lewego górnego do prawego dolnego rogu macierzy, tworząc listę współrzędnych x, y dla każdej trasy. Trasy nie mogą się wycofać i muszą kończyć się na
(len(s)-1,len(s[0])-1)
.Zsumuj liczby całkowite na każdej ścieżce współrzędnych i zwróć minimalny koszt.
print
Można łatwo zmienić na wyjście wykaz współrzędnych na najkrótszej trasie.źródło
or
przypadku warunkowych. Dziękuję Ci!APL (Dyalog Classic) , 33 bajty
Wypróbuj online!
{ }
funkcja z argumentem⍵
+\+⍀⍵
weź częściowe sumy według wiersza i kolumny, aby ustalić pesymistyczną górną granicę odległości ścieżek( )⍣≡
powtarzaj aż do konwergencji:(⍉3⌊/⊣/,⊢,⊢/)⍣2
min odległości do sąsiadów, tj. zrobić dwa razy (( )⍣2
): dodaj do lewej kolumny (⊣/,
) do self (⊢
) i dołącz kolumny z prawej strony (,⊢/
), znajdź minima w poziomych trójkach (3⌊/
) i transponuj (⍉
)⍵+
dodaj wartość każdego węzła do jego minimalnych odległości do sąsiadów⊢⌊
staraj się pokonać aktualne najlepsze odległości⊃⌽,
na koniec zwróć prawą dolną komórkęźródło