Der Zähler für sich wiederholende Bytes


19

Ihre Aufgabe ist es, ein nicht leeres Programm / eine nicht leere Funktion mit der Bytezahl L zu schreiben , die bei M- maliger Wiederholung prüft, ob eine gegebene positive ganze Zahl N gleich L × M ist .

Theoretisch sollten Sie eine beliebige Anzahl von Wiederholungen unterstützen (ein beliebiger positiver ganzzahliger Wert von M ), aber es ist in Ordnung, wenn es aufgrund von Spracheinschränkungen nicht über einen bestimmten Schwellenwert funktionieren kann. Das Lesen des Quellcodes Ihres Programms oder der Zugriff auf Informationen darüber ist strengstens untersagt .

Für die Ausgabe sollten Sie einen konsistenten Wert für einen der Zustände (entweder wahr oder falsch) auswählen und einen anderen (nicht unbedingt konsistenten) möglichen Wert für den anderen Zustand verwenden ( Diskussion ).

Ihre Antworten werden mit der Länge L (in Bytes) Ihres Anfangsprogramms bewertet, wobei weniger Bytes besser sind.

Beispiel

Nehmen wir an, Ihr (erstes) Programm ist ABCDE. Dann:

  • ABCDE(1 Wiederholung) sollte prüfen, ob der Eingang gleich 5 ist .
  • ABCDEABCDE(2 Wiederholungen) sollten prüfen, ob die Eingabe gleich 10 ist .
  • ABCDEABCDEABCDE(3 Wiederholungen) sollten prüfen, ob die Eingabe gleich 15 ist . Etc...

Die Bewertung dieses Beispielcodes wäre 5 , da die ursprüngliche Quelle 5 Byte lang ist.


Nur zur Verdeutlichung: Quellcode der Länge Lverkettet nach sich selbst soll Mmal zurückliefern, ob seine Eingabe Ngleich istL*M ?

Antworten:


12

Gelee , 1 Byte

Die Ausgabe ist 0 für eine Übereinstimmung, ungleich Null für eine Nichtübereinstimmung.

Probieren Sie es online!

Wie es funktioniert

Dies macht sich das zu liberale Ausgabeformat zunutze. Das M- fache Wiederholen dekrementiert einfach das M- fache der Eingabe , sodass das Ergebnis genau dann Null ist, wenn die Eingabe LM ist , wobei L = 1 ist .


Oh Gott, ich habe das nicht kommen sehen ... ( inb4 portiert es jeder zu anderen Esolangs ... )
Mr. Xcoder

Ich hatte eine 0-Byte-Antwort im Hinterkopf, aber wie gesagt . : P
Erik der Outgolfer

