Enésimo termo da sequência de Van Eck


41

Produza o enésimo termo da sequência de Van Eck.

A sequência de Van Eck é definida como:

  • Começa com 0.
  • Se o último termo for a primeira ocorrência desse termo, o próximo termo será 0.
  • Se o último termo ocorreu anteriormente, o próximo termo é quantos passos atrás foi a ocorrência mais recente.

https://oeis.org/A181391

https://www.youtube.com/watch?v=etMJxB-igrc

https://www.youtube.com/watch?v=8VrnqRU7BVU

Sequência: 0,0,1,0,2,0,2,2,1,6,0,5,0,2, ...

Testes:

Entrada | Saída

  • 1 | 0 0
  • 8 2
  • 19 5
  • 27 9
  • 52 42.
  • 64 0 0

EDITAR

1 indexado é preferido, 0 indexado é aceitável; isso pode alterar algumas das soluções já enviadas.

Apenas o nono termo, por favor.

Mesmo (exceto pelo fato de já ter publicado parte), parece que os jogadores de código e os observadores de número de arquivos têm uma sobreposição decente.


9
Assisti ao vídeo sobre o numphphile no trabalho e ia postar isso quando chegasse em casa. Maldito seja por chegar lá primeiro. : P
Draco18s 10/06

17
Ele precisa ser indexado 1 ou podemos usar a indexação 0?
Robin Ryder

6
Podemos retornar ou produzir a sequência infinita?
Jo King

2
... ou os primeiros ntermos?
Shaggy

@ Draco18s Mesmo assim, eu vim aqui para publicá-lo depois de ver o vídeo Numberphile, quando vi isso.
Geza Kerecsenyi

Respostas:


25

JavaScript (ES6),  46 41  37 bytes

n=>(g=p=>--n?g(g[p]-n|0,g[p]=n):p)(0)

Experimente online!

Quão?

Não precisamos armazenar a sequência completa. Só precisamos acompanhar a última posição de cada número inteiro que aparece na sequência. Usamos o objeto subjacente da função recursiva g para esse propósito.

Para um dado termo p , não precisamos definir g[p] para sua posição absoluta real na sequência, porque estamos interessados ​​apenas na distância com a posição atual. É por isso que podemos simplesmente armazenar o valor atual da entrada n , que é usada como um contador decrescente no código.

Portanto, a distância é dada por g[p]n . Convenientemente, isso avalia o NaN se esta é a primeira ocorrência de p , que pode ser facilmente transformada no 0 esperado .

Comentado

n => (             // n = input
  g = p =>         // g = recursive function taking p = previous term of the sequence
                   //     g is also used as an object to store the last position of
                   //     each integer found in the sequence
    --n ?          // decrement n; if it's not equal to 0:
      g(           //   do a recursive call:
        g[p] - n   //     subtract n from the last position of p
                   //     if g[p] is undefined, the above expression evaluates to NaN
        | 0,       //     in which case we coerce it to 0 instead
        g[p] = n   //     update g[p] to n
      )            //   end of recursive call
    :              // else:
      p            //   we've reached the requested term: stop recursion and return it
)(0)               // initial call to g with p = 0

18

Python 3 , 69 63 62 bytes

f=lambda n,l=0,*s:f(n-1,l in s and~s.index(l),l,*s)if n else-l

Experimente online!

Nota: como Erik, o Outgolfer mencionado, esse código também funciona bem no Python 2.

Indexado a 0 (embora, para ser totalmente perverso, você possa indexá-lo -1, alterando if npara if~n: P)

Utiliza o maravilhoso "operador estrela" da embalagem do Python, para construir recursivamente a série, até nchegar a zero.

A função constrói a série na ordem inversa, para evitar a reversão para a pesquisa. Além disso, ele realmente armazena as negações de todos os elementos, porque convertê-los de volta no final era livre (caso contrário, -teria que ser um espaço) e economiza um byte ao longo do caminho, usando em ~s.index(l)vez de -~s.index(l).

Poderia ter 51 bytes se as tuplas Python tivessem as mesmas findfunções que as strings (retornando -1 se não for encontrado, em vez de gerar um erro), mas essa sorte não ...


3
Na verdade, o "operador em estrela" que você está usando não é o operador de desempacotamento do Python 3, mas o operador vararg que também existe no Python 2.
Erik the Outgolfer

3
O primeiro é, mas o segundo não está descompactando spara a chamada recursiva?
ArBo 10/06

1
Eu testei em Python 2 e funciona.
Erik the Outgolfer

