El contador de bytes repetitivo


19

Su tarea es escribir un programa no vacío / función de la cuenta de bytes L , la cual, cuando se repite M veces, comprueba si un positivo dado número entero N es igual a L x M .

Debería, en teoría, admitir un número arbitrario de repeticiones (un valor entero positivo arbitrario de M ), pero está bien si, debido a las limitaciones del lenguaje, no puede funcionar por encima de un cierto umbral. Está estrictamente prohibido leer el código fuente de su programa o acceder a información al respecto .

Para proporcionar resultados, debe elegir un valor consistente para uno de los estados (verdadero o falso) y usar cualquier otro resultado posible (no necesariamente consistente) para el otro estado ( Discusión ).

Sus respuestas se puntuarán según la longitud L de su programa inicial (en bytes), con menos bytes mejor.

Ejemplo

Digamos que su programa (inicial) es ABCDE. Luego:

  • ABCDE(1 repetición) debe verificar si la entrada es igual a 5 .
  • ABCDEABCDE(2 repeticiones) debe verificar si la entrada es igual a 10 .
  • ABCDEABCDEABCDE(3 repeticiones) debe verificar si la entrada es igual a 15 . Etc ...

La puntuación de este código de muestra sería 5 , ya que la fuente inicial tiene 5 bytes de longitud.


Solo para aclarar: ¿el código fuente de longitud Lconcatenado después de sí mismo Mdebería devolver si su entrada Nes igual aL*M ?

Respuestas:


12

Gelatina , 1 byte

La salida es 0 para una coincidencia, no cero para una no coincidencia.

Pruébalo en línea!

Cómo funciona

Esto aprovecha el formato de salida excesivamente liberal. La repetición de M veces simplemente disminuye la entrada M veces, por lo que el resultado será cero si y solo si la entrada es LM , donde L = 1 .


Oh dios, no vi venir esto ... ( inb4 todos lo portan a otros esolangs ... )
Sr. Xcoder

Tenía una respuesta de 0 bytes en mente, pero, eh, quine . : P
Erik the Outgolfer

