Lo creas o no, todavía no tenemos un desafío de código de golf para una simple prueba de primalidad . Si bien puede que no sea el desafío más interesante, particularmente para los idiomas "usuales", puede no ser trivial en muchos idiomas.
El código de Rosetta presenta listas por idioma de enfoques idiomáticos para las pruebas de primalidad, una que usa la prueba de Miller-Rabin específicamente y otra que usa la división de prueba . Sin embargo, "más idiomático" a menudo no coincide con "más corto". En un esfuerzo por hacer de Programming Puzzles y Code Golf el sitio de referencia para el golf de código, este desafío busca compilar un catálogo del enfoque más corto en todos los idiomas, similar a "¡Hola, Mundo!" y Golf un quine por gran bien! .
Además, la capacidad de implementar una prueba de primalidad es parte de nuestra definición de lenguaje de programación , por lo que este desafío también servirá como un directorio de lenguajes de programación probados.
Tarea
Escriba un programa completo que, dado un entero estrictamente positivo n como entrada, determine si n es primo e imprima un valor verdadero o falso en consecuencia.
Para el propósito de este desafío, un número entero es primo si tiene exactamente dos divisores estrictamente positivos. Tenga en cuenta que esto excluye a 1 , que es su único divisor estrictamente positivo.
Su algoritmo debe ser determinista (es decir, producir la salida correcta con probabilidad 1) y, en teoría, debería funcionar para enteros arbitrariamente grandes. En la práctica, puede suponer que la entrada se puede almacenar en su tipo de datos, siempre que el programa funcione para enteros del 1 al 255.
Entrada
Si su idioma puede leer desde STDIN, aceptar argumentos de la línea de comandos o cualquier otra forma alternativa de entrada del usuario, puede leer el entero como su representación decimal, representación unaria (usando un carácter de su elección), matriz de bytes (grande o little endian) o un solo byte (si este es el tipo de datos más grande de su idioma).
Si (y solo si) su idioma no puede aceptar ningún tipo de entrada del usuario, puede codificar la entrada en su programa.
En este caso, el número entero codificado debe ser fácilmente intercambiable. En particular, puede aparecer solo en un solo lugar en todo el programa.
Para fines de puntuación, envíe el programa que corresponde a la entrada 1 .
Salida
La salida debe escribirse en STDOUT o en la alternativa más cercana.
Si es posible, la salida debe consistir únicamente en un valor verdadero o falso (o una representación de cadena del mismo), opcionalmente seguido de una nueva línea nueva.
La única excepción a esta regla es la salida constante del intérprete de su idioma que no se puede suprimir, como un saludo, códigos de color ANSI o sangría.
Reglas adicionales
No se trata de encontrar el idioma con el enfoque más corto para las pruebas principales, se trata de encontrar el enfoque más corto en cada idioma. Por lo tanto, ninguna respuesta se marcará como aceptada.
Las presentaciones en la mayoría de los idiomas se puntuarán en bytes en una codificación preexistente apropiada, generalmente (pero no necesariamente) UTF-8.
El idioma Piet , por ejemplo, se puntuará en codeles, que es la elección natural para este idioma.
Algunos idiomas, como las carpetas , son un poco difíciles de puntuar. En caso de duda, por favor pregunte en el Meta .
A diferencia de nuestras reglas habituales, siéntase libre de usar un idioma (o versión de idioma) incluso si es más nuevo que este desafío. Si alguien quiere abusar de esto creando un lenguaje donde el programa vacío realiza una prueba de primalidad, felicidades por allanar el camino para una respuesta muy aburrida.
Tenga en cuenta que debe haber un intérprete para que se pueda probar el envío. Se permite (e incluso se recomienda) escribir este intérprete usted mismo para un idioma previamente no implementado.
Si su idioma de elección es una variante trivial de otro lenguaje (potencialmente más popular) que ya tiene una respuesta (piense en dialectos BASIC o SQL, shells Unix o derivados triviales de Brainfuck como Headsecks o Unary), considere agregar una nota a la respuesta existente que la misma solución o una muy similar también es la más corta en el otro idioma.
Se permiten funciones integradas para probar la originalidad . Este desafío tiene la intención de catalogar la solución más corta posible en cada idioma, por lo que si es más corto usar un incorporado en su idioma, hágalo.
A menos que se hayan anulado anteriormente, se aplican todas las reglas estándar de código de golf , incluido http://meta.codegolf.stackexchange.com/q/1061 .
Como nota al margen, no desestime las respuestas aburridas (pero válidas) en idiomas donde no hay mucho para jugar golf; todavía son útiles para esta pregunta, ya que trata de compilar un catálogo lo más completo posible. Sin embargo, sobre todo vota las respuestas en idiomas en los que el autor realmente tuvo que esforzarse para jugar golf en el código.
Catalogar
El Fragmento de pila al final de esta publicación genera el catálogo a partir de las respuestas a) como una lista de la solución más corta por idioma yb) como una tabla de clasificación general.
Para asegurarse de que su respuesta se muestre, comience con un título, utilizando la siguiente plantilla de Markdown:
## Language Name, N bytes
¿Dónde N
está el tamaño de su envío? Si mejora su puntaje, puede mantener los puntajes antiguos en el título, tachándolos. Por ejemplo:
## Ruby, <s>104</s> <s>101</s> 96 bytes
Si desea incluir varios números en su encabezado (por ejemplo, porque su puntaje es la suma de dos archivos o desea enumerar las penalizaciones de la bandera del intérprete por separado), asegúrese de que el puntaje real sea el último número en el encabezado:
## Perl, 43 + 2 (-p flag) = 45 bytes
También puede hacer que el nombre del idioma sea un enlace que luego aparecerá en el fragmento:
## [><>](http://esolangs.org/wiki/Fish), 121 bytes
Respuestas:
¡Hola Mundo! 13
fuente
Hexagonía , 29 bytes.
La versión legible de este código es:
Explicación: Comprueba si hay un número de 2 a n-1 que divide n.
Inicializacion:
Escriba n en una celda de memoria y n-1 en otra:
Caso especial n = 1:
Imprime un 0 y termina
El lazo
Calcule n% a y disminuya a. Termine si a = 1 o n% a = 0.
Caso a = 1:
Aumente un 0 a un 1, imprímalo y finalice. (El puntero de instrucciones se ejecuta en dirección NE y recorre los bucles desde la esquina este hasta la esquina sudoeste. Y $ se asegura de que ignora el siguiente comando)
Caso a% n = 0:
Imprima el 0 y termine (el puntero de instrucciones está ejecutando SW y recorre en bucle a la parte superior a la @
fuente
Hexagonía ,
218925855 bytesAviso: Etoplay ha superado esta respuesta con una solución 4 de longitud lateral.
¡El primer programa de hexagonía no trivial (es decir, no lineal)! Se basa en el mismo enfoque factorial al cuadrado que la respuesta Laberinto de Sp3000 . Después de comenzar con un hexágono de la talla 10, me las arreglé para comprimirlo hasta un tamaño 5. Sin embargo, yo era capaz de volver a utilizar un código duplicado y todavía hay un buen montón de no-ops en el código, por lo que el tamaño 4 podría simplemente ser posible.
Explicación
Para darle sentido al código, primero tenemos que desplegarlo. Hexagony agrega cualquier código fuente al siguiente número hexagonal centrado con no-ops (
.
), que es61
. Luego reorganiza el código en un hexágono regular del tamaño correspondiente:Esto es bastante complejo con rutas de ejecución cruzadas y superpuestas y múltiples punteros de instrucción (IP). Para explicar cómo funciona, primero veamos una versión no protegida donde el flujo de control no pasa por los bordes, solo se usa una IP y las rutas de ejecución son lo más simples posible:
Nota al margen: el código anterior comienza con la ejecución de la primera línea, que está llena de no-ops. Luego, cuando la IP llega al borde noreste, se ajusta a la esquina más a la izquierda (el
)
), donde comienza el código real.Antes de comenzar, una palabra sobre el diseño de memoria de Hexagony. Es un poco como la cinta de Brainfuck con esteroides. De hecho, no es una cinta, pero es una cuadrícula hexagonal en sí (una infinita), donde cada borde tiene un valor entero, que inicialmente es 0 (y a diferencia del Brainfuck estándar, los valores son enteros de precisión arbitraria con signo). Para este programa, usaremos cuatro aristas:
Vamos a calcular el factorial en el borde Una , la cuenta atrás nuestra entrada en el borde C y almacenamos otra copia de la entrada (para el módulo) en el borde D . B se usa como un borde temporal para los cálculos.
El puntero de memoria (MP) comienza en el borde A y apunta hacia el norte (esto es importante para mover el MP). Ahora aquí está el primer bit del código:
)
incrementos de borde A a1
como la base de la factorial.}
hace que el MP gire a la derecha, es decir, se mueva hacia el borde C (apuntando hacia el noreste). Aquí leemos la entrada como un entero con?
. Luego tomamos otro giro a la derecha al borde D con}
.=
invierte el MP, de manera que señala en el vértice compartido con C .&
copia el valor de C (la entrada) en D ; el valor se copia desde la izquierda porque el valor actual no es positivo (cero). Finalmente, hacemos que el MP gire a la izquierda de nuevo a C con{
.A continuación,
<
técnicamente es una rama, pero sabemos que el valor actual es positivo, por lo que la IP siempre girará a la derecha hacia>
. Una rama golpeó por los actos secundarios como un espejo, de tal manera que la IP se mueve horizontalmente de nuevo, hacia el(
, lo que disminuye el valor de C .La siguiente rama, en realidad
<
es una rama ahora. Así es como nos desplazamos de abajo a abajo . Si bien el valor actual en C es positivo, la IP gira a la derecha (para ejecutar el bucle). Una vez que lleguemos a cero, en su lugar girará a la izquierda.n-1
1
Veamos el bucle "cuerpo". El
|
son espejos simples, el>
y<
también se utilizan como espejos de nuevo. Eso significa que el cuerpo del bucle real se reduce a}
mueve el MP al borde B ,=
invierte su dirección para enfrentar el vértice ABC .)
incrementa el valor: esto solo es relevante para la primera iteración, donde el valor de B sigue siendo cero: queremos asegurarnos de que sea positivo, de modo que la siguiente instrucción&
copie al vecino correcto , es decir , A , es decir, el valor actual del factorial cálculo, en B .}
luego mueve el MP a A , lo=
invierte nuevamente para enfrentar el vértice común.*
multiplica ambos vecinos, es decir, los bordes B y C y almacena el resultado en A . Finalmente, tenemos otro}=
para volver a C , aún frente al vértice ABC .Espero que puedan ver cómo esto calcula el factorial de
n-1
en una .Así que ahora que lo hemos hecho, el contador de bucle en C es cero. Queremos cuadrar el factorial y luego tomar el módulo con la entrada. Eso es lo que hace este código:
Desde C es cero,
&
copia el vecino de la izquierda, es decir, el factorial en A .}=*
mueve a B y almacena el producto de las dos copias del factorial (es decir, el cuadrado) en B .{
retrocede a C , pero no invierte el MP. Sabemos que el valor actual es ahora positiva, por lo que&
de entrada copias de D a C .'
la MP hacia atrás a la derecha, es decir, en A . Recuerde, el cuadrado de la factorial está en B y la entrada está en C . Entonces%
calcula(n-1)!^2 % n
, exactamente lo que estamos buscando.!
imprime el resultado como un entero (0 o 1) y@
finaliza el programa.De acuerdo, pero esa era la versión sin golf. ¿Qué pasa con la versión de golf? Necesita saber dos cosas más sobre Hexagony:
]
y a la anterior con[
. (También puede elegir uno específico con#
, pero eso es para otro momento).También hay algunos comandos nuevos en él:
\
y/
son espejos|
, y~
multiplica el valor actual por-1
.Entonces, ¿cómo se traduce la versión sin golf a la de golf? El código de configuración lineal
)}?}=&{
y la estructura básica del bucle se pueden encontrar aquí:Ahora el cuerpo del bucle cruza los bordes varias veces, pero lo más importante, el cálculo real se transfiere a la IP anterior (que comienza en la esquina izquierda, moviéndose hacia el noreste):
Después de rebotar en la rama hacia el sureste, la IP se envuelve alrededor del borde hacia los dos
=
en la esquina superior izquierda (que, juntos, son un no-op), luego rebota en el/
. El~
invierte el signo del valor de la corriente, que es importante para las iteraciones posteriores. La IP se envuelve alrededor del mismo borde nuevamente y finalmente golpea[
donde el control se transfiere a la otra IP.Este ahora ejecuta lo
~}=)&}=*}
que deshace la negación y luego solo ejecuta el cuerpo del bucle sin golf (menos el=
). Finalmente, toca]
qué control de manos vuelve a la IP original. (Tenga en cuenta que la próxima vez que ejecutemos esta IP, comenzará desde donde se quedó, por lo que primero llegará a la esquina. Necesitamos que el valor actual sea negativo para que la IP salte de nuevo al borde noroeste en lugar del sureste.)Una vez que la IP original reanuda el control, rebota
\
, ejecuta el resto=
y luego golpea>
para alimentar la siguiente iteración del bucle.Ahora la parte realmente loca: ¿qué sucede cuando termina el ciclo?
La IP se mueve hacia el noreste
<
y se envuelve hacia la diagonal noreste. Por lo tanto, termina en la misma ruta de ejecución que el cuerpo del bucle (&}=*}]
). Lo cual es realmente genial, porque ese es exactamente el código que queremos ejecutar en este punto, al menos si agregamos otro=}
(porque}=}
es equivalente a{
). Pero, ¿cómo no vuelve a entrar en el ciclo anterior? Porque]
cambia a la siguiente IP, que ahora es la IP (hasta ahora no utilizada) que comienza en la esquina superior derecha, moviéndose hacia el sur oeste. A partir de ahí, la IP continúa a lo largo del borde, se ajusta a la esquina superior izquierda, se mueve hacia abajo en la diagonal, rebota|
y termina@
mientras ejecuta el bit final de código lineal:(El
)(
es un no-op, por supuesto, tuve que agregar el(
porque)
ya estaba allí).Uf ... qué desastre ...
fuente
1
) . ¿De qué1
estás hablando allí?)
solía ser a1
.Pyth, 4 bytes
Impresiones
True
oFalse
.fuente
P_
Retina , 16 bytes
Pruébalo en línea!
Comencemos con un clásico: detectar primos con una expresión regular . La entrada debe darse en unario , utilizando cualquier carácter imprimible repetido. El conjunto de pruebas incluye una conversión de decimal a unario por conveniencia.
Un programa Retina que consiste en una sola línea trata esa línea como una expresión regular e imprime el número de coincidencias encontradas en la entrada, que será
0
para números compuestos y números1
primos.La búsqueda anticipada garantiza que la entrada no sea compuesta: el rastreo intentará cada subcadena posible (de al menos 2 caracteres)
(..+)
, la búsqueda anticipada intentará coincidir con el resto de la entrada repitiendo lo que se capturó aquí. Si esto es posible, eso significa que la entrada tiene un divisor mayor que 1, pero que es menor que sí mismo. Si ese es el caso, la anticipación negativa hace que la coincidencia falle. Para los primos no existe tal posibilidad, y el partido continúa.El único problema es que esta búsqueda anticipada también acepta
1
, por lo que descartamos al unir al menos dos caracteres con..
.fuente
CJam, 4 bytes
CJam tiene un operador incorporado para pruebas de primalidad.
fuente
limp
pimp
mi cjampimp
es objetivamente más proxenetal~mp
q
lee una línea de entrada, lai
analiza como un número entero ymp
está integrada. CJam tiene dos grupos de dos personajes incorporados: los "extendidos" comienzane
y los "matemáticos" comienzanm
HTML + CSS, 254 + n máx. * 28 bytes
Podemos verificar la primalidad usando expresiones regulares. Mozilla tiene
@document
, que se define como:Para filtrar elementos a través de CSS en función de la URL actual. Este es un solo pase, por lo que tenemos que hacer dos pasos:
1. Obteniendo entrada
La forma más corta que puedo imaginar para obtener información y transferirla a la URL es un
GET
formulario con casillas de verificación. Para la expresión regular, solo necesitamos una cadena única para contar las apariencias.Entonces comenzamos con esto (61 bytes):
Tenemos dos
<p>
s únicos para indicar si el número ingresado es primo (1) o no (0). También definimos la forma y su acción.Seguido de n max casillas de verificación con el mismo nombre (n max * 28 bytes):
Seguido por el elemento de envío (34 bytes):
2. Mostrar respuesta
Necesitamos el CSS (159 bytes) para seleccionar la
<p>
visualización (1 o 0):»Pruébelo en codepen.io (solo firefox)
fuente
Ayuda, WarDoq! , 1 byte
Salidas 1 si la entrada es primo, 0 de lo contrario.
fuente
Hexagonía , 28 bytes.
Como Etoplay me derrotó absolutamente en esta pregunta , sentí que tenía que superar su otra respuesta .
Pruébalo en línea!
Utilizo el teorema de Wilson, como Martin hizo en su respuesta : dado
n
, produzco(n-1!)² mod n
Aquí se desarrolló el programa:
Y aquí está la versión legible :
Explicación:
El programa tiene tres pasos principales: inicialización , factorial y de salida .
El modelo de memoria de Hexagony es una cuadrícula hexagonal infinita. Estoy usando 5 ubicaciones de memoria, como se muestra en este diagrama:
Me referiré a estas ubicaciones (y a los números enteros almacenados en ellas) por sus etiquetas en ese diagrama.
Inicialización
El puntero de instrucciones ( IP ) comienza en la esquina superior izquierda, hacia el este. El puntero de memoria ( MP ) comienza en IN .
Primero,
?
lee el número de la entrada y lo almacena en IN . La IP permanece en el camino azul, reflejado por\
. La secuencia"&(
mueve el MP hacia atrás y hacia la izquierda (hacia A ), copia el valor de IN a A y lo disminuye.El IP a continuación, sale de un lado del hexágono y entra de nuevo en el otro lado (en el camino verde). Ejecuta
'+
que mueve el MP a B y copia lo que había en una .<
redirige la IP a Occidente.Factorial:
Calculo el factorial de una manera específica, por lo que la cuadratura es fácil. Almaceno
n-1!
en B y C de la siguiente manera.El puntero de instrucciones comienza en el camino azul, en dirección Este.
='
invierte la dirección de la MP y se mueve hacia atrás para C . Esto es equivalente a{=
tener el lugar=
donde fue útil más adelante.&{
copia el valor de A a C , entonces se mueve el MP de nuevo a una . El IP a continuación, sigue el camino verde, sin hacer nada, antes de llegar al camino rojo, golpear\
y yendo hacia el camino de naranja.Con
(>
, decrementamos A y redirigimos la IP Este. A continuación se realiza un rama:<
. Para A positivo , continuamos por el camino naranja. De lo contrario, la IP se dirige hacia el noreste.'*
mueve el MP a B y almacena A * C en B . Aquí es(n-1)*(n-2)
donde estaba la entrada inicialn
. La IP luego vuelve a entrar en el bucle inicial y continúa disminuyendo y multiplicándose hasta que A llega0
. (informátican-1!
)NB : en los siguientes bucles,
&
almacena el valor de B en C , ya que C tiene un valor positivo almacenado en él ahora. Esto es crucial para la computación factorial.Salida:
Cuando A alcanza
0
. La rama dirige la IP a lo largo del camino azul.=*
invierte la MP y almacena el valor de B * C en A . Luego, la IP sale del hexágono y vuelve a entrar en el camino verde; ejecutar"%
. Esto mueve el MP a OUT y calcula A mod IN , o(n-1!)² mod n
.Lo siguiente
{"
actúa como no operativo, ya que se cancelan mutuamente.!
imprime la salida final y*+'(
se ejecutan antes de la terminación:@
.Después de la ejecución, (con una entrada de
5
) la memoria se ve así:Las bellas imágenes del flujo de control se realizaron con el Hexagony Coloror de Timwi .
Gracias a Martin Ender por generar todas las imágenes, ya que no pude hacerlo en mi PC.
fuente
Mornington Crescent , 2448 bytes
Estamos de vuelta en Londres!
Timwi fue muy amable al implementar las estaciones de control de flujo
Temple
yAngel
en IDE esotérico , así como también agregar entradas y análisis de enteros a la especificación del lenguaje.Este es probablemente mejor golf que el "¡Hola, mundo!", Porque esta vez escribí un script de CJam para ayudarme a encontrar el camino más corto entre dos estaciones. Si desea usarlo (aunque no sé por qué alguien querría ...), puede usar el intérprete en línea . Pega este código:
Aquí las dos primeras líneas son las estaciones que desea verificar. Además, pegue el contenido de este pastebin en la ventana de entrada.
La salida le mostrará qué líneas están disponibles en las dos estaciones, y luego una lista de todas las estaciones que conectan las dos, ordenadas por la longitud de los nombres de las estaciones. Los muestra a todos, porque a veces es mejor usar un nombre más largo, ya sea porque permite una línea más corta o porque la estación es especial (como Bank o Temple), por lo que desea evitarlo. Hay algunos casos extremos en los que dos estaciones no están conectadas por ninguna otra estación (en particular, las líneas Metropolitana y Distrital nunca se cruzan), en cuyo caso tendrá que descubrir otra cosa. ;)
En cuanto al código MC real, se basa en el enfoque factorial cuadrado como muchas otras respuestas porque MC tiene multiplicación, división y módulo. Además, pensé que un solo bucle sería conveniente.
Un problema es que los bucles son bucles do-while, y la disminución y el incremento son caros, por lo que no puedo calcular fácilmente
(n-1)!
(paran > 0
). En cambio, estoy computandon!
y luego divido porn
al final. Estoy seguro de que hay una mejor solución para esto.Cuando comencé a escribir esto, pensé que almacenar
-1
en Hammersmith sería una buena idea para poder disminuirlo más barato, pero al final esto puede haber costado más de lo que ahorró. Si encuentro la paciencia para rehacer esto, podría intentar simplemente mantener un-1
recorrido en Upminster para poder usar Hammersmith para algo más útil.fuente
Brachylog (V2), 1 byte
Pruébalo en línea!
Brachylog (V1), 2 bytes
Esto utiliza el predicado incorporado
#p - Prime
, que restringe su entrada para ser un número primo.Brachylog es mi intento de hacer una versión de Prolog de Code Golf, que es un lenguaje de golf de código declarativo que utiliza el seguimiento y la unificación.
Solución alternativa sin incorporado: 14 bytes
Aquí hay un desglose del código anterior:
fuente
Haskell, 49 bytes
Usando el corolario de xnor al teorema de Wilson :
fuente
main=interact$\n-> ...
?interact...read
allí en algún lugar, lo que lo hace mucho más largo que soloreadLn
. A menudo, lado
notación puede ser más concisa de lo que cabría esperar, especialmente cuando la alternativa es una lambda.Laberinto , 29 bytes
Lee un entero de STDIN y las salidas
((n-1)!)^2 mod n
. El teorema de Wilson es bastante útil para este desafío.El programa comienza en la esquina superior izquierda, comenzando con el
1
cual multiplica la parte superior de la pila por 10 y agrega 1. Esta es la forma en que Labyrinth construye grandes números, pero dado que las pilas de Labyrinth están llenas de ceros, el efecto final es como si nosotros solo presioné un 1.?
luego leen
de STDIN y lo:
duplica.}
desplazan
a la pila auxiliar, que se utilizará al final del módulo.(
luego disminuyen
, y estamos listos para comenzar a calcular el factorial al cuadrado.Nuestro segundo
:
(duplicado) está en un cruce, y aquí entran en juego las características de flujo de control de Labyrinth. En un cruce después de que se ejecuta una instrucción, si la parte superior de la pila es positiva, giramos a la derecha, para negativo giramos a la izquierda y para cero seguimos recto. Si intentas girar pero chocas contra una pared, Labyrinth te hace girar en la otra dirección.Porque
n = 1
, dado que la parte superior de la pila están
disminuida, o0
, seguimos adelante. Luego llegamos a un no-op'
seguido de otra disminución(
que nos pone en-1
. Esto es negativo, por lo que giramos a la izquierda, ejecutando+
plus (-1 + 0 = -1
),{
paran
volver de la pila auxiliar a main y%
modulo (-1 % 1 = 0
). Luego salimos con!
y terminamos con@
.Para
n > 1
, en el segundo:
giramos a la derecha. Luego cambiamos}
nuestro contador de bucle copiado a la pila auxiliar, duplicamos:
y multiplicamos dos veces**
, antes de volver a cambiar el contador{
y disminuirlo(
. Si seguimos siendo positivos, intentamos girar a la derecha pero no podemos, por lo que Labyrinth nos hace girar a la izquierda, continuando el ciclo. De lo contrario, la parte superior de la pila es nuestro contador de bucle que se ha reducido a 0, que+
agregamos a nuestro calculado((n-1)!)^2
. Finalmente,n
retrocedemos con{
entonces módulo%
, salida!
y terminamos@
.Dije que
'
es un no-op, pero también se puede usar para depurar. ¡Corre con la-d
bandera para ver el estado de la pila cada vez que'
se pasa por alto!fuente
Bash + GNU utilidades, 16
4 bytes guardados gracias a @Dennis
2 bytes guardados gracias a @Lekensteyn
La entrada es una línea tomada de STDIN. La salida es una cadena vacía para falsey y una cadena no vacía para verdadero. P.ej:
fuente
factor|awk NF==2
Java,
126121 bytesSupongo que necesitamos una respuesta Java para el marcador ... así que aquí hay un simple ciclo de división de prueba:
Como es habitual en Java, el requisito de "programa completo" lo hace mucho más grande de lo que sería si fuera una función, debido principalmente a la
main
firma.En forma expandida:
Editar: arreglado y revisado por Peter en los comentarios. ¡Gracias!
fuente
1
es primo. De lo contrario, habría un ahorro de 4 caracteres al eliminarp
y decirfor(;i<n;)n=n%i++<1?0:n;System.out.print(n>0);
class P{public static void main(String[]a){int i=2,n=Short.valueOf(a[0]);for(;i<n;)n=n%i++<1?0:n;System.out.print(n>1);}}
funciona.valueOf
usted, puede usarnew
, como ennew Short(a[0])
, onew Long(a[0])
, que es un poco más corto.public
modificador.Cerebro-Flak ,
112108 bytesPruébalo en línea!
Cómo funciona
Inicialmente, la primera pila contendrá un número entero positivo n , la segunda pila estará vacía.
Comenzamos decrementando n de la siguiente manera.
n = 1
Si n = 1 es cero, el ciclo while
se omite por completo. Finalmente, se ejecuta el código restante.
n> 1
Si n - 1 no es cero, ingresamos al ciclo que n = 1 omite. No es un bucle "real"; el código solo se ejecuta una vez. Logra lo siguiente.
n% k se calcula utilizando el algoritmo de módulo de 42 bytes de la respuesta de mi prueba de divisibilidad .
Finalmente, interpretamos los resultados para determinar la originalidad de n .
fuente
{}
.1 0
son dos valores. Por otro lado, aceptaríamos matrices siempre y cuando el lenguaje las considere verdaderas o falsas y múltiples elementos de la pila es lo más cercano que Brain-Flak tiene a las matrices. Podría valer la pena llevar esto a meta.1 0
es verdad. chat.stackexchange.com/transcript/message/32746241#32746241R,
3729 bytesUtiliza la división de prueba.
scan()
lee un número entero de STDIN ycat()
escribe en STDOUT.Generamos un vector de longitud que
n
consiste en los enteros 1 an
módulon
. Probamos si cada uno es 0 al negar (!
), que devuelve un valor lógico que es verdadero cuando el número es 0 y falso cuando es mayor que 0. La suma de un vector lógico es el número de elementos verdaderos, y para los números primos esperamos los únicos módulos distintos de cero son 1 yn
, por lo tanto, esperamos que la suma sea 2.¡Guardado 8 bytes gracias a flodel!
fuente
f=function(x)sum(!x%%1:x)==2
usted puede hacerlo en 28 bytes.TI-BASIC, 12 bytes
Muy claro.
randIntNoRep(
da una permutación aleatoria de todos los enteros de 1 aAns
.Esto dobla un poco las reglas; porque las listas en TI-BASIC están limitadas a 999 elementos que interpreté
lo que significa que se puede suponer que todos los tipos de datos acomodan la entrada. OP está de acuerdo con esta interpretación.
Una solución de 17 bytes que realmente funciona hasta 10 ^ 12 más o menos:
fuente
randIntNoRep(
que es dos.PARI / GP, 21 bytes
Funciona para entradas ridículamente grandes, porque este tipo de cosas es para lo que PARI / GP está hecho.
fuente
isprime
hace una prueba de primalidad APR-CL, por lo que se ralentiza bastante a medida que las entradas se hacen muy grandes.ispseudoprime(input)
realiza una prueba principal probable AES BPSW, que será mucho más rápida para más de 100 dígitos. Todavía no se conocen contraejemplos después de 35 años. La versión 2.1 y anterior de Pari, anterior a 2002, usa un método diferente que puede dar resultados falsos fácilmente, pero nadie debería estar usando eso.TI-BASIC, 24 bytes
Tenga en cuenta que los programas TI-Basic usan un sistema de tokens, por lo que contar caracteres no devuelve el valor de byte real del programa.
Vota la respuesta de Thomas Kwa , es superior.
Muestra:
Ahora vuelve
0
si no es primo, o1
si lo es.fuente
Apilar gatos , 62 + 4 = 66 bytes
Debe ejecutarse con los
-ln
indicadores de la línea de comandos (por lo tanto, +4 bytes). Imprime0
para números compuestos y1
para números primos.Pruébalo en línea!
Creo que este es el primer programa no trivial de Stack Cats.
Explicación
Una introducción rápida a Stack Cats:
-1
se inserta a en la pila inicial, y luego se empuja toda la entrada por encima de eso. En este caso, debido a la-n
bandera, la entrada se lee como un entero decimal.-1
en la parte inferior, se ignorará. Nuevamente, debido a la-n
bandera, los valores de la pila simplemente se imprimen como enteros decimales separados por salto de línea.<<(\-_)
convierte en(_-/)>>
. Este objetivo de diseño impone restricciones bastante severas sobre qué tipos de operadores y construcciones de flujo de control existen en el lenguaje, y qué tipo de funciones puede calcular en el estado de la memoria global.Para colmo, cada programa de Stack Cats tiene que ser auto-simétrico. Puede notar que este no es el caso para el código fuente anterior. Para eso está la
-l
bandera: refleja implícitamente el código a la izquierda, utilizando el primer carácter para el centro. Por lo tanto, el programa real es:La programación efectiva con todo el código es altamente no trivial y poco intuitiva y todavía no se ha dado cuenta de cómo un humano puede hacerlo. Bruscamente forzamos ese programa para tareas más simples, pero no hubiéramos podido acercarnos a eso a mano. Afortunadamente, hemos encontrado un patrón básico que le permite ignorar la mitad del programa. Si bien esto es ciertamente subóptimo, actualmente es la única forma conocida de programar efectivamente en Stack Cats.
Entonces, en esta respuesta, la plantilla de dicho patrón es la siguiente (hay alguna variabilidad en cómo se ejecuta):
Cuando se inicia el programa, la cinta de pila se ve así (por entrada
4
, por ejemplo):Se
[
mueve la parte superior de la pila hacia la izquierda (y la cabeza de la cinta): a esto le llamamos "empujar". Y se<
mueve la cabeza de la cinta sola. Entonces, después de los dos primeros comandos, tenemos esta situación:Ahora
(...)
es un bucle que se puede usar con bastante facilidad como condicional: el bucle se ingresa y se deja solo cuando la parte superior de la pila actual es positiva. Como actualmente es cero, omitimos la primera mitad del programa. Ahora el comando central es*
. Esto es simplementeXOR 1
, es decir, alterna el bit menos significativo de la parte superior de la pila, y en este caso convierte el0
en1
:Ahora nos encontramos con la imagen especular de la
(...)
. Esta vez la parte superior de la pila es positivo y nos haga entrar en el código. Antes de analizar lo que sucede dentro de los paréntesis, permítanme explicar cómo terminaremos al final: queremos asegurarnos de que al final de este bloque, tengamos el cabezal de la cinta en un valor positivo nuevamente (para que el bucle termina después de una única iteración y se utiliza simplemente como un condicional lineal), que la pila a la derecha mantiene la salida y que el derecho pila de que tiene una-1
. Si ese es el caso, dejamos el ciclo, nos>
movemos hacia el valor de salida y lo]
empujamos hacia adentro-1
para que tengamos una pila limpia para la salida.Eso es eso. Ahora dentro de los paréntesis podemos hacer lo que queramos para verificar la primalidad siempre y cuando nos aseguremos de configurar las cosas como se describe en el párrafo anterior al final (que puede hacerse fácilmente presionando y moviendo la cabeza de la cinta). Primero intenté resolver el problema con el teorema de Wilson, pero terminé con más de 100 bytes, porque el cálculo factorial al cuadrado es bastante costoso en Stack Cats (al menos no he encontrado un camino corto). Así que fui con la división de prueba y eso resultó mucho más simple. Veamos el primer bit lineal:
Ya has visto dos de esos comandos. Además,
:
intercambia los dos valores superiores de la pila actual y^
XOR el segundo valor en el valor superior. Esto hace:^
un patrón común para duplicar un valor en una pila vacía (sacamos un cero encima del valor y luego convertimos el cero en0 XOR x = x
). Luego de esto, la sección de nuestra cinta se ve así:El algoritmo de división de prueba que he implementado no funciona para la entrada
1
, por lo que deberíamos omitir el código en ese caso. Podemos asignar fácilmente1
a0
y todo lo demás a valores positivos con*
, por lo que aquí es cómo lo hacemos:Es decir, nos convertimos
1
en0
, omitimos una gran parte del código si lo conseguimos0
, pero por dentro lo deshacemos inmediatamente*
para recuperar nuestro valor de entrada. Solo necesitamos asegurarnos nuevamente de que terminamos con un valor positivo al final de los paréntesis para que no comiencen a repetirse. Dentro del condicional, movemos una pila hacia la derecha con>
y luego iniciamos el ciclo principal de división de prueba:Las llaves (en lugar de paréntesis) definen un tipo diferente de bucle: es un bucle do-while, lo que significa que siempre se ejecuta al menos una iteración. La otra diferencia es la condición de terminación: al ingresar al bucle, Stack Cat recuerda el valor superior de la pila actual (
0
en nuestro caso). El bucle se ejecutará hasta que este mismo valor se vuelva a ver al final de una iteración. Esto es conveniente para nosotros: en cada iteración simplemente calculamos el resto del siguiente divisor potencial y lo movemos a esta pila en la que estamos comenzando el ciclo. Cuando encontramos un divisor, el resto es0
y el ciclo se detiene. Intentaremos los divisores comenzando enn-1
y luego los disminuiremos a1
. Eso significa a) sabemos que esto terminará cuando lleguemos1
a más tardar y b) podemos determinar si el número es primo o no inspeccionando el último divisor que probamos (si es1
, es primo, de lo contrario no lo es).Hagámoslo. Hay una sección lineal corta al principio:
Ya sabes lo que la mayoría de esas cosas hacen ahora. Los nuevos comandos son
-
y!
. Stack Cats no tiene operadores de incremento o decremento. Sin embargo, tiene-
(negación, es decir, multiplicar por-1
) y!
(NO a nivel de bit, es decir, multiplicar por-1
y disminuir). Estos se pueden combinar en un incremento!-
o decremento-!
. Por lo tanto, disminuimos la copian
en la parte superior-1
, luego hacemos otra copian
en la pila a la izquierda, luego buscamos el nuevo divisor de prueba y lo colocamos debajon
. Entonces, en la primera iteración, obtenemos esto:En iteraciones posteriores,
3
se reemplazará con el siguiente divisor de prueba y así sucesivamente (mientras que las dos copiasn
siempre tendrán el mismo valor en este punto).Este es el cálculo del módulo. Como los bucles terminan en valores positivos, la idea es comenzar desde
-n
y agregarle repetidamente el divisor de pruebad
hasta obtener un valor positivo. Una vez que lo hacemos, restamos el resultadod
y esto nos da el resto. La parte difícil aquí es que no podemos simplemente poner una-n
parte superior de la pila y comenzar un ciclo que agregad
: si la parte superior de la pila es negativa, no se ingresará el ciclo. Tales son las limitaciones de un lenguaje de programación reversible.Entonces, para evitar este problema, comenzamos con la
n
parte superior de la pila, pero lo negamos solo en la primera iteración. De nuevo, eso suena más simple de lo que parece ser ...Cuando la parte superior de la pila es positiva (es decir, solo en la primera iteración), la negamos con
-
. Sin embargo, no podemos hacerlo(-)
porque no estaríamos dejando el ciclo hasta que-
se aplicara dos veces. Así que movemos una celda hacia la izquierda<
porque sabemos que hay un valor positivo allí (el1
). Bien, ahora hemos negado de manera confiablen
en la primera iteración. Pero tenemos un nuevo problema: la cabeza de la cinta ahora está en una posición diferente en la primera iteración que en cualquier otra. Necesitamos consolidar esto antes de seguir adelante. El siguiente<
mueve la cabeza de la cinta hacia la izquierda. La situación en la primera iteración:Y en la segunda iteración (recuerde que hemos agregado
d
una vez-n
ahora):El siguiente condicional fusiona estos caminos nuevamente:
En la primera iteración, el cabezal de la cinta apunta a cero, por lo que se omite por completo. Sin embargo, en otras iteraciones, el cabezal de la cinta apunta a uno, así que ejecutamos esto, nos movemos hacia la izquierda e incrementamos la celda allí. Como sabemos que la celda comienza desde cero, ahora siempre será positiva para que podamos abandonar el ciclo. Esto garantiza que siempre terminemos dos pilas a la izquierda de la pila principal y que ahora podamos retroceder
>>
. Luego, al final del ciclo módulo lo hacemos-_
. Usted ya sabe-
._
es restar lo que^
es para XOR: si la parte superior de la pila esa
y el valor debajo esb
reemplazadoa
porb-a
. Desde la primera vez negadaa
sin embargo,-_
reemplazaa
conb+a
, añadiendo asíd
en nuestro total acumulado.Una vez que finaliza el ciclo (hemos alcanzado un valor positivo), la cinta se ve así:
El valor más a la izquierda podría ser cualquier número positivo. De hecho, es el número de iteraciones menos uno. Hay otro bit lineal corto ahora:
Como dije antes, necesitamos restar el resultado
d
para obtener el resto real (3-2 = 1 = 4 % 3
), por lo que solo lo hacemos_
una vez más. Luego, necesitamos limpiar la pila que hemos estado incrementando a la izquierda: cuando probamos el siguiente divisor, debe ser cero nuevamente, para que la primera iteración funcione. Entonces nos movemos allí y empujamos ese valor positivo en la otra pila auxiliar con<<]
y luego volvemos a nuestra pila operativa con otra>
. Nos detenemosd
con:
y vuelva a insertarla en el-1
con]
y luego nos movemos hacia el resto de nuestra pila condicional con<]]
. Ese es el final del ciclo de división de prueba: esto continúa hasta que obtengamos un resto cero, en cuyo caso la pila a la izquierda contienen
El mayor divisor (aparte den
).Después de que finaliza el ciclo, hay justo
*<
antes de que unamos1
nuevamente las rutas con la entrada . El*
simplemente se vuelve el cero en una1
, lo que vamos a necesitar un poco, y luego se pasa al divisor con<
(por lo que estamos en la misma pila que para la entrada1
).En este punto, ayuda a comparar tres tipos diferentes de entradas. Primero, el caso especial
n = 1
donde no hemos hecho nada de eso de la división de prueba:Luego, nuestro ejemplo anterior
n = 4
, un número compuesto:Y finalmente,
n = 3
un número primo:Entonces, para los números primos, tenemos un
1
en esta pila, y para los números compuestos tenemos0
un número positivo o mayor que2
. Nos dirigimos esta situación en el0
o1
que necesitamos con la siguiente pieza final de código:]
simplemente empuja este valor a la derecha. A continuación,*
se utiliza para simplificar la situación condicionada en gran medida: alternando el bit menos significativo, nos volvemos1
(primer) en0
,0
(compuesto) en el valor positivo1
, y todos los demás valores positivos seguirán siendo positivo. Ahora solo necesitamos distinguir entre0
y positivo. Ahí es donde usamos otro(:)
. Si la parte superior de la pila es0
(y la entrada fue un primo), esto simplemente se omite. Pero si la parte superior de la pila es positiva (y la entrada era un número compuesto), esto se intercambia con el1
, de modo que ahora tenemos0
para compuesto y1
para primos: solo dos valores distintos. Por supuesto, son lo opuesto a lo que queremos generar, pero eso se soluciona fácilmente con otro*
.Ahora todo lo que queda es restaurar el patrón de pilas esperado por nuestro marco circundante: cabeza de cinta en un valor positivo, resultado en la parte superior de la pila a la derecha, y un solo
-1
en la pila a la derecha de eso . Esto es para lo que=<*
sirve.=
intercambia la parte superior de las dos pilas adyacentes, moviendo así-1
a la derecha del resultado, por ejemplo, para ingresar4
nuevamente:Luego nos movemos a la izquierda con
<
y convertimos ese cero en uno con*
. Y eso es eso.Si desea profundizar en cómo funciona el programa, puede utilizar las opciones de depuración. Agregue el
-d
indicador e insértelo"
donde desee ver el estado actual de la memoria, por ejemplo , de esta manera , o use el-D
indicador para obtener un seguimiento completo de todo el programa . Alternativamente, puede usar EsotericIDE de Timwi, que incluye un intérprete de Stack Cats con un depurador paso a paso.fuente
>:^]
debería ser el logotipo oficial de Stack CatsHaskell, 54 bytes
No hay mucho que explicar.
fuente
main=do n<-readLn;print$n>1&&mod(product[1..n-1]+1)n<1
main=do n<-readLn;print$mod(product[1..n-1]^2)n>0
es de 49 bytes.Rubí, 15 + 8 = 23 bytes
Ejecución de muestra:
fuente
JavaScript,
3936 bytesGuardado 3 bytes gracias a ETHproductions:
Muestra verdadero para un primo, falso de lo contrario.
El bucle for prueba cada número i desde n-1 hasta que yo sea un divisor. Si el primer divisor encontrado es 1, entonces es un número primo.
Solución anterior (39 bytes):
Cómo quedó una prueba innecesaria:
Solo publiqué la solución de 39 bytes porque la mejor respuesta de JavaScript ya era de 40 bytes.
fuente
&&i
realidad, no hace nada en este programa, por lo que puede eliminarlo.n>1
sin embargo, debe agregarse a la condición final, si no desea1
ser primo.1
el bucle for lo harán%--i
una vez:1%0
vuelveNaN
y detiene el bucle. Cuandoalert
se llamai
ya es igual a0
lo que1==i
devuelvefalse
.Caracoles, 122
La entrada debe darse en unario. Los dígitos pueden ser cualquier combinación de caracteres, excepto las nuevas líneas.
En este lenguaje de coincidencia de patrones 2D, el estado del programa consiste únicamente en la ubicación actual de la cuadrícula, el conjunto de celdas que se han emparejado y la posición en el código del patrón. También es ilegal viajar a un cuadrado coincidente. Es complicado, pero es posible almacenar y recuperar información. La restricción contra viajar a una celda coincidente se puede superar mediante retroceso, teletransportación (
t
) y aserciones (=
,!
) que dejan la cuadrícula sin modificar después de completarse.La factorización para un número compuesto impar comienza marcando un conjunto de celdas mutuamente no adyacentes (azul en el diagrama). Luego, de cada celda amarilla, el programa verifica que haya un número igual de celdas no azules a cada lado de la celda azul adyacente al desplazarse de un lado a otro entre los dos lados. El diagrama muestra este patrón para una de las cuatro celdas amarillas que deben verificarse.
Código anotado:
fuente
C, 67 bytes
Imprime
!1
(un valor de falsey, según la definición de Peter Taylor )0
si(n-1)!^2 == 0 (mod n)
, y1
otra manera.EDITAR : después de una discusión en el chat,
puts("!1"+p%n)
parece ser considerado un poco engañoso, así que lo he reemplazado. El resultado es un byte más largo.EDITAR : Corregido para entradas grandes.
Soluciones más cortas
56 bytes : como se recomienda en los comentarios de pawel.boczarski, podría tomar la entrada en unario leyendo el número de argumentos de la línea de comando:
invocando el programa como
51 bytes : si permite la "salida" mediante códigos de retorno:
fuente
puts("!1"+p%n)
¿Cómo podrías hacera+b
para loschar*
valores?"!1"
comienza en la direccióna
, entoncesa+1
encontrará la cadena"1"
.strcat(const char*,const char*)
.)p=p*i*i%n
ap*=i*i%n
Python 3, 59 bytes
Ahora usa en
input()
lugar de argumentos de línea de comando. Gracias a @Beta Decayfuente
input()
sería mucho más corton=m=int(input())
,print(all(n%m for m in range(2,n)))
n%i<1
lugar.APL,
4013 bytesSala de primera instancia con el mismo algoritmo que mi R respuesta . Asignamos
x
a la entrada de STDIN (⎕
) y obtenemos el resto parax
dividido por cada entero de 1 ax
. Cada resto se compara con 0, lo que nos da un vector de unos y ceros que indica qué números enteros se dividenx
. Esto se suma usando+/
para obtener el número de divisores. Si este número es exactamente 2, esto significa que los únicos divisores son 1 yx
, por lo tanto,x
es primo.fuente
Pitón 2, 44
Al igual que la respuesta de Python de Sp3000 , pero evita almacenar la entrada contando la variable
n
desde1
el valor de entrada.fuente
Metaprogramación de plantilla C ++.
166131119 bytes.El código se compila si la constante es primo y no se compila si es compuesto o 1.
(todas las líneas nuevas, excepto la final, se eliminan en la versión "real").
Me imagino que "falla al compilar" es un valor de retorno falso para un lenguaje de metaprogramación. Tenga en cuenta que no se vincula (por lo tanto, si lo alimenta con primos, obtendrá errores de vinculación) como un programa completo de C ++.
El valor a probar es el entero en la última "línea".
ejemplo vivo .
fuente