Znajdź numer Rocco


12

Zadano mi to pytanie w wywiadzie, ale nie byłem w stanie znaleźć żadnego rozwiązania. Nie wiem, czy pytanie było słuszne, czy nie. Próbowałem dużo, ale nie mogłem znaleźć żadnego rozwiązania. Szczerze mówiąc, nic nie przyszło mi do głowy.

Liczby Rocco

Dodatnia liczba całkowita jest liczbą Rocco, jeśli można ją przedstawić jako lub , gdzie jest liczbą pierwszą.nn=p(p+14)n=p(p14)p

Pierwsze 10 liczb Rocco to:

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

Zadanie

Kod musi przyjmować dodatnią liczbę całkowitą jako dane wejściowe i określać, czy jest to liczba Rocco, czy nie.

Punkty brownie

  • Napisz funkcję, która oblicza i drukuje liczbę liczb Rocco mniejszą lub równą 1 milionowi.
  • Napisz funkcję, która oblicza i drukuje liczbę liczb Rocco z pytania bonusowego (powyżej jednego), które są liczbą pierwszą.

5
Witam i witam w PPCG. Prowadzimy wyzwania (Twój wygląd wygląda naprawdę interesująco), które mają obiektywne kryteria punktacji i wygranej. Spróbuj zmodyfikować swój post, aby to uwzględnić. Jako cel zalecam golf-golfa , ponieważ najłatwiej jest to zrobić poprawnie. Ponadto chcesz uniknąć tych bonusów; skoncentruj się na jednym wyraźnym zadaniu.
Adám

3
wynik byłby liczbą całkowitą : czy nie masz na myśli logicznej, czy dane wejściowe były liczbą Rocco, czy nie?
Adám

5
Bonus 2: print 0. Wszystkie liczby Rocco są złożone (n*..), więc nie ma liczb pierwszych w żadnym zakresie.
TFeld

4
„Punkty bonusowe” mogą być po prostu wartościami na stałe i wcale nie są korzystne dla wyzwania. Polecam je usunąć.
Erik the Outgolfer

5
Zredagowałem pytanie i tagi. Jeśli nie wyrażasz zgody, wycofaj się lub edytuj dalej. Jak powiedział @EriktheOutgolfer, uważam, że bonusy powinny zostać usunięte.
Arnauld

Odpowiedzi:


10

05AB1E , 8 bajtów

Zwraca jeśli jest liczbą Rocco, lub przeciwnym razie.1n0

fDŠ/α14å

Wypróbuj online!

W jaki sposób?

Biorąc dodatnia , test my czy istnieje czynnik pierwszy o takie, że:npn

|pnp|=14

Skomentował

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 bajtów

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

Wypróbuj online!

W jaki sposób?

Biorąc pod uwagę dodatnią liczbę całkowitą , szukamy liczby pierwszej takiej, że lub .nxx(x+14)=nx(x14)=n

Stąd następujące równania kwadratowe:

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

Dodatni pierwiastek z to:(1)

x0=49+n7

a dodatni pierwiastek z to:(2)

x1=49+n+7

Dlatego problem jest równoważny z testowaniem, czy lub jest liczbą pierwszą.x0x1

Aby to zrobić, używamy klasycznej funkcji testu pierwotności rekurencyjnej, z dodatkowym testem, aby upewnić się, że nie zapętla się na zawsze, jeśli na wejściu zostanie podana liczba niewymierna.

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)

Główna funkcja owijania:

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

6

Perl 6 , 45 28 bajtów

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

Wypróbuj online!

n+49±7n

Wyjaśnienie:

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

6

Regex (ECMAScript), 64 62 bajtów

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

Wykorzystuje to wariant algorytmu mnożenia krótko opisany w akapicie mojego obfitego numeru wyrażenia regularnego . To jest spoiler . Więc nie czytaj dalej, jeśli nie chcesz, aby zepsuta Ci była jakaś zaawansowana magia wyrażeń regularnych . Jeśli chcesz spróbować samemu odkryć tę magię, zdecydowanie polecam zacząć od rozwiązania niektórych problemów z listy zalecanych problemów oznaczonych spoilerem w tym wcześniejszym poście i samodzielnego wymyślenia matematycznych spostrzeżeń.

Algorytm mnożenia jest tutaj zaimplementowany inaczej, ponieważ twierdzimy, że dwie znane wartości pomnożone razem są równe innej znanej wartości (jak również zrobiono w alternatywnej wersji wyrażenia regularnego w tym poście , aby sprawdzić, czy liczba jest idealnym kwadratem). W większości moich dotychczasowych odpowiedzi na wyrażenia regularne mnożenie jest realizowane jako obliczenie (a nie twierdzenie, mówiąc pojęciowo), gdzie celem jest znalezienie iloczynu dwóch znanych liczb. Obie metody działają w obu okolicznościach, ale pod względem golfowym są gorsze w wykonywaniu wzajemnej pracy.

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

Wypróbuj 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 bajtów

ṗ;14{+|-};?×

Wprowadź numer kandydata jako argument wiersza polecenia. Wyjścia truelub false. Wypróbuj online!

Wyjaśnienie

Kod jest predykatem, którego dane wejściowe są nieograniczone i których wynikiem jest liczba, którą testujemy.

ṗ             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

(Wskazówki są mile widziane. To {+|-}nadal jest niezręczne.)


3

Brachylog , 9 bajtów

Odmienne podejście następnie DLosc „s odpowiedź

Ċ-14&∋ṗ&×