Mi primer pensamiento. Golpeado por 23 minutos :(
Khuldraeseth na'Barya

11

Haskell, 8 bytes

(-8+).id

Pruébalo en línea!

Como muchas otras respuestas, devuelve 0 para verdadero y no 0 para falso al restar repetidamente la longitud del código del número de entrada.


Estaba tan cerca de jugar para llegar a esto ...
totalmente humano

8

Retina , 21 20 bytes

\d+
*
^$
_
^_{20}

_

Pruébalo en línea! Simplemente repita la parte en la ventana Código para ver cómo maneja los múltiplos.

Da 0los enteros múltiples y positivos correctos para todo lo demás.

Explicación

Veamos primero el programa único:

\d+
*

Esto convierte un número decimal a unario (utilizando _como dígito unario).

^$
_

Si la cadena está vacía (lo que no puede suceder en este momento, porque se garantiza que la entrada sea positiva), la reemplazamos con una sola _.

^_{20}

Ahora nos deshacemos de los primeros 20 guiones bajos. Si la entrada fue 20, esto da como resultado una cadena vacía.

_

Y finalmente contamos el número de guiones bajos en el resultado, que es cero si la entrada fuera 20 .


Ahora, ¿qué sucede cuando repetimos el código fuente? Como no insertamos un salto de línea al unirnos a los programas, la primera línea irá directamente al final de la última línea, obtenemos esto cuando duplicamos el programa:

\d+
*
^$
_
^_{20}

_\d+
*
^$
_
^_{20}

_

Ahora, en lugar de contar los guiones bajos, terminamos con la siguiente etapa:

_\d+
*

Esta etapa no hace nada, porque no hay más dígitos en la cadena de trabajo en este punto, por lo que la expresión regular no puede coincidir.

^$
_

Ahora esta etapa se vuelve relevante. Si la entrada fue un múltiplo más pequeño de 20, la cadena se ha vaciado por la copia anterior del código fuente. En ese caso, lo convertimos en un solo guión bajo, que sabemos que nuestro programa nunca podrá volver a convertir en una cadena vacía. De esta manera nos aseguramos de que solo se acepte el M th múltiplo (y no todos los múltiplos hasta el M ª).

^_{20}

Eliminamos los primeros 20 guiones bajos una vez más. Entonces, M repeticiones del código fuente eliminarán 20M guiones bajos de la cadena, si es posible.

_

Y cuando llegamos al final del programa, todavía contamos los guiones bajos para que las entradas válidas den cero.


6

Fragmento de código de máquina x86 de 32 bits, 1 byte

48                      dec    eax

Entrada en EAX, salida en EAX: 0 para verdadero, no cero para falso. (También deja el indicador ZF establecido en verdadero, sin establecer en falso, para que pueda je was_equal). Como "bono", no tiene que preocuparse por la envoltura; El x86 de 32 bits solo puede direccionar 4GiB de memoria, por lo que no puede hacer que M sea lo suficientemente grande como para envolverlo todo y encontrar 1 == 2**32 + 1o algo así.

Para realizar una función invocable, agregue una 0xC3 retinstrucción después de repetir 0x48M veces. (No se cuenta en el recuento total, porque muchos idiomas necesitan repetir solo el cuerpo de la función, o una expresión, para poder competir).

Se puede comercializar desde GNU C con el prototipo __attribute__((regparm(1))) int checkeqM(int eax); de regparmatributo de función x86 de GNU C , como -mregparm, usa EAX para pasar el primer argumento entero.

Por ejemplo, este programa completo toma 2 args, y JITs M copias de la instrucción + a reten un búfer, y luego lo llama como una función. (Requiere montón ejecutable; compilar con gcc -O3 -m32 -z execstack)

/******* Test harness: JIT into a buffer and call it ******/
// compile with gcc -O3 -no-pie -fno-pie -m32 -z execstack
// or use mprotect or VirtualProtect instead of -z execstack
// or mmap(PROT_EXEC|PROT_READ|PROT_WRITE) instead of malloc

// declare a function pointer to a regparm=1 function
// The special calling convention applies to this function-pointer only
// So main() can still get its args properly, and call libc functions.
// unlike if you compile with -mregparm=1
typedef int __attribute__((regparm(1))) (*eax_arg_funcptr_t)(unsigned arg);

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    if (argc<3) return -1;
    unsigned N=strtoul(argv[1], NULL, 0), M = strtoul(argv[2], NULL, 0);

    char *execbuf = malloc(M+1);   // no error checking
    memset(execbuf, 0x48, M);     // times M  dec eax
    execbuf[M] = 0xC3;            // ret
    // Tell GCC we're about to run this data as code.  x86 has coherent I-cache,
    // but this also stops optimization from removing these as dead stores.
    __builtin___clear_cache (execbuf, execbuf+M+1);
     //   asm("" ::: "memory");  // compiler memory barrier works too.

    eax_arg_funcptr_t execfunc = (eax_arg_funcptr_t) execbuf;
    int res = execfunc(N);
    printf("%u == %u  =>  %d\n", N,M, res );
    return !!res;   // exit status only takes the low 8 bits of return value
}

los ejecutables que no son PIE se cargan más abajo en la memoria virtual; puede hacer un malloc contiguo más grande.

$ gcc -g -O3 -m32 -no-pie -fno-pie -fno-plt -z execstack coderepeat-i386.c
$ time ./a.out 2747483748 2747483748   # 2^31 + 600000100 is close to as big as we can allocate successfully
2747483748 == 2747483748  =>  0

real    0m1.590s     # on a 3.9GHz Skylake with DDR4-2666
user    0m0.831s
sys     0m0.755s

