Primes que no sean Optimus

36

Reto

Dado un entero de entrada n > 0, genera el número de primos (que no sea n, si nes primo) que se pueden producir al alterar un dígito en la expansión decimal de n (sin cambiar el número de dígitos).

Ejemplos

Por ejemplo, n = 2. Al alterar un dígito en la expansión decimal de 2, podemos obtener tres números primos adicionales 3, 5, 7, entonces a(n) = 3.

Para otro ejemplo n = 13,. Al alterar un dígito, puede obtener primos 11, 17, 19, 23, 43, 53, 73, 83, entonces a(13) = 8.

Para un ejemplo final, n = 20. Al alterar un dígito, puede obtener primos 23, 29, entonces a(20) = 2.

Secuencia

Aquí están los primeros 20 términos para comenzar. Este es OEIS A048853 .

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

Reglas

  • Se puede suponer que la entrada y la salida encajan en el tipo de entero nativo de su idioma.
  • La entrada y la salida se pueden dar en cualquier formato conveniente .
  • Ignorar los ceros a la izquierda (por ejemplo, 03no es un número primo en esta formulación).
  • Un programa completo o una función son aceptables. Si es una función, puede devolver el resultado en lugar de imprimirlo.
  • Si es posible, incluya un enlace a un entorno de prueba en línea para que otras personas puedan probar su código.
  • Las lagunas estándar están prohibidas.
  • Este es el por lo que se aplican todas las reglas habituales de golf, y gana el código más corto (en bytes).
AdmBorkBork
fuente
44
Estoy tratando de pensar en el más pequeño npara el que es la salida 0. Creo que es n = 200. También creo que vienen en racimos: 200,202,204,206,208, 320,322,...,328, 510,...,518, 620,...628, 840,...,848, etc
Ingeniero tostadas
¿"Se puede suponer que la entrada y la salida encajan en el tipo entero nativo de su idioma" indica que no se nos permite tomar la entrada como cadena?
Dead Possum
1
@DeadPossum No, eso está permitido. Solo que no necesita preocuparse por 2 ^ 100 como entrada si solo está usando enteros de 32 bits, por ejemplo.
AdmBorkBork
Avíseme si me voy por la borda ... Tengo 3 presentaciones diferentes ahora
Patrick Roberts
2
@EngineerToast Después de encontrar el primer ejemplo de prime (294001), finalmente pensé en buscarlo en OEIS: A192545 y A158124 . También relevante: A143641 .
Ørjan Johansen

Respuestas:

10

05AB1E , 17 16 14 11 bytes

