Інші, ніж Оптимус


36

Виклик

При вхідному цілому число n > 0, вихідному число простих чисел ( другом , ніж n, якщо nсам по собі є простою) , який може бути отриманий шляхом зміни одну цифри в десятковому розкладанні п (без зміни кількості цифр).

Приклади

Наприклад, n = 2. Змінивши одну цифру в десятковому розширенні 2, ми можемо придумати три додаткові прості числа 3, 5, 7, так що a(n) = 3.

Для іншого прикладу n = 13. Змінивши одну цифру, ви можете отримати прості символи 11, 17, 19, 23, 43, 53, 73, 83, так a(13) = 8.

Для останнього прикладу n = 20. Змінивши одну цифру, ви можете отримати прості символи 23, 29, так a(20) = 2.

Послідовність

Ось перші 20 термінів для початку роботи. Це OEIS A048853 .

4, 3, 3, 4, 3, 4, 3, 4, 4, 4, 7, 4, 8, 4, 4, 4, 7, 4, 7, 2

Правила

  • Можна вважати, що вхід і вихід відповідають цілому цілому типу вашої мови.
  • Введення та вихід можуть бути задані у будь-якому зручному форматі .
  • Ігноруйте провідні нулі (наприклад, 03не є простим числом за цією формулюванням).
  • Прийнятна або повна програма, або функція. Якщо функція, ви можете повернути вихід, а не надрукувати його.
  • Якщо можливо, додайте посилання на онлайн-тестувальне середовище, щоб інші люди могли спробувати ваш код!
  • Стандартні лазівки заборонені.
  • Це тому діють усі звичайні правила гольфу, і найкоротший код (у байтах) виграє.

4
Я намагаюся думати про найменший, nдля якого результат 0. Я думаю, що це n = 200. Я також думаю , що вони приходять в пучках: 200,202,204,206,208, 320,322,...,328, 510,...,518, 620,...628, 840,...,848і т.д.
інженер Toast

Чи "Припустимо, що" Вхід і вихід можуть відповідати вкладному цілому типу вашої мови "говорить про те, що нам заборонено приймати введення як рядок?
Мертвий Поссум

1
@DeadPossum Ні, це дозволено. Тільки що вам не потрібно турбуватися про 2 ^ 100 як вхід, якщо ви використовуєте, наприклад, 32-бітні цілі числа.
AdmBorkBork

Повідомте мене, якщо я за борт ... У мене зараз 3 різні подання
Патрік Робертс

2
@EngineerToast Знайшовши перший приклад prime (294001), я нарешті подумав переглянути його на OEIS: A192545 та A158124 . Також актуально: A143641 .
Ørjan Johansen

Відповіді:


10

05AB1E , 17 16 14 11 байт

ā°`<Ÿʒ.L}pO

Пояснення:

ā             Push inclusive range from 1 to the length of the input
 °            Raise 10 to the power of each element
  `           Push each element to the stack
   <          Decrement the topmost element
    Ÿ         Inclusive range
              For 13, this creates an array like [10 11 12 13 14 .. 98 99]
     ʒ.L}     Only keep elements with a levenshtein distance to the input of
              exactly one
         p    Check each element for primality
          O   Sum

Спробуйте в Інтернеті! або до 100 .


1
.L? Серйозно? .L?!?!
Erik the Outgolfer

@EriktheOutgolfer L.
Okx

Я маю на увазі, є вбудована відстань Левенштейна!
Erik the Outgolfer

@EriktheOutgolfer ¯ \ _ (ツ) _ / ¯
Okx

Я знаю, що минуло деякий час, але ви можете видалити, <щоб зберегти байт. Навіть якщо фільтр не видаляє 100/ 1000/ 10000/ і т. Д., Він ніколи не є простим, тому не вплине на вихід.
Кевін Круїссен

5

Python 2 , 146 136 127 121 118 байт

Дякуємо @ Mr.Xcoder за пропозиції

lambda I:sum(all(i%v for v in range(2,i))*sum(z!=x for z,x in zip(I,`i`))==1for i in range(1+10**~-len(I),10**len(I)))

Пояснення:

Згенеруйте числа, довжина яких дорівнює довжині введення, пропускаючи спочатку (1,10,100,1000, ...)

for i in range(1+10**~-len(I),10**len(I))

Перевірте, чи генерується число відрізняється від введення лише однією цифрою

sum(z!=x for z,x in zip(I,`i`))==1

