Skaczący wskaźnik

21

Załóżmy, że mamy tablicę o długości ze wskaźnikami wskazującymi na pewne miejsce w tablicy: proces „ przeskakiwania wskaźnika ” ustawi każdy wskaźnik na lokalizację wskaźnika, na który wskazuje.psn

Dla celów tego wyzwania wskaźnikiem jest (liczony od zera) indeks elementu tablicy, co oznacza, że ​​każdy element w tablicy będzie większy lub równy i mniejszy niż . Za pomocą tej notacji proces można sformułować w następujący sposób:0n

for i = 0..(n-1) {
  ps[i] = ps[ps[i]]
}

Oznacza to (dla tego wyzwania), że wskaźniki są aktualizowane na miejscu w kolejności sekwencyjnej (tj. Najpierw niższe wskaźniki).

Przykład

Przeanalizujmy przykład: :ps = [2,1,4,1,3,2]

i = 0:the element at position ps[0] = 2 points to 4ps = [4,1,4,1,3,2]i = 1:the element at position ps[1] = 1 points to 1ps = [4,1,4,1,3,2]i = 2:the element at position ps[2] = 4 points to 3ps = [4,1,3,1,3,2]i = 3:the element at position ps[3] = 1 points to 1ps = [4,1,3,1,3,2]i = 4:the element at position ps[4] = 3 points to 1ps = [4,1,3,1,1,2]i = 5:the element at position ps[5] = 2 points to 3ps = [4,1,3,1,1,3]

Zatem po jednej iteracjiprzeskakiwania wskaźnika ” otrzymujemy tablicę .[4,1,3,1,1,3]

Wyzwanie

Biorąc pod uwagę tablicę z wyjściowymi indeksami, tablica uzyskana przez iterację opisanego powyżej przeskakiwania wskaźnika, aż tablica się już nie zmieni.

Zasady

Twój program / funkcja pobierze i zwróci / wyśle ​​ten sam typ, listę / wektor / tablicę itp., Które

  • gwarantuje się, że będzie niepusty i
  • na pewno zawiera tylko wpisy .0p<n

Warianty: możesz wybrać

  • użyć indeksowania 1 lub
  • używaj rzeczywistych wskaźników,

należy jednak wspomnieć o tym w zgłoszeniu.

Przypadki testowe

[0]  [0]
[1,0]  [0,0]
[1,2,3,4,0]  [2,2,2,2,2]
[0,1,1,1,0,3]  [0,1,1,1,0,1]
[4,1,3,0,3,2]  [3,1,3,3,3,3]
[5,1,2,0,4,5,6]  [5,1,2,5,4,5,6]
[9,9,9,2,5,4,4,5,8,1,0,0]  [1,1,1,1,4,4,4,4,8,1,1,1]
ბიმო
źródło
Powiązane: Przeskocz tablicę
ბიმო
Czy możemy przyjmować długość njako dodatkowy wkład?
Kevin Cruijssen
2
@KevinCruijssen, zobacz tę meta dyskusję .
Kudłaty
Szkoda, że ​​wpisy muszą być aktualizowane sekwencyjnie; gdyby mogły być aktualizowane jednocześnie, Mathematica miałaby rozwiązanie składające się z 21 znaków #[[#]]&~FixedPoint~#&.
Greg Martin

Odpowiedzi:

8

JavaScript, 36 bajtów

Zmienia oryginalną tablicę wejściową.

a=>a.map(_=>a.map((x,y)=>a[y]=a[x]))

Wypróbuj online

Kudłaty
źródło
6

Haskell, 56 bajtów