$ echo $?
0

 # perf stat output:
       670,816      page-faults               #    0.418 M/sec                  
 6,235,285,157      cycles                    #    3.885 GHz                    
 5,370,142,756      instructions              #    0.86  insn per cycle         

Tenga en cuenta que GNU C no admite tamaños de objeto mayores que ptrdiff_t(con signo de 32 bits), pero mallocymemset hacer aún el trabajo, por lo que este programa tiene éxito.

Fragmento de código de máquina ARM Thumb, 2 bytes

 3802            subs    r0, #2

El primer argumento de entrada r0y valor de retorno r0es la convención de llamada ARM estándar. Esto también establece banderas (el ssufijo). Hecho de la diversión; la no versión de establecer -flag desub es una instrucción de 32 bits de ancho.

La instrucción de devolución que debe agregar es bx lr .

Fragmento de código de máquina AArch64, 4 bytes

d1001000        sub     x0, x0, #0x4

Funciona para enteros de 64 bits. Entrada / salida enx0 , según la convención de llamada estándar. int64_t foo(uint64_t);

AArch64 no tiene un modo Thumb (todavía), por lo que 1 instrucción es lo mejor que podemos hacer.


Nota para cualquier persona que se encuentre con esto: la llamada a __builtin___clear_cachesolo es necesaria porque está ejecutando la memoria de la que recibió malloc. Si obtuviste la memoria mmap, la optimización no ocurre.
Joseph Sible: reinstala a Mónica el

4

V , 16 (o 1) bytes

Respuesta aburrida:

<C-x>

un byte

Respuesta menos aburrida:

uÓ^$/0
16Ø^a$

Pruébalo en línea!

Hexdump:

00000000: 75d3 5e24 2f30 0a31 3601 d85e 1261 240a  u.^$/0.16..^.a$.

De hecho, escribí esto unos 5 minutos después de que salió el desafío. Me tomó 30 minutos arreglar este horrible montón de código de espagueti que llamo un idioma .





2

Brain-Flak , 24 bytes

({}[(((()()()){}){}){}])

Pruébalo en línea!

Devuelve 0para igual y algo más para no igual.

Cómo funciona:

({} #pop the top of the stack
  [(((()()()){}){}){}] #subtract 24
) #push the result.

Los ntiempos de ejecución de este código se restarán n * 24de la entrada, dando 0 solo cuando la entrada = n*24.



2

TI-Basic (serie 83), 4 bytes

:Ans-4

Toma entrada Ans: por ejemplo, puede escribir 17:prgmCODEGOLFpara ejecutar esto con una entrada de 17. Imprime (y devuelve Ans) el valor 0si la entrada es igual a L × M , y un valor distinto de cero de lo contrario.

Tenga en cuenta que :es parte del código, por lo que si ingresa esto en el editor de programas, debería ver

PROGRAM:CODEGOLF
::Ans-4

si lo ingresas una vez y

PROGRAM:CODEGOLF
::Ans-4:Ans-4:An
s-4

si lo ingresas tres veces.



1

Befunge-98 , 15 bytes

]#<@.-&+
>fv
v+

Pruébalo en línea!

¡Pruébalo doblado!

Utiliza 0 para igual y cualquier otra cosa para desigual.

Explicación:

Este código repetido muchas veces se verá así:

]#<@.-&+
>fv
v+]#<@.-&+
>fv
v+]#<@.-&+
>fv
 .
 .
 .
v+]#<@.-&+
>fv
v+
  1. ]vuelta a la derecha. Envía la IP hacia abajo.

  2. >moverse hacia el este Envía el derecho de propiedad intelectual.

  3. f empujar un 16.

  4. vmoverse hacia el sur Envía la IP hacia abajo. Si es la última vez, vaya al paso 8.

  5. ]vuelta a la derecha. Envía la IP a la izquierda.

  6. +añadir. Agrega el 16 a la parte superior de la pila.

  7. vmoverse hacia el sur Envía la IP hacia abajo. Ir al paso 2.

  8. <moverse hacia el oeste Envía la IP a la izquierda.

  9. #omitir. salta sobre ]y envuélvete hasta el final.

  10. +añadir. Agrega el 16 a la parte superior de la pila.

  11. &entrada. Empuje un número del usuario.

  12. -sustraer. obtener la diferencia de suma en la que estábamos trabajando y la entrada.

  13. .impresión. Imprime el resultado.

  14. @ final.



