Encuentra el primo más pequeño de una subcadena

17

En 1946, Erdos y Copeland demostraron que cierto número es un número normal , es decir, los dígitos en su expansión decimal están distribuidos uniformemente.

Los usuarios ingresarán una secuencia de dígitos y encontrará el primo más pequeño que contiene esa cadena en la base 10.

Ejemplo:

input   -> output
"10"    -> 101
"03"    -> 103
"222"   -> 2221
"98765" -> 987659

El código más corto en bytes gana. Sé que algunos lenguajes (Mathica, Sage, Pari-GP ...) vienen con funciones integradas relacionadas con números primos. -50 bytes si su programa no se basa en tales funciones. No intentes engañar a esto, por favor, si tu idioma ya tiene una gran ventaja, no reclames el bono.

Editar

Según algunos comentarios a continuación, el primo más pequeño que contiene "03" es 3. ¿Esto realmente hace la diferencia? Lo único en lo que puedo pensar es que quizás los números son más fáciles de manejar que las cadenas.

En casos como "03", el resultado preferido sería 103. Sin embargo, no considero que sea la parte fundamental de su programa, por lo que puede ignorar cualquier cero inicial si le otorga un recuento de bytes más bajo.

izabera
fuente
55
Esto parece una buena base para una tarea del Proyecto Euler
John Dvorak
El primo más pequeño que contiene "03" es 03. Tal vez debería agregar una regla que aclare que la entrada puede contener ceros a la izquierda pero la salida no.
Level River St
2
@steveverrill no existe un número como 03. Si quisiste decir 3, entonces eso no contiene "03".
John Dvorak
3
@ JanDvorak 03 es una representación válida del número 3. (2.9 ... recurrente infinitamente, equivalente a 2 + 9/9, también es considerado por algunos como una representación válida). Entiendo por el ejemplo dado que 03 no es aceptable representación para esta pregunta. Este es un punto pedante, pero dado el abuso habitual de las reglas, creo que vale la pena hacerlo.
Level River St
1
Creo que la mejor manera de expresarlo sería encontrar el número más pequeño que, cuando se convierte en una cadena, contendría "03".
Thebluefish

Respuestas:

13

Golfscipt 33 32 bytes = -18 puntaje

2{:x,2>{x\%!},!!x`3$?)!|}{)}/;;x

Explicación:

  • 2{...}{)}/- comenzando con 2, mientras algo es cierto, incremente la parte superior de la pila
  • ;;x- descarte los valores intermedios recopilados por {}{}/y la entrada, luego coloque el último valor probado allí

  • :x,2>- almacenar el valor como x, luego generar una lista de 2ax-1

  • {x\%!},!!- mantenga aquellos que xes divisible por, luego coaccionar a booleano (no vacío)
  • x`3?)!- busque la entrada en forma de texto de x( -1si no se encuentra), incrementar, negar.
  • | - o
John Dvorak
fuente
7

Programa Haskell, 97 caracteres = 47 puntos

main=getLine>>= \i->print$head$[x|x<-[2..],all((/=0).mod x)[2..x-1],i`Data.List.isInfixOf`show x]

Función Haskell, 75 caracteres = puntaje 25

p i=head$[x|x<-[2..],all((/=0).mod x)[2..x-1],i`Data.List.isInfixOf`show x]

El tipo de pes (Integral a, Show a) => [Char] -> a. Si proporciona su propio tipo integral, puede buscar por infijo en su propia representación de esos valores. El estándar Integerusa la notación decimal esperada para enteros.

No muy rapido. Cuadrático en el valor (no tamaño) de la salida.

versión sin golf:

import Data.List
leastPrime infix = head $ filter prime' [2..]
  where prime' x  = all (\n-> x`mod`n /= 0) [2..x-1]
                 && i `isInfixOf` show x
main = print . leastPrime =<< getLine

ejemplo:

Prelude> let p i=head$[x|x<-[2..],all((/=0).mod x)[2..x-1],i`Data.List.isInfixOf`show x]
Prelude> p "0"
101
Prelude> p "00"
1009
Prelude> p "000" -- long pause
10007
John Dvorak
fuente
3

Java: 175 caracteres.