foldr(\_->([]#))=<<id
x#a@(b:c)=(x++[(x++a)!!b])#c
x#_=x

Aktualizacje Haskell i lokalne nie pasują do siebie.

Wypróbuj online!

nimi
źródło
5

C ++ 14 (gcc) , 61 bajtów

Jako nienazwana ogólna lambda. Wymaga sekwencyjnych kontenerów takich jak std::vector.

[](auto&c){auto d=c;do{d=c;for(auto&x:c)x=c[x];}while(d!=c);}

Wypróbuj online!

Bierpfurz
źródło
5

Szybki , 68 53 bajtów

{a in for _ in a{var i=0;a.forEach{a[i]=a[$0];i+=1}}}

Wypróbuj online!

-15 dzięki BMO

Sean
źródło
2
Witamy w PPCG! Nie znam Swift, ale na codegolf.SE domyślnie przyjmuje się wpisane funkcje lambda, które, jak sądzę, liczą się jako zamknięcie. Może to być 53 bajty (nie trzeba liczyć f=). Życzymy miłego pobytu tutaj!
ბიმო
Dziękuję za powitanie i porady, które wykorzystałem do zaktualizowania mojej odpowiedzi.
Sean
Co powiesz na używanie mapzamiast forEachskracania?
jaeyong śpiewał
4

JavaScript (ES6), 41 bajtów

f=a=>a+''==a.map((x,i)=>a[i]=a[x])?a:f(a)

Wypróbuj online!

Arnauld
źródło
Gah! Czekałem na opublikowanie tego wyzwania, abym mógł opublikować dokładnie to samo rozwiązanie: \ Cholera umiejętności ninja! : p
Kudłaty
2
@shaggy 🐱‍👤 (to ma być Ninja Cat ... ale prawdopodobnie nie jest obsługiwany wszędzie)
Arnauld
4

Japt, 15 13 7 bajtów

Zmienia oryginalną tablicę wejściową.

££hYXgU

Spróbuj (dodatkowe bajty mają zapisać zmodyfikowane dane wejściowe w konsoli)

££hYXgU
£           :Map
 £          :  Map each X at index Y
  hY        :    Replace the element at index Y
    XgU     :    With the element at index X
Kudłaty
źródło
4

Java 8, 105 54 bajtów

a->{for(int l=a.length,i=0;i<l*l;)a[i%l]=a[a[i++%l]];}

Zmienia tablicę wejściową zamiast zwracać nową, aby zapisać bajty.

lminsolth2)

Wypróbuj online.

Wyjaśnienie:

a->{                // Method with integer-array parameter and no return-type
  int l=a.length,   //  Length of the input-array
  i=0;i<l*l;)       //  Loop `i` in the range [0, length squared):
    a[i%l]=         //   Set the (`i` modulo-length)'th item in the array to:
      a[            //    The `p`'th value of the input-array,
        a[i++%l]];} //    where `p` is the (`i` modulo-length)'th value of the array
Kevin Cruijssen
źródło
3

Japt , 17 bajtów


®
£hYUgX
eV ?U:ß

Wypróbuj wszystkie przypadki testowe

Wydaje się, że powinien być krótszy, ale niestety moja początkowa myśl o UmgUtym nie działa, ponieważ każdy guzyskuje dostęp do oryginału, Ua nie modyfikuje go na każdym kroku. Odpowiednia konserwacja różnych komponentów kosztuje również garść bajtów.

Wyjaśnienie:

           #Blank line preserves input in U long enough for the next line

®          #Copy U into V to preserve its original value

£hY        #Modify U in-place by replacing each element X with...
   UgX     #The value from the current U at the index X

eV ?U      #If the modified U is identical to the copy V, output it
     :ß    #Otherwise start again with the modified U as the new input
Kamil Drakari
źródło
2

Rubinowy , 37 34 bajtów

->a{a.size.times{a.map!{|x|a[x]}}}

Wypróbuj online!

Zwraca przez modyfikację tablicy wejściowej w miejscu.

Kirill L.
źródło
2

R , 60 58 bajtów

-2 bajty dzięki @digEmAll za przeczytanie reguł.

function(x,n=sum(x|1)){for(i in rep(1:n,n))x[i]=x[x[i]];x}

Wypróbuj online!

1-indeksowany.

n jest długością tablicy wejściowej.

