Простые числа кроме Оптимуса


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 После нахождения первого простого примера (294001) я наконец-то подумал о поиске его в OEIS: A192545 и A158124 . Также актуально: A143641 .
Орджан Йохансен,

Ответы:


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?!?!
Эрик Outgolfer

@EriktheOutgolfer L.
Okx

Я имею в виду, есть встроенное расстояние Левенштейна!
Эрик 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 исправлен
Мертвый Опоссум

1
Вы не нуждаетесь 0в r(0,10). r(10)достаточно.
Мистер Кскодер

1
Также я предлагаю lambda I,r=range:
изложить

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

Mathematica, 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 преобразовать [...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)

Например, чтобы вычислить сумму массива, вы должны передать значение initialValueof 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()заменяет цифру at 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

Python 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

@DeadPossum Некоторые ответы. Почему бы этого не допустить ?!
Мистер Кскодер

На сегодня у меня закончились голоса, но я буду как можно скорее +1: D
Мертвый Опоссум

@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

Попробуйте онлайн!

Ungolfed / Пояснение

                              İ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оператор для условного приращения, использовался тот факт, что логическое значение true, когда приведение к целому числу становится 1, используется $c += $f == 2;вместо if ($f == 2) $c++;.

1
вам не нужно определять $ c, он считается
равным

@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.