Ponteiro pulando

21

Suponha que tenhamos uma matriz de comprimento com ponteiros apontando para algum local da matriz: O processo de " salto do ponteiro " definirá cada ponteiro para o local em que o ponteiro aponta.psn

Para o objetivo desse desafio, um ponteiro é o índice (com base em zero) de um elemento da matriz, isso implica que todos os elementos na matriz serão maiores ou iguais a e menores que . Usando esta notação, o processo pode ser formulado da seguinte maneira:0n

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

Isso significa (para esse desafio) que os ponteiros são atualizados no local em ordem sequencial (ou seja, índices mais baixos primeiro).

Exemplo

Vamos trabalhar com um exemplo, :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]

Então, após uma iteração de " ponteiro pulando ", obtemos a matriz .[4,1,3,1,1,3]

Desafio

Dada uma matriz com índices, a matriz obtida iterando o ponteiro descrito acima pulando até que a matriz não mude mais.

Regras

Seu programa / função pegará e retornará / produzirá o mesmo tipo, uma lista / vetor / matriz etc. que

  • é garantido para ser não vazio e
  • é garantido que contenha apenas as entradas .0p<n

Variantes: você pode escolher

  • usar indexação baseada em 1 ou
  • use ponteiros reais,

no entanto, você deve mencionar isso em sua submissão.

Casos de teste

[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]
ბიმო
fonte
Related: Salte a matriz
ბიმო 23/01
Estamos autorizados a tomar o comprimento ncomo entrada adicional?
Kevin Cruijssen 24/01
2
@KevinCruijssen, veja esta meta-discussão .
Shaggy
É uma pena que as entradas precisem ser atualizadas sequencialmente; se eles pudessem ser atualizados simultaneamente, o Mathematica teria a solução de 21 caracteres #[[#]]&~FixedPoint~#&.
Greg Martin

Respostas:

8

JavaScript, 36 bytes

Modifica a matriz de entrada original.

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

Experimente online

Shaggy
fonte
6

Haskell, 56 bytes

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

Haskell e atualizações no local são uma má combinação.

Experimente online!

nimi
fonte
5

C ++ 14 (gcc) , 61 bytes

Como lambda genérico sem nome. Requer recipientes seqüenciais como std::vector.

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

Experimente online!

Bierpfurz
fonte
5

Rápido , 68 53 bytes

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

Experimente online!

-15 graças ao BMO

Sean
fonte
2
Bem-vindo ao PPCG! Eu não sei Swift, mas no codegolf.SE o padrão é aceitar funções lambda digitadas que eu acho que um fechamento contaria como. Portanto, isso pode ter 53 bytes (você não precisa contar f=). Aproveite a sua estadia aqui!
ბიმო 24/01
Obrigado pelas boas-vindas e conselhos que utilizei para atualizar minha resposta.
Sean
Que tal usar em mapvez de forEachreduzi-lo?
jaeyong Sung
4

JavaScript (ES6), 41 bytes

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

Experimente online!

Arnauld
fonte
Gah! Eu estava esperando que esse desafio fosse publicado para que eu pudesse postar exatamente a mesma solução: \ Droga de suas habilidades ninjas! : p
Shaggy
2
@shaggy 🐱‍👤 (este deveria ser um gato ninja ... mas provavelmente não é suportado em todos os lugares)
Arnauld
4

05AB1E (herdado) , 8 bytes

ΔDvDyèNǝ

Experimente online!

Explicação

Δ          # apply until the top of the stack stops changing
 D         # duplicate current list
  v        # for each (element y, index N) in the list
   Dyè     # get the element at index y
      Nǝ   # and insert it at index N

05AB1E , 14 bytes

[D©vDyèNǝ}D®Q#

Experimente online!

Emigna
fonte
4

Japonês, 15 13 7 bytes

Modifica a matriz de entrada original.

££hYXgU

Experimente (bytes adicionais são para gravar a entrada modificada no console)

