Para ser justos, esto se basa en una pregunta de StackExchange, pero es una buena pregunta.
El desafío es bastante simple:
- Tomar una cadena de números
- Encuentra e imprime el número primo contiguo más grande en la cadena
Puntuación:
- El menor número de personajes gana.
- Víctor probablemente será una entrada de golfscript, pero no lo consideraremos en contra de ellos, porque todos nos divertimos y aprendemos cosas, ¿verdad?
- El ganador será premiado cuando note que en realidad no he marcado el botón verde.
Suposiciones
- La cadena es solo números
- Si la cadena contiene letras, puede tener un comportamiento indefinido
- La cadena contiene al menos 1 primo
- Si la cadena no contiene 1 número primo válido, puede tener un comportamiento indefinido
- La velocidad no es una restricción.
- Use un algoritmo principal más corto sobre uno más rápido.
- Si su entrada finalmente termina, está bien, solo asegúrese de que pueda suceder antes de la muerte por calor del universo.
- Se puede suponer que la longitud de la cadena tiene menos de 15 caracteres.
Por ejemplo:
>> Input: 3571
<< Output: 3571
>> Input: 123
<< Output: 23
>> Input: 1236503
<< Output: 236503
>> Input: 46462
<< Output: 2
>> Input: 4684
<< Output: ValueError: max() arg is an empty sequence
>> Input: 460
<< Output: 0 # Note, zero is not a prime, but the above string has no valid prime
>> Input: 4601
<< Output: 601
>> Input: "12 monkeys is a pretty good movie, but not as good as se7en"
<< Output: ValueError: Fight Club was also good, I find Brad Pitt to be a consistantly good actor.
Posibles implementaciones:
- Encuentre todas las subcadenas de la entrada, verifique si son primos. - Legostormtroopr (original)
- Encuentre todos los enteros menos que la entrada, verifique si están en la entrada y luego verifique si es primo - Ben Reich
- Tome una lista de todos los números primos menos que la entrada, verifique si está en la entrada - daniero
Respuestas:
GolfScript
4037Esto observa todos los números menores o iguales a la entrada, se filtra a los que son subcadenas de la entrada y luego se filtra más abajo a los números primos. Luego, toma el elemento más grande (que obviamente tiene la mayor cantidad de dígitos).
Vamos a dividirlo en dos secciones principales:
Esta parte del código se filtra a todas las cadenas enteras contenidas en la entrada. Utiliza acento grave para convertir los números en cadenas y luego
?
para determinar el índice de la subcadena. Dado que se?
devuelve-1
en el caso de que no haya contención, incremente el uso)
para que la salida sea0
para no subcadenas, lo que se comportará bien con el,
filtrado.Esta parte del código se filtra hasta los números primos contando el número de factores menor que el número dado (un número entero es un factor solo si
number factor %!
es 1. Un número primo tendrá exactamente 1 factor estrictamente menor que él mismo)1=
.Como los números están en orden, toma el último y limpia la pila usando
)\;
Obviamente, esto no es tan eficiente como sea posible (ya que itera innecesariamente sobre todos los enteros menos que la entrada), pero aún termina con una gran entrada como
1236503
relativamente rápido en mi computadora (1 minuto).fuente
Python 2.7 - 84
Aquí hay una implementación de referencia para superar, la usé para el resultado de ejemplo en la pregunta, por lo que está garantizado que funcione * No es una garantía real
Mejora descarada basada en la solución mucho mejor de Ben Reich que la original. Con la mayor asistencia de Volatility
Los encantamientos anteriores de la segunda línea incluyen:
La versión original - 143
fuente
p
y reemplácelonot p(x)
consum(x%i for i in range(2,x))<1
: debería funcionar y reducirlo a 86 caracteres.sum(x%i for i in range(2,x))
será bastante alto para la mayoría de los números. Pero el generador es una gran idea y lo llegué a 91.all(x%i for i in range(2,x))
en su lugar.all
y ahorrando entre los(`x`in`N`)
ahorrados unos cuantos más también!Rubí 61
Tome todos los números primos hasta N y vea si están en la cadena
Creo que esto solo funciona en Ruby 1.9 y versiones posteriores, pero no estoy seguro.
fuente
Scala (83 caracteres)
No estaba seguro de cómo proporcionar entradas al programa, así que consideré
n
la entrada. Aquí está la solución real (según la cual se evalúa la longitud de la solución). Debajo de eso hay una forma ejecutable de la solución (que aún no está desarrollada) para su ejecución junto con la salida (para las muestras que da OP).Solución:
Solución ejecutable:
Salida de muestra:
Explicación:
Los pasos son bastante sencillos.
input -> Buscar todas las subcadenas -> filtrar no primos -> buscar el valor más largo
main(Array[String])
: El método proporciona una entrada de muestra y ejecuta el métodoq(String)
para cada entradaq(String)
: Ajusta la lógica real del programa dep(String)
modo que cualquier excepción se informe adecuadamente. Ayuda a formatear mejor la salida porque las entradas no válidas van a llegarNumberFormatException
a donde la falta de un primo arrojará unUnsupportedOperationException
p(String)
: Lógica real del programa. Dividamos la explicación de esto en partesn.inits
: Crea unIterator
para iterar sobre la entrada de cadena (n
)flatMap(f)
: Aplica una operación enIterator
y empuja el resultado a unList
_.tails.toList.init.map(BigInt(_))
: DivideString
y elimina losString
s vacíos de la resultanteList
. Finalmente convierte elString
a aBigInt
que es equivalente ajava.math.BigInteger
. Por razones de golf,BigInt
se selecciona (nombre más corto).filter(f)
: sif
devuelvefalse
, el valor se elimina de la resultanteList
_ isProbablePrime 1
: Esta línea podría haberse escrito como_.isProbablePrime(1)
pero la representación utilizada guarda 1 byte. Esta línea en realidad verifica si el valor es primo (probabilísticamente; dado quecertainty
está configurado como1
, el tiempo de ejecución aumenta pero el sistema se asegura (más o menos) de que el número es primo.max
: Encuentra el valor máximo (String
longitud no basada. Valor máximo real)fuente
J (
2422)Leer desde el teclado es en realidad más corto que definir una función.
Prueba:
Explicación:
1!:1[1
: lee una línea de texto desde el teclado".\.\
: la evaluación (".
) de cada sufijo (\.
) de cada prefijo (\
) de la cadena.;
: aplanar la matriz*1&p:
: multiplique cada valor por si es primo o no (por lo que todos los no primos serán cero)>./
: obtener el mayor valor en la listafuente
Haskell, 94
main=getLine>>=print.maximum.filter(\x->and$map((0/=).mod x)[2..x-1]).map read.init.scanr(:)[]
fuente
main = getLine >>= print . maximum . filter isPrime . map read . allNums
Es la forma original. obtiene una línea y le da (>>=
) a la gran función combinada, combinada con el.
operador infijo, que simplemente coloca el resultado de la función derecha en la función izquierda. cosas como(\x -> ...)
son expresiones lambda. los parámetros de la función se aplican sin paréntesis y las funciones se pueden aplicar parcialmente ((0/=)
por ejemplo, es una función que verifica si un número no es 0).allNums = init . scanr (:) []
.scanr
explora e inicializa elimina el último valor del resultado del explorador, que es una cadena vacía, que no se puede leer en un entero.map read
lee una lista de cadenas a sus valores destinados. en este caso, Integer u otra cosa de la clase de tipos Integral, porqueisPrime
necesita una Integral.filter isPrime
hace exactamente lo que dice.isPrime x = and $ map ((0/=). mod x) [2..(x-1)]
significa, dada una lista de 2 a (x-1), hacer la verificación de división y luego aplicarand
a la lista Bool.Perl 6 (40 caracteres, 41 bytes)
Primera
get
entrada en$_
, esto acorta la llamada de coincidencia de expresiones regulares.:ex
da una concordancia exhaustiva para la expresión regular, dará todas las posibilidades. El hiperoperador+«
(o+<<
también funciona) creará números con los objetos Match, a los que se pasagrep
con&is-prime
sub como selector. Finalmente, tome el máximo de la lista restante y envíela.fuente
Mathematica
6747Explicación
El código es una función pura. No tiene nombre En él,
#
representa la cadena de entrada completa.StringCases
toma la entrada, # y comprueba las subcadenas,a
de un carácter o más (es por eso que se usó __ en lugar de _) que son primos; PrimeQ debe devolver True para la subcadena.Todos los casos favorables, es decir, las subcadenas que son primos, se devuelven por defecto en una lista.
〚1〛
, o[[1]]
toma la primera parte, es decir, el primer elemento de esa lista de primos.element[[1]]
es la abreviaturaPart[element, 1]
. Si hay más de un primo, el primero será el primo más largo (StringCases
verifica primero las subcadenas más largas).Ejemplos
fuente
〚1〛
personajes fue sádico para nosotros, no matemáticos, programadores. (localización frenéticamente me preocupaba que me estoy quedando ciego, a continuación, buscar en otros soportes con la confusión que aparezcan nítidamente, mientras que éste no es!)〚1〛
tiene corchetes dobles y es equivalente a[[1]]
. Los usé porque un paréntesis doble cuenta como un solo carácter.Perl 6 (50 caracteres, 51 bytes)
+«
asigna cadenas a números,max
obtiene el mayor número,get
recibe una línea./(.+)<?{(+$0).is-prime}>/
es una expresión regular que obtiene todos los primos<?{}>
es una aserción de código.is-prime
esInt
un método de clase que verifica si el número es primo. Necesito convertir el valor en número usando+
, porque esStr
por defecto.:ex
significa que intenta encontrar TODAS las coincidencias (incluidas aquellas en las que se superponen otras). Debido al error de Rakudo Perl, actualmente es imposible de usarm//
aquí.Esto funciona para cualquier número, y si elimina
max
(o lo reemplazasort
) obtendrá una lista de todos los números primos en el número, para obtener un bono adicional (no es que esto le dé puntos, ni nada). Por ejemplo (consort
en este caso):fuente