1

Carbón , 13 bytes

PI⁼Iθ×¹³L⊞Oυω

Pruébalo en línea! Según mi respuesta a Doblo la fuente, ¡tú doblas la salida! Explicación:

         ⊞Oυω   Push empty string to predefined empty list
        L       Take the length
     ×¹³        Multiply by 13
  ⁼Iθ           Compare to the input
 I              Cast to string
P               Print without moving the cursor

Se las arregla para dar salida 1a la verdad y 0a la falsedad. Repeticiones posteriores comparan contra la entrada 13, 26, 39, 52etc, pero cada vez la respuesta se sobreimprime tan sólo se ve la respuesta final.


1

JavaScript ES6, 32 bytes

((f=k=>n=>n>0?n==k:f(k+32))(32))

si verdadero es 0 y falso como otros, 31 bytes

(f=k=>n=>n>0?n-k:_=>f(k+_))(31)

console.log([
    ((f=k=>n=>n>0?n==k:f(k+32))(32)) (31),
    ((f=k=>n=>n>0?n==k:f(k+32))(32)) (32),
    ((f=k=>n=>n>0?n==k:f(k+32))(32)) (33),
    ((f=k=>n=>n>0?n==k:f(k+32))(32)) (64),
    ((f=k=>n=>n>0?n==k:f(k+32))(32))((f=k=>n=>n>0?n==k:f(k+32))(32)) (32),
    ((f=k=>n=>n>0?n==k:f(k+32))(32))((f=k=>n=>n>0?n==k:f(k+32))(32)) (63),
    ((f=k=>n=>n>0?n==k:f(k+32))(32))((f=k=>n=>n>0?n==k:f(k+32))(32)) (64),
    ((f=k=>n=>n>0?n==k:f(k+32))(32))((f=k=>n=>n>0?n==k:f(k+32))(32))((f=k=>n=>n>0?n==k:f(k+32))(32)) (96)
]);


1

MIPS, 4 bytes

Usos $a0como argumento y valor de retorno.

0x2084fffc    addi $a0, $a0, -4

MIPS, 8 bytes (utilizando la convención de llamadas MIPS)

0x2084fff8    addi $a0, $a0, -8
0x00041021    move $v0, $a0

x86, 5 bytes

Esta es mi primera respuesta x86, por lo que sus comentarios son bienvenidos. Utiliza la convención _fastcall con ecx como primer argumento.

83 e9 05                sub    $0x5,%ecx
89 c8                   mov    %ecx,%eax

Peter Cordes tiene una solución de 1 byte en los comentarios.


Comentario Brainfuck : La parte difícil es conseguir que devuelva un solo valor. De lo contrario, algo como esto sería fácil.

- >,[-<->] < .

1
Su fragmento de código x86 sería del mismo tamaño para enteros de 32 bits, no es necesario limitarlo a 8. Pero si usara una convención de llamada personalizada (arg en AL, retval en otro lugar), podría usar el especial AL de 2 bytes codificación sub $4, %al/ mov %al, %dl. O aún regrese en AL / EAX y luego obtenga la solución de Dennis, con dec %eax(1 byte en modo de 32 bits). Y sí, las convenciones de llamadas personalizadas están bien para asm. Es asm, no solo "asm que es fácil llamar desde C"; el código real escrito en asm usa convenciones de llamadas personalizadas donde ayuda, por lo que esto es totalmente justificable.
Peter Cordes

1
La convención de llamada normal de ARM es el primer argumento en el r0que también es el retval, por lo que Thumb sub r0, #2es de 2 bytes.
Peter Cordes