Mein erster Gedanke. 23 Minuten geschlagen :(
Khuldraeseth na'Barya

11

Haskell, 8 Bytes

(-8+).id

Probieren Sie es online!

Wie bei vielen anderen Antworten wird 0 für Wahrheit und Nicht-0 für Falschheit zurückgegeben, indem die Länge des Codes wiederholt von der eingegebenen Zahl subtrahiert wird.


Ich war so nahe dran, daran zu basteln ...
totalhuman

8

Netzhaut , 21 bis 20 Bytes

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

_

Probieren Sie es online! Wiederholen Sie einfach den Teil im Codefenster , um zu sehen, wie er mit den Vielfachen umgeht.

Gibt 0für alles andere die richtigen multiplen und positiven ganzen Zahlen an.

Erläuterung

Schauen wir uns zuerst das einzelne Programm an:

\d+
*

Dadurch wird eine Dezimalzahl in eine unäre Zahl umgewandelt (wobei _als unäre Ziffer verwendet wird).

^$
_

Wenn der String leer ist (was an dieser Stelle nicht passieren kann, da die Eingabe garantiert positiv ist), ersetzen wir ihn durch einen einzelnen _.

^_{20}

Jetzt werden die ersten 20 Unterstriche entfernt. Wenn die Eingabe nicht erfolgreich war 20, wird eine leere Zeichenfolge angezeigt.

_

Und schließlich zählen wir die Anzahl der Unterstriche im Ergebnis, die Null ist, wenn die Eingabe war 20.


Was passiert nun, wenn wir den Quellcode wiederholen? Da wir beim Verbinden der Programme keinen Zeilenvorschub einfügen, wird die erste Zeile direkt am Ende der letzten Zeile eingefügt. Dies erhalten wir, wenn das Programm verdoppelt wird:

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

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

_

Anstatt nun die Unterstriche zu zählen, erhalten wir die folgende Stufe:

_\d+
*

Diese Phase führt zu nichts, da sich zu diesem Zeitpunkt keine weiteren Ziffern in der Arbeitszeichenfolge befinden, sodass der reguläre Ausdruck nicht übereinstimmen kann.

^$
_

Jetzt wird diese Phase relevant. Wenn die Eingabe ein kleineres Vielfaches von 20 war, wurde die Zeichenfolge durch die vorherige Kopie des Quellcodes geleert. In diesem Fall verwandeln wir es in einen einzelnen Unterstrich, von dem wir wissen, dass er von unserem Programm nie wieder in einen leeren String umgewandelt werden kann. Auf diese Weise stellen wir sicher, dass nur das M- te Vielfache akzeptiert wird (und nicht alle Vielfachen bis zum M- ten).

^_{20}

Wir entfernen die ersten 20 Unterstriche noch einmal. Daher werden bei M- Wiederholungen des Quellcodes nach Möglichkeit 20 Millionen Unterstriche aus dem String entfernt.

_

Und wenn wir am Ende des Programms angelangt sind, zählen wir immer noch Unterstriche, sodass gültige Eingaben Null ergeben.


6

x86 32-Bit-Maschinencodefragment, 1 Byte

48                      dec    eax

Eingabe in EAX, Ausgabe in EAX: 0 für wahr, ungleich Null für falsch. (Lässt auch das ZF-Flag auf true gesetzt, nicht auf false gesetzt, damit Sie es tun können je was_equal). Als "Bonus" müssen Sie sich keine Sorgen um die Verpackung machen. 32-Bit x86 kann nur 4 GB Arbeitsspeicher adressieren, sodass Sie M nicht groß genug machen können, um den gesamten Weg zu umschließen und 1 == 2**32 + 1etwas zu finden oder so.

Um eine aufrufbare Funktion zu erstellen, fügen Sie eine 0xC3 retAnweisung hinzu, nachdem Sie 0x48M-mal wiederholt haben. (Wird in der Gesamtzahl nicht mitgezählt, da viele Sprachen nur den Funktionskörper oder einen Ausdruck wiederholen müssen, um konkurrieren zu können.)

Calleable aus GNU C mit dem Prototyp __attribute__((regparm(1))) int checkeqM(int eax); GNU C der regparmx86 Funktionsattribut , wie -mregparmverwendet EAX die erste Ganzzahl Arg- passieren.

Dieses vollständige Programm nimmt beispielsweise 2 Argumente und JITs M Kopien der Anweisung + a retin einen Puffer und ruft sie dann als Funktion auf. (Erfordert einen ausführbaren Heap; Kompilieren mit 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
}

Nicht-PIE-ausführbare Dateien werden im virtuellen Speicher niedriger geladen. kann ein größeres zusammenhängendes malloc tun.

$ 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         

Beachten Sie, dass GNU C nicht unterstützen Objektgrößen größer als ptrdiff_t(32-Bit unterzeichnet), aber mallocund memsetimmer noch arbeiten, so dass dieses Programm erfolgreich ist .

ARM Thumb-Maschinencodefragment, 2 Bytes

 3802            subs    r0, #2

Das erste Argument r0und der Rückgabewert in r0sind die Standardkonventionen für ARM-Aufrufe. Dies setzt auch Flags (das sSuffix). Lustige Tatsache; Die Version ohne Flags subist eine 32-Bit-Anweisung.

Die Rückgabeanweisung, die Sie anhängen müssen, lautet bx lr.

AArch64-Maschinencodefragment, 4 Bytes

d1001000        sub     x0, x0, #0x4

Funktioniert für 64-Bit-Ganzzahlen. Eingabe / Ausgabe in x0Übereinstimmung mit der Standardaufrufkonvention. int64_t foo(uint64_t);

AArch64 hat (noch) keinen Thumb-Modus, daher ist 1 Befehl das Beste, was wir tun können.


Hinweis für alle anderen, die dies bemerken: Der Aufruf an __builtin___clear_cacheist nur erforderlich, weil Sie den Speicher ausführen, von dem Sie Daten erhalten haben malloc. Wenn Sie mmapstattdessen den Speicher abgerufen haben, findet die Optimierung nicht statt.
Joseph Sible-Reinstate Monica

4

V , 16 (oder 1) Bytes

Langweilige Antwort:

<C-x>

ein Byte.

Weniger langweilige Antwort:

uÓ^$/0
16Ø^a$

Probieren Sie es online!

Hexdump:

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

Ich schrieb dies ungefähr 5 Minuten nachdem die Herausforderung herauskam. Ich brauchte 30 Minuten, um diesen schrecklichen Haufen Spaghetti-Code zu flicken, den ich eine Sprache nenne .





2

Brain-Flak , 24 Bytes

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

Probieren Sie es online!

Gibt 0für gleich und etwas anderes für nicht gleich zurück.

Wie es funktioniert:

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

Diese Code-Laufzeiten nwerden n * 24von der Eingabe abgezogen und geben nur dann 0, wenn die Eingabe = n*24.



2

TI-Basic (Serie 83), 4 Byte

:Ans-4

Nimmt Eingaben auf Ans: Sie könnten beispielsweise eingeben 17:prgmCODEGOLF, um dies mit einer Eingabe von auszuführen 17. Gibt Ansden Wert aus (und zurück ), 0wenn die Eingabe gleich L × M ist , andernfalls einen Wert ungleich Null.

Beachten Sie, dass dies :Teil des Codes ist. Wenn Sie dies also in den Programmeditor eingeben, sollten Sie dies sehen

PROGRAM:CODEGOLF
::Ans-4

wenn Sie es einmal eingeben und

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

wenn Sie es dreimal eingeben.



1

Befunge-98 , 15 Bytes

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

Probieren Sie es online!

Probieren Sie es doppelt aus!

Verwendet 0 für gleich und alles andere für ungleich.

Erläuterung:

Dieser Code, der viele Male wiederholt wird, sieht ungefähr so ​​aus:

]#<@.-&+
>fv
v+]#<@.-&+
>fv
v+]#<@.-&+
>fv
 .
 .
 .
