Trova un numero Rocco


12

Mi è stata posta questa domanda in un'intervista, ma non sono riuscito a trovare una soluzione. Non so se la domanda fosse giusta o meno. Ho provato molto ma non sono riuscito a trovare alcuna soluzione. Onestamente, non mi è venuto in mente niente.

Numeri di Rocco

Un numero intero positivo è un numero di Rocco se può essere rappresentato come o , dove è un numero primo.nn=p(p+14)n=p(p14)p

I primi 10 numeri di Rocco sono:

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

Compito

Il tuo codice deve accettare un numero intero positivo come input e determinare se si tratta di un numero Rocco o meno.

Punti Brownie

  • Scrivi una funzione che calcola e stampa il conteggio dei numeri di Rocco inferiore o uguale a 1 milione.
  • Scrivi una funzione che calcola e stampa il conteggio dei numeri di Rocco dalla domanda bonus (sopra quella) che sono primi.

5
Ciao e benvenuto in PPCG. Ospitiamo sfide (le tue sembrano davvero interessanti) che hanno obiettivi obiettivi e criteri vincenti. Prova a modificare il tuo post per includerlo. Consiglio il code-golf come obiettivo, dal momento che è il più semplice da ottenere. Inoltre, vuoi evitare quei bonus; concentrati solo su un compito chiaro.
Adám,

3
l'output sarebbe un numero intero : non intendi un valore booleano se l'input fosse un numero Rocco o no?
Adám,

5
Bonus 2: print 0. Tutti i numeri di Rocco sono composti (n*..), quindi nessun numero primo in nessun intervallo.
TFeld

4
I "punti bonus" possono essere semplicemente valori codificati e non sono affatto utili alla sfida. Consiglio di rimuoverli.
Erik the Outgolfer,

5
Ho modificato la domanda e i tag. Sentiti libero di ripristinare o modificare ulteriormente se non sei d'accordo. Come ha detto @EriktheOutgolfer, penso che i bonus dovrebbero essere rimossi.
Arnauld,

Risposte:


10

05AB1E , 8 byte

Restituisce 1 se n è un numero Rocco o 0 contrario.

fDŠ/α14å

Provalo online!

Come?

Dato un numero intero positivo n , testiamo se esiste un fattore primo p di n tale che:

|pnp|=14

Commentate

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 byte

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

Provalo online!

Come?

Dato un numero intero positivo n , stiamo cercando un numero primo x tale che x(x+14)=n oppure x(x14)=n .

Da qui le seguenti equazioni quadratiche:

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

La radice positiva di (1) è:

x0=49+n7

(2)

x1=49+n+7

x0x1

Per fare ciò, usiamo la classica funzione di test di primalità ricorsiva, con un test aggiuntivo per assicurarci che non si loop per sempre se viene dato un numero irrazionale come input.

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)

Funzione wrapper principale:

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

6

Perl 6 , 45 28 byte

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

Provalo online!

n+49±7n

Spiegazione:

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

6

Regex (ECMAScript), 64 62 byte

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

Questo utilizza una variante dell'algoritmo di moltiplicazione brevemente descritto in un paragrafo dei miei post postgex di numeri abbondanti . Questo è uno spoiler . Quindi non leggere oltre se non vuoi che qualche magia regex unaria avanzata venga viziata per te . Se vuoi provare a capire da solo questa magia, ti consiglio vivamente di risolvere alcuni problemi nell'elenco dei problemi raccomandati consecutivamente contrassegnati con spoiler in questo post precedente e provare a elaborare le intuizioni matematiche in modo indipendente.

L'algoritmo di moltiplicazione è implementato diversamente qui perché stiamo affermando che due valori noti moltiplicati insieme equivalgono a un altro valore noto (come anche nella versione alternativa della regex in questo post , per verificare che un numero sia un quadrato perfetto). Nella maggior parte delle altre mie risposte regex postate finora, la moltiplicazione viene implementata come un calcolo (non un'asserzione, concettualmente parlando) in cui l'obiettivo è quello di trovare il prodotto di due numeri noti. Entrambi i metodi funzionano in entrambe le circostanze, ma per quanto riguarda il golf, sono peggiori nel fare il reciproco lavoro.

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

Provalo 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

Brachylog , 13 12 byte

ṗ;14{+|-};?×

Immettere il numero candidato come argomento della riga di comando. Uscite trueo false. Provalo online!

Spiegazione

Il codice è un predicato il cui input non è vincolato e il cui output è il numero che stiamo 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

(I suggerimenti sono ben accetti. {+|-}Sembra ancora goffo.)


3

Brachylog , 9 byte

Approccio diverso quindi DLosc s' risposta

Ċ-14&∋ṗ&×

Prende N come output, restituisce [P, P-14] o [P + 14, P] attraverso l'ingresso (prima il numero più grande)

spiegazione

Ċ              # 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)

Provalo online!


2

