Saut de pointeur

21

Supposons que nous ayons un tableau de longueur avec des pointeurs pointant vers un emplacement dans le tableau: Le processus de " saut de pointeur " définira chaque pointeur sur l'emplacement vers lequel le pointeur vers lequel il pointe.psn

Aux fins de ce défi, un pointeur est l'index (de base zéro) d'un élément du tableau, cela implique que chaque élément du tableau sera supérieur ou égal à et inférieur à . En utilisant cette notation, le processus peut être formulé comme suit:0n

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

Cela signifie (pour ce défi) que les pointeurs sont mis à jour sur place dans un ordre séquentiel (c'est-à-dire des indices inférieurs en premier).

Exemple

Voyons un exemple, :ps = [2,1,4,1,3,2]

i = 0:l'élément en position ps [0] = 2 pointe vers 4ps = [4,1,4,1,3,2]i = 1:l'élément en position ps [1] = 1 pointe vers 1ps = [4,1,4,1,3,2]i = 2:l'élément en position ps [2] = 4 pointe vers 3ps = [4,1,3,1,3,2]i = 3:l'élément en position ps [3] = 1 pointe vers 1ps = [4,1,3,1,3,2]i = 4:l'élément en position ps [4] = 3 pointe vers 1ps = [4,1,3,1,1,2]i = 5:l'élément en position ps [5] = 2 pointe vers 3ps = [4,1,3,1,1,3]

Donc, après une itération de " saut de pointeur ", nous obtenons le tableau .[4,1,3,1,1,3]

Défi

Étant donné un tableau avec des indices, le tableau obtenu en itérant le saut de pointeur décrit ci-dessus jusqu'à ce que le tableau ne change plus.

Règles

Votre programme / fonction prendra et retournera / affichera le même type, une liste / vecteur / tableau etc. qui

  • est garanti non vide et
  • est garanti pour ne contenir que les entrées .0p<n

Variantes: vous pouvez choisir

  • d'utiliser l'indexation basée sur 1 ou
  • utiliser des pointeurs réels,

cependant, vous devez le mentionner dans votre soumission.

Cas de test

[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]
ბიმო
la source
Related: Aller le tableau
ბიმო
Sommes-nous autorisés à prendre la longueur ncomme entrée supplémentaire?
Kevin Cruijssen
2
@KevinCruijssen, voir cette méta discussion .
Shaggy
C'est dommage que les entrées doivent être mises à jour séquentiellement; s'ils pouvaient être mis à jour simultanément, Mathematica aurait la solution à 21 caractères #[[#]]&~FixedPoint~#&.
Greg Martin

Réponses:

8

JavaScript, 36 octets

Modifie le tableau d'entrée d'origine.

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

Essayez-le en ligne

Hirsute
la source
6

Haskell, 56 octets

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

Haskell et les mises à jour sur place sont un mauvais match.

Essayez-le en ligne!

nimi
la source
5

C ++ 14 (gcc) , 61 octets

Comme lambda générique sans nom. Nécessite des conteneurs séquentiels comme std::vector.

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

Essayez-le en ligne!

Bierpfurz
la source
5

Swift , 68 53 octets

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

Essayez-le en ligne!

-15 grâce à BMO

Sean
la source
2
Bienvenue chez PPCG! Je ne connais pas Swift, mais sur codegolf.SE la valeur par défaut est d'accepter les fonctions lambda typées qui, je suppose, compteraient comme une fermeture. Cela peut donc être de 53 octets (vous n'avez pas besoin de compter f=). Bon séjour ici!
ბიმო
Merci pour l'accueil et les conseils que j'ai utilisés pour mettre à jour ma réponse.
Sean
Que diriez-vous d'utiliser mapau lieu de forEachle raccourcir?
jaeyong chanté le
4

JavaScript (ES6), 41 octets

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

Essayez-le en ligne!

Arnauld
la source
Gah! J'attendais que ce défi soit publié pour que je puisse poster exactement la même solution: \ Damn your ninja skills! : p
Shaggy
2
@shaggy 🐱‍👤 (c'est censé être un Ninja Cat ... mais ce n'est probablement pas pris en charge partout)
Arnauld
4

Japt, 15 13 7 octets

Modifie le tableau d'entrée d'origine.

££hYXgU