v+]#<@.-&+
>fv
v+
  1. ]Rechtskurve. Sendet die IP nach unten.

  2. >bewege dich nach Osten. Sendet die IP richtig.

  3. f Drücke eine 16.

  4. vbewege dich nach Süden. Sendet die IP nach unten. Wenn dies das letzte Mal ist, fahren Sie mit Schritt 8 fort.

  5. ]Rechtskurve. Sendet die IP links.

  6. +hinzufügen. Fügt die 16 oben im Stapel hinzu.

  7. vbewege dich nach Süden. Sendet die IP nach unten. Weiter zu Schritt 2.

  8. <bewege dich nach Westen. Sende die IP links.

  9. #überspringen. überspringen ]und bis zum Ende umwickeln.

  10. +hinzufügen. Fügt die 16 oben im Stapel hinzu.

  11. &Eingang. Schieben Sie eine Nummer vom Benutzer.

  12. -subtrahieren. Ermitteln Sie die Differenz aus der Summe, an der wir gearbeitet haben, und der Eingabe.

  13. .drucken. Drucken Sie das Ergebnis.

  14. @ Ende.



1

Kohle , 13 Bytes

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

Probieren Sie es online! Basierend auf meiner Antwort, dass ich die Quelle verdopple, verdoppeln Sie die Ausgabe! Erläuterung:

         ⊞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

Verwaltet die Ausgabe 1für wahr und 0falsch. Nachfolgende Wiederholungen vergleichen den Eingang vor 13, 26, 39, 52etc. , aber jedes Mal die Antwort überdruckt , so dass nur die endgültige Antwort ist zu sehen.


1

JavaScript ES6, 32 Bytes

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

wenn wahr ist 0 und falsch wie andere, 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

Verwendet $a0als Argument und Rückgabewert.

0x2084fffc    addi $a0, $a0, -4

MIPS, 8 Bytes (unter Verwendung der MIPS-Aufrufkonvention)

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

x86, 5 Bytes

Dies ist meine erste x86-Antwort. Feedback ist also willkommen. Verwendet die _fastcall-Konvention mit ecx als erstes Argument.

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

Peter Cordes hat eine 1-Byte-Lösung in den Kommentaren.


Brainfuck-Kommentar : Der schwierige Teil ist, Brainfuck dazu zu bringen, einen einzelnen Wert zurückzugeben. Sonst wäre so etwas einfach.

- >,[-<->] < .

