O contador de bytes repetitivo

19

A sua tarefa é escrever um programa / função não-vazia de contagem de bytes G , que, quando utilizadas M vezes, verifica se um determinado número inteiro positivo N é igual a L x M .

Em teoria, você deve suportar um número arbitrário de repetições (um valor inteiro positivo arbitrário de M ), mas tudo bem se, devido a limitações de idioma, ele não puder funcionar acima de um determinado limite. É estritamente proibido ler o código fonte do seu programa ou acessar informações sobre ele .

Para fornecer saída, você deve escolher um valor consistente para um dos estados (verdadeiro ou falso) e usar qualquer outra saída possível (não necessariamente consistente) para o outro estado ( Discussão ).

Suas respostas serão pontuadas pelo comprimento L do seu programa inicial (em bytes), com menos bytes sendo melhores.

Exemplo

Digamos que seu programa (inicial) seja ABCDE. Então:

  • ABCDE(1 repetição) deve verificar se a entrada é igual a 5 .
  • ABCDEABCDE(2 repetições) deve verificar se a entrada é igual a 10 .
  • ABCDEABCDEABCDE(3 repetições) deve verificar se a entrada é igual a 15 . Etc ...

A pontuação desse código de exemplo seria 5 , pois a fonte inicial tem 5 bytes.

Mr. Xcoder
fonte
Apenas para esclarecer: o código-fonte de comprimento Lconcatenado após o Mtempo deve retornar se sua entrada Né igual aL*M ?

Respostas:

12

Geléia , 1 byte

A saída é 0 para uma correspondência, diferente de zero para uma não correspondência.

Experimente online!

Como funciona

Isso tira proveito do formato de saída excessivamente liberal. A repetição de tempos M simplesmente diminui os tempos M de entrada , de modo que o resultado será zero se e somente se a entrada for LM , onde L = 1 .

