Знайдіть номер Рокко


12

Мені було задано це питання в інтерв'ю, але я не зміг знайти жодного рішення. Я не знаю, правильно було це питання чи ні. Я багато намагався, але не зміг досягти жодного рішення. Чесно кажучи, нічого не прийшло мені в голову.

Номери Рокко

Позитивне ціле число - це число Рокко, якщо воно може бути представлене або як або , де - просте число.nn=p(p+14)n=p(p14)p

Першими 10 номерами Rocco є:

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

Завдання

Ваш код повинен приймати додаткове ціле число як вхідне значення та визначати, чи є це число Рокко чи ні.

Точки Брауні

  • Напишіть функцію, яка обчислює та друкує кількість чисел Рокко менших або рівних 1 мільйона.
  • Напишіть функцію, яка обчислює та роздруковує кількість номерів Рокко із бонусного питання (над одним), які є простими.

5
Привіт і ласкаво просимо до PPCG. Ми приймаємо виклики (виглядає це дуже цікаво), які мають об'єктивні критерії оцінки та виграш. Спробуйте відредагувати свою публікацію, щоб включити її. Я рекомендую код-гольф в якості мети, оскільки це найпростіше отримати правильний. Також ви хочете уникати цих бонусів; просто зосередиться на одному чіткому завданні.
Adám

3
Вихід буде цілим числом : Ви не маєте на увазі булевого значення для того, чи був вхід числом Рокко чи ні?
Adám

5
Бонус 2: print 0. Всі номери Rocco є складовими (n*..), тому немає простих ліній у будь-якому діапазоні.
TFeld

4
"Бонусні бали" можуть бути просто кодованими значеннями і зовсім не корисні для виклику. Я рекомендую їх видалити.
Ерік Аутгольфер

5
Я відредагував питання та теги. Якщо ви не погоджуєтесь, можете відмовитися або відредагувати далі. Як сказав @EriktheOutgolfer, я думаю, що бонуси потрібно зняти.
Арнольд

Відповіді:


10

05AB1E , 8 байт

Повертає якщо - число Рокко, або іншому випадку.1n0

fDŠ/α14å

Спробуйте в Інтернеті!

Як?

Дано натуральне число , ми перевіряємо , чи існує простий множник про таких , що:npn

|pnp|=14

Прокоментував

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 байт

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

Спробуйте в Інтернеті!

Як?

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

Звідси такі квадратичні рівняння:

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

(1)

x0=49+n7

(2)

x1=49+n+7

x0x1

Для цього ми використовуємо класичну функцію тесту на рекурсивну первинність із додатковим тестом, щоб переконатися, що вона не циклічно вічно, якщо їй введено ірраціональне число.

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)

Основна функція обгортки:

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


6

Regex (ECMAScript), 64 62 байти

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

Тут використовується варіант алгоритму множення, коротко описаний в абзаці мого рядового регекс-поста . Це спойлер . Тому не читайте більше, якщо ви не хочете, щоб якась просунута онірна регекс-магія зіпсована для вас . Якщо ви хочете спробувати вирішити цю магію самостійно, я настійно рекомендую почати з вирішення деяких проблем у списку послідовно позначених спойлерами рекомендованих проблем у цій попередній публікації та намагатися самостійно придумати математичну інформацію.

Алгоритм множення тут реалізований по-різному, тому що ми стверджуємо, що два відомих значення, помножених разом, дорівнюють іншому відомому значенню (як це робиться в альтернативній версії регулярного вираження в цій публікації , щоб перевірити, чи число є ідеальним квадратом). У більшості інших моїх опублікованих регекс-відповідей поки що множення реалізується як обчислення (а не твердження, концептуально кажучи), де метою є добуток двох відомих чисел. Обидва способи працюють в обох обставинах, але важко виконувати завдання один одного.

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

Спробуйте в Інтернеті!


 # 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

Брахілог , 13 12 байт

ṗ;14{+|-};?×

Введіть номер кандидата як аргумент командного рядка. Виходи trueабо false. Спробуйте в Інтернеті!

Пояснення

Код - це предикат, чий вхід не обмежений, чий вихід - це число, яке ми тестуємо.

ṗ             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

(Поради вітаються. Це {+|-}все ще відчуває незграбність.)


3

Брахілог , 9 байт

Різний підхід тоді DLosc «s відповідь

Ċ-14&∋ṗ&×

Приймає N як вихід, повертає [P, P-14] або [P + 14, P] назад через вхід (найбільше число спочатку)

пояснення

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

Спробуйте в Інтернеті!


2

Pyth, 22 20 байт

}Qsm*Ld+Ld_B14fP_TSh