@EriktheOutgolfer hmm, mas não é o segundo uso desembalar embora? A função não precisa suportar varargs para usar essa sintaxe.
ArBo 11/06

@ArBo: Não é diferente de def func(f, *args): f(*args); descompactar chamadas de função internas é py2 válido. O que é PY3 única-se descompactar dentro compreensões lista / DICT (ie [1, 2, *s]) ou desembalar variáveis: a, *b = [1,2,3,4].
Ehsan Kia 13/06

9

R , 62 bytes

function(n){while(sum(F|1)<n)F=c(match(F[1],F[-1],0),F)
+F[1]}

Experimente online!

Constrói a lista ao contrário; matchretorna o primeiro índice de F[1](o valor anterior) em F[-1](o restante da lista), retornando 0se nenhuma correspondência for encontrada.

Fé inicializado FALSEe coagido 0na primeira passagem do whileloop.


2
Estou meio que maravilhado com o quão bom matché esse problema quando você o constrói dessa maneira. Realmente limpo.
CriminallyVulgar

O sinal de mais na segunda linha faz alguma coisa aqui? Eu assumi que ele consertou um caso de borda, mas não consigo encontrar um para ele.
CriminallyVulgar

1
@CriminallyVulgar deve coagir Fa 0quando n==1então ele voltaria FALSE.
Giuseppe

Ahh, entendi. Faz sentido, eu estava tentando vários intervalos, mas não o valor único.
CriminallyVulgar

9

Perl 6 , 47 42 bytes

-5 bytes graças a nwellnhof

{({+grep(@_[*-1],:k,[R,] @_)[1]}...*)[$_]}

Experimente online!

Codeblock anônimo que gera o elemento indexado 0 na sequência.

Explicação:

{                                            } # Anonymous codeblock
 (                                      )[$_]  # Return the nth element
                                    ...*       # Of the infinite sequence
  {                            }  # Where each element is
    grep(        :k        )[1]   # The key of the second occurrence
         @_[*-1],                 # Of the most recent element
                   ,[R,] @_       # In the reversed sequence so far
   +     # And numify the Nil to 0 if the element is not found

8

Shell Bourne, 102 bytes

until [ 0"$i" -eq $1 ];do i=$((${i:-0}+1)) a=${n:-0};eval 'n=$(($i-${m'$a:-$i'}))' m$a=$i;done;echo $a

experimente online


3
Bem-vindo ao PPCG!
Arnauld


6

J , 29 23 bytes