Pobiera N jako wynik, zwraca [P, P-14] lub [P + 14, P] z powrotem przez wejście (najpierw największa liczba)

wyjaśnienie

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

Wypróbuj online!


2

Pyth, 22 20 bajtów

}Qsm*Ld+Ld_B14fP_TSh

Wypróbuj online tutaj .

}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

Edycja: Zapisane 3 bajty jako dane wejściowe zawsze będą dodatnie, więc nie trzeba odfiltrowywać wartości ujemnych z listy. Naprawiono także błąd dotyczący danych wejściowych 1i 2kosztu 1 bajta. Poprzednia wersja:}Qsm*Ld>#0+Ld_B14fP_TU


2

05AB1E , 16 15 14 bajtów

Zaoszczędziłem 1 bajt, obliczając 14 z zamiast žvÍ(nie mogę uwierzyć, że o tym nie pomyślałem).

Zaoszczędzono 1 bajt dzięki Emignie

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

Wypróbuj online! lub Przetestuj wszystkie dane wejściowe

Wyjaśnienie

                 # 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
Możesz zapisać bajt, zmieniając }˜såna Q}Zużycie danych niejawnych. Test-Suite musiałby zostać zmieniony się trochę coś jak to by zmusić go do pracy wtedy. Również bardziej oczywisty sposób pisania žvÍlub byłby 14;)
Emigna

Dzięki! Po co ułatwiać, kiedy możesz wcisnąć 14 w najbardziej skomplikowany sposób / facepalm :)
Wisław


2

Retina 0.8.2 , 61 bajtów

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

Wypróbuj online! Wyjaśnienie:

.+
$*

Konwertuj na unary.

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

\1przechwytuje większy z dwóch czynników. \2przechwytuje stałą 14, oszczędzając bajt. \3przechwytuje mniejszy z dwóch czynników, minus 1. Zapewnia to również, że oba czynniki wynoszą co najmniej 2.

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

Sprawdź dwa czynniki, aby upewnić się, że co najmniej jeden z nich jest liczbą pierwszą. Pomysł użycia \2?został bezwstydnie skradziony z odpowiedzi @ Deadcode.

(?<-3>\1)+

Powtórz większy z dwóch czynników kilka razy równy jeden mniej niż mniejszy z dwóch czynników. Ponieważ już raz udało nam się uchwycić większy czynnik, to w końcu przechwytuje iloczyn dwóch czynników.

$(?(3)1)

Upewnij się, że produkt jest równy podanej liczbie.

Bezpośrednie tłumaczenie do siatkówki 1, zastępując $*z *1miałyby taką samą liczbę bajtów ale bajt można zapisać zastępując wszelkie 1S z _S i wówczas *1można zastąpić *zamiast *_. Poprzednia odpowiedź Retina 1 na 68 bajtów:

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

0m`^_{14}$

Wypróbuj online! Wyjaśnienie:

.+
*

Konwertuj na unary.

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

Znajdź wszystkie pary czynników.

Am` (__+)\1+$

Upewnij się, że jeden jest najlepszy.

(_+) \1

Weź absolutną różnicę.

0m`^_{14}$

Sprawdź, czy są jakieś 14.


1

JavaScript (węzeł Babel) , 69 bajtów

Cholera, myślałem, że mam zamiar pokonać odpowiedź Arnaulds, ale nie .....: c

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

Wypróbuj online!

Chcę pozbyć się x=>[...Array(x)].some(części za pomocą rekurencji, aby z czasem mogła się ona skrócić

Wyjaśnienie

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

Wykorzystuje formułę

n/pp==14




1

APL (NARS) 16 znaków, 32 bajty

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

{π⍵} znalazłby faktoryzację swojego argumentu i przypuszczamy, że ostatnim elementem jego wyniku (lista dzielników n) jest maksymalny główny dzielnik n; Tutaj przypuszczamy, że jedną równoważną definicją liczby Rocco jest: n jest liczbą Rocco <=> podstawa współczynnika maksimum n: r jest taka, że ​​jest prawdą 14 = ∣rn ÷ r [dla pseudokodu C jako 14 == abs (rn / r) ta definicja liczby Rocco wydaje się w końcu OK w zakresie 1..1000000]; zakres wartości ok wyniesie 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 # (interaktywny kompilator Visual C #) , 99 bajtów

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

Wypróbuj online!

Enumerable.Range uderza ponownie :) Używając zwariowanej flagi kompilatora, możesz trochę zredukować rzeczy, chociaż jestem fanem waniliowego rozwiązania.

C # (interaktywny kompilator Visual C #) + /u:System.Linq.Enumerable, 77 bajtów

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

Wypróbuj online!

Poniżej znajduje się port rozwiązania Arnaulda, które wydawało się całkiem fajne. Jest obecnie najdłuższy, ale prawdopodobnie można go trochę pograć w golfa.

C # (interaktywny kompilator Visual C #) , 101 bajtów

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

Wypróbuj online!


0

APL (NARS) 30 znaków, 60 bajtów

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

Tutaj 0π to funkcja powiedz, jeśli jedna liczba jest liczbą pierwszą, sprawdź:

 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 odpowiedzi (niekonkurencyjne)

Bardzo podobały mi się odpowiedzi @Arnauld, więc je przetłumaczyłem.

123 bajty , w oparciu o odpowiedź 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(||)

Wyjaśnienie:

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 bajtów , w oparciu o odpowiedź 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

Wyjaśnienie:

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 bajtów

Dane wyjściowe według kodu wyjścia nie powiodły się ( 1) dla liczb Rocco.

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

Wypróbuj online!

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.