rep(1:n,n)replikuje 1:n nczasy (np. n=3 => 1,2,3,1,2,3,1,2,3)

Pętla nrazy tablica . Stan ustalony na pewno zostanie osiągnięty do tego czasu, tak naprawdę do końca czasu n-1 poprzez, jak sądzę. Dowód pozostawiono czytelnikowi.

ngm
źródło
1
Myślę, że możesz usunąć +1i po prostu wziąć dane oparte na 1, post stwierdza: Możesz wybrać indeksowanie oparte na 1
digEmAll
-4 przełączając na scan()dla wejścia. Zawsze uważam, że moje scan()rozwiązania nie są optymalne, więc miej oko na krótszy sposób przypisania xi nrazem: n=length(x<-scan());for(i in rep(1:n,n))x[i]=x[x[i]];x Wypróbuj online!
CriminallyVulgar
2

Czysty , 80 bajtów

import StdEnv

limit o iterate\b=foldl(\l i=updateAt i(l!!(l!!i))l)b(indexList b)

Wypróbuj online!

Obrzydliwe
źródło
2

Clojure , 136 bajtów

(defn j[a](let[f(fn[a](loop[i 0 a a](if(= i(count a))a(recur(inc i)(assoc a i(a(a i)))))))](loop[p nil a a](if(= p a)a(recur a(f a))))))

Wypróbuj online!

Ethan McCue
źródło
Witam i witam w PPCG. Czy można podać link do tłumacza online, który umożliwiłby łatwą weryfikację rozwiązania? Co więcej, loop [nie możesz się stać loop[?
Jonathan Frech
1
Najnowsza edycja powinna naprawić błędy testowe. Przepraszamy za niedogodności dla wszystkich.
Ethan McCue
1

Perl 5, 35 34 26 bajtów

wykorzystując fakt, że konwergencja jest osiągana co najwyżej dla liczby wielkości iteracji

$_=$F[$_]for@F x@F;$_="@F"

26 bajtów

$_=$F[$_]for@F;/@F/ or$_="@F",redo

34 bajty

$_=$F[$_]for@F;$_="@F",redo if!/@F/

35 bajtów

Nahuel Fouilleul
źródło
1

Węgiel drzewny , 16 bajtów

FθFLθ§≔θκ§θ§θκIθ

Wypróbuj online! Link jest do pełnej wersji kodu. Niestety, wszystkie zwykłe funkcje mapowania działają tylko na kopii tablicy, w wyniku czego po prostu permutują elementy, zamiast je przeskakiwać, więc kod musi zrobić wszystko ręcznie. Wyjaśnienie:

Fθ

Powtórz wewnętrzną pętlę raz dla każdego elementu. To tylko zapewnia, że ​​wynik się ustabilizuje.

FLθ

Pętla nad wskaźnikami tablicowymi.

§≔θκ§θ§θκ

Pobierz element tablicy pod bieżącym indeksem, użyj go do zaindeksowania tablicy i zastąp bieżący element tą wartością.

Iθ

Rzuć elementy na łańcuch i domyślnie wydrukuj każdy w osobnej linii.

Neil
źródło
1

F #, 74 73 bajtów

fun(c:'a[])->let l=c.Length in(for i in 0..l*l do c.[i%l]<-c.[c.[i%l]]);c

Nic specjalnego. Wykorzystuje ideę modułu widoczną w innych odpowiedziach.

LSM07
źródło
1

K, 27 bajtów

{{@[x;y;:;x x y]}/[x;!#x]}/
  • {..}/ stosuje lambda {..} do arg (do konwergencji)

  • wewnątrz zewnętrznej lambda:

    • {..}/[x;y]stosuje iteracyjnie lambda do x (aktualizowanego przy każdej iteracji) i elementu y (y jest listą wartości i używa elementu przy każdej iteracji). W tym przypadku arg y jest !#x(do liczby x, czyli indeksów tablicy)

    • @[x;y;:;x x y] zmień tablicę x (przy indeksie y przypisz x [x [y]])

J. Sendra
źródło