Dennis
fonte
Oh Deus, eu não vi isso vindo ... ( portos inb4 todos lo para outras esolangs ... )
Mr. Xcoder
Eu tinha uma resposta de 0 byte em mente, mas, eh, quine . : P
Erik the Outgolfer 23/03
Meu primeiro pensamento. Espancado por 23 minutos :(
Khuldraeseth na'Barya
11

Haskell, 8 bytes

(-8+).id

Experimente online!

Como muitas outras respostas, ele retorna 0 para verdade e não 0 para falsidade, subtraindo repetidamente o comprimento do código do número de entrada.

nimi
fonte
Eu estava tão perto de mexer com isso ...
totalmente humano
8

Retina , 21 20 bytes

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

_

Experimente online! Apenas repita a parte na janela Código para ver como ela lida com os múltiplos.

Fornece 0os inteiros múltiplos e positivos corretos para todo o resto.

Explicação

Vamos dar uma olhada no programa único primeiro:

\d+
*

Isso converte um número decimal em unário (usando _ como dígito unário).

^$
_

Se a sequência estiver vazia (o que não pode acontecer neste momento, porque a entrada é garantida como positiva), substituímos por uma única _ .

^_{20}

Agora nos livramos dos 20 primeiros sublinhados. Se a entrada foi20 , isso resulta em uma sequência vazia.

_

E, finalmente, contamos o número de sublinhados no resultado, que é zero se a entrada foi 20 .


Agora, o que acontece quando repetimos o código fonte. Como não inserimos um avanço de linha ao ingressar nos programas, a primeira linha irá para o final da última linha, obtemos isso quando o dobro do programa:

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

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

_

Agora, em vez de contar os sublinhados, terminamos com o seguinte estágio:

_\d+
*

Esse estágio não faz nada, porque não há mais dígitos na cadeia de trabalho nesse momento, portanto, a regex não pode corresponder.

^$
_

Agora, esse estágio se torna relevante. Se a entrada tiver um múltiplo menor de 20, a sequência será esvaziada pela cópia anterior do código-fonte. Nesse caso, nós o transformamos em um único sublinhado, que sabemos que nunca poderá ser transformado em uma sequência vazia novamente pelo nosso programa. Dessa forma, garantimos que apenas o M- múltiplo seja aceito (e nem todos os múltiplos até o M- ésimo).

^_{20}

Removemos os 20 primeiros sublinhados mais uma vez. Portanto, M repetições do código-fonte removerão 20 M de sublinhados da string, se possível.

_

E quando chegamos ao final do programa, ainda contamos sublinhados para que as entradas válidas dêem zero.

Martin Ender
fonte
6

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

48                      dec    eax

Entrada no EAX, saída no EAX: 0 para true, diferente de zero para false. (Também deixa o sinalizador ZF definido como verdadeiro, não definido como falso, para que você possaje was_equal ). Como um "bônus", você não precisa se preocupar com a embalagem; O x86 de 32 bits pode endereçar apenas 4GiB de memória, então você não pode fazer M grande o suficiente para envolver e encontrar 1 == 2**32 + 1algo assim.

Para criar uma função que pode ser chamada, anexe um 0xC3 ret instrução após repetir 0x48M vezes. (Não é contado na contagem total, porque muitas linguagens precisam repetir apenas o corpo da função, ou uma expressão, para poder competir).

Pode ser chamado do GNU C com o atributo de função x86 do protótipo __attribute__((regparm(1))) int checkeqM(int eax); GNU Cregparm , como -mregparm, usa EAX para passar o primeiro argumento inteiro.

Por exemplo, este programa completo leva 2 args e JITs M copia a instrução + a retem um buffer e a chama como uma função. (Requer heap executável; compile com 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
}

os executáveis ​​não PIE são carregados mais baixo na memória virtual; pode fazer um malloc contíguo maior.

$ 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         

Note-se que GNU C não suporta objeto tamanhos maiores do que ptrdiff_t(assinado de 32 bits), mas malloce memsetfazer ainda trabalho, então este programa bem-sucedido.

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

 3802            subs    r0, #2

O primeiro argumento de entrada r0e o valor de retorno r0é a convenção de chamada padrão do ARM. Isso também define sinalizadores (o ssufixo). Fato engraçado; o não versão de definição de -flag de subuma instrução de largura de 32 bits.

A instrução de retorno que você precisa anexar é bx lr .

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

d1001000        sub     x0, x0, #0x4

Funciona para números inteiros de 64 bits. Entrada / saída emx0 , conforme a convenção de chamada padrão. int64_t foo(uint64_t);

O AArch64 ainda não possui o modo Thumb, portanto, 1 instrução é a melhor que podemos fazer.

Peter Cordes
fonte
Nota para qualquer pessoa que se depare com isso: a chamada para __builtin___clear_cacheé necessária apenas porque você está executando a memória da qual obteve malloc. Se você obteve a memória mmap, a otimização não acontece.
Joseph Sible-Reinstate Monica
4

V , 16 (ou 1) bytes

Resposta chata:

<C-x>

um byte.

Resposta menos chata:

uÓ^$/0
16Ø^a$

Experimente online!

Hexdump:

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

Na verdade, eu escrevi isso cerca de 5 minutos após o desafio. Levei 30 minutos para consertar essa pilha horrível de código de espaguete que eu chamo de linguagem .

DJMcMayhem
fonte
3

Perl 5 -p , 6 bytes

$_-=6;

Experimente online!

usa 0para igual

Ton Hospel
fonte
1
Também uma -psolução Perl 6 válida .
Nwellnhof
2

Flak cerebral , 24 bytes

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

Experimente online!

Retorna 0para igual e outra coisa para não igual.

Como funciona:

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

Esse ntempo de execução do código subtrairá n * 24da entrada, fornecendo 0 somente quando a entrada = n*24.

MegaTom
fonte
2

TI-Basic (série 83), 4 bytes

:Ans-4

Recebe entrada Ans: por exemplo, você pode digitar 17:prgmCODEGOLFpara executá-lo com uma entrada de 17. Imprime (e retorna Ans) o valor 0se a entrada for igual a L × M e, caso contrário, um valor diferente de zero.

Observe que isso :faz parte do código; portanto, se você estiver inserindo isso no editor de programas, deverá ver

PROGRAM:CODEGOLF
::Ans-4

se você digitar uma vez e

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

se você digitar três vezes.

Misha Lavrov
fonte
1

Haskell , 12 bytes

(-)$0
 +12--

Experimente online!

Saídas 0 para verdade e algum número inteiro diferente de zero para falsidade.

Solução alternativa, 12 bytes

id
 .(-)12--

Experimente online!

totalmente humano
fonte
1

Befunge-98 , 15 bytes

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

Experimente online!

Experimente dobrou!

Usa 0 para igual e qualquer outra coisa para desigual.

Explicação:

Este código repetido várias vezes será algo como isto:

]#<@.-&+
>fv
v+]#<@.-&+
>fv
v+]#<@.-&+
>fv
 .
 .
 .
v+]#<@.-&+
>fv
v+
  1. ]vire à direita. Envia o IP para baixo.

  2. >mude para o leste. Envia o IP certo.

  3. f pressione 16.

  4. vmude para o sul. Envia o IP para baixo. Se for a última vez, vá para a etapa 8.

  5. ]vire à direita. Envia o IP para a esquerda.

  6. +adicionar. Adiciona os 16 ao topo da pilha.

  7. vmude para o sul. Envia o IP para baixo. Vá para a etapa 2.

  8. <mude para o oeste. Envie o IP para a esquerda.

  9. #pular. pule por cima ]e enrole até o fim.

  10. +adicionar. Adiciona os 16 ao topo da pilha.

  11. &entrada. Empurre um número do usuário.

  12. -subtrair. obtenha a diferença de soma em que estávamos trabalhando e a entrada.

  13. .impressão. Imprima o resultado.

  14. @ fim.

MegaTom
fonte
1

Carvão vegetal , 13 bytes

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

Experimente online!Com base na minha resposta para eu dobrar a fonte, você dobra a saída! Explicação:

         ⊞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

Gerencia a saída 1para verdade e 0falsidade. Repetições subsequentes comparar a contra a entrada 13, 26, 39,52 etc., mas cada vez que a resposta é sobreposta de modo somente a resposta final é visto.