Спробуйте його онлайн тут .

}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

Редагувати: збережені 3 байти, оскільки вхід завжди буде позитивним, тому не потрібно фільтрувати негативні значення зі списку. Також виправлено помилку для входів 1і 2, коштуючи 1 байт. Попередня версія:}Qsm*Ld>#0+Ld_B14fP_TU


2

05AB1E , 16 15 14 байт

Збережено 1 байт, обчислюючи 14, а не žvÍ(не вірю, я не думав про це в першу чергу).

Збережено 1 байт завдяки Еміньї

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

Спробуйте в Інтернеті! або Перевірте всі входи

Пояснення

                 # 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
Ви можете зберегти байт, перейшовши }˜såна Q}Zвикористання неявного введення. Ваш Test-Suite повинен бути змінений трохи до чого - щось на зразок цього , щоб змусити його працювати тоді. Також більш очевидний спосіб написання žvÍчи був би 14;)
Емінья

Дякую! Навіщо робити це легко , коли ви можете натиснути 14 в найбільш складний шлях / Facepalm :)
Віслав


2

Сітківка 0,8,2 , 61 байт

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

Спробуйте в Інтернеті! Пояснення:

.+
$*

Перетворити в одинарне.

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

\1фіксує більший з двох факторів. \2фіксує константу 14, економлячи байт. \3фіксує менший з двох факторів, мінус 1. Це також забезпечує, що обох факторів принаймні 2.

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

Перевірте два фактори, щоб переконатися, що принаймні один із них є основним. Ідея використання \2?була безсоромно вкрадена з відповіді @ Deadcode.

(?<-3>\1)+

Повторіть більший з двох факторів кілька разів, рівний одному меншому, ніж менший з двох факторів. Оскільки ми вже зафіксували більший коефіцієнт, як тільки це закінчується, то фіксуємо добуток двох факторів.

$(?(3)1)

Переконайтесь, що виріб дорівнює заданому числу.

Прямий переклад на Retina 1 шляхом заміни $*на *1матиме однаковий кількість байтів, але байт можна зберегти, замінивши всі 1s на _s, і тоді *1можна замінити на, *а не на *_. Попередня відповідь Retina 1 на 68 байт:

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

0m`^_{14}$

Спробуйте в Інтернеті! Пояснення:

.+
*

Перетворити в одинарне.

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

Знайдіть усі пари факторів.

Am` (__+)\1+$

Переконайтесь, що одне є основним.

(_+) \1

Візьміть абсолютну різницю.

0m`^_{14}$

Перевірте, чи є 14.


1

JavaScript (Babel Node) , 69 байт

Чорт, я хоч і збирався перемогти відповідь Арнальдса, але ні .....: c

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

Спробуйте в Інтернеті!

Я хочу позбутися x=>[...Array(x)].some(частини за допомогою рекурсії, щоб вона з часом скоротилася

Пояснення

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

Він використовує формулу

n/pp==14




1

APL (NARS) 16 символів, 32 байти

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

{π⍵} знайдеться факторизація його аргументу, і ми припускаємо, що останній елемент його результату (перелік дільників n) - це максимальний простий дільник n; Тут ми припускаємо, що одне еквівалентне визначення числа Рокко: n - число Рокко <=> максимальний коефіцієнт, простим з n: r є таким, що це істинно 14 = ∣rn ÷ r [для псевдокоду C як 14 == abs (rn / r) це визначення числа Рокко здається нарешті нормальним у діапазоні 1..1000000]; діапазон значення ok буде 1..maxInt; тест:

 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 # (Visual C # Interactive Compiler) , 99 байт

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

Спробуйте в Інтернеті!

Enumerable.Range вражає знову :) Використовуючи шалений прапор компілятора, ви можете трохи зменшити речі, хоча я є прихильником ванільного рішення.

C # (Visual C # Interactive Compiler) + /u:System.Linq.Numerable, 77 байт

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

Спробуйте в Інтернеті!

Нижче - порт рішення Арнальда, який здався досить крутим. Наразі це найдовше, але його, мабуть, можна пограти в гольф.

C # (Visual C # Interactive Compiler) , 101 байт

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

Спробуйте в Інтернеті!


0

APL (NARS) 30 символів, 60 байт

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

Тут 0π - функція сказати, якщо одне число є простим, перевірити:

 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 відповіді (неконкурентовані)

Мені дуже сподобалися відповіді @Arnauld, тому я їх переклав.

123 байти на основі відповіді 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(||)

Пояснення:

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 байт на основі відповіді 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

Пояснення:

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?

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.