1{(,~#|1+}.i.{.)@]^:[&0

Experimente online!

O trabalho real é feito no verbo da iteração do verbo power ^:, que itera tantas vezes quanto o argumento [, iniciando a iteração com o valor constante 0 &0...

  • (#|1+}.i.{.)É isso que itera. Quebrando tudo ...
  • }.i.{.Encontre o índice do i.cabeçalho da lista {.no final da lista }.. Isso retornará um índice baseado em 0; portanto, se o item atual for encontrado 1 anterior, retornará 0. Se não for encontrado, retornará o comprimento da lista, ou seja, o comprimento da cauda.
  • 1+Adicione um ao valor para corrigir a indexação baseada em 0, já que o "quanto tempo atrás" da Ven Eck é baseado em 1. Observe que, se não foi encontrado, o valor agora será o comprimento da lista completa.
  • #|Retorne o restante do valor calculado na etapa anterior, quando dividido pelo comprimento da lista completa. Observe que isso transforma "não encontrado" em 0, mas mantém todos os outros valores inalterados.
  • ,~Anexe o novo valor à frente da lista. Usamos a frente em vez de durar apenas por conveniência.
  • 1{ retorne o segundo item da lista, pois calculamos muitas vezes porque é mais curto.

6

Python , 51 bytes

f=lambda n,i=1:n>i and[f(n,i+1),i][f(n-1)==f(n+~i)]

Experimente online!

Saídas Falsepara 0. Implementa a especificação literalmente, procurando o número inteiro positivo mais baixo, ital que f(n-1)==f(n-i-1). Se essa pesquisa levar a i>=n, o elemento anterior não apareceu antes e nós produzimos 0.

Em vez de fazer algo razoável como armazenar valores anteriores em uma lista, a função os recalcula recursivamente do zero sempre que necessário e, às vezes, quando não necessário. Isso faz com que a função funcione muito lentamente para entradas acima de 10 ou mais.


5

APL (Dyalog Unicode) , 19 17 bytes SBCS

Muito obrigado a ngn, Adám, Richard Park e H.PWiz por sua ajuda na escrita e no golfe desta resposta no The APL Orchard , um ótimo lugar para aprender sobre APL e obter sua ajuda.

Editar: -2 bytes de Adám.

⊃(⊢,⍨≢|1∘↓⍳⊃)⍣⎕-1

Experimente online!

Explicação

⊃(⊢,⍨≢|1∘↓⍳⊃)⍣⎕-1

                 -1  We initialize our array of results with -1.
 (           )⍣⎕     repeats the train (in parentheses) our input, ⎕, times.
        1∘↓⍳⊃        We take the index of the head (our last element in the sequence).
                     To signify "element not found", this returns the length of the array.
      ≢|             We take our index modulo the length of the array.
                     This turns our "element not found" from the length of the array to 0.
  ⊢,⍨                And we prepend to our array.
                    Finally, we return the first element of the array,
                     which is the most recently-generated.
                     This is the ⍵-th element of the Van Eck sequence.


4

05AB1E , 8 bytes

F¯Rćk>Dˆ

n

Explicação:

F         # Loop the (implicit) input amount of times:
 ¯        #  Push the global array
  R       #  Reverse it
   ć      #  Extract the head; push the remainder and the head to the stack
    k     #  Get the 0-based index of the head in the remainder (-1 if not found)
     >    #  Increase it by 1 to make it 1-indexed (or 0 if not found)
      Dˆ  #  Add a copy to the global array
          # (after the loop, output the top of the stack implicitly as result,
          #  which is why we need the `D`/duplicate)

1
Essa é uma maneira estranha de censurar palavrões!
negativo sete

1
@negativeseven Lol, levei alguns minutos para saber o que você quis dizer, mas acho que você está se referindo ao F¯Rćk? ;)
Kevin Cruijssen 22/06

4

Java, 96 80 76 bytes

n->{int i,v=0,m[]=new int[n];for(;--n>0;m[v]=n,v=i<1?0:i-n)i=m[v];return v;}

Não ofuscado:

Function<Integer, Integer> vanEck =
n -> {

    int i;                  // i is the value of n when v was previously encountered
    int v = 0;              // v is the current element of vanEck sequence
    int[] m = new int[n];   // m[v] is the value of n when v was previously encountered

    while (--n > 0) {       // n is used as a decrementing counter

        i = m[v];
        m[v] = n;
        v = i == 0 ? 0 : i - n;
    }

    return v;
};

2
Você poderá remover alguns bytes alterando o loop while para um loop for.
MegaTom 11/06

1
Olá, você pode jogar mais golfe inline a declaração de int[]na intdeclaração e também usar em <1vez de ==0. Exemplo:int f(int n){int l[]=new int[n],i=0,j,v=0;while(++i<n){j=l[v];l[v]=i;v=j<1?0:i-j;}return v;}
Olivier Grégoire

2
E agora um lambda, bem como o golfe mencionado por @MegaTom para um total de 80 bytes:n->{int l[]=new int[n],i=0,j,v=0;for(;++i<n;l[v]=i,v=j<1?0:i-j)j=l[v];return v;}
Olivier Grégoire

1
Finalmente, você pode procurar dicas para jogar golfe em Java .
Olivier Grégoire

3

Carvão , 23 bytes

≔⁰θF⊖N«≔⊕⌕⮌υθη⊞υθ≔ηθ»Iθ

Experimente online! Link é a versão detalhada do código. Explicação:

≔⁰θ

Defina o primeiro termo como 0.

F⊖N«

n-1Tempos de loop . (Se a indexação 0 for aceitável, ela poderá ser removida para economia de 1 byte.)

≔⊕⌕⮌υθη

O próximo termo é o índice incrementado do termo atual na lista reversa de termos anteriores.

⊞υθ

Adicione o termo atual à lista de termos anteriores.

≔ηθ

Defina o termo atual para o próximo.

»Iθ

Imprima o termo atual no final do loop.



2

Geléia , 8 bytes

ẎiḢ$;µ¡Ḣ

nnth

Experimente online!

Quão?

ẎiḢ$;µ¡Ḣ - Link: n
     µ¡  - repeat this monadic link n times - i.e. f(f(...f(n)...)):
         - (call the current argument L)
Ẏ        -   tighten (ensures we have a copy of L, so that Ḣ doesn't alter it)
   $     -   last two links as a monad:
  Ḣ      -     head (pop off & yield leftmost of the copy)
 i       -     first index (of that in the rest) or 0 if not found
    ;    -   concatenate with L
       Ḣ - head

Observe que, sem a final, nós realmente coletamos[a(n), a(n-1), ..., a(2), a(1), n]



2

Haskell , 68 67 66 bytes

Implementação bastante direta (usando a indexação baseada em 0).

f n|all((/=f(n-1)).f)[0..n-2]=0|m<-n-1=[k|k<-[1..],f(m-k)==f m]!!0

Experimente online!





2

Python 3 , 128 114 111 102 99 bytes

102 -> 99 bytes, graças a Jonathan Frech

f=lambda n,i=1,l=[0]:f(n,i+1,l+[l[i-2::-1].index(l[-1])+1if l[-1]in l[:-1]else 0])if n>i else l[-1]

Experimente online!


Você pode negar sua condição e usar em -vez de !=salvar um byte.
Jonathan Frech

Além disso, como seu golfe parece não ter efeitos colaterais, você pode usar listas em vez de tuplas.
Jonathan Frech

@ JonathanFrech Mas se eu tiver uma lista como argumento padrão, ela não funcionará corretamente para chamadas consecutivas?
ruohola 13/06

Por que não deveria?
Jonathan Frech

1
Provavelmente porque seu script anterior modificou a lista, ou seja, não teve nenhum efeito colateral: exemplo .
Jonathan Frech


1

Python 3 , 112 bytes

a=[0]
for _ in a*int(input()):k=a[-1];a+=k in a[:-1]and[a[::-1].index(k)+~a[-2::-1].index(k)]or[0]
print(-a[-2])

Experimente online!

-3 bytes graças ao mypetlion


A segunda linha pode tornar for _ in a*int(input()):k=a[-1];a+=k in a[:-1]and[a[::-1].index(k)+~a[-2::-1].index(k)]or[0]- se para salvar 3 bytes.
mypetlion 11/06

@mypetlion thanks
HyperNeutrino


1

CJam (15 bytes)

0a{_(#)\+}qi*0=

Demonstração online . Este é um programa completo e indexado a 0.

Dissecação

0a      e# Push the array [0]
{       e# Loop...
  _(#   e#   Copy the array, pop the first element, and find its index in the array
  )\+   e#   Increment and prepend
}qi*    e# ... n times, where n is read from stdin
0=      e# Take the first element of the array

0

Clojure, 69 bytes

#((fn f[i c t](if(= i 1)t(f(dec i)(assoc c t i)(-(or(c t)i)i))))%{}0)

Infelizmente, uma abordagem mais funcional parece ser mais longa.


0

DC, 94 91 90 bytes

A entrada é obtida durante o programa. Salve isso em um arquivo e execute "dc" para executar. Definitivamente não é o mais curto, mas me divirto com desafios como esses no DC. A entrada é um índice baseado em 1, conforme preferencial.

[st1si0swlbxltlwlu1-sulu0!=m]sm[dlt=qSsli1+siz0!=b0siLs]sb[0pq]sf[lisw2Q]sq?2-dsu1>f0dlmxp

Main control macro
[st                         ]sm   save top value as target
[  1si0sw                   ]sm   reset i to 1 and w to 0
[        lbx                ]sm   execute macro b to get next value in w
[           ltlw            ]sm   restore target to the stack and add w to the stack
[               lu1-su      ]sm   decrement the user inputted variable
[                     lu0!=m]sm   if the user inputted variable is not 0 recurse

Next value finder macro
[dlt=q                  ]sb     if the value on the stack is the target, quit
[     Ss                ]sb     save top value to s register
[       li1+si          ]sb     increment i register
[             z0!=b     ]sb     recurse if still more values            
[                  0si  ]sb     set i to 0 (will be saved to w if relevant)
[                     Ls]sb     move top value of s register to stack

[lisw2Q]sq   Load i, save it to w, and then quit this macro and the one that called it

[0pq]sf print 0 and quit the program
```

0

C ++ (clang) , 241 235 234 219 197 189 bytes

197 -> 189 bytes, graças ao tetocat

#import<bits/stdc++.h>
int f(int n,int i=0,std::vector<int>l={0}){return~-n>i?l.push_back(find(begin(l),end(l)-1,l[i])-end(l)+1?find(rbegin(l)+1,rend(l),l[i])-rbegin(l):0),f(n,i+1,l):l[i];}

Experimente online!


0

Pitão , 18 bytes

VQ=Y+?YhxtYhY0Y;hY

Experimente online!

Constrói a sequência ao contrário e imprime o primeiro elemento (último termo da sequência).

VQ                 # for N in range(Q) (Q=input)
  =Y+         Y    # Y.prepend(
        xtY        #   Y[1:].index(    )
           hY      #               Y[0]
       h           #                     +1
     ?Y      0     #                        if Y else 0)
               ;hY # end for loop and print Y[0]
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.