££hYXgU
£           :Map
 £          :  Map each X at index Y
  hY        :    Replace the element at index Y
    XgU     :    With the element at index X
Shaggy
fonte
4

Java 8, 105 54 bytes

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

Modifica a matriz de entrada em vez de retornar uma nova para salvar bytes.

length2

Experimente online.

Explicação:

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
fonte
3

Japonês , 17 bytes


®
£hYUgX
eV ?U:ß

Experimente todos os casos de teste

Parece que deveria ser mais curto, mas infelizmente meu pensamento inicial UmgUnão funciona porque cada um gacessa o original em Uvez de modificá-lo a cada passo. Preservar diferentes componentes também custa um punhado de bytes.

Explicação:

           #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
fonte
2

Ruby , 37 34 bytes

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

Experimente online!

Retorna modificando a matriz de entrada no local.

Kirill L.
fonte
2

R , 60 58 bytes

-2 bytes graças a @digEmAll por ler as regras.

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

Experimente online!

1 indexado.

n é o comprimento da matriz de entrada.

rep(1:n,n)replica 1:n nvezes (por exemplo n=3 => 1,2,3,1,2,3,1,2,3)

Repetir os ntempos da matriz . O estado estacionário será alcançado até então, com certeza, de fato até o final da n-1ª vez, acho. Cabe ao leitor fornecer a prova.

ngm
fonte
1
Eu acho que você pode remover o +1e simplesmente pegar a entrada baseada em 1, o post afirma: Você pode optar por usar a indexação baseada em 1
digEmAll
-4 mudando para scan()para entrada. Sempre sinto que minhas scan()soluções não são ótimas, portanto, fique de olho em uma maneira mais curta de atribuir xe nreunir: n=length(x<-scan());for(i in rep(1:n,n))x[i]=x[x[i]];x Experimente on-line!
CriminallyVulgar
2

Limpo , 80 bytes

import StdEnv

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

Experimente online!

Furioso
fonte
2

Clojure , 136 bytes

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

Experimente online!

Ethan McCue
fonte
Olá e bem-vindo ao PPCG. Seria possível que você fornecesse um link para um intérprete on-line para que você pudesse verificar facilmente sua solução? Além disso, loop [não pode se tornar loop[?
Jonathan Frech
1
A edição mais recente deve corrigir as falhas do teste. Desculpe pelo transtorno a todos.
Ethan McCue
1

Perl 5, 35 34 26 bytes

usando o fato de que a convergência é atingida no máximo para o número de iterações de tamanho

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

26 bytes

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

34 bytes

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

35 bytes

Nahuel Fouilleul
fonte
1

Carvão , 16 bytes

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

Experimente online! Link é a versão detalhada do código. Infelizmente, todas as funções de mapeamento usuais operam apenas em uma cópia da matriz, com o resultado de que elas apenas permutam os elementos em vez de saltá-los, portanto o código precisa fazer tudo manualmente. Explicação:

Fθ

Repita o loop interno uma vez para cada elemento. Isso apenas garante que o resultado se estabilize.

FLθ

Faça um loop sobre os índices da matriz.

§≔θκ§θ§θκ

Obtenha o elemento da matriz no índice atual, use-o para indexar na matriz e substitua o elemento atual por esse valor.

Iθ

Transmitir os elementos para string e imprimir implicitamente cada um em sua própria linha.

Neil
fonte
1

F #, 74 73 bytes

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

Nada especial. Usa a ideia do módulo vista em outras respostas.

LSM07
fonte
1

K, 27 bytes

{{@[x;y;:;x x y]}/[x;!#x]}/
  • {..}/ aplica lambda {..} sobre arg (até convergência)

  • dentro lambda exterior:

    • {..}/[x;y]aplica lambda iterativamente sobre x (atualizado a cada iteração) e um item de y (y é uma lista de valores e usa um item em cada iteração). Nesse caso, arg y é !#x(até a contagem x, isto é, índices da matriz)

    • @[x;y;:;x x y] alterar matriz x (no índice y atribuir x [x [y]])

J. Sendra
fonte