Il contatore di byte ripetitivi


19

Il vostro compito è quello di scrivere un programma non vuoto / funzione del numero di byte L , che, quando utilizzate M volte, controlla se un dato intero positivo N è uguale a L × M .

In teoria, dovresti supportare un numero arbitrario di ripetizioni (un valore intero positivo arbitrario di M ), ma va bene se, a causa delle limitazioni del linguaggio, non può funzionare oltre una certa soglia. È severamente vietato leggere il codice sorgente del programma o accedere a informazioni al riguardo .

Per fornire un output, è necessario scegliere un valore coerente per uno degli stati (sia vero che falso) e utilizzare qualsiasi altro output possibile (non necessariamente coerente) per l'altro stato ( Discussione ).

Le risposte verranno assegnate in base alla lunghezza L (in byte) del programma iniziale , con meno byte migliori.

Esempio

Supponiamo che il tuo programma (iniziale) sia ABCDE. Poi:

  • ABCDE(1 ripetizione) dovrebbe verificare se l'ingresso è uguale a 5 .
  • ABCDEABCDE(2 ripetizioni) dovrebbe verificare se l'ingresso è uguale a 10 .
  • ABCDEABCDEABCDE(3 ripetizioni) dovrebbe verificare se l'ingresso è uguale a 15 . Eccetera...

Il punteggio di questo codice di esempio sarebbe 5 , poiché l'origine iniziale è lunga 5 byte.


Giusto per chiarire: il codice sorgente della lunghezza Lconcatenato dopo i Mtempi stessi dovrebbe restituire se il suo input Nè uguale aL*M ?

Risposte:


12

Gelatina , 1 byte

L'output è 0 per una corrispondenza, diverso da zero per una non corrispondenza.

Provalo online!

Come funziona

Questo sfrutta il formato di output eccessivamente liberale. Ripetendo M volte semplicemente diminuisce l'ingresso M volte, quindi il risultato sarà zero se e solo se l'ingresso è LM , dove L = 1 .


Oddio non l'ho visto arrivare ... ( inb4 tutti lo portano ad altri esolang ... )
Mr. Xcoder

Avevo in mente una risposta di 0 byte, ma, eh, quine . : P
Erik the Outgolfer

Il mio primo pensiero. Battuto per 23 minuti :(
Khuldraeseth na'Barya il

11

Haskell, 8 byte

(-8+).id

Provalo online!

Come molte altre risposte, restituisce 0 per verità e non 0 per falsità sottraendo ripetutamente la lunghezza del codice dal numero di input.


Ero così vicino a armeggiare per arrivare a questo ...
totalmente umano il

8

Retina , 21 20 byte

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

_

Provalo online! Basta ripetere la parte nella finestra del codice per vedere come gestisce i multipli.

Fornisce 0numeri interi multipli e positivi corretti per tutto il resto.

Spiegazione

Diamo un'occhiata prima al programma singolo:

\d+
*

Questo converte un numero decimale in unario (usando _come cifra unaria).

^$
_

Se la stringa è vuota (cosa che non può succedere a questo punto, perché si garantisce che l'input sia positivo), la sostituiamo con una singola _.

^_{20}

Ora ci liberiamo dei primi 20 caratteri di sottolineatura. Se l'input era 20, questo risulta in una stringa vuota.

_

E infine contiamo il numero di caratteri di sottolineatura nel risultato, che è zero se fosse l'input 20.


Ora cosa succede quando ripetiamo il codice sorgente. Dal momento che non inseriamo un avanzamento di riga quando ci uniamo ai programmi, la prima riga andrà proprio alla fine dell'ultima riga, otteniamo questo quando il doppio del programma:

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

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

_

Ora invece di contare i trattini bassi, finiamo con la seguente fase:

_\d+
*

Questa fase non fa nulla, perché a questo punto non ci sono più cifre nella stringa di lavoro, quindi la regex non può corrispondere.

^$
_

Ora questa fase diventa rilevante. Se l'input era un multiplo più piccolo di 20, la stringa è stata svuotata dalla copia precedente del codice sorgente. In tal caso, lo trasformiamo in un singolo trattino di sottolineatura, che sappiamo che non potrà mai più essere trasformato in una stringa vuota dal nostro programma. In questo modo ci assicuriamo che sia accettato solo il M multiplo (e non tutti i multipli fino al M th).

^_{20}

Rimuoviamo ancora una volta i primi 20 caratteri di sottolineatura. Quindi M ripetizioni del codice sorgente rimuoveranno 20 M trattini bassi dalla stringa, se possibile.

_

E quando arriviamo alla fine del programma, contiamo ancora i trattini bassi in modo che gli input validi diano zero.


6

frammento di codice macchina x86 a 32 bit, 1 byte

48                      dec    eax

Input in EAX, output in EAX: 0 per vero, diverso da zero per falso. (Inoltre, lascia il flag ZF impostato su true, non impostato su false, quindi è possibile je was_equal). Come "bonus", non devi preoccuparti di avvolgere; L'x86 a 32 bit può indirizzare solo 4GiB di memoria, quindi non puoi rendere M abbastanza grande da avvolgere completamente e trovare 1 == 2**32 + 1o qualcosa del genere.

Per rendere una funzione richiamabile, aggiungere 0xC3 retun'istruzione dopo aver ripetuto 0x48M volte. (Non conteggiato nel conteggio totale, perché molte lingue devono ripetere solo il corpo della funzione, o un'espressione, per poter competere).

Chiamabile da GNU C con il prototipo dell'attributo della funzione x86 di __attribute__((regparm(1))) int checkeqM(int eax); GNU Cregparm , come -mregparm, usa EAX per passare il primo numero intero arg.

Ad esempio, questo programma completo accetta 2 arg e JITs M copia l'istruzione + a retin un buffer e quindi lo chiama come funzione. (Richiede heap eseguibile; compilare 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
}