ā°`<Ÿʒ.L}pO

Explicación:

ā             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

Pruébalo en línea! o hasta 100 .

Okx
fuente
1
.L? ¿Seriamente? .L?!?!
Erik the Outgolfer
@EriktheOutgolfer L.
Okx
Quiero decir, ¡hay un lugar para la distancia levenshtein!
Erik the Outgolfer
@EriktheOutgolfer ¯ \ _ (ツ) _ / ¯
Okx
Sé que ha pasado un tiempo, pero puedes eliminarlo <para guardar un byte. Incluso si el filtro no elimina el 100/ 1000/ 10000/ etc., nunca es un primo de todos modos, por lo que no afectará la salida.
Kevin Cruijssen
5

Python 2 , 146136127121118 bytes

Gracias a @ Mr.Xcoder por sugerencias

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

Explicación:

Genere números con longitud igual a la longitud de entrada, omitiendo primero (1,10,100,1000, ...)

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

Verifique que el número generado difiera de la entrada en solo un dígito

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

Compruebe si hay prima

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

Contar

sum(...)    

Pruébalo en línea!

Zarigüeya muerta
fuente
¿Podría ser más corto no hacer de esto una lambda, y hacerlo r=range, ya que lo usa muchas veces ...?
Stewie Griffin
1
¿Funciona esto para cosas como 143? Porque veo range(1,10), eso excluye 0y 103es primordial
Sr. Xcoder
@ Mr.Xcoder solucionado
Dead Possum
1
No necesitas 0en r(0,10). r(10)es suficiente
Sr. Xcoder
1
Además, sugiero ponerlo así:lambda I,r=range:
Sr. Xcoder
4

Javascript (ES6) 148 bytes

Toma la entrada como una cadena y regresa como un número

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)

Fragmento de código de ejemplo:

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>

Herman L
fuente
3

Mathematica, 105 bytes

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

Pruébalo en línea!

Functionque espera un número entero positivo #. Establece figual a la función IntegerDigitsque devuelve la lista de dígitos de su entrada. Tomamos el Rangede ga 10g(ambos inclusive), donde g=10^Length@f@#/10está la mayor potencia del 10menor o igual a la entrada #, entonces Countel ntal que PrimeQ@n&&MatchQ[f@n-f@#,{x=0...,_,x}]&&n!=#. PrimeQ@ncomprueba si nes primo, MatchQ[f@n-f@#,{x=0...,_,x}]comprueba si la diferencia entre la lista de dígitos de ny #es de la forma {0..., _, 0...}, y n!=#asegura que ny #son Unequal.

ngenisis
fuente
3

JavaScript (ES6), 153 142 139 bytes

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)

Acepta entradas como una cadena. Comportamiento indefinido para entrada no válida, aunque debería terminar sin error en cualquier cadena que se me ocurra. Sin embargo, no necesariamente antes de la muerte por calor del universo, particularmente para cuerdas largas.

Manifestación

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>

Mejoras

Ahorró 11 bytes refactorizando las reduce()llamadas en map()llamadas y copiando implícitamente la matriz aen el parámetro de la función, en lugar de hacerlo dentro del contexto de la splice()llamada.

Guardado 3 bytes gracias a @Neil sugerencia 's para convertir [...Array(10)]a [...''+1e9].

Código no minificado

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
)

Explicación

La función utiliza dos niveles map()para sumar la cantidad de permutaciones que pasan la prueba de primalidad, que se tomó prestada y modificada de esta respuesta .

(Respuesta original)

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

Entonces, por ejemplo, para calcular la suma de una matriz, pasaría un initialValuede 0y devolvería un aggregateigual a accumulator + currentValue. Modificando ligeramente este enfoque, calculamos el número de permutaciones que pasan la prueba de primalidad:

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

Eso es esencialmente lo interno reduce(), que itera todas las permutaciones de la digitArrayal cambiar cada decimaluna a una específica permutatedDigit. Luego necesitamos un exterior reduce()para iterar todos los posibles permutatedDigitcon los que reemplazar cada uno decimal, lo cual es justo 0-9.

Anormalidades en la implementación

[...''+1e9].map((u,j)=>...era el camino más corto @Neil podía pensar en iterar un argumento 0a través 9. Sería preferible hacerlo u, pero uno es útil para cada elemento de la matriz, en este caso.

i+jen la condición ternaria, verifica que 0no haya una permutación posible del dígito inicial, según la especificación de desafío. j!=casegura que el original nno sea candidato para pasar la prueba de primalidad.

(a.splice(i,1,j),a.join``)Es un desastre. splice()reemplaza el dígito en decimal == icon el permutatedDigit == j, pero como splice()devuelve los elementos eliminados (en este caso, sería igual a [a[i]]) en lugar de la matriz modificada, debemos usar el operador de coma para pasar la matriz modificada aa la prueba de primalidad, pero no antes de join()iniciarla en una cadena de números.

Por último, eval()es guardar un byte ya que, en comparación con el enfoque más canónico, es más corto:

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

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

La referencia a la prueba principal pse inicializa en un argumento no utilizado para la map()llamada.

Patrick Roberts
fuente
Creo que la página de consejos dice que [...''+1e9]es más corta.
Neil
2

Python 2 , 134 bytes

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

Pruébalo en línea!

Más elegante, versión más larga:

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

La entrada se toma como una cadena.


Explicación (versión anterior)

  • lambda x,r=range,l=len:- Define una lambda con un parámetro de cadena xy dos parámetros constantes r=rangey l=len.

  • sum(1...)- Obtenga la longitud, que ahorra 1 byte len([...]).

  • for f in r(10**~-l(x),10**l(x))- Genera absolutamente todos los números con el mismo orden de magnitud que la entrada (espere 0). Por ejemplo, una entrada de 3, daría como resultado [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 - Comprueba si el número actual está exactamente a 1 dígito de la entrada y si es mayor que 1.

  • all(f%v for v in r(2,f)) - Comprueba si el número actual es primo.

Sr. Xcoder
fuente
1
Puede cambiar sum(1for..ifBOOL)para sum(BOOLfor)guardar algunos bytes
Dead Possum
¿Se nos permite tomar la entrada como cadena? Mirando "Se puede suponer que la entrada y la salida encajan en el tipo entero nativo de su idioma" No estoy seguro
Dead Possum
@DeadPossum Algunas de las respuestas sí. ¿Por qué no se permitiría?
Sr. Xcoder
Me quedé sin votos para hoy, pero haré +1 lo antes posible: D
Dead Possum
@DeadPossum Claro. ¡No lo olvides o te enviaré un ping! ( </joke>)
Sr. Xcoder
1

JavaScript (ES6), 137 bytes

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)

Adapta mi otra respuesta en un envío de programa completo utilizando los métodos de API web prompt()y alert().

Patrick Roberts
fuente
1

Bean , 126 bytes

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

Pruébalo en línea!

Una adaptación de mi envío de JavaScript de programa completo .

JavaScript equivalente

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

Explicación

ase inicializa implícitamente como la primera línea de entrada como una cadena y la última instrucción sse emite implícitamente, que contiene la suma de las permutaciones principales.

Patrick Roberts
fuente
1

Casco , 32 bytes

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

Pruébalo en línea!

Ungolfed / Explicación

                              İ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
ბიმო
fuente
1

Japt , 28 23 bytes

-5 bytes gracias a @ETHproductions.

¬x@AÇ|Y©+UhYZsÃâ kUn)èj

Toma una cadena como entrada.

Pruébalo en línea!

Justin Mariner
fuente
Tal vez otra pareja con ¬x@AÇ|Y©+UhYZsÃâ kUn)èj?
ETHproductions
1

PHP , 151 147 141 140 136 134 129 128 bytes

-6 bytes gracias a @Einacio; -1 byte gracias a @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;

Pruébalo en línea!

Formateado, con comentarios:

<?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;

Para que sea lo más corto posible, he:

  • asignaciones combinadas $f = $t = 1;
  • husmear en un ++incremento como parte de otra expresión $f += $i % $t++ == 0(el incremento se ejecuta después de la operación de módulo y, por lo tanto, no afecta su resultado);
  • y en lugar de usar una ifinstrucción para un incremento condicional, hemos utilizado el hecho de que boolean verdadero cuando se convierte como un entero se convierte en 1, usando en $c += $f == 2;lugar de if ($f == 2) $c++;.
WebSmithery
fuente
1
no necesita definir $ c, cuenta como 0 en el primer + =
Einacio
@Einacio ¿Cuáles son las reglas del golf? ¿Está permitido, ya que da un aviso de advertencia variable indefinido?
WebSmithery
@Einacio Aparentemente, cualquier salida a STDERR puede ignorarse, así que gracias por la sugerencia.
WebSmithery
1
+1 para uso de levenshtein. ¡Buena idea! $i%$t++<1es más corto que $i%$t++==0.
Tito
0

PHP, 100 + 1 bytes

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;

Ejecutar como tubería -nRo probarlo en línea .

Descompostura

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
Titus
fuente
0

Java 8, 201 194 bytes

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

Explicación:

Pruébalo aquí

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):"") dará como resultado estos enteros:

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

Kevin Cruijssen
fuente
0

JavaScript (ES7), 118 bytes

Toma la entrada como una cadena.

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

Pruébalo en línea!

Comentado

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
Arnauld
fuente
0

Ruby con -rprime101 bytes

-rprime10Floor(losol10norte)+1norte

->n{d=n.digits;Prime.each(10**l=d.size).count{|x|d.zip(e=x.digits).count{|a,b|a==b}==l-1&&e.size==l}}

Pruébalo en línea!

Tinta de valor
fuente