Essayez-le (des octets supplémentaires sont pour écrire l'entrée modifiée sur la console)

££hYXgU
£           :Map
 £          :  Map each X at index Y
  hY        :    Replace the element at index Y
    XgU     :    With the element at index X
Hirsute
la source
4

Java 8, 105 54 octets

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

Modifie le tableau d'entrée au lieu d'en renvoyer un nouveau pour économiser des octets.

length2

Essayez-le en ligne.

Explication:

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
la source
3

Japt , 17 octets


®
£hYUgX
eV ?U:ß

Essayez tous les cas de test

Cela semble être plus court, mais malheureusement, ma pensée initiale UmgUne fonctionne pas, car chacun gaccède à l'original Uplutôt que de le modifier à chaque étape. La préservation de différents composants coûte également une poignée d'octets.

Explication:

           #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
la source
2

Rubis , 37 34 octets

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

Essayez-le en ligne!

Renvoie en modifiant le tableau d'entrée sur place.

Kirill L.
la source
2

R , 60 58 octets

-2 octets grâce à @digEmAll pour avoir lu les règles.

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

Essayez-le en ligne!

1 indexé.

n est la longueur du tableau d'entrée.

rep(1:n,n)reproduit les 1:n ntemps (par exemple n=3 => 1,2,3,1,2,3,1,2,3)

Parcourez les ntemps de tableau . L'état stable sera atteint d'ici là à coup sûr, en fait d'ici la fin de la n-1 fois à travers je pense. La preuve est laissée au lecteur.

ngm
la source
1
Je pense que vous pouvez supprimer le +1et prendre simplement l'entrée basée sur 1, le message indique: Vous pouvez choisir d'utiliser l'indexation basée sur 1
digEmAll
-4 en basculant sur scan()pour entrée. J'ai toujours l'impression que mes scan()solutions ne sont pas optimales, alors gardez un œil sur une manière plus courte de les assigner xet nensemble: n=length(x<-scan());for(i in rep(1:n,n))x[i]=x[x[i]];x essayez-la en ligne!
CriminallyVulgar
2

Nettoyer , 80 octets

import StdEnv

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

Essayez-le en ligne!

Οurous
la source
2

Clojure , 136 octets

(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))))))

Essayez-le en ligne!

Ethan McCue
la source
Bonjour et bienvenue chez PPCG. Serait-il possible pour vous de fournir un lien vers un interprète en ligne afin que l'on puisse facilement vérifier votre solution? En outre, loop [ne peut pas devenir loop[?
Jonathan Frech
1
L'édition la plus récente devrait corriger les échecs de test. Désolé pour la gêne occasionnée à tout le monde.
Ethan McCue
1

Perl 5, 35 34 26 octets

en utilisant le fait que la convergence est atteinte au maximum pour le nombre de taille d'itérations

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

26 octets

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

34 octets

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

35 octets

Nahuel Fouilleul
la source
1

Fusain , 16 octets

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

Essayez-le en ligne! Le lien est vers la version détaillée du code. Malheureusement, toutes les fonctions de mappage habituelles ne fonctionnent que sur une copie du tableau, le résultat étant qu'elles permutent simplement les éléments plutôt que de les sauter, le code doit donc tout faire manuellement. Explication:

Fθ

Répétez la boucle intérieure une fois pour chaque élément. Cela garantit simplement que le résultat se stabilise.

FLθ

Faites une boucle sur les indices du tableau.

§≔θκ§θ§θκ

Obtenez l'élément de tableau à l'index en cours, utilisez-le pour indexer dans le tableau et remplacez l'élément en cours par cette valeur.

Iθ

Castez les éléments en chaîne et imprimez implicitement chacun sur leur propre ligne.

Neil
la source
1

F #, 74 73 octets

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

Rien de spécial. Utilise l'idée de module vue dans d'autres réponses.

LSM07
la source
1

K, 27 octets

{{@[x;y;:;x x y]}/[x;!#x]}/
  • {..}/ applique lambda {..} sur arg (jusqu'à convergence)

  • intérieur lambda extérieur:

    • {..}/[x;y]applique lambda de manière itérative sur x (mis à jour à chaque itération) et un élément de y (y est une liste de valeurs, et utilise un élément à chaque itération). Dans ce cas, arg y est !#x(jusqu'au nombre x, c'est-à-dire les index du tableau)

    • @[x;y;:;x x y] modifier le tableau x (à l'index y attribuer x [x [y]])

J. Sendra
la source