gli eseguibili non PIE vengono caricati più in basso nella memoria virtuale; può fare un malloc contiguo più 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         

Si noti che GNU C non supporta oggetti di dimensioni superiori a ptrdiff_t(segno a 32 bit), ma malloce memsetfare ancora lavoro, quindi questo programma ha successo.

Frammento di codice macchina pollice ARM, 2 byte

 3802            subs    r0, #2

Il primo argomento in r0e il valore restituito in r0è la convenzione di chiamata ARM standard. Questo imposta anche flag (il ssuffisso). Fatto divertente; la versione non -flag di subè un'istruzione larga a 32 bit.

L'istruzione di ritorno che devi aggiungere è bx lr.

Frammento di codice macchina AArch64, 4 byte

d1001000        sub     x0, x0, #0x4

Funziona con numeri interi a 64 bit. Ingresso / uscita in x0, secondo la convenzione di chiamata standard. int64_t foo(uint64_t);

AArch64 non ha una modalità Thumb (ancora), quindi 1 istruzione è la migliore che possiamo fare.


Nota per chiunque si imbatta in questo: la chiamata a __builtin___clear_cacheè necessaria solo perché stai eseguendo la memoria che hai ricevuto malloc. Se invece si ottiene la memoria mmap, l'ottimizzazione non avviene.
Joseph Sible: ripristina Monica il

4

V , 16 (o 1) byte

Risposta noiosa:

<C-x>

un byte.

Risposta meno noiosa:

uÓ^$/0
16Ø^a$

Provalo online!

hexdump:

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

In realtà l'ho scritto circa 5 minuti dopo l'uscita della sfida. Mi ci sono voluti 30 minuti per rattoppare questo orribile mucchio di codice spaghetti che io chiamo una lingua .





2

Brain-Flak , 24 byte

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

Provalo online!

ritorna 0 per uguale e qualcos'altro per non uguale.

Come funziona:

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

Questo ntempo di esecuzione del codice verrà sottratto n * 24dall'input, dando 0 solo quando input = n*24.



2

TI-Basic (serie 83), 4 byte

:Ans-4

Accetta input Ans: ad esempio, potresti digitare 17:prgmCODEGOLFper eseguirlo con un input di 17. Stampa (e restituisce Ans) il valore 0se l'ingresso è uguale a L × M e un valore diverso da zero in caso contrario.

Nota che :fa parte del codice, quindi se stai inserendo questo nell'editor del programma, dovresti vedere

PROGRAM:CODEGOLF
::Ans-4

se lo inserisci una volta e

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

se lo inserisci tre volte.



1

Befunge-98 , 15 byte

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

Provalo online!

Provalo raddoppiato!

Usa 0 per uguale e qualsiasi altra cosa per disuguale.

Spiegazione:

Questo codice ripetuto più volte sarà simile al seguente:

]#<@.-&+
>fv
v+]#<@.-&+
>fv
v+]#<@.-&+
>fv
 .
 .
 .
v+]#<@.-&+
>fv
v+
  1. ]svolta a destra. Invia l'IP verso il basso.

  2. >spostati ad est. Invia l'IP giusto.

  3. f spingere un 16.

  4. vspostati a sud. Invia l'IP verso il basso. Se questa è l'ultima volta, vai al passaggio 8.

  5. ]svolta a destra. Invia l'IP rimasto.

  6. +Inserisci. Aggiunge il 16 in cima alla pila.

  7. vspostati a sud. Invia l'IP verso il basso. Vai al passaggio 2.

  8. <spostati a ovest. Invia l'IP a sinistra.

  9. #Salta. saltare sopra ]e avvolgere fino alla fine.

  10. +Inserisci. Aggiunge il 16 in cima alla pila.

  11. &ingresso. Invia un numero dall'utente.

  12. -sottrarre. ottenere la differenza di somma su cui stavamo lavorando e l'input.

  13. .Stampa. Stampa il risultato.

  14. @ fine.



1