Перевірка на прайм

all(i%v for v in range(2,i))

Рахувати

sum(...)    

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


Може бути коротше, щоб не зробити це лямбда, і зробіть r=range, оскільки ви його використовуєте багато разів ...?
Стюі Гріффін

1
Чи працює це для таких речей 143? Оскільки я бачу range(1,10), це виключає 0і 103є головним
містер Xcoder

@ Mr.Xcoder виправлено
Dead Possum

1
Вам не потрібно 0в r(0,10). r(10)достатньо.
Містер Xcoder

1
Також пропоную поставити це як таке:lambda I,r=range:
Містер Xcoder

4

Javascript (ES6) 148 байт

Приймає введення як рядок і повертається як число

n=>(n.replace(/./g,"$`a$' ").split` `.map(s=>s&&[..."0123456789"].map(d=>r+=+(t=s.replace(/a/,d))[0]&&t^n&&(p=v=>t>1&(--v<2||t%v&&p(v)))(t)),r=0),r)

Приклад фрагмента коду:

f=
n=>(n.replace(/./g,"$`a$' ").split` `.map(s=>s&&[..."0123456789"].map(d=>r+=+(t=s.replace(/a/,d))[0]&&t^n&&(p=v=>t>1&(--v<2||t%v&&p(v)))(t)),r=0),r)

for(var k=1;k<=20;k++)
  o.innerText+=f(""+k)+" "
<pre id=o></pre>



3

Математика, 105 байт