class s{public static void main(String[]a){int i,n=2,p;for(;;){p=1;for(i=3;i<n;i++)if(n%i==0)p=0;if((n==2||p>0)&&(""+n).indexOf(a[0])>=0) {System.out.println(n);break;}n++;}}}
comodín
fuente
Puede guardar 1 personaje colocando el espacio entre indexOf(a[0])>=0)y {System.out.println(n).
ProgramFOX
@ProgramFOX Gracias.
comodín el
Creo que puedes guardar fácilmente (unos 8) caracteres reemplazando tu boolean p=truepor algo así int p=1y así sucesivamente.
florian h
declarar todas sus entradas a la vez reducirá aún más el tamaño de su programa.
Olivier Grégoire
3

Mathematica 58

(n=1;While[StringCases[ToString[p=Prime@n],#]=={},n++];p)&

Tiempos relativos en mi Mac (2.6 GHz i7 con 8 GB de memoria).

Encuentra el primo más pequeño que contiene "01".

AbsoluteTiming[(n = 1; While[StringCases[ToString[p = Prime@n], #] == {}, n++]; p) &["01"]]

{0.000217, 101}


Encuentra el primo más pequeño que contiene "012345".

AbsoluteTiming[(n = 1; While[StringCases[ToString[p = Prime@n], #] == {}, n++]; p) &["012345"]]

{5.021915, 10123457}


Encuentra el primo más pequeño que contiene "0123456".

AbsoluteTiming[(n = 1; While[StringCases[ToString[p = Prime@n], #] == {}, n++]; p) &["0123456"]]

{87.056245, 201234563}

DavidC
fuente
Puedes usar StringFreeQpara hacerlo más corto.
alephalpha
2

Sabio , 72

Se ejecuta en el mensaje interactivo

a=raw_input()
i=0
p=2
while a not in str(p):i+=1;p=Primes().unrank(i)
p

Primes().unrank(i)da el inúmero primo th, siendo el 0 primo 2.

usuario12205
fuente
2

R, 56 caracteres -50 = 6

k=2;n=scan(,"");while(!grepl(n,k)|sum(!k%%2:k)>1)k=k+1;k

Tome la entrada como stdin. Incrementa k hasta que k es primo (probado sumando las instancias para las cuales k mod 2 a k son ceros, por lo tanto FALSO ya que 0 convertido en lógico es FALSO) y contiene la cadena dada como entrada (probada con un grep simple, aquí grepl ya que queremos un resultado lógico).

Uso:

> k=2;n=scan(,"");while(!grepl(n,k)|sum(!k%%2:k)>1)k=k+1;k
1: "03"
2: 
Read 1 item
[1] 103
> k=2;n=scan(,"");while(!grepl(n,k)|sum(!k%%2:k)>1)k=k+1;k
1: "003"
2: 
Read 1 item
[1] 2003
plannapus
fuente
2

Shell oneliner (coreutils): 45 caracteres

No se define una función aquí ... solo una línea que toma un argumento $ny escanea el rango entero (en realidad un poco más para acortar el código). La versión de 55 caracteres:

seq 5e9|grep $n|factor|awk '{if(NF==2)print $2}'|head -n1

Ni siquiera es demasiado lento. Para n=0123456vuelve 201234563en 81.715s. Eso es impresionantemente rápido para una larga tubería con dos procesadores de cadena.

Eliminando dos caracteres (hasta 53) y una tubería, podemos hacer que funcione aún más rápido:

seq 5e9|grep $n|factor|awk '{if(NF==2){print $2;exit}}'

Y finalmente, un poco de sedmagia para reducirlo a 45 caracteres , aunque la impresión es fea:

seq 5e9|grep $n|factor|sed -n '/: \w*$/{p;q}'

n = 000 -> 10007: 10007 (usuario 0.017s)

n = 012345 -> 10123457: 10123457 (usuario 7.11s)

n = 0123456 -> 201234563: 201234563 (usuario 66.8s)

Orión
fuente
2

J - 38 caracteres -50 = -12 pts

Normalmente en J, estarías usando los builtins muy optimizados dedicados a los números primos, por lo que no voy a pedir disculpas por la lentitud en la ejecución.

>:@]^:(>./@(E.":)*:]=*/@(+.i.)@])^:_&2

Explicado:

  • >:@]^:(...)^:_&2- Comenzando con 2, incremente hasta que (...)devuelva falso.
  • (+.i.)@]- Tome el MCD del contador con cada número entero más pequeño que él. (Usamos la convención GCD (X, 0) = X.)
  • ]=*/@- Tome el producto de todos estos números y pruebe la igualdad en el mostrador. Si el contador es primo, la lista era todo 1, excepto el MCD con 0; de lo contrario, habrá al menos un MCD mayor que 1, por lo que el producto será mayor que el contador.
  • >./@(E.":)- Pruebe si la representación de cadena del contador ( ":) contiene la cadena ( E.) en cualquier punto. >./es la función max, y la usamos porque E.devuelve un vector booleano con un 1 donde la subcadena comienza en la cadena principal.
  • *:- NAND lógico los resultados juntos. Esto será falso solo si ambas entradas eran verdaderas, es decir, si el contador era primo y contenía la subcadena.

Uso:

   >:@]^:(>./@(E.":)*:]=*/@(+.i.)@])^:_&2 '03'
103
   >:@]^:(>./@(E.":)*:]=*/@(+.i.)@])^:_&2 '713'
2713

Para la posteridad, aquí está la versión que usa el primer incorporado (30 caracteres de largo, pero sin bonificación):

>:@]^:(>./@(E.":)*:1 p:])^:_&2

1 p:] prueba el contador de primalidad, en lugar del truco GCD.

Algoritmo de tiburón
fuente
2

Brachylog (v2), 3 bytes en la codificación de Brachylog

ṗ≜s

Pruébalo en línea!

Envío de funciones, tomando datos del argumento de la derecha, dando salida al mutar el argumento de la izquierda. (Esto es lo opuesto a la convención normal de Brachylog; vea esta meta publicación para más discusión. Cambiar los argumentos en el orden más habitual costaría tres bytes). El enlace TIO tiene un contenedor que llama a la función con la convención de llamada apropiada e imprime el resultado.

Explicación

ṗ≜s
 ≜   Find the integer closest to zero
ṗ      which is prime {implicit: and output it via the left argument}
  s    and which is a substring of the {right argument}

Lamentablemente, Brachylog es tan apropiado para este problema que, de acuerdo con las reglas del problema, ni siquiera puedo intentar obtener el bono (lo que irónicamente significa que es incapaz de ganar).

Una de las razones por las que me gusta tanto Brachylog es que la programación es una comunicación entre humanos y computadoras, y por lo tanto un lenguaje "perfecto" le permitiría traducir directamente la especificación del problema al inglés; las ideas a través de las cuales se planteó el problema y a través de las cuales se escribe el programa serían las mismas. Brachylog puede alcanzar este ideal sorprendentemente a menudo; la pregunta aquí es "encontrar el primo más pequeño que contiene una subcadena dada", y literalmente puedo encadenar los conceptos de "subcadena más pequeña, primo, que contiene" en el orden correcto y tener un programa de trabajo. Como tal, Brachylog dice mucho más sobre la naturaleza de la comunicación que un lenguaje en el que tenía que especificar explícitamente un algoritmo para resolver el problema; a veces cuando hablas con otros humanos, tratamos de explicar un problema explicando los pasos que tomaría para resolverlo, pero eso es raro. Entonces, ¿por qué nuestros idiomas deberían ser diferentes?

ais523
fuente
1

JavaScript 83 bytes = 33 puntaje

Golfizado:

for(s=prompt(n=x=0);!n;x++)for(n=(''+x).match(s)?2:0;n&&n<x;n=x%n?n+1:0);alert(x-1)

Sin golf (un poco):

s=prompt() // get the input
n = 0
for(x=0;!n;x++) // stop when n is non-zero
    if ((''+x).match(s)) { // if x matches the pattern, check if x is prime
        for(n=2;n&&n<x;)
            n = (x%n == 0) ? 0 : n+1; // if x%n is zero, x is not prime so set n=0
        // if n is non-zero here, x is prime and matches the pattern
    }
alert(x-1)
DocMax
fuente
0

Javascript (Node.JS) - 93 bytes = 43 puntos

l:for(i=x=process.argv[2];j=i;i++){while(--j>2)if(!(i%j*(""+i).match(x)))continue l
throw i}

En forma extraída con nombres de variables sensibles:

outerLoop:for (currentTry=inputNumber=process.argv[2]; primeIterator=currentTry; currentTry++ ) {
    while (--primeIterator > 2) 
        if(!(currentTry % primeIterator * (""+currentTry).match(inputNumber)))
            continue outerLoop;
    throw i
}
Tiddo
fuente
0

Óxido 0.9 136 bytes = 86 puntos

fn main(){
   let mut n:u32=2;
   while n.to_str().find_str(std::os::args()[1])==None ||
         range(2,n).find(|&x|n%x==0)!=None {
      n=n+1;
   }
   print!("{}",n);
}

Muy explícito a pesar de la compacidad. Demasiado espacio gastado en la cadena de encontrar. :(

Aquí la versión sin espacios en blanco (136 caracteres)

fn main(){let mut n:u32=2;while n.to_str().find_str(std::os::args()[1])==None||range(2,n).find(|&x|n%x==0)!=None{n=n+1;}print!("{}",n);}
ilmale
fuente
0

Perl 6 , 36-50 = -14 puntos

{$^a;first {/$a/&&$_%%one ^$_},2..*}

Pruébalo en línea!

Teniendo en cuenta $_%%one ^$_es el único 2 bytes más pequeño más grande que .is-prime, creo que vale la pena para el bono. Esto agota el tiempo para el último caso de prueba.

Explicación:

{                                  }  # Anonymous code block
 $^a;                                 # Assign input to $a
     first                    ,2..*   # Find the first number
           {                 }        # Which
            /$a/                        # Contains the input
                &&                      # And
                  $_%%one ^$_           # Is prime
Jo King
fuente
¿2 bytes más pequeños?
Solo ASCII el
lol @ la parte de la pregunta que dice "No trates de engañar en esto, por favor, si tu idioma ya tiene una gran ventaja, no reclames el bono".
Solo ASCII el
@ Solo ASCII Bueno, todavía estoy siendo golpeado por GolfScript, así que ...:$
Jo King
0

Python 3 , 80 79 bytes - 50 = 30 29 puntaje

-1 byte gracias al uso creativo de @ ASCII-only de en %slugar destr

El caso de prueba "98765" aún no se ha confirmado debido a cuánto tiempo se tarda en realizar la prueba. Confirmado para el caso de prueba "98765" después de un par de horas, pero con un enfoque similar que utiliza la evaluación de cortocircuito para evitar algunas pruebas de primalidad, funciona. mucho mas rápido. Alternativamente, esto puede ser ~ 2 veces más rápido si sabemos que "2" no es una entrada (podemos evitar verificar los números pares de primalidad) configurando i=3inicialmente y i+=2en el bucle, sin costo adicional de bytes.

def f(x):
 i=2
 while(x in"%s"%i)*all(i%j for j in range(2,i))-1:i+=1
 return i

Pruébalo en línea!

Explicación de la whilecondición ( (x in"%s"%i)*all(i%j for j in range(2,i))-1):

(x in"%s"%i): True/ 1si el contador actual contiene la secuencia deseada de números en él; False/ de lo 0contrario.

all(i%j for j in range(2,i)): True/ 1si el contador actual siempre tiene un resto cuando se divide por cualquier número entero de 2 (inclusive) a sí mismo (exclusivo), es decir, es primo; False/ /0 contrario.

Los *multiplica las dos condiciones juntos, y actúa como un andoperador - el producto esTrue / 1si y sólo si ambas condiciones son True/ 1.

El -1actúa como notoperador: False/ 0- 1 resulta en-1 , lo que se considera verdadero, mientras que True/ 1- 1 da como resultado 0, lo que se considera falso. Por lo tanto, el ciclo continúa mientras el número no contiene la secuencia de números deseada o no es primo.

Reemplace la * con andy agregue paréntesis alrededor de todo menos el-1 para obtener una solución equivalente mucho más rápida (que es un poco más larga).

Una solución de 76 bytes - 50 = 26 en Python 2 dada por @ ASCII-only (utiliza en ``lugar de str(),

def f(x):
 i=2
 while(x in`i`)*all(i%j for j in range(2,i))-1:i+=1
 return i

Pruébalo en línea!

Neil A.
fuente
¿por qué no py2
Solo para ASCII el
@ Solo ASCII No he usado mucho Python 2 y uso principalmente Python 3, así que eso es lo que juego. Aunque parece que la mayoría de las veces Python 2 termina siendo más corto ...
Neil A.
Hiciste un error tipográfico, en el primero que tienesreturn I
solo ASCII el
79
Solo ASCII el
0

JavaScript, 65-50 = 15 puntos

x=>(f=y=>(''+y).match(x)&&(p=n=>--n<2||y%n&&p(n))(y)?y:f(y+1))(x)

Pruébalo en línea!

Yair Rand
fuente