Você já está perdido?


31

Sua tarefa é implementar a sequência inteira A130826 :

um n é o menor número inteiro positivo, tal que um n - n é um múltiplo inteiro de três e duas vezes o número de divisores de (a n - n) / 3 dá o n th prazo nas primeiras diferenças da sequência produzidos pelo Flavio Peneira de Josefo.

Perdeu ainda? Bem, é realmente muito fácil.

A peneira Flavius ​​Josephus define uma sequência inteira como a seguir.

  1. Comece com a sequência de números inteiros positivos e defina k = 2 .

  2. Remover todos os k th inteiro da sequência, começando com o k th .

  3. Incremento k e volte para a etapa 2.

f n é o n th inteiro (1-indexados) que nunca é removido.

Se - como sempre - σ 0 (k) denota o número de divisores positivos do inteiro k , podemos definir a n como o menor número inteiro positivo, de modo que 0 ((a n - n) / 3) = f n + 1 - f n .

Desafio

Escreva um programa ou função que use um número inteiro positivo n como entrada e imprima ou retorne um n .

Aplicam-se as regras padrão de . Que ganhe o menor código!

Exemplos trabalhados

Se removermos cada segundo elemento dos números inteiros positivos, ficaremos com

 1  3  5  7  9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 ...

Depois de remover todos os terceiros elementos do restante, obtemos

 1  3  7  9 13 15 19 21 25 27 31 33 37 39 ...

Agora, remover cada quarto, depois quinto e sexto elemento nos leva

 1  3  7 13 15 19 25 27 31 37 39 ...
 1  3  7 13 19 25 27 31 39 ...
 1  3  7 13 19 27 31 39 ...
 1  3  7 13 19 27 39 ...

A última linha mostra os termos f 1 a f 7 .

As diferenças dos elementos consecutivos destes termos são

 2  4  6  6  8 12

Dividindo essas diferenças futuras por 2 , obtemos

 1  2  3  3  4  6 

Essas são as contagens do divisor de destino.

  • 4 é o primeiro inteiro k tal que σ 0 ((k - 1) / 3) = 1 . De fato, σ 0 (1) = 1 .
  • 8 é o primeiro inteiro k tal que σ 0 ((k - 2) / 3) = 2 . De fato, σ 0 (2) = 2 .
  • 15 é o primeiro inteiro k tal que σ 0 ((k - 3) / 3) = 3 . De fato, σ 0 (4) = 3 .
  • 16 é o primeiro inteiro k tal que σ 0 ((k - 4) / 3) = 3 . De fato, σ 0 (4) = 3 .
  • 23 é o primeiro inteiro k tal que σ 0 ((k - 5) / 3) = 4 . De fato, σ 0 (6) = 4 .
  • 42 é o primeiro inteiro k tal que σ 0 ((k - 6) / 3) = 6 . De fato, σ 0 (12) = 6 .

Casos de teste

   n     a(n)

   1        4
   2        8
   3       15
   4       16
   5       23
   6       42
   7       55
   8      200
   9       81
  10       46
  11      119
  12      192
  13      205
  14   196622
  15    12303
  16       88
  17      449
  18      558
  19      127
  20     1748
  21   786453
  22       58
  23     2183
  24     3096
  25     1105
  26   786458
  27 12582939
  28      568
  29     2189
  30     2730

14
Palavra-chave no OEIS: burro ("uma sequência sem importância").
orlp 24/12/16

15
Burro? Poderia salvar o mundo!
Dennis

3
Esse trocadilho ...
Mego

Respostas:


7

Geléia, 30 29 27 25 bytes

Economizei 2 bytes graças à notificação do @Dennis Æde mais 2 bytes por combinar as duas cadeias.

RUð÷‘Ċ×µ/
‘Ç_ÇH0Æd=¥1#×3+

Experimente online!

Esta foi provavelmente a mais divertida que já tive com Jelly. Comecei na segunda linha, que calcula f n de n usando a fórmula no OEIS, e é bastante bonito.

Explicação

RUð ÷ 'Ċ × µ / Link auxiliar para calcular F n . Argumento: n
R Obter números [1..n]
 U Reverse
        / Reduza em "arredondar para os próximos 2 múltiplos":
   ÷ Divida pelo próximo número
    'Incremento para pular vários
     Ċ Teto (arredondado para cima)
      × Multiplique pelo próximo número

'Ç_ÇH0Æd = ¥ 1 # × 3 + Link principal. Argumento: n
'Incremento n
 Ç Calcular F n + 1 
   Ç Calcular F n
  _ Subtrair
    H Divida por 2
     0 1 # A partir de 0, encontre o primeiro candidato para (a n -n) / 3
                   que satisfaça ...
      Δd σ 0 ((a n- n) / 3)
        = = (F n + 1 -F n ) / 2
            × 3 Multiplique por 3 para transformar (a n- n) / 3 em n- n
              + Adicione n para transformar um n- n em um n

3