Neil
fonte
1

JavaScript ES6, 32 bytes

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

se verdadeiro for 0 e falso como outros, 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)
]);

l4m2
fonte
1

MIPS, 4 bytes

Usa $a0como argumento e valor de retorno.

0x2084fffc    addi $a0, $a0, -4

MIPS, 8 bytes (usando a convenção de chamada MIPS)

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

x86, 5 bytes

Esta é a minha primeira resposta x86, por isso é bem-vindo. Usa a convenção _fastcall com ecx como primeiro argumento.

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

Peter Cordes tem uma solução de 1 byte nos comentários.


Comentário de Brainfuck : A parte difícil é fazer com que o cérebro retorne um único valor. Caso contrário, algo assim seria fácil.

- >,[-<->] < .
qwr
fonte
1
Seu fragmento de código x86 teria o mesmo tamanho para números inteiros de 32 bits, sem necessidade de limitar a 8. Mas se você usasse uma convenção de chamada personalizada (arg em AL, retval em outro lugar), poderia usar o AL especial de 2 bytes codificação sub $4, %al/ mov %al, %dl. Ou ainda retorne no AL / EAX e você terá a solução de Dennis com dec %eax(1 byte no modo de 32 bits). E sim, convenções de chamada personalizadas são adequadas para asm. É asm, não apenas "asm fácil de chamar de C"; O código real escrito em asm usa convenções de chamada personalizadas onde ajuda, portanto, isso é totalmente justificável.
Peter Cordes
1
A convenção de chamada normal do ARM é o primeiro argumento em r0que também é o retval; portanto, Thumb sub r0, #2tem 2 bytes.
Peter Cordes
1
Observe que nenhuma dessas funções é necessária: elas requerem um retno final do bloco de repetição antes que você possa chamá-las. Normalmente, incluo a retcontagem de bytes em minhas respostas x86 asm. Mas acho que fazer sentido dobrar as regras aqui apenas para o corpo da função faz sentido; caso contrário, muitas linguagens não podem competir.
Peter Cordes
1
(nvm, isso não deixa o retval em% al). xchg %eax, %ecx/ sub $4, %al/ xchg %eax, %ecxtem 4 bytes e segue a convenção _fastcall. Usando o AL, as codificações curtas imm8 e xchg-with-eax geralmente são úteis para o código de golfe.
Peter Cordes
1
Eu costumo usar objdump -drwC -Mintelpara obter um hexdump dos bytes de código de máquina. add r32, imm8também é de 3 bytes: opcode + ModR / M + imm8. Todas as instruções que podem receber um imm32 possuem um código de operação alternativo que aceita um imm8 com extensão de sinal. Veja felixcloutier.com/x86/ADD.html por exemplo; todas as instruções ALU "clássicas" (mas não MOV) que datam de 8086 têm todas essas codificações, incluindo as AL / AX / EAX especiais sem modr / m, apenas op + imm8 / 16/32. Esta resposta tem exemplos
Peter Cordes
1

Oitava: 23 bytes

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

Se N = L * M, a expressão retorna 0+i(ou seja, um número puramente imaginário), caso contrário, a expressão resulta em um número complexo com um componente real.

Para um resultado um pouco melhor, com o custo de um byte extra:

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

Se N = L * M, a expressão retornará -1 , caso contrário, um número positivo.

Demo:

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

PS, você pode obter o mesmo resultado, +24;if N==ans;-1;end;ansmas o número de bytes é o mesmo

Tasos Papastylianou
fonte
1

Lua, 56 46 bytes

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

Emite um 0 (sem uma nova linha à direita) se for igual e nada ou uma série de números negativos (com zero precedente em alguns casos) se não for igual.

Sozinho: Experimente online!

Repetidas várias vezes: Experimente online!

Explicação

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

Na primeira iteração (quando aainda não foi definido e, portanto nil, é ), define acomo um número obtido da entrada, caso contrário, para si próprio. Nos dois casos, 46 é subtraído de a.

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

Isso apenas imprime ase for menor que (para cuidar de casos em que a entrada foi maior que o comprimento total) ou igual a zero e a string vazia, caso contrário.

-10 bytes para lembrar que Lua faz conversões entre números e seqüências de caracteres automaticamente. Ops.

ivzem
fonte
0

JavaScript (ES6), 47 bytes

Esta é usando a mesma técnica que Benoit Esnard em esta resposta (de I dobrar a fonte, você dobrar a produção! ).

Imprime 0 se n = 47 * M , ou um valor diferente de zero.

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

Demonstração para M = 1

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

Demonstração para M = 2

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

Arnauld
fonte
0

Flak cerebral , 24 bytes

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

Experimente online!

Apenas subtrai 24 da entrada. Saídas 0para true e qualquer outra coisa para false.

Flak cerebral , 68 bytes

{<>}<>(({}[((((()()()()){}){}()){}){}])<>{})((){[()](<{}<>>)}{}<>{})

Experimente online!

Este é mais sofisticado que gera 1para verdadeiro e 0para falso.

Assistente de Trigo
fonte