A083569: O menor m não ocorre anteriormente, de modo que m + n é primo

26

Defina uma sequência indexada 1 da seguinte maneira:

  • A083569(1) = 1
  • A083569(n)onde né um número inteiro maior que 1, é o menor número inteiro m que não ocorre anteriormente, de modo que m+né um número primo.

Sua tarefa é receber ne retornar A083569(n).

 n  A083569(n)
 1  1
 2  3
 3  2
 4  7
 5  6
 6  5
 7  4
 8  9
 9  8
10 13
11 12
12 11
13 10
14 15
15 14
16 21
17 20
18 19
19 18
20 17

Mais casos de teste podem ser encontrados aqui . A sequência original no OEIS pode ser encontrada aqui .

Isso é . A resposta mais curta em bytes vence. Aplicam-se brechas padrão .

Freira Furada
fonte
@ Mr.Xcoder "Defina uma sequência indexada em 1 da seguinte maneira"
Leaky Nun

Respostas:

14

Haskell , 87 86 83 80 74 69 bytes

Obrigado ao xnor por sugerir algumas alterações que salvaram 3 bytes!

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

Experimente online!

Eu sou novo em Haskell, e no golfe de Haskell, o feedback é apreciado!

Explicação

Nós definimos uma função f n. Definimos f ncomo o primeiro elemento !!0da lista:

[m|m<-[1..],all((>0).mod(n+m))[2..n+m-1],all((/=m).f)[1..n-1]]

Discriminado:

[m|          # Numbers m
m<-[1..],    # From the integers greater than 0
all          # Forall x
(>0).mod(n+m)# n+m mod x is not zero
[2..n+m-1]   # from the integers from 2 to n+m-1
all          # Forall
((/=m).f)    # when f is applied the result is not m
[1..n-1]     # from the integers from 1 to n-1
Assistente de Trigo
fonte
3
Bem-vindo ao golfe Haskell! O [2,3..]pode ser apenas [2..], contando até 1 é padrão. Há um embutido notElem.
xnor
@xnor Obrigado! Acabei encontrando uma maneira melhor de usá-lo, notElemmas a primeira dica foi útil e vou me certificar de manter a segunda no bolso de trás.
Wheat Wizard
Parece que sua nova revisão começa f 1errado, deve ser 1.
xnor
@xnor Corrigido, infelizmente, ao custo de 3 bytes.
Assistente de trigo
6

Geléia , 16 15 bytes

Rɓ²R+⁸ÆPTḟḢṭµ/Ṫ

Isto assume A083569 (n) ≤ n² (a sequência parece estar crescendo linearmente).

Experimente online!

Como funciona

Rɓ²R+⁸ÆPTḟḢṭµ/Ṫ  Main link. Argument: n

R                Range; yield [1, ..., n].
 ɓ               Begin a dyadic chain with swapped arguments.
            µ/   Reduce the range by that chain.
                 If we call the chain f, this computes f(2,1), then f(3,f(2,1)),
                 then f(4,f(3,f(2,1)), etc.
                 The left argument is an integer k, the right one an array A.
  ²                Square; yield k².
   R               Range; yield [1, ..., k²].
    +⁸             Add k, yielding [1+k, ..., k²+k].
      ÆP           Test each sum for primality.
        T          Truth; get all indices of 1‘s. This finds all m in [1, ..., k²]
                   such that m+k is prime.
         ḟ         Filterfalse; remove all resulting elements that appear in A.
          Ḣ        Head; extract the first remaining result.
           ṭ       Tack; append the extracted integer to A.
                 This computes the first n elements of the sequence.
              Ṫ  Tail; extract the last, n-th element.
Dennis
fonte
4
De fato, A083569(n)é no máximo o nprimeiro primo maior do que npor sua definição, que é no máximo o 2nprimeiro primo, que (para n≥3) é menor que 4n*log(n)pelos resultados de Rosser-Schoenfeld.
Greg Martin
Enquanto @GregMartin verificou-se, ainda é uma suposição bastante selvagem para fazer ...
Esolanging Fruit
4
@ Challenger5 Eu prefiro "palpite".
Dennis
6

Pitão - 18 17 15 bytes

Obrigado a @isaacg por me salvar dois bytes!

De volta a este site, depois de ter estado ocupado por um tempo, espero que este ainda seja melhor.

esmaYf&-TYP_+Th

Experimente online aqui .

Maltysen
fonte
4
Bem-vindo de volta ao PPCG!
Leaky Nun
@LeakyNun Thanks :)
Maltysen
1
-TYé um byte menor que !/YT, e realmente, nos mesmos casos.
Isaacg
Você pode salvar outro byte, alterando +hdTpara +Th.
Isaacg
@isaacg, oh, lança o primeiro elemento para uma lista? Isso é muito legal.
Maltysen 19/06/19
3

C # (.NET Core) , 169 bytes

n=>{if(n<2)return 1;var p=new int[n-1];int i=0,j,s;for(;i<n-1;)p[i]=f(++i);for(i=1;;i++){for(j=2,s=i+n;j<s&&s%j++>0;);if(j==s&!System.Array.Exists(p,e=>e==i))return i;}}

Experimente online!

De longe a forma mais ineficiente para calcular os resultados, por isso, abster-se de cálculo f(n)para n>=30com este código. A primeira etapa é calcular recursivamente os valores de f(1)para f(n-1)e, em seguida, prossiga para o cálculo f(n)pesquisando o primeiro i, que n+ié primo e inão está na lista de valores anteriores.

Charlie
fonte
3

x86-64 Assembly, 57 55 bytes

Eu sou novo no golfe, então comentários / feedback são apreciados.

Nota: isso é otimizado para o comprimento do código da máquina, não para o comprimento da fonte.

0: 89 f8 ff cf 74 32 97 89 fe 89 f1 ff c6 89 f0 99
1: f7 f1 85 d2 e0 f7 85 c9 75 ed 89 f9 ff c9 56 29
2: fe 56 57 51 89 fc e8 d3 ff ff ff 59 5f 5e 39 c6
3: e0 ef 96 5e 74 d1 c3

Define uma função, usando a convenção padrão (ou seja, valor de retorno em eax, primeiro argumento em edi, todos os registros salvos pelo chamador, exceto ebx) que pega um número inteiro de 32 bits sem sinal e retorna o menor m etc.

Fonte:

    .globl a083569
    // edi = original, probably don't touch
    // esi = candidate prime, if it's not a repeat we return edi-this
a083569:
    mov %edi, %eax
    dec %edi
    jz end
    xchg %eax, %edi
    mov %edi, %esi
primecheck:
    mov %esi, %ecx
    inc %esi
primeloop:
    mov %esi, %eax
    cdq
    div %ecx
    test %edx, %edx
    loopnz primeloop
/* end */
    // if esi isn't prime, then ecx is now one or greater.
    test %ecx, %ecx
    jnz primecheck
    // esi is now our target prime: check if it's not already one
    mov %edi, %ecx
    dec %ecx
    push %rsi   /* we need a flag-safe way to restore this later */
    sub %edi, %esi
chkdup:
    push %rsi
    push %rdi
    push %rcx
    mov %ecx, %edi
    call a083569
    pop %rcx
    pop %rdi
    pop %rsi
    cmp %eax, %esi
    loopne chkdup
/* end loop - chkdup */
    xchg %esi, %eax
    pop %rsi
    je primecheck
/* end outer loop - primecheck */
end:
    ret

Experimente online!

ObsequiousNewt
fonte
1

Clojure, 158 155 bytes

#(loop[r[0 1]i 1](if(= i %)(last r)(recur(conj r(nth(for[j(range):when(=((set r)j)(seq(for[k(range 2(+ 1 i j)):when(=(mod(+ 1 i j)k)0)]j)))]j)0))(inc i))))

Isso ainda pode ter um pouco de gordura, não estou muito satisfeito, (+ 1 i j)mas essa foi a maneira mais fácil de lidar com o caso base n = 1e o resto. ((set r)j)retorna nilse jnão estiver no conjunto e, (seq ())em uma lista vazia, retorna nulo também. Calcula n = 1000em 48 segundos.

Atualização: removida nilda =verificação, pois o código funciona corretamente também sem ela.

NikoNyrh
fonte
1

Ruby , 62 + 8 = 70 bytes

Usa a -rprimebandeira.

f=->n,o=[]{o<<f[n-1,o]if n>1;Prime.find{|i|i>n&&o|[i-n]!=o}-n}

Experimente online!

Value Ink
fonte
1

Python, 194 170 110 bytes

84 bytes salvos por Leaky Nun

2 bytes salvos por mathmandan

def s(n):
 a=[s(j)for j in range(1,n)];i=1
 while(i in a)|any((i+n)%j<1for j in range(2,i+n)):i+=1
 return i

Define uma função s (n) que recebe um número como entrada e retorna A083569 (n).

Experimente Online

Madison Silver
fonte
1
Você pode considerar incluir este link do TIO .
Leaky Nun
1
Você pode usar p=lambda n:any(n%i<1for i in range(2,n))para a verificação de primalidade.
Leaky Nun
1
110 bytes
Freira vazada
1
Você pode usar o bit a bit ou para salvar um casal bytes:while(i in a)|any(...
mathmandan