Python 2 , 121 119 118 bytes

n=input();r=range(1,4**n);d=s,=r*1,
for k in r:del s[k::k+1];d+=sum(k%j<1for j in r)*2,
print d.index(s[n]-s[n-1])*3+n

O tempo de execução deve ser aproximadamente O (16 n ) com O (4 n ) uso de memória. Substituir 4**npor 5<<n- o que acho suficiente - melhoraria drasticamente isso, mas não estou convencido de que funcione para valores arbitrariamente grandes de n .

Experimente online!

Comportamento assintótico e limites superiores de um n

Defina b n como (a n - n) / 3 , ou seja, o menor número inteiro positivo k tal que σ 0 (k) = ½ (f n + 1 - f n ) .

Como observado na página OEIS, f n ~ ¼πn 2 , então f n + 1 - f n ~ π (n + 1) 2 - 2πn 2 = π (2n + 1) ~ ½πn .

Dessa forma, ½ (f n + 1 - f n ) ~ ¼πn . Se o número real é um primo p , o menor número inteiro positivo com divisores p é 2 p-1 , então b n pode ser aproximado por 2 c n , onde c n ~ ¼πn .

Portanto, b n <4 n será válido para n suficientemente grande e, considerando que 2 ¼πn <2 n << (2 n ) 2 = 4 n , estou confiante de que não há contra-exemplos.

Como funciona

n=input();r=range(1,4**n);d=s,=r*1,

Isso configura algumas referências para o nosso processo iterativo.

  • n é a entrada do usuário: um número inteiro positivo.

  • r é a lista [1, ..., 4 n - 1] .

  • s é uma cópia de r .

    Repetir a lista uma vez com r*1cria uma cópia superficial, portanto, modificar s não modificará r .

  • d é inicializado como a tupla (s) .

    Este primeiro valor não é importante. Todos os outros terão contagens divisórias de números inteiros positivos.

for k in r:del s[k::k+1];d+=sum(k%j<1for j in r)*2,

Para cada número inteiro k de 1 a 4 n - 1 , fazemos o seguinte.

  • del s[k::k+1]pega todo (k + 1) th inteiro em s - começando com (k + 1) th - e exclui essa fatia de s .

    Esta é uma maneira simples de armazenar um intervalo inicial da peneira de Flavius ​​Josephus em s . Ele irá calcular muito mais do que os necessários n + 1 termos iniciais, mas utilizando um único forciclo de actualizar ambos s e d poupa alguns bytes.

  • d+=sum(k%j<1for j in r)*2,conta quantos elementos de r dividem k uniformemente e acrescentam 0 (k) a d .

    Como d foi inicializado como uma tupla simples , 0 (k) é armazenado no índice k .

print d.index(s[n]-s[n-1])*3+n

Isso encontra o primeiro índice de f n + 1 - f n em d , que é o menor k tal que 0 (k) = f n + 1 - f n , em seguida, calcula um n como 3k + 1 e imprime o resultado.


2

Java 8, 336 , 305 , 303 , 287 , 283 279 bytes

57 bytes removidos graças ao Kritixi Lithos

Golfe

class f{static int g(int s,int N){return s<1?N+1:g(s-1,N+N/s);}static int h(int k){int u=0,t=1,i;for(;u!=(g(k,k)-g(k,k-1))/2;t++)for(i=1,u=0;i<=t;)if(t%i++<1)u++;return 3*t-3+k;}public static void main(String[]a){System.out.print(h(new java.util.Scanner(System.in).nextInt()));}}

Ungolfed

class f {
    static int g(int s,int N){return s < 1 ? N + 1 : g(s - 1, N + N / s);}

    static int h(int k) {
        int u = 0, t = 1, i;
        // get the first number with v divisors
        while(u != (g(k, k) - g(k, k - 1))/2){
            u = 0;
            for (i = 1; i <= t; i++)
                if (t % i < 1) u++;
            t++;
        }
        // 3*(t-1)+k = 3*t+k-3
        return 3 * t + k - 3;
    }

    public static void main(String[] a) {
        System.out.print(h(new java.util.Scanner(System.in).nextInt()));
    }
}

Eu acho que analisar os argumentos da linha de comando como um inté mais curto do que usar java.util.Scanner. Mas mesmo se você estiver usando o Scanner, você pode fazer System.out.print(h(new java.util.Scanner().nextInt()))e remover a linha anterior
Kritixi Lithos

@KritixiLithos thx, consertando agora ...
Bobas_Pett

Dentro int h(), você pode alterá-lo para int v = (g(k,k)-g(k,k-1))/2,u = 0,t = 1;. Você pode alterar sua instrução if (que está dentro do loop for) de if(t%i==0)paraif(t%i<1)
Kritixi Lithos

Além disso, você pode mudar a sua função gpara retornar usando operadores ternários algo como return s==0?N+1:g(s-1,N+N/2)-ish
Kritixi Lithos