Carbone , 13 byte

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

Provalo online! Sulla base della mia risposta per raddoppiare la fonte, raddoppi l'output! Spiegazione:

         ⊞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

Riesce a produrre 1per verità e 0falsità. Successive ripetizioni confrontare l'ingresso contro 13, 26, 39, 52ecc ma ogni volta la risposta è sovrastampato soltanto la risposta finale è visto.


1

JavaScript ES6, 32 byte

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

se vero è 0 e falso come altri, 31 byte

(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 byte

Utilizza $a0come argomento e valore restituito.

0x2084fffc    addi $a0, $a0, -4

MIPS, 8 byte (utilizzando la convenzione di chiamata MIPS)

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

x86, 5 byte

Questa è la mia prima risposta x86 quindi benvenuti feedback. Utilizza la convenzione _fastcall con ecx come primo argomento.

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

Peter Cordes ha una soluzione da 1 byte nei commenti.


Commento di Brainfuck : la parte difficile è ottenere brainfuck per restituire un singolo valore. Altrimenti qualcosa del genere sarebbe facile.

- >,[-<->] < .

1
Il tuo frammento di codice x86 avrebbe le stesse dimensioni per numeri interi a 32 bit, non è necessario limitare a 8. Ma se hai usato una convenzione di chiamata personalizzata (arg in AL, retval da qualche altra parte), potresti usare lo speciale AL a 2 byte codifica sub $4, %al/ mov %al, %dl. O ancora tornare in AL / EAX e quindi ottenere la soluzione di Dennis, con dec %eax(1 byte in modalità 32 bit). E sì, le convenzioni di chiamata personalizzate vanno bene per asm. È asm, non solo "asm che è facile da chiamare da C"; il vero codice scritto in asm usa convenzioni di chiamata personalizzate dove aiuta, quindi questo è totalmente giustificabile.
Peter Cordes,

1
La normale convenzione di chiamata di ARM è il primo argomento in r0cui è anche il valore di retval, quindi il pollice sub r0, #2è di 2 byte.
Peter Cordes,

1
Nota che nessuna di queste sono funzioni : richiedono una retfine del blocco di ripetizione prima di poterle chiamare. Normalmente includo i retconteggi in byte per le mie risposte asm x86. Ma penso che piegare le regole qui solo al corpo della funzione abbia un senso, altrimenti molte lingue non possono competere affatto.
Peter Cordes,

1
(nvm, questo non lascia il retval in% al). xchg %eax, %ecx/ sub $4, %al/ xchg %eax, %ecxè di 4 byte e segue la convenzione _fastcall. L'uso delle codifiche corte AL, imm8 e xchg-with-eax sono spesso utili per il golf del codice.
Peter Cordes,

1
Di solito lo uso objdump -drwC -Mintelper ottenere un hexdump dei byte del codice macchina. add r32, imm8è anche 3 byte: opcode + ModR / M + imm8. Tutte le istruzioni che possono prendere un imm32 hanno un codice operativo alternativo che accetta un imm8 con segno esteso. Vedi ad esempio felixcloutier.com/x86/ADD.html ; tutte le istruzioni ALU "classiche" (ma non MOV) risalenti all'8086 hanno tutte quelle codifiche, comprese quelle speciali AL / AX / EAX senza modr / m, solo op + imm8 / 16/32. Questa risposta ha degli esempi
Peter Cordes,

1

Ottava: 23 byte

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

Se N = L * M, l'espressione ritorna 0+i(cioè un numero puramente immaginario), altrimenti l'espressione si traduce in un numero complesso con un componente reale.

Per un risultato leggermente migliore al costo di un byte extra:

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

Se N = L * M l'espressione ritorna -1, altrimenti un numero 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, puoi ottenere lo stesso risultato con +24;if N==ans;-1;end;ansma il bytecount è lo stesso


1

Lua, 56 46 byte

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

Emette uno 0 (senza una nuova riga finale) se uguale e niente o una serie di numeri negativi (con lo zero precedente in alcuni casi) se non uguale.

Da solo: provalo online!

Ripetuto più volte: provalo online!

Spiegazione

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

Alla prima iterazione (quando anon è stato ancora definito ed è quindi nil), imposta aun numero preso dall'input, altrimenti a se stesso. In entrambi i casi, viene quindi sottratto 46a .

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

Questo stampa e basta a se è inferiore a (per occuparsi dei casi in cui l'input era maggiore della lunghezza totale) o uguale a zero, e altrimenti la stringa vuota.

-10 byte per ricordare che Lua esegue automaticamente le conversioni tra numeri e stringhe. Ops.


0

JavaScript (ES6), 47 byte

Questo sta usando la stessa tecnica di Benoit Esnard in questa risposta (da quando raddoppio la fonte, raddoppi l'output! ).

Stampa 0 se n = 47 * M , o altrimenti un valore diverso da zero.

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

Demo per M = 1

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

Demo per M = 2

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


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.