1
Ihr x86-Codefragment hat dieselbe Größe für 32-Bit-Ganzzahlen, ohne dass eine Beschränkung auf 8 erforderlich ist. Wenn Sie jedoch eine benutzerdefinierte Aufrufkonvention (arg in AL, retval an einer anderen Stelle) verwenden, können Sie das 2-Byte-AL-Spezial verwenden codieren sub $4, %al/ mov %al, %dl. Oder kehren Sie immer noch in AL / EAX zurück und Sie erhalten Dennis 'Lösung mit dec %eax(1 Byte im 32-Bit-Modus). Und ja, benutzerdefinierte Anrufkonventionen sind für asm in Ordnung. Es ist asm, nicht nur "asm, das von C aus einfach aufzurufen ist"; Realer Code, der in asm geschrieben wurde, verwendet benutzerdefinierte Aufrufkonventionen, wenn dies hilfreich ist. Dies ist also durchaus vertretbar.
Peter Cordes

1
Die normale Aufrufkonvention von ARM lautet first arg, r0wobei es sich auch um das Retval handelt. Thumb sub r0, #2ist also 2 Byte.
Peter Cordes

1
Beachten Sie, dass keine dieser Funktionen : Sie benötigen ein retam Ende des Wiederholungsblocks, bevor Sie sie aufrufen können. Normalerweise beziehe ich die Anzahl der retin Bytes für meine x86-ASM-Antworten ein. Aber ich denke , die Regeln hier nur die Funktion Biegekörper Sinn macht, sonst viele Sprachen überhaupt nicht konkurrieren können.
Peter Cordes

1
(nvm, dabei bleibt das Retval nicht in% al). xchg %eax, %ecx/ sub $4, %al/ xchg %eax, %ecx4 Bytes ist , und folgt die _fastcall Konvention. Bei der Verwendung von AL sind imm8- und xchg-with-eax-Kurzcodierungen häufig hilfreich für Code-Golf.
Peter Cordes

1
Normalerweise verwende ich objdump -drwC -Mintel, um einen Hexdump der Maschinencode-Bytes zu erhalten. add r32, imm8ist auch 3 Bytes: Opcode + ModR / M + imm8. Alle Befehle, die eine imm32 annehmen können, haben einen alternativen Opcode, der eine vorzeichenerweiterte imm8 annimmt. Siehe zum Beispiel felixcloutier.com/x86/ADD.html ; Alle "klassischen" ALU-Befehle (aber nicht MOV), die auf 8086 zurückgehen, haben all diese Codierungen, einschließlich der speziellen AL / AX / EAX-Befehle ohne Modr / M, nur op + imm8 / 16/32. Diese Antwort hat Beispiele
Peter Cordes

1

Oktave: 23 Bytes

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

Wenn N = L * M ist, gibt der Ausdruck 0+i(dh eine rein imaginäre Zahl) zurück, andernfalls ergibt der Ausdruck eine komplexe Zahl mit einer reellen Komponente.

Für ein etwas schöneres Ergebnis auf Kosten eines zusätzlichen Bytes:

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

Wenn N = L * M, wird der Ausdruck zurückgegeben -1, andernfalls eine positive Zahl.

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, Sie können das gleiche Ergebnis mit bekommen, +24;if N==ans;-1;end;ansaber der bytecount ist der gleiche


1

Lua, 56 46 Bytes

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

Gibt eine 0 (ohne nachfolgende Zeile) aus, wenn sie gleich ist, und entweder nichts oder eine Reihe negativer Zahlen (in einigen Fällen mit vorangestellter Null), wenn sie nicht gleich sind.

Alleine: Online ausprobieren!

Ein paar Mal wiederholt: Probieren Sie es online!

Erläuterung

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

Bei der ersten Iteration (wenn anoch nicht definiert und daher festgelegt nil) wird aauf eine Zahl gesetzt, die der Eingabe entnommen wurde, andernfalls auf sich selbst. In beiden Fällen wird dann 46 abgezogen a.

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

Dies wird nur gedruckt, awenn es kleiner als (um Fälle zu berücksichtigen, in denen die Eingabe größer als die Gesamtlänge war) oder gleich Null ist, andernfalls die leere Zeichenfolge.

-10 Bytes um sich daran zu erinnern, dass Lua automatisch Umrechnungen zwischen Zahlen und Strings vornimmt. Hoppla.


0

JavaScript (ES6), 47 Byte

Dies verwendet die gleiche Technik wie Benoit Esnard in dieser Antwort (von ich verdopple die Quelle, Sie verdoppeln die Ausgabe! ).

Gibt 0 aus, wenn n = 47 * M ist , oder andernfalls einen Wert ungleich Null.

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

Demo für M = 1

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

Demo für M = 2

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


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.