Pyth, 22 20 byte

}Qsm*Ld+Ld_B14fP_TSh

Provalo online qui .

}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

Modifica: i 3 byte salvati come input saranno sempre positivi, quindi non è necessario filtrare i valori negativi dall'elenco. Risolto anche un bug per gli input 1e che 2costava 1 byte. Versione precedente:}Qsm*Ld>#0+Ld_B14fP_TU


2

05AB1E , 16 15 14 byte

Salvato 1 byte calcolando 14 con invece di žvÍ(non posso credere di non aver pensato a questo in primo luogo).

Salvato 1 byte grazie a Emigna

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

Provalo online! oppure Test di tutti gli input

Spiegazione

                 # 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
È possibile salvare un byte modificando }˜sål' Q}Zutilizzo di input implicito. Il tuo Test-Suite dovrebbe essere cambiato un po 'a qualcosa come questo per farlo funzionare, allora. Inoltre, un modo più ovvio di scrivere žvÍo sarebbe 14;)
Emigna

Grazie! Perché semplificare quando puoi spingere 14 nel modo più complicato / facepalm :)
Wisław,


2

Retina 0.8.2 , 61 byte

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

Provalo online! Spiegazione:

.+
$*

Converti in unario.

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

\1cattura il più grande dei due fattori. \2cattura la costante 14, salvando un byte. \3cattura il più piccolo dei due fattori, meno 1. Questo assicura anche che entrambi i fattori siano almeno 2.

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

Controlla i due fattori per assicurarti che almeno uno di essi sia primo. L'idea di usare è \2?stata spudoratamente rubata dalla risposta di @ Deadcode.

(?<-3>\1)+

Ripeti il ​​più grande dei due fattori un numero di volte uguale a uno in meno del minore dei due fattori. Dato che abbiamo già catturato il fattore più grande una volta che questo finisce per catturare il prodotto dei due fattori.

$(?(3)1)

Assicurarsi che il prodotto sia uguale al numero indicato.

Una traduzione diretta in Retina 1 sostituendola $*con *1avrebbe lo stesso numero di byte, ma un byte potrebbe essere salvato sostituendo tutte le 1s con se _quindi i *1potrebbero essere sostituiti *anziché *_. Retina 1 precedente risposta per 68 byte:

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

0m`^_{14}$

Provalo online! Spiegazione:

.+
*

Converti in unario.

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

Trova tutte le coppie di fattori.

Am` (__+)\1+$

Assicurati che uno sia primo.

(_+) \1

Prendi la differenza assoluta.

0m`^_{14}$

Controlla se ce ne sono 14.


1

JavaScript (nodo Babele) , 69 byte

Accidenti, pensavo che avrei battuto la risposta di Arnaulds ma no .....: c

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

Provalo online!

Voglio liberarmi della x=>[...Array(x)].some(parte usando la ricorsione in modo che possa accorciarsi nel tempo

Spiegazione

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

Usa la formula

n/pp==14




1

APL (NARS) 16 caratteri, 32 byte

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

{π⍵} troverebbe la fattorizzazione del suo argomento e supponiamo che l'ultimo elemento del suo risultato (l'elenco dei divisori di n) sia il massimo divisore primo di n; Supponiamo che una definizione equivalente del numero di Rocco sia: n è un numero di Rocco <=> il fattore massimo primo di n: r è tale che è vero 14 = ∣rn ÷ r [per C pseudocodice come 14 == abs (rn / r) questa definizione del numero di Rocco sembra finalmente ok nell'intervallo 1..1000000]; l'intervallo del valore ok sarebbe 1..maxInt; test:

 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 # (compilatore interattivo Visual C #) , 99 byte

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

Provalo online!

Enumerable.Range colpisce ancora :) Usando la pazza bandiera del compilatore, puoi ridurre un po 'le cose, anche se sono un po' un fan della soluzione alla vaniglia.

C # (compilatore interattivo Visual C #) + /u:System.Linq.Enumerable, 77 byte

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

Provalo online!

Di seguito è riportato un port della soluzione di Arnauld che sembrava piuttosto interessante. Attualmente è il più lungo, ma probabilmente può essere giocato a golf.

C # (compilatore interattivo Visual C #) , 101 byte

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));}

Provalo online!


0

APL (NARS) 30 caratteri, 60 byte

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

Qui 0π è la funzione dire se un numero è un numero primo, test:

 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 risposte (non competitivo)

Mi sono piaciute molto le risposte di @Arnauld, quindi le ho tradotte.

123 byte , in base alla risposta 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(||)

Spiegazione:

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 byte , in base alla risposta 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

Spiegazione:

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?

0

Python 2 , 58 byte

Output per codice di uscita, non riuscito ( 1) per i numeri di Rocco.

P=k=1.
n=input()
exec"P*=k*k;k+=1;P%k*abs(n/k-k)==14>y;"*n

Provalo online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.