2
@KritixiLithos lol neste momento u deve apenas postar isso como ur própria solução separada
Bobas_Pett

1

Mathematica, 130 116 106 103 bytes

3Catch@Do[f=#2⌈#/#2+1⌉&~Fold~Reverse@Range@#&;If[Tr[2+0Divisors@k]==f[#+1]-f@#,Throw@k],{k,∞}]+#&

ou

3Catch@Do[f=#2⌈#/#2+1⌉&~Fold~Reverse@Range@#&;If[2DivisorSum[k,1&]==f[#+1]-f@#,Throw@k],{k,∞}]+#&

Acabou sendo quase idêntico ao código Jelly do @ Pietu1998 ...

Explicação

Catch@

Catcho que quer que seja Throw-ed (jogado).

Do[ ... ,{k,∞}]

Loop infinito; kinicia 1e incrementa todas as iterações.

f= ...

Atribuir f:

Reverse@Range@#

Encontre {1, 2, ... , n}. Inverta.

#2⌈#/#2+1⌉&

Uma função que gera teto (n1 / n2 + 1) * n2

f= ... ~Fold~ ... &

Atribua fuma função que aplique recursivamente a função acima à lista a partir de duas etapas acima, usando cada saída como a primeira entrada e cada elemento da lista como a segunda entrada. A "saída" inicial (primeira entrada) é o primeiro elemento da lista.

Tr[2+0Divisors@k]==f[#+1]-f@#

Verifique se o dobro do número de divisores de ké igual a f (n + 1) - f (n).

If[ ... ,Throw@k]

Se a condição for True, Throwo valor de k. Caso contrário, continue em loop.

3 ... +#&

Multiplique a saída por 3 e adicione n.

Versão de 130 bytes

Catch@Do[s=#+1;a=k-#;If[3∣a&&2DivisorSigma[0,a/3]==Differences[Nest[i=1;Drop[#,++i;;;;i]&,Range[s^2],s]][[#]],Throw@k],{k,∞}]&

1

Perl 6 , 154 149 136 107 107 bytes

->\n{n+3*first ->\o{([-] ->\m{m??&?BLOCK(m-1).rotor(m+0=>1).flat!!1..*}(n)[n,n-1])/2==grep o%%*,1..o},^Inf}

Ungolfed:

-> \n {                    # Anonymous sub taking argument n
  n + 3 * first -> \o {    # n plus thrice the first integer satisfying:
    (                      #
      [-]                  #
      -> \m {              # Compute nth sieve iteration:
        m                  # If m is nonzero,
          ?? &?BLOCK(m-1).rotor(m+0=>1).flat # then recurse and remove every (m+1)-th element;
          !! 1..*          # the base case is all of the positive integers
      }                    #
      (n)                  # Get the nth sieve
      [n,n-1]              # Get the difference between the nth and (n-1)th elements (via the [-] reduction operator above)
    ) / 2                  # and divide by 2;
    ==                     # We want the number that equals
    grep o %% *, 1..o      # the number of divisors of o.
  }
  ,^Inf
}

1

05AB1E ,35 34 39 bytes

1Qi4ë[N3*¹+NÑg·¹D>‚vyy<LRvy/>îy*}}‚Æ(Q#

Parece horrível, assim como o desempenho em tempo de execução. Demora vários segundos para a entrada que gera valores pequenos. Não tente números como 14; acabará encontrando o resultado, mas levaria séculos.

Explicação

Funciona como 2 programas chamados seqüencialmente. O primeiro calcula F n + 1 - F n e o segundo determina um n com base em sua definição, usando uma abordagem de força bruta.

F n + 1 - F n é avaliado para cada iteração, mesmo que seja invariável por loop. Torna o tempo do código ineficiente, mas reduz o código.

Experimente online!


Eu não tenho certeza se entendi. Por que não pode calcular a peneira acima de 65.536?
Dennis

Isso resulta do fato de gerar todos os números inteiros entre 0 e 65536 ( žHL) e filtrar os valores que não satisfazem as restrições da peneira. Penso que a primeira parte deste programa deve ser totalmente reescrita com uma abordagem completamente diferente para torná-lo jogável.
Osable

A menos que haja limitações (como números inteiros de largura fixa) que o impeçam, espera-se que as respostas funcionem para qualquer entrada, com tempo e memória suficientes.
Dennis

Por isso, criei outro algoritmo de peneira. Pode ser jogável, mas não achei melhor no 05AB1E. No entanto, há um contra-exemplo given enough time and memory, já que eu já vi várias respostas em outras perguntas que foram tão lentas que era quase impossível dizer se elas produziram a saída correta ou não. Por esse motivo, coloquei o cálculo da peneira fora do loop e me custou 2 bytes.
Osable

Não há necessidade de tornar seu código eficiente. Você pode fazer da implementação golf / slow sua submissão e incluir a mais rápida / mais longa como uma nota lateral. Receio ter que insistir no limite dinâmico, mesmo que custe um byte.
Dennis
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.