Codificar a los policías y ladrones (ladrones)

12

Este es un desafío de . El hilo de los policías a este desafío está aquí

Una pregunta interesante para pensar es la siguiente:

Si tengo una secuencia de números, ¿cuántos de ellos debo proporcionar antes de que quede claro de qué secuencia estoy hablando?

Por ejemplo, si quiero hablar sobre los enteros positivos en orden a partir de , podría decir , pero ¿es realmente suficiente?1 , 2 , 3 , ...11,2,3,

Tengo una forma de responder a esta pregunta, y ser un jugador de código implica el golf de código. Ha proporcionado suficientes términos de una secuencia si el código más corto que produce esos términos produce todos los términos de la secuencia. Si pensamos en esto en términos de código de golf, esto significaría que ha proporcionado suficientes casos de prueba para que el código más corto que pasa los casos de prueba haga la tarea deseada.

Desafío

Este desafío es un desafío de . En el cual los policías presentarán casos de prueba y los ladrones tendrán que encontrar una forma más corta de falsificar los casos de prueba que no sea la secuencia prevista. Los policías presentarán lo siguiente:

  • Una pieza de código que toma un entero positivo como entrada y produce un entero como salida. Este código puede ser cero o uno indexado, pero debe quedar claro cuál es la indexación. Este código definirá su secuencia.

  • Cualquier plataforma relevante o requisitos de idioma que puedan afectar a la salida, por ejemplo, el tamaño de longint.

  • Un número , junto con los primeros términos de la secuencia calculados por el código. Estos actuarán como "casos de prueba".nnn

Los ladrones encontrarán un programa en el mismo lenguaje que es más corto que el presentado y pasa todos los casos de prueba (produce la misma salida para las primeras entradas que el código del policía). El código del ladrón también debe diferir en la salida del programa del policía para un número mayor que .nnn

Puntuación

Los ladrones serán puntuados en la cantidad de grietas que encuentren, con más grietas mejorando. Una respuesta se puede descifrar nuevamente al encontrar una respuesta válida más corta que la grieta original. Si una respuesta se descifra por segunda vez, el punto se otorga a la segunda galleta en lugar de a la primera.

Ad Hoc Garf Hunter
fuente
2
¿No estamos permitiendo que los ladrones se golpeen entre sí por descifrar una respuesta (es decir, la grieta más corta en el idioma ganador)
Fəˈnɛtɪk
@ Sonidos de fəˈnɛtɪk, bueno, agregué eso.
Ad Hoc Garf Hunter

Respuestas:

5

JavaScript, la respuesta de fəˈnɛtɪk (17 bytes)

x=>"11237"[x]||22

Bueno, fue fácil codificar para obtener una puntuación mucho más baja ... Difiere de la implementación de referencia para cualquier entrada , 0 indexada. Esto utiliza un truco de golf JS muy conocido: la indexación en una secuencia con un número entero que excede los límites de la misma devuelve un valor falso ( ), por lo que simplemente se puede forzar a un valor predeterminado mediante el uso de OR lógico ( ), en este caso , manejando el último término de la secuencia pero también los que siguen.x6undefined||22

Pruebas

let f=x=>"11237"[x]||22

for (x of [1,2,3,4,5,6,7]) {
  console.log(x + ' -> ' + f(x))
}

Alternativamente, ¡ pruébelo en línea!

Sr. Xcoder
fuente
4

Haskell , la respuesta de Laikoni , 15 bytes

b n=n*div(n+1)2

Pruébalo en línea!

Por lo general, señalaría algo como esto en un comentario, pero luego pensé que los policías y los ladrones son un poco más feroces.

Esta es solo la respuesta de BMO menos el caso especial para b 42. Debido a que el original de Laikoni pasa por punto flotante, no es necesario: solo encuentre un número lo suficientemente grande como para dar errores de redondeo en eso, pero no en la Integeraritmética exacta . Por ejemplo:

a 100000000000000000000000 = 4999999999999999580569600000000000000000000000
b 100000000000000000000000 = 5000000000000000000000000000000000000000000000
Ørjan Johansen
fuente
Pensé que esto podría ser posible (por lo tanto, escribí que se puede reescribir para los términos requeridos) pero no encontré un valor para el que funciona ... ¡Bien hecho!
ბიმო
4

Python 2 , la respuesta de xnor , 43 bytes

n=69

f=lambda n,p=2:n<1or-~f(n-(~-2**p%p<2),p+1)

Pruébalo en línea!

Créditos

Una gran parte del crédito por este crack debe ir a @ Mr.Xcoder, quien primero publicó un comentario sobre un posible ataque con este método, y a @PoonLevi, que encontró una solución de 44 bytes.

¿Cómo?

Teoría

pap

(1)ap11(modp)

En particular, para :a=2

2p11(modp)

Entonces, existe algún número entero positivo tal que:k

2p1=kp+1

Lo que lleva a:

2 p - 1 = 2 k p + 1 2 p - 1 1

2p=2kp+2
2p1=2kp+1
(2)2p11(modp)

Esta última fórmula es de la que se deriva el código Python y ahora se mantiene para , a pesar de que no es relativamente primo consigo mismo.2p=22