F=Count[Range[f=IntegerDigits;g=10^Length@f@#/10,10g],n_/;PrimeQ@n&&MatchQ[f@n-f@#,{x=0...,_,x}]&&n!=#]&;

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

Functionяке очікує додатне ціле число #. Встановлює fрівну функції, IntegerDigitsяка повертає список цифр її вводу. Бере Rangeвід gдо 10g(включно), де g=10^Length@f@#/10знаходиться найбільша потужність 10менше або дорівнює вхідному #, то таким чином, що . перевіряє, чи є простим, перевіряє, чи є різниця між переліком цифр та форми , і гарантує, що це так і є .CountnPrimeQ@n&&MatchQ[f@n-f@#,{x=0...,_,x}]&&n!=#PrimeQ@nnMatchQ[f@n-f@#,{x=0...,_,x}]n#{0..., _, 0...}n!=#n#Unequal


3

JavaScript (ES6), 153 142 139 байт

n=>([...n].map((c,i,[...a])=>[...''+1e9].map((u,j)=>s+=j+i&&j!=c?p((a.splice(i,1,j),a.join``)):0),s=0,p=q=>eval('for(k=q;q%--k;);k==1')),s)

Приймає введення як рядок. Невизначена поведінка для недійсного введення, хоча воно має припинятися без помилок у будь-якому рядку, про який я можу придумати. Не обов’язково перед тепловою смертю Всесвіту, особливо для довгих струн.

Демо

f=
n=>([...n].map((c,i,[...a])=>[...''+1e9].map((u,j)=>s+=j+i&&j!=c?p((a.splice(i,1,j),a.join``)):0),s=0,p=q=>eval('for(k=q;q%--k;);k==1')),s)
console.log([...''+1e19].map((_,i)=>f(i+1+'')).join())
i.onchange=()=>console.log(f(i.value))
<input id=i>

Поліпшення

Збережено 11 байт шляхом рефакторингу reduce()викликів у map()виклики та неявного копіювання масиву aв параметр функції, а не в контексті splice()виклику.

Збережено 3 байт завдяки @Neil пропозицією «s , щоб перетворити [...Array(10)]в [...''+1e9].

Немініфікований код

input => (
  [...input].map(
    (char, decimal, [...charArray]) =>
      [...'' + 1e9].map(
        (unused, digit) => sum +=
          digit + decimal && digit != char ?
            prime(
              (
                charArray.splice(decimal, 1, digit)
                , charArray.join``
              )
            ) :
            0
      )
    , sum = 0
    , prime = test => eval('for(factor = test; test % --factor;); factor == 1')
  )
  , sum
)

Пояснення

Функція використовує дворівневий map()підсумок кількості перестановок, які проходять тест первинності, який був запозичений і модифікований з цієї відповіді .

(Оригінальна відповідь)

reduce((accumulator, currentValue, currentIndex, array) => aggregate, initialValue)

Так, наприклад, для обчислення суми масиву, ви б передати initialValueз 0, і повернути , aggregateрівні accumulator + currentValue. Змінюючи цей підхід трохи, ми замість цього обчислюємо кількість перестановок, які проходять тест первинності:

reduce(
  (passedSoFar, currentDecimal, currentIndex, digitArray) =>
    isValidPermutation() ?
      passedSoFar + prime(getPermutation()) :
      passedSoFar
  , 0
)

Це по суті внутрішнє reduce(), яке ітералізує всі перестановки digitArray, змінюючи кожну decimalна конкретну permutatedDigit. Тоді нам потрібна зовнішня, reduce()щоб повторити всі можливі permutatedDigit, з якими можна замінити кожен decimal, який справедливий 0-9.

Аномалії в реалізації

[...''+1e9].map((u,j)=>...був найкоротшим шляхом @Neil міг придумати, щоб ітерація аргумент 0через 9. Краще це робити з u, але uв цьому випадку це не корисно для кожного елемента в масиві.

i+jу потрійних перевірках стану, щоб переконатися, що 0неможлива перестановка провідної цифри, відповідно до специфікації виклику. j!=cгарантує, що оригінал nне є кандидатом для проходження тесту на первинність.

(a.splice(i,1,j),a.join``)є свого роду безлад. splice()замінює цифру на decimal == iна permutatedDigit == j, але оскільки splice()повертає вилучені елементи (у цьому випадку було б дорівнювати [a[i]]) замість модифікованого масиву, ми повинні використовувати оператор комами для передачі модифікованого масиву aв тест первинності, але не перед тим, як використовувати join()його в рядок числа.

Нарешті, eval()полягає в збереженні байта, оскільки порівняно з більш канонічним підходом він коротший:

q=>eval('for(k=q;q%--k;);k==1')

q=>{for(k=q;q%--k;);return k==1}

Посилання на основний тест pініціалізується у невикористаному аргументі map()виклику.


Я думаю, що на сторінці підказок [...''+1e9]йде коротше.
Ніл

2

Пітон 2 , 134 байти

lambda x,r=range,l=len:sum(~-f*(~-l(x)==sum(`f`[t]==x[t]for t in r(l(x))))and all(f%v for v in r(2,f))for f in r(10**~-l(x),10**l(x)))

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

Більш елегантна, довша версія:

lambda x,r=range,l=len:l(filter(lambda f:(~-f*(~-l(x)==sum(`f`[t]==x[t]for t in r(l(x)))))*all(f%v for v in r(2,f)),r(10**~-l(x),10**l(x))))

Вхід приймається як рядок.


Пояснення (старша версія)

  • lambda x,r=range,l=len:- Визначає лямбда з параметром String xі двома постійними параметрами r=rangeі l=len.

  • sum(1...)- Отримайте довжину, яка економить 1 байт len([...]).

  • for f in r(10**~-l(x),10**l(x))- Створює абсолютно всі числа з тим же порядком, що і вхід (очікуємо 0). Наприклад, введення в 3результаті призведе до [1, 2, 3, 4, 5, 6, 7, 8, 9].

  • sum(1for t in r(l(x))if`f`[t]==x[t])==~-l(x)and f>1 - Перевіряє, чи поточне число знаходиться в точності на 1 цифру від входу, і чи воно вище 1.

  • all(f%v for v in r(2,f)) - Перевіряє, чи є поточне число простим.


1
Ви можете змінити, sum(1for..ifBOOL)щоб sum(BOOLfor)зберегти кілька байт
Dead Possum

Чи дозволяється нам приймати введення як рядок? Дивлячись на "Введення та виведення можна припустити, що вони відповідають цілому цілому типу вашої мови" Я не впевнений
Dead Possum

@DeadPossum Деякі відповіді є. Чому б це не дозволили ?!
Містер Xcoder

Сьогодні мені не вистачає голосів, але постане +1 якнайшвидше: D
Dead Possum

@DeadPossum Звичайно. Не забувайте, інакше я пінг вам! ( </joke>)
Містер Xcoder

1

JavaScript (ES6), 137 байт

i=(a=prompt()).length;s=0;while(i--)for(j=0;j<=9;j++){(b=[...a]).splice(i,1,j);k=b=b.join('');while(b%--k);s+=i+j&&a[i]!=j&&k==1}alert(s)

Моя інша відповідь адаптує до повнопрограмного подання за допомогою методів Web API prompt()та alert().


1

Бін , 126 байт

00000000: a64d a065 8050 80a0 5d20 8001 a64d a06f  ¦M e.P. ] ..¦M o
00000010: 8025 39b5 cb81 2065 27a6 4da0 6680 2581  .%9µË. e'¦M f.%.
00000020: 0035 cb81 2066 27a6 53d0 80cd a05e 8043  .5Ë. f'¦SÐ.Í ^.C
00000030: cf20 5d00 2080 82a0 65a5 3a20 66a6 4da0  Ï ]. .. e¥: f¦M 
00000040: 6780 4da0 5e80 53d0 80a0 5e20 807b 2300  g.M ^.SÐ. ^ .{#.
00000050: b5cc a05e 8f4b c120 6728 264d a06f 814e  µÌ ^.KÁ g(&M o.N
00000060: cecc a065 8b20 6681 4cd0 84a0 5d20 6581  ÎÌ e. f.LÐ. ] e.
00000070: 2066 814c a067 8025 3a26 206f b130        f.L g.%:& o±0

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

Адаптація моєї повної програми JavaScript .

JavaScript еквівалент

i=a.length
s=0
while(i--){
  j=10
  while(j--){
    (b=[...a]).splice(i,1,j)
    k=b=b.join('')
    while(b%--k);
    s+=i+j&&a[i]!=j&&k==1
  }
}
s

Пояснення

aімпліцитно ініціалізується як перший рядок введення як рядок, а останній оператор sнеявно виводиться, який містить суму простих перестановок.


1

Лушпиння , 32 байти

Lof§&ȯ=1Σzo±≠d⁰o=Ld⁰L↑o≤Ld⁰Lmdİp

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

Безголів / пояснення

                              İp  -- get all primes
                            md    -- and convert them to list of digits
                     ↑o≤   L      -- take as long as the lenghth of these digit lists are ≤ ..
                        Ld⁰       -- .. the number of digits of input 
 of                               -- from those primes filter:
               o=Ld⁰L             --   same number of digits as input
   §&                             --   and
        Σz                        --   the number of..
          o±≠d⁰                   --   .. digits that differ from input digits ..
     ȯ=1                          --   .. must be one
L                                 -- finally count them


1

PHP , 151 147 141 140 136 134 129 128 байт

-6 байт завдяки @Einacio; -1 байт завдяки @Titus

<?php for($i=$m=10**strlen($n=$argv[1]);$i-->$m/10;)if(levenshtein($n,$i)==$f=$t=1){while($t<$i)$f+=$i%$t++<1;$c+=$f==2;}echo$c;

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

Відформатовано, з коментарями:

<?php
// Work through each integer with the same number of digits as the input $argv[1].
for ($i = $m = 10 ** strlen($n = $argv[1]); $i-- > $m / 10;)
    // Is it exactly one digit different from the input?
    if (levenshtein($n, $i) == $f = $t = 1) {
        // Count its factors.
        while ($t < $i) $f += $i % $t++ < 1;
        // If there are exactly 2 factors then it's a prime, so increment the counter.
        $c += $f == 2;
    }
// Print the final count.
echo $c;

Щоб зробити це якомога коротшим, я:

  • комбіновані завдання $f = $t = 1;
  • крокувати з ++кроком як частина іншого виразу $f += $i % $t++ == 0(приріст виконується після операції з модулем і так не впливає на його результат);
  • і замість того, щоб використовувати ifоператор для умовного приросту, використовували той факт, що булева істина при передачі як ціле число стає 1, використовуючи, $c += $f == 2;а не if ($f == 2) $c++;.

1
вам не потрібно визначати $ c, це вважається 0 на першому + =
Ейнасіо

@Einacio Які правила гольфу? Це дозволено, оскільки воно дає невизначене попередження про змінну?
WebSmithery

@Einacio Мабуть, будь-який вихід STDERR можна ігнорувати, тому дякую за пропозицію.
WebSmithery

1
+1 для використання levenshtein. Хороша ідея! $i%$t++<1коротше, ніж $i%$t++==0.
Тит


0

PHP, 100 + 1 байт

for(;~($a=$argn)[$i];$i++)for($d=-!!$i;$d++<9;$c+=$k==1)for($a[$i]=$d,$k=$a;--$k&&$a%$k;);echo$c-$i;

Запустіть як трубу -nRабо спробуйте в Інтернеті .

зламатися

for(;~($n=$argn)[$i];$i++)  # loop through argument digits, restore $n in every iteration
    for($d=-!!$i;               # loop $d from 0 (1 for first digit)
        $d++<9;                 # ... to 9
        $c+=$k==1                   # 3. if divisor is 1, increment counter
    )
        for($n[$i]=$d,              # 1. replace digit
            $k=$n;--$k&&$n%$k;      # 2. find largest divisor of $n smaller than $n
        );
echo$c-$i;                  # print counter - length

0

Java 8, 201 194 байт

n->{String s=n+"";int r=0,i=0,j,k,t,u,l=s.length();for(;i<l;i++)for(j=0;++j<10;r+=n==u|t<2?0:1)for(u=t=new Integer(s.substring(0,i)+j+(i<l?s.substring(i+1):"")),k=2;k<t;t=t%k++<1?0:t);return r;}

Пояснення:

Спробуйте тут.

n->{                        // Method with integer as parameter and return-type
  String s=n+"";            //  String representation of the input-int
  int r=0,                  //  Result-integer
      i=0,j,k,              //  Index-integers
      t,u,                  //  Temp integers
      l=s.length();         //  Length of the String
  for(;i<l;i++)             //  Loop (1) from 0 to `l` (exclusive)
    for(j=0;++j<10;         //   Inner loop (2) from 1 to 10 (exclusive)
        r+=                 //     And after every iteration, raise the result by:
           n==u             //      If the current number equals the input
           |t<2?            //      or it is not a prime:
            0               //       Add nothing to the result-counter
           :                //      Else:
            1)              //       Raise the result-counter by one
      for(                  //    Inner loop (3)
          u=t=              //     First set both `u` and `t` to:
              new Integer(  //      Convert the following String to an integer: 
               s.substring(0,i)
                            //       Get the substring from 0 to `i` (exclusive)
               +j           //       + `j`
               +(i<l?       //       + If `i` is smaller than the String-length:
                  s.substring(i+1)
                            //          The substring from 0 to `i` (inclusive)
                 :          //         Else:
                  "")),     //          Nothing
          k=2;              //     And start `k` at 2
              k<t;          //     Continue looping as long as `k` is smaller than `t`
        t=t%k++<1?          //     If `t` is divisible by `k`:
           0                //      Change `t` to 0
          :                 //     Else:
           t                //      Leave `t` as is
      );                    //    End of inner loop (3)
                            //    (`t` remained the same after loop 3? -> It's a prime)
                            //   End of inner loop (2) (implicit / single-line body)
                            //  And of loop (1) (implicit / single-line body)
  return r;                 //  Return the result-counter
}                           // End of method

new Integer(s.substring(0,i)+j+(i<l?s.substring(i+1):"") призведе до цих цілих чисел:

Для 0-9: 1, 2, 3, 4, 5, 6, 7, 8, 9.
Для 10: 10, 20, 30, 40, 50, 60, 70, 80, 90, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19.
Для 11: 11, 21, 31, 41, 51, 61, 71, 81, 91, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19.
тощо.


0

JavaScript (ES7), 118 байт

Вводиться як рядок.

n=>[...2**29+'4'].map(d=>n.replace(/./g,c=>s+=d+i>0&(P=k=>N%--k?P(k):N-n&&k==1)(N=p+d+n.slice(++i),p+=c),i=p=0),s=0)|s

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

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

n =>                        // n = input number (as a string)
  [...2**29 + '4']          // generate "5368709124" (all decimal digits)
  .map(d =>                 // for each digit d in the above string:
    n.replace(/./g, c =>    //   for each digit c in n:
      s +=                  //     increment s if the following code yields 1:
        d + i > 0 & (       //       if this is not the first digit of n or d is not "0":
          P = k =>          //         P = recursive function taking k and using N:
            N % --k ?       //           decrement k; if k is not a divisor of N:
              P(k)          //             do recursive calls until it is
            :               //           else:
              N - n &&      //             return true if N is not equal to n
              k == 1        //             and k is equal to 1 (i.e. N is prime)
          )(                //         initial call to P ...
            N =             //           ... with N defined as:
              p +           //             the current prefix p
              d +           //             followed by d
              n.slice(++i), //             followed by the trailing digits
                            //             (and increment the pointer i)
            p += c          //           append c to p
          ),                //         end of initial call
          i = p = 0         //         start with i = p = 0
    ),                      //   end of replace()
    s = 0                   //   start with s = 0
  ) | s                     // end of map(); return s

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