1
Tenga en cuenta que ninguna de estas son funciones : requieren un retal final del bloque de repetición antes de que pueda llamarlas. Normalmente retincluyo los recuentos en bytes para mis respuestas asm x86. Pero creo que doblar las reglas aquí solo para el cuerpo de la función tiene sentido, de lo contrario, muchos lenguajes no pueden competir en absoluto.
Peter Cordes

1
(nvm, esto no deja el retval en% al). xchg %eax, %ecx/ sub $4, %al/ xchg %eax, %ecxEs de 4 bytes, y sigue la convención _fastcall. Usando AL, las codificaciones cortas imm8 y xchg-with-eax a menudo son útiles para el golf de código.
Peter Cordes

1
Usualmente uso objdump -drwC -Mintelpara obtener un hexadecimal de los bytes del código de máquina. add r32, imm8también es de 3 bytes: opcode + ModR / M + imm8. Todas las instrucciones que pueden tomar un imm32 tienen un código de operación alternativo que toma un imm8 con signo extendido. Ver felixcloutier.com/x86/ADD.html por ejemplo; Todas las instrucciones ALU "clásicas" (pero no MOV) que datan de 8086 tienen todas esas codificaciones, incluidas las AL / AX / EAX especiales sin modr / m, solo op + imm8 / 16/32. Esta respuesta tiene ejemplos
Peter Cordes

1

Octava: 23 bytes

+23;[ans,i]((N==ans)+1)

Si N = L * M, la expresión devuelve 0+i (es decir, un número puramente imaginario), de lo contrario, la expresión da como resultado un número complejo con un componente real.

Para obtener un resultado ligeramente más agradable a costa de un byte adicional:

+24;[ans,-1]((N==ans)+1)

Si N = L * M, la expresión devuelve -1 ; de lo contrario, un número positivo.

Manifestación:

N=48;
+24;[ans,-1]((N==ans)+1)                                                 #>> 24 
+24;[ans,-1]((N==ans)+1)+24;[ans,-1]((N==ans)+1)                         #>> -1
+24;[ans,-1]((N==ans)+1)+24;[ans,-1]((N==ans)+1)+24;[ans,-1]((N==ans)+1) #>> 23

PD, puedes obtener el mismo resultado con +24;if N==ans;-1;end;ans pero el bytecount es el mismo


1

Lua, 56 46 bytes

a=(a or io.read())-46io.write(a<=0 and a or"")

Emite un 0 (sin una nueva línea final) si es igual y nada o una serie de números negativos (con cero anterior en algunos casos) si no es igual.

Solo: ¡ Pruébelo en línea!

Repetido muchas veces: ¡ Pruébelo en línea!

Explicación

a=(a or io.read())-46

En la primera iteración (cuando aaún no se ha definido y, por lo tanto nil, está ), se establece aen un número tomado de la entrada, de lo contrario a sí mismo. En ambos casos, 46 se resta de a.

io.write(a<=0 and a or"")

Esto solo se imprime asi es menor que (para ocuparse de los casos en que la entrada fue mayor que la longitud total) o igual a cero, y la cadena vacía de lo contrario.

-10 bytes para recordar que Lua realiza conversiones entre números y cadenas automáticamente. Whoops


0

JavaScript (ES6), 47 bytes

Esto está utilizando la misma técnica que Benoit Esnard en esta respuesta (de doble de la fuente, ¡duplica la salida! ).

Imprime 0 si n = 47 * M , o un valor distinto de cero de lo contrario.

n=prompt(setTimeout`alert(n)`)-47/*
n-=47//*///

Demostración para M = 1

n=prompt(setTimeout`alert(n)`)-47/*
n-=47//*///

Demo para M = 2

n=prompt(setTimeout`alert(n)`)-47/*
n-=47//*///n=prompt(setTimeout`alert(n)`)-47/*
n-=47//*///


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.