Wyzwanie
Biorąc pod uwagę macierz stochastyczną lewą lub prawą, gdzie granica, gdy x zbliża się do nieskończoności macierzy, do potęgi x zbliża się do macierzy ze wszystkimi wartościami skończonymi, zwróć macierz, do której się zbiega. Zasadniczo, chcesz ciągle mnożyć macierz, aż wynik się nie zmieni.
Przypadki testowe
[[7/10, 4/10], [3/10, 6/10]] -> [[4/7, 4/7], [3/7, 3/7]]
[[2/5, 4/5], [3/5, 1/5]] -> [[4/7, 4/7], [3/7, 3/7]]
[[1/2, 1/2], [1/2, 1/2]] -> [[1/2, 1/2], [1/2, 1/2]]
[[1/3, 2/3], [2/3, 1/3]] -> [[1/2, 1/2], [1/2, 1/2]]
[[1/10, 2/10, 3/10], [4/10, 5/10, 6/10], [5/10, 3/10, 1/10]] -> [[27/130, 27/130, 27/130], [66/130, 66/130, 66/130], [37/130, 37/130, 37/130]]
[[1/7, 2/7, 4/7], [2/7, 4/7, 1/7], [4/7, 1/7, 2/7]] -> [[1/3, 1/3, 1/3], [1/3, 1/3, 1/3], [1/3, 1/3, 1/3]]
Zasady
- Obowiązują standardowe luki
- Możesz wybrać, czy chcesz matrycę stochastyczną prawą czy lewą
- Możesz użyć dowolnego rozsądnego typu liczby, takiego jak zmiennoprzecinkowe, wymierne, dziesiętne nieskończone precyzyjne itp
- Jest to golf golfowy , więc najkrótsze przesłanie w bajtach dla każdego języka zostaje ogłoszone zwycięzcą dla jego języka. Żadna odpowiedź nie zostanie zaakceptowana
Odpowiedzi:
R ,
4443 bajtówWypróbuj online!
Po prostu mnoży, aż znajdzie stałą macierz. Najwyraźniej
X!=(X=X%*%m)
porównuje, a następnie zmienia przypisanieX
, więc to jest miłe.Dzięki @Vlo za odcięcie bajtu; mimo że przekreślone 44 jest nadal regularne 44.
źródło
function(m){ while(any(m!=(m=m%*%m)))0 m}
nie działa. Niedokładności numeryczne uniemożliwiające uruchomienie warunku zakończenia?Oktawa ,
454235 bajtówWypróbuj online!
Zaoszczędź 3 bajty dzięki Giuseppe i 7 dodatkowych dzięki Luisowi Mendo!
Wykorzystuje to, że wektor własny odpowiadający wartości własnej 1 (również maksymalnej wartości własnej) jest wektorem kolumny powtarzanym dla każdej wartości macierzy granicznej. Musimy znormalizować wektor, aby suma 1 była stochastyczna, po prostu powtarzamy go, aby wypełnić macierz. Nie jestem zbyt dobrze zaznajomiony z golfem Octave, ale nie byłem w stanie znaleźć funkcjonalnego sposobu powtarzania mnożenia, a pełny program wydaje się, że zawsze będzie dłuższy.
Możemy użyć,
any(A)
ponieważ z ograniczeń wiemy, że macierz musi opisywać nieredukowalny łańcuch Markowa, a więc każdy stan musi być osiągalny z innych stanów. Dlatego przynajmniej jedna wartość w każdej kolumnie musi być niezerowa.źródło
eigs
zawsze zwraca odpowiadający mu wektor własny1
? Moja pamięć łańcuchów Markowa jest trochę rozmyta.eigs
zwraca wartość zaczynając od największej wartości własnej. Dziękujemy również za golfa!Wolfram Language (Mathematica) , 14 bajtów
Wyjścia zmiennoprzecinkowe:
Wypróbuj online!
Wolfram Language (Mathematica) , 30 bajtów
Frakcje wyjściowe:
Wypróbuj online!
źródło
Galaretka , 6 bajtów
To jest pełny program.
Wypróbuj online!
źródło
APL (Dyalog) ,
186 bajtów12 bajtów zapisanych dzięki @ H.PWiz
Wypróbuj online!
źródło
+.×⍨⍣≡
dla 6 bajtów. To znaczy, kwadrat, dopóki nic się nie zmienik / q, 10 bajtów
k / q, ponieważ program jest identyczny w obu językach. Kod jest tak naprawdę idiomatyczny k / q.
Wyjaśnienie
{..}
jest poza składnią lambda, zx
parametrem niejawnym$[x]
ma $ jako operator mnożenia macierzy binarnej, pod warunkiem, że tylko jeden parametr tworzy jednoargumentowy operator, który pozostawił mnożenie przez macierz Markowa/[x]
stosuje lewe mnożenie aż do zbieżności, zaczynając od samego x.źródło
C (gcc) ,
207192190181176 bajtów + 2 bajty flagi-lm
piętnaściesiedemnaściedwadzieścia dwa bajty dzięki ceilingcat .return A;
.Wypróbuj online!
źródło
Python 3 ,
7561 bajtówWypróbuj online!
W przypadkach testowych występują niedokładności typu float, więc wartości mogą się nieco różnić od dokładnych ułamków.
PS.
numpy.allclose()
jest używany, ponieważnumpy.array_equal()
jest dłuższy i podatny na pływanie nieścisłości.-14 bajtów Dzięki HyperNeutrino;) O tak, zapomniałem operatora @; P
źródło
dot
zamiastmatmul
: Dx=n@n
: P tio.run/…f=
przodu, ponieważ jest rekurencyjnie nazywany;)Java 8,
356339 bajtów-17 bajtów dzięki @ceilingcat .
Zdecydowanie niewłaściwy język .. Cholerna precyzja zmiennoprzecinkowa ..
Wyjaśnienie:
Wypróbuj online.
źródło
float
/double
nie ma właściwej precyzji zmiennoprzecinkowej,java.math.BigDecimal
należy zamiast niej użyć. I zamiast po prostu+-*/
, BigDecimals użyć.add(...)
,.subtract(...)
,.multiply(...)
,.divide(...)
. Więc coś tak prostego, jak się7/10
stajenew BigDecimal(7).divide(new BigDecimal(10))
. Ponadto,,scale,RoundingMode
wdivide
są wymagane dla wartości z „nieskończonymi” wartościami dziesiętnymi (jak1/3
istnienie0.333...
). Główną metodą można oczywiście grać w golfa, ale nie zawracałem sobie głowy wyszukiwaniem i zamianą, aby przekonwertować zmiennoprzecinkowe na BigDecimals.