Encontre um número Rocco


12

Fiz essa pergunta em uma entrevista, mas não consegui descobrir nenhuma solução. Não sei se a pergunta estava certa ou não. Eu tentei muito, mas não consegui encontrar nenhuma solução. Honestamente falando, nada veio à minha mente.

Números Rocco

Um número inteiro positivo é um número Rocco se puder ser representado como ou , onde é um número primo.nn=p(p+14)n=p(p14)p

Os 10 primeiros números de Rocco são:

32,51,95,147,207,275,351,435,527,627

Tarefa

Seu código deve aceitar um número inteiro positivo como entrada e determinar se é um número Rocco ou não.

Brownie points

  • Escreva uma função que calcule e imprima a contagem de números Rocco menor ou igual a 1 milhão.
  • Escreva uma função que calcule e imprima a contagem de números Rocco a partir da pergunta de bônus (acima de um) que é primo.

5
Olá e bem-vindo ao PPCG. Organizamos desafios (os seus parecem realmente interessantes) que têm critérios objetivos de pontuação e vitória. Tente editar sua postagem para incluir isso. Eu recomendo o código-golfe como objetivo, pois é o mais fácil de acertar. Além disso, você deseja evitar esses bônus; apenas se concentre em uma tarefa clara.
Adám 29/01/19

3
a saída seria um número inteiro : você não quer dizer um booleano para saber se a entrada era um número Rocco ou não?
Adám 29/01/19

5
Bônus 2: print 0. Todos os números Rocco são compostos (n*..), portanto, não há números primos em nenhum intervalo.
precisa saber é o seguinte

4
Os "pontos de bônus" podem simplesmente ser valores codificados e não são benéficos para o desafio. Eu recomendo removê-los.
Erik the Outgolfer

5
Eu editei a pergunta e as tags. Sinta-se à vontade para reverter ou editar mais, se você não concordar. Como o @EriktheOutgolfer disse, acho que os bônus devem ser removidos.
Arnauld

Respostas:


10

05AB1E , 8 bytes

Retorna se for um número Rocco ou caso contrário.1n0

fDŠ/α14å

Experimente online!

Quão?

Dado um número inteiro positivo , testamos se existe um fator primo de tal que:npn

|pnp|=14

Comentado

fDŠ/α14å  # expects a positive integer n as input       e.g. 2655
f         # push the list of unique prime factors of n  -->  2655, [ 3, 5, 59 ]
 D        # duplicate it                                -->  2655, [ 3, 5, 59 ], [ 3, 5, 59 ]
  Š       # moves the input n between the two lists     -->  [ 3, 5, 59 ], 2655, [ 3, 5, 59 ]
   /      # divide n by each prime factor               -->  [ 3, 5, 59 ], [ 885, 531, 45 ]
    α     # compute the absolute differences
          # between both remaining lists                -->  [ 882, 526, 14 ]
     14å  # does 14 appear in there?                    -->  1

11

JavaScript (ES7), 55 bytes

n=>(g=k=>k>0&&n%--k?g(k):k==1)(n=(49+n)**.5-7)|g(n+=14)

Experimente online!

Quão?

nxx(x+14)=nx(x14)=n

Daí as seguintes equações quadráticas:

(1)x2+14xn=0
(2)x214xn=0

(1)

x0=49+n7

(2)

x1=49+n+7

x0x1

Para fazer isso, usamos a função clássica de teste de primalidade recursiva, com um teste adicional para garantir que ela não se repita para sempre se receber um número irracional como entrada.

g = k =>    // k = explicit input; this is the divisor
            // we assume that the implicit input n is equal to k on the initial call
  k > 0 &&  // abort if k is negative, which may happen if n is irrational
  n % --k ? // decrement k; if k is not a divisor of n:
    g(k)    //   do a recursive call
  :         // else:
    k == 1  //   returns true if k is equal to 1 (n is prime)
            //   or false otherwise (n is either irrational or a composite integer)

Função principal do invólucro:

n => g(n = (49 + n) ** .5 - 7) | g(n += 14)

6

Perl 6 , 45 28 bytes

((*+49)**.5+(7|-7)).is-prime

Experimente online!

n+49±7n

Explicação:

 (*+49)**.5                   # Is the sqrt of input+49
           +(7|-7)            # Plus or minus 7
(                 ).is-prime  # Prime?

6

Regex (ECMAScript), 64 62 bytes

aa+14n=a(a+14)aa+14