Ahora, para la parte más importante: lo contrario del pequeño teorema de Fermat no es cierto. Podemos tener para algún número compuesto . Dichos números se llaman pseudoprimos de Fermat para basar . Los pseudoprimos de Fermat a la base 2 también se conocen como números de Poulet .n aan11(modn)na

El primer pseudoprimo de Fermat a base (o primer número de Poulet) es , para lo cual tenemos:n = 341 = 11 × 312n=341=11×31

2 341 - 1 1

234111(mod341)
234111(mod341)

Esto significa que nuestro algoritmo va a devolver en lugar de la esperada 69 º primer .347341347

Implementación

@PoonLevi encontró la siguiente solución de 44 bytes, que se basa directamente en :(2)

f=lambda n,p=1:n and-~f(n-(~-2**p%p==1),p+1)

Al usar en <2lugar de ==1, guardamos 1 byte pero introducimos en la secuencia, porque :2 1 - 1 012110(mod1)

f=lambda n,p=1:n and-~f(n-(~-2**p%p<2),p+1)

Pruébalo en línea!

Al comenzar con , obtenemos los términos esperados en 1 porque hacemos una iteración menos:p=2

f=lambda n,p=2:n and-~f(n-(~-2**p%p<2),p+1)

Pruébalo en línea!

El último truco es usar en n<1orlugar de n and. Esto es igual de largo pero hace que la última iteración devuelva True en lugar de 0 , por lo tanto, agrega el desplazamiento que falta a cada término.

Arnauld
fuente
Felicitaciones a todos ustedes! Esta es la solución que tenía en mente. Creo que es curioso que, por la motivación del desafío "Si tengo una secuencia de números, ¿cuántos de ellos debo proporcionar antes de que quede claro de qué secuencia estoy hablando?", Los primeros 50 números primos aparentemente no son suficientes. un alienígena de Python-golf asumiría que estás hablando de una secuencia diferente.
xnor
@xnor Me encanta la idea de un "alienígena de Python-golf"
dylnan
2

Haskell , la respuesta de Laikoni , 26 22 bytes

-4 bytes al no usar infijo div, ¡gracias a Laikoni !

b 42=0;b n=n*div(n+1)2

Pruébalo en línea!

Explicación

0n20ceiling(realToFrac n/2)div(n+1)2n>20

b 42=0
ბიმო
fuente
Ah, no pensé en eso. Tengo un enfoque diferente que conduce a una grieta de 20 bytes en caso de que desee resolver un poco más. También ((n+1)`div`2)-> div(n+1)2.
Laikoni
@Laikoni: ¡Sí, no lo reveles todavía! Oopsies, sí, ha pasado bastante tiempo desde que jugué al golf, lo actualizaré.
ბიმო
2

> <> , respuesta de crashoz 203 bytes

:l2-$g:0=?;n:





M
-
B
"
BM
",
7M
!"
BBM
!",
7CM
!"-
BBBM
!!",
7BBMM
!!,,
7BBBMM
!!,,
7BBBMM
!!!,,
7BBBBMM
!!!,,
7BBBBMM
!!!!,,
7BBBBBMM
!!!!,,
7BBBBBMM
!!!!!,,
7BBBBBBMM

Pruébalo en línea!

Iba a hacer algo inteligente con el hecho de que los números pares / impares anteriores n=20eran los mismos, excepto por un elemento repetido en el centro, pero era más fácil codificar cada elemento.

La entrada es a través de la -vbandera. No imprime nada para elementos superiores a 34.

Jo King
fuente
2

Pascal (FPC) , la respuesta de AlexRacer , 80 bytes

var n,m:word;begin read(n);while n<>0 do begin n:=n div 2;m:=m+n;end;write(m)end.

Pruébalo en línea!

0n120n=128127126

Esta parece una respuesta tardía, pero de todos modos gracias @AlexRacer por un buen rompecabezas.

r_64
fuente
1
Wow, esto es incluso más corto que el que tenía. Bienvenido a PPCG!
AlexRacer
1

Husk , descifrando 5 bytes de BMO con  3  2 bytes

-1 gracias a BMO ( LdΣ-> ya que, cuando se le da un Tnum, Lrealiza la "representación de la longitud de la cadena")

Pruébalo en línea!

a(0)a(23)a(24)
3←d+164

T(0)=010

Jonathan Allan
fuente
¡Felicitaciones, esa fue mi solución exacta! Sin embargo acabo de señalar que para TNum s Ly Ld son equivalentes ahorro que un byte;)
ბიმო
Ah, busqué "dígito" en la wiki para tratar de encontrar la longitud digital, pero no detecté esa Lanulación como "representación de longitud de cadena" Tnum.
Jonathan Allan
(Tenga en cuenta que solo son equivalentes para enteros no negativos, lo suficientemente bueno para esto.)
Jonathan Allan
0

JavaScript, la respuesta de fəˈnɛtɪk , 23 bytes

0n14

x=>14-`${73211e9}`[x]|0

Pruébalo en línea!

¿Cómo?

La expresión se `${73211e9}`expande a la cadena "73211000000000", proporcionando una tabla de búsqueda de 14 valores que se restan de 14, lo que da la secuencia esperada.

n14

(14 - undefined) | 0
=== NaN | 0
=== 0

21 bytes

NaNn14

x=>14-`${73211e9}`[x]

Pruébalo en línea!

Arnauld
fuente