Isso usa uma variante do algoritmo de multiplicação descrito brevemente em um parágrafo dos meus abundantes números regex post . Este é um spoiler . Portanto , não leia mais se não quiser que você estrague uma mágica avançada de expressões regulares unárias . Se você quiser tentar descobrir essa mágica, eu recomendo começar resolvendo alguns problemas na lista de problemas recomendados consecutivamente identificados por spoilers neste post anterior e tentando criar as idéias matemáticas de forma independente.

O algoritmo de multiplicação é implementado de maneira diferente aqui, porque estamos afirmando que dois valores conhecidos multiplicados juntos são iguais a outro valor conhecido (como também foi feito na versão alternativa do regex neste post , para testar se um número é um quadrado perfeito). Na maioria das minhas outras respostas regex postadas até agora, a multiplicação é implementada como um cálculo (não uma afirmação, conceitualmente falando), onde o objetivo é encontrar o produto de dois números conhecidos. Ambos os métodos funcionam em ambas as circunstâncias, mas em termos de golfe, são piores no trabalho um do outro.

^(?=(x((x{14})(x+)))(?=(\1*)\4\2*$)(\1*$\5))\6\3?(?!(xx+)\7+$)

Experimente online!


 # For the purposes of these comments, the input number = N.
 ^
 # Find two numbers A and A+14 such that A*(A+14)==N.
 (?=
     (x((x{14})(x+)))   # \1 = A+14; \2 = \1-1; \3 = 14; \4 = A-1; tail -= \1
     (?=                # Assert that \1 * (\4+1) == N.
         (\1*)\4\2*$    # We are asserting that N is the smallest number satisfying
                        # two moduli, thus proving it is the product of A and A+14
                        # via the Chinese Remainder Theorem. The (\1*) has the effect
                        # of testing every value that satisfies the "≡0 mod \1"
                        # modulus, starting with the smallest (zero), against "\4\2*$",
                        # to see if it also satisfies the "≡\4 mod \2" modulus; if any
                        # smaller number satisfied both moduli, (\1*) would capture a
                        # nonzero value in \5. Note that this actually finds the
                        # product of \4*\1, not (\4+1)*\1 which what we actually want,
                        # but this is fine, because we already subtracted \1 and thus
                        # \4*\1 is the value of tail at the start of this lookahead.
                        # This implementation of multiplication is very efficient
                        # golf-wise, but slow, because if the number being tested is
                        # not even divisible by \1, the entire test done inside this
                        # lookahead is invalid, and the "\1*$" test below will only
                        # fail after this useless test has finished.
     )
     (\1*$\5)           # Assert that the above test proved \1*(\4+1)==N, by
                        # asserting that tail is divisible by \1 and that \5==0;
                        # \6 = tool to make tail = \1
 )
 # Assert that either A or A+14 is prime.
 \6                     # tail = \1 == A+14
 \3?                    # optionally make tail = A
 (?!(xx+)\7+$)          # Assert tail is prime. We don't need to exclude treating
                        # 1 as prime, because the potential false positive of N==15
                        # is already excluded by requiring \4 >= 1.
 


3

Braquilog , 13 12 bytes

ṗ;14{+|-};?×

Digite o número do candidato como um argumento da linha de comandos. Saídas trueou false. Experimente online!

Explicação

O código é um predicado cuja entrada é irrestrita e cuja saída é o número que estamos testando.

ṗ             Let the input ? be a prime number
 ;14          Pair it with 14, yielding the list [?, 14]
    {+|-}     Either add or subtract, yielding ?+14 or ?-14
         ;?   Pair the result with the input, yielding [?+14, ?] or [?-14, ?]
           ×  Multiply; the result must match the candidate number

(Dicas são bem-vindas. Isso {+|-}ainda parece desajeitado.)


3

Braquilog , 9 bytes

Abordagem diferente, então DLosc 's resposta

Ċ-14&∋ṗ&×

Pega N como saída, retorna [P, P-14] ou [P + 14, P] pela entrada (primeiro número maior)

explicação

Ċ              # The 'input' is a pair of numbers
 -14           #   where the 2nd is 14 smaller then the first
    &∋ṗ        #   and the pair contains a prime
       &×      #   and the numbers multiplied give the output (N)

Experimente online!


2

Pitão, 22 20 bytes

}Qsm*Ld+Ld_B14fP_TSh

Experimente online aqui .

}Qsm*Ld+Ld_B14fP_TShQ   Implicit: Q=eval(input())
                        Trailing Q inferred
                  ShQ   Range [1-(Q+1)]
              fP_T      Filter the above to keep primes
   m                    Map the elements of the above, as d, using:
          _B14            [14, -14]
       +Ld                Add d to each
    *Ld                   Multiply each by d
  s                     Flatten result of map
}Q                      Is Q in the above? Implicit print

Editar: salvos 3 bytes como entrada sempre será positivo, portanto, não é necessário filtrar valores negativos da lista. Também foi corrigido um bug para entradas 1e 2custava 1 byte. Versão anterior:}Qsm*Ld>#0+Ld_B14fP_TU


2

05AB1E , 16 15 14 bytes

Economizei 1 byte computando 14 com em vez de žvÍ(não posso acreditar que não pensei nisso em primeiro lugar).

Guardado 1 byte graças a Emigna

ÅPε7·D(‚+y*Q}Z

Experimente online! ou Teste todas as entradas

Explicação

                 # Implicit input n
ÅP               # Push a list of primes up to n
  ε         }    # For each prime in the list...
   7·            # Push 14 (by doubling 7)
     D(‚         # Push -14 and pair them together to get [14,-14]
        +        # Add [14,-14] to the prime
         y*      # Multiply the prime to compute p(p-14) and p(p+14)
           Q     # Check if the (implicit) input is equal to each element
             Z   # Take the maximum

1
Você pode salvar um byte, alterando }˜såpara a Q}Zutilização de entrada implícita. Seu teste-Suite teria que ser mudado um pouco para algo como este para fazê-lo funcionar então. Além disso, uma forma mais óbvia de escrever žvÍou seria 14;)
Emigna

Obrigado! Por que se torna mais fácil quando você pode empurrar 14 na forma / facepalm mais complicado :)
Wisław


2

Retina 0.8.2 , 61 bytes

.+
$*
^((1{14})1(1)+)(?<=(?<!^\4+(..+))\2?)(?<-3>\1)+$(?(3)1)

Experimente online! Explicação:

.+
$*

Converta para unário.

^((1{14})1(1)+)

\1captura o maior dos dois fatores. \2captura a constante 14, salvando um byte. \3captura o menor dos dois fatores, menos 1. Isso também garante que ambos os fatores sejam pelo menos 2.

(?<=(?<!^\4+(..+))\2?)

Verifique os dois fatores para garantir que pelo menos um deles seja primo. A idéia de usar \2?foi descaradamente roubada da resposta da @ Deadcode.

(?<-3>\1)+

Repita o maior dos dois fatores um número de vezes igual a um menor que o menor dos dois fatores. Como já capturamos o fator maior, isso acaba capturando o produto dos dois fatores.

$(?(3)1)

Verifique se o produto é igual ao número fornecido.

Uma tradução direta para a Retina 1, substituindo $*por *1, teria a mesma contagem de bytes, mas um byte poderia ser salvo substituindo todos os 1s por se _então *1poderia ser substituído por, em *vez de *_. Resposta anterior da retina 1 para 68 bytes:

.+
*
Lw$`^(__+)(?=(\1)+$)
$1 _$#2*
Am` (__+)\1+$
(_+) \1

0m`^_{14}$

Experimente online! Explicação:

.+
*

Converta para unário.

Lw$`^(__+)(?=(\1)+$)
$1 _$#2*

Encontre todos os pares de fatores.

Am` (__+)\1+$

Garanta que um seja primo.

(_+) \1

Pegue a diferença absoluta.

0m`^_{14}$

Verifique se existem 14.


1

JavaScript (Nó Babel) , 69 bytes

Porra, eu acho que ia vencer a resposta de Arnaulds, mas não .....: c

x=>[...Array(x)].some((a,b)=>x/(a=(p=n=>--b-1?n%b&&p(n):n)(b))-a==14)

Experimente online!

Quero me livrar da x=>[...Array(x)].some(peça usando a recursão, para que ela fique mais curta com o tempo

Explicação

x=>[...Array(x)]                                                              Creates a range from 0 to x-1 and map:

                .some((a,b)=>                                                 Returns True if any of the following values is true
                             x/                                              Input number divided by
                                (a=(p=n=>--b-1?n%b&&p(n):n)(b))               recursive helper function. Receives a number (mapped value) as parameters and returns 
                                                                              the same number if it is prime, otherwise returns 1. Take this value
                                                                              and assign to variable a
                                                               -a            Subtract a from the result  
                                                                     ==14    Compare result equal to 14

Ele usa a fórmula

n/pp==14




1

APL (NARS) 16 caracteres, 32 bytes

{14=∣r-⍵÷r←↑⌽π⍵}

{π⍵} encontraria a fatoração de seu argumento e supomos que o último elemento de seu resultado (a lista de divisores de n) seja o divisor primário máximo de n; Aqui supomos que uma definição equivalente do número de Rocco é: n é um número de Rocco <=> fator máximo primo de n: r é tal que seja verdadeiro 14 = nrn ÷ r [para o pseudocódigo C como 14 == abs (rn / r) esta definição de número de Rocco parece finalmente aprovada no intervalo 1..1000000]; o intervalo do valor ok seria 1..maxInt; teste:

 f←{14=∣r-⍵÷r←↑⌽π⍵}
 {⍞←{1=f ⍵:' ',⍵⋄⍬}⍵⋄⍬}¨1..10000
32  51  95  147  207  275  351  435  527  627  851  1107  1247  1395  1551  1887  2067  2255  2451  2655  2867  3551  4047  4307  4575  5135  5427  5727  6035  6351  6675  7347  8051  8787  9167  9951   

1

C # (compilador interativo do Visual C #) , 99 bytes

n=>Enumerable.Range(2,n).Any(p=>Enumerable.Range(2,p).All(y=>y>=p|p%y>0)&(n==p*(p+14)|n==p*(p-14)))

Experimente online!

Enumerable.Range ataca novamente :) Usando a bandeira do compilador maluca, você pode reduzir um pouco as coisas, embora eu seja meio fã da solução de baunilha.

C # (Compilador interativo do Visual C #) + /u:System.Linq.Enumerable, 77 bytes

n=>Range(2,n).Any(p=>Range(2,p).All(y=>y>=p|p%y>0)&(n==p*(p+14)|n==p*(p-14)))

Experimente online!

Abaixo está um porto da solução de Arnauld que parecia bem legal. Atualmente é o mais longo, mas provavelmente pode ser jogado alguns.

C # (compilador interativo do Visual C #) , 101 bytes

n=>{bool g(int k)=>--k<2?n>1:n%k>0&g(k);var d=Math.Sqrt(n+49)-7;return(n=(int)d)==d&(g(n)|g(n+=14));}

Experimente online!


0

APL (NARS) 30 caracteres, 60 bytes

{∨/{0=1∣⍵:0π⍵⋄0}¨(7,¯7)+√49+⍵}

Aqui 0π é a função digamos que se um número é primo, teste:

 f←{∨/{0=1∣⍵:0π⍵⋄0}¨(7,¯7)+√49+⍵}
 {⍞←{1=f ⍵:' ',⍵⋄⍬}⍵⋄⍬}¨0..700
32  51  95  147  207  275  351  435  527  627

0

F #, 2 respostas (não competidor)

Gostei muito das respostas de @Arnauld, então as traduzi.

123 bytes , com base na resposta JavaScript

fun n->let t=int<|sqrt(float n+49.)in Seq.map(fun n->Seq.filter(fun i->n%i=0)[1..n]|>Seq.length=2)[t-7;t+7]|>Seq.reduce(||)

Explicação:

fun n->let t=int<|sqrt(float n+49.)in Seq.map(fun n->Seq.filter(fun i->n%i=0)[1..n]|>Seq.length=2)[t-7;t+7]|>Seq.reduce(||) //Lambda which takes an integer, n
       let t=int<|sqrt(float n+49.)                                                                                         //let t be n, converted to float, add 49 and get square root, converted back to int (F# type restrictions)
                                   in                                                                                       //in the following...
                                                                                                  [t-7;t+7]                 //Subtract and add 7 to t in a list of 2 results (Lists and Seqs can be interchanged various places)
                                      Seq.map(fun n->Seq.filter(fun i->n%i=0)[1..n]|>Seq.length=2)                          //See if either are prime (here, if either result has 2 and only 2 divisors)
                                                                                                           |>Seq.reduce(||) //And logically OR the resulting sequence

125 bytes , com base na resposta 05AB1E

fun n->let l=Seq.filter(fun i->n%i=0)[2..n-1]in let m=Seq.map(fun i->n/i)l in Seq.map2(fun a b->abs(a-b))l m|>Seq.contains 14

Explicação:

fun n->let l=Seq.filter(fun i->n%i=0)[2..n-1]in let m=Seq.map(fun i->n/i)l in Seq.map2(fun a b->abs(a-b))l m|>Seq.contains 14  //Lambda which takes an integer, n
       let l=Seq.filter(fun i->n%i=0)[2..n-1]                                                                                  //let l be the list of n's primes 
                                             in                                                                                //in...
                                                let m=Seq.map(fun i->n/i)l                                                     //m, which is n divided by each of l's contents
                                                                           in                                                  //and then...
                                                                              Seq.map2(fun a b->abs(a-b))l m                   //take the absolute difference between each pair of items in the two sequences to make a new sequence
                                                                                                            |>Seq.contains 14  //and does the resulting sequence contain the number 14?

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.