Geben Sie die Quelle Bit für Bit aus

18

Schreiben Sie ein nicht leeres Programm oder eine Funktion, die bei Aufruf einen einzelnen Wert (1 oder 0) ausgibt und bei mehrfachem Aufruf die Ausgabenummern die Binärdarstellung des Quellcodes Ihres Programms (auf derselben Codepage, aus der Ihr Code kompiliert wurde) erzeugt /interpretiert).

Wenn Ihr Quellcode beispielsweise abc(in ASCII) wäre, wären die Ausgaben:

1st call:  0           // ASCII letter 'a'
2nd call:  1
3rd call:  1
4th call:  0
5th call:  0
6th call:  0
7th call:  0
8th call:  1

9th call:  0           // ASCII letter 'b'
10th call: 1
11th call: 1
12th call: 0
13th call: 0
14th call: 0
15th call: 1
16th call: 0

17th call: 0           // ASCII letter 'c'
18th call: 1
19th call: 1
20th call: 0
21st call: 0
22nd call: 0
23rd call: 1
24th call: 1

After the 24th call, the behaviour is undefined.

Die Binärdarstellung der Quelle muss mindestens ein 0-Bit und ein 1-Bit enthalten.

Anstelle von 1 und 0 können Sie auch zwei unterschiedliche, konsistente Werte (z. B. trueund false) ausgeben .

Selbstmodifizierende Programme, die die Binärdarstellung der Originalquelle ausgeben, sind zulässig, sofern sie den Quellcode nicht lesen, um herauszufinden, was als Nächstes gedruckt werden soll.

Das ist , also gewinnt die kürzeste Antwort in Bytes.

Steadybox
quelle

Antworten:

8

Funky , 47 41 37 Bytes

Gibt eine Zahl zurück, die ein Bit darstellt.

f=_=>1&("%b"%("f="+f)[i//8])>>7-i++%8

Dies verwendet das Quine-Format von f=_=>"f="+f. Es nimmt die Zeichen an der Position ⌊i / 8⌋ , dann erhält das Bit für den Pairity des Nehmens , n >> 7-i%8wo nist der ASCII - Wert des aktuellen Zeichens.

Dies ist eine iterative Funktion, die imit jedem Aufruf inkrementiert wird. Sobald der Quellcode nicht mehr vorhanden ist, wird der Code für nimmer geschrieben.

Probieren Sie es online!

Ein Taco
quelle
Ist das ein Polyglott mit JavaScript?
Stan Strum
9

Bash , 105 Bytes

trap -- 'trap|xxd -b -c1|cut -d\  -f2|tr -d \\n|cut -c`x=\`cat f||echo 1\`;echo $((x+1))>f;echo $x`' EXIT

HINWEIS : Stellen Sie sicher, dass sich fin dem Verzeichnis, in dem Sie dies testen, keine wichtige Datei befindet .


Wenn Sie dies testen möchten, können Sie den folgenden Befehl verwenden:

for i in $(seq 848); do bash path/to/script.sh 2> /dev/null; done | tr -d \\n

Welches sollte die gleiche Ausgabe geben xxd -c1 -b path/to/script.sh|cut -d\ -f2|tr -d \\n.

Erläuterung

Hierfür wird der trapTrick verwendet, mit dem der Aufruf trapinnerhalb der trapAktion einfach diese Zeile ausgibt. Als nächstes wird diese Ausgabe weitergeleitet, xxddie sie in eine Binärdatei konvertiert ( xxd -bpfunktioniert leider nicht - daher die Problemumgehung mit cut& tr):

xxd -c1 -b $0|cut -d\  -f2|tr -d \\n

Davon interessiert uns nur ein Bit, mit Ndem wir auswählen können cut -cN.

Um herauszufinden, was Nwir verwenden (denken Sie daran, dass dies der Teil ist, der nach jedem Aufruf erhöht werden muss), versuchen Sie einfach x, den Inhalt der Datei festzulegen, fund setzen Sie ihn auf 1, falls er nicht vorhanden ist:

x=`cat f||echo 1`

Als letztes müssen Sie die Datei aktualisieren f- schreiben x+1Sie darauf:

echo $((x+1))>f
ბიმო
quelle
7

TI-Basic (TI-83-Serie), 592 357 309 Byte

"123456789ABCDEF02A3132333435363738394142434445463004AA003FB958833404593FB9588338045A3F3230363FDA582B383F303FCE5A405A6B3232333F5A70BB0FAA002BBB0CAA002B5A2B313FB932BA32F01058713459713511BB0FAA002BBB0CAA002B597031377132722B31→Str1
iPart(X/4→Y
iPart(X/8→Z
206
IS>(X,8
0
If Z and Z<223
Z+inString(Str1,sub(Str1,Z,1
iPart(2fPart(2^(X-4Y-5)inString(Str1,sub(Str1,Y+17-2Ans,1

Diese Tabelle ist eine mögliche Referenz für die Binärdarstellung des Quellcodes durch den Taschenrechner, obwohl ich letztendlich gerade den Debugger von Virtual TI verwendet habe.

Zum Vergleich und / oder für historisches Interesse: die ersten in TI-Basic geschriebenen Quines .

Wie es funktioniert

Str1speichert den Quellcode (jetzt in herrlichem Hexadezimalformat, spart viel Platz gegenüber der vorherigen Binärversion) und lässt die Bits weg, in denen der Inhalt von sich Str1selbst dargestellt werden würde.

Wir gehen davon aus, dass das Programm auf einem Rechner Speicher , das beginnt gelöscht hat gerade, so Xist 0. Jedes Mal, wenn wir das Programm durchlaufen, erhöhen wir es X.

Normalerweise berechnen wir nur das halbe Byte, aus dem wir ein bisschen extrahieren, aus dem wir es lesen Str1, von hexadezimal nach binär konvertieren und es drucken möchten. Wenn wir auf dem Teil des Quellcodes, die Lagerungs- Str1(was zwei Drittel der Gesamtlänge des Programms), dann wir ersten Umzugs in dem entsprechenden Teil der Zeichenfolge zu speichern 31, 32und so weiter.

Mischa Lawrow
quelle
4

Java 8, 249 241 237 234 148 Bytes

int i;v->{String s="int i;v->{String s=%c%s%1$c;return s.format(s,34,s).charAt(-i/8)>>(--i&7)&1;}";return s.format(s,34,s).charAt(-i/8)>>(--i&7)&1;}

Entschuldigung im Voraus für die langen Erklärungen. :)

  • Satte 89 Bytes gespeichert dank @Nevay .

Probieren Sie es hier aus.

Erläuterung:

int i;                     // Index-integer on class-level
v->{                       // Method with empty unused parameter and integer return-type
  String s="int i;v->{String s=%c%s%1$c;return s.format(s,34,s).charAt(-i/8)>>(--i&7)&1;}";
                           //  String containing the unformatted source code
  return s.format(s,34,s)  //    Quine to get the source code,
      .charAt(-i/8)        //     and get the character at index `-i/8`
     >>                    //    And bitwise right-shift it with:
       (--i&7)             //     `i-1` bitwise-AND 7
                           //     by first decreasing `i` by 1 with `--i`
      &1;                  //   Then bitwise-AND everything above with 1
}                          // End of method

Zusätzliche Erklärung:

-Teil:

  • String s enthält den unformatierten Quellcode
  • %s wird verwendet, um diesen String mit in sich selbst zu setzen s.format(...)
  • %c, %1$cund 34dienen zum Formatieren der doppelten Anführungszeichen ( ")
  • s.format(s,34,s) setzt alles zusammen

Probieren Sie es hier aus, wobei einige Teile entfernt / modifiziert wurden, um zu überprüfen, ob es sich um einen eigenen Quellcode handelt.

-Teil:


Alte 233 Bytes Antwort:

int i;v->{String s="int i;v->{String s=%c%s%1$c;return Long.toString((s.format(s,34,s).charAt(i/8)&255)+256,2).substring(1).charAt(i++%%8);}";return Long.toString((s.format(s,34,s).charAt(i/8)&255)+256,2).substring(1).charAt(i++%8);}

Probieren Sie es hier aus.

Erläuterung:

int i;                           // Index-integer on class-level
v->{                             // Method with empty unused parameter and char return-type
  String s="int i;v->{String s=%c%s%1$c;return Long.toString((s.format(s,34,s).charAt(i/8)&255)+256,2).substring(1).charAt(i++%%8);}";
                                 //  String containing the unformatted source code
  return Long.toString(
          (s.format(s,32,s)      //  Quine-formatting
          .charAt(i/8)           //  Take the current character
           &255)+256,2).substring(1)
                                 //  Convert it to an 8-bit binary-String 
         .charAt(i++%8);         //  And return the bit at index `i` modulo-8
                                 //  and increase index `i` by 1 afterwards with `i++`
}                                // End of method

Zusätzliche Erklärung:

-Teil:

Gleiche Erklärung wie oben, jedoch ergänzt durch:

  • %%ist die maskierte Form des Modulo-Zeichens ( %)

Probieren Sie es hier aus, wobei einige Teile entfernt / modifiziert wurden, um zu überprüfen, ob es sich um einen eigenen Quellcode handelt.

-Teil:

  • i/8wird automatisch bei ganzzahliger Division abgeschnitten, wenn ialso 0-7 ist, wird es 0; Wenn i8-15 ist, wird es werden 1; etc.
  • Nimmt also s.charAt(i/8)das aktuelle Zeichen des Quellcodes achtmal hintereinander. Probieren Sie es hier mit einer modifizierten Version.
  • 255ist 0xFFoder 11111111(der maximale Wert für ein Byte ohne Vorzeichen)
  • 256ist 0x100oder 100000000.
  • Das &überträgt das ASCII-Zeichen auf eine Ganzzahl. An diesem Punkt ist es irgendwo zwischen 0und 255( 00000000zu 11111111).
  • Long.toString(...,2) konvertiert es in die 9-Bit-Binär-String-Darstellung
  • +256und stellt .substring(1)sicher, dass führende Nullen vorhanden sind, und konvertiert das 9-Bit in ein 8-Bit.

Probieren Sie es hier aus, wobei einige Teile entfernt / geändert wurden, um die gesamten Bytes zu überprüfen.

Kevin Cruijssen
quelle
1
149 Bytes:int i;v->{String s="int i;v->{String s=%c%s%1$c;return 1&s.format(s,34,s).charAt(-i/8)>>(--i&7);}";return 1&s.format(s,34,s).charAt(-i/8)>>(--i&7);}
Nevay
@Nevay Satte 88 Bytes gespeichert. Vielen Dank! Und da es tatsächlich ein ganz anderer Ansatz ist als ursprünglich, habe ich die alte Antwort beibehalten und die neue hinzugefügt. (Wenn du willst, entferne ich es wieder und du kannst es selbst posten, aber du hast mir in der Vergangenheit gesagt, dass du lieber den XD-Code anderer Leute spielst, anstatt deine eigene Antwort zu
posten
2

Javascript ES6, 73 58 52 Bytes

o=_=>`o=${o}`.charCodeAt((o.n=1+o.n|0)/8)>>(7-o.n%8)&1

Erläuterung

Aufschlüsselung des Codes:

  • o=_=>: definiere eine Funktion.
  • `o=${o}`: konstruiere einen String; owird in einen String konvertiert, der in diesem Fall der Quellcode der Funktion ist.
  • .charCodeAt(: Ermittelt ein Zeichen in der Zeichenkette als ASCII-Zeichencode.
  • (o.n=1+o.n|0)/8: Wählen Sie einen Charakter. Hier wird auch der Zähler inkrementiert.
  • )>>(7-o.n%8): Verschieben Sie den resultierenden Zeichencode so, dass sich das gewünschte Bit an der richtigen Position befindet.
  • &1: Alle anderen Bits auf 0 setzen.
RamenChef
quelle
Sie können dies mit einem Lambda ino=_=>(o+'').charCodeAt(('n'in top?++n:n=0)/8|0)>>(7-n%8)&1
ATaco 25.10.17
Dies gilt als Definition einer Funktion.
ATaco
1
Versuchen Sieo=_=>('o='+o).charCodeAt(('n'in top?++n:n=0)/8|0)>>(7-n%8)&1
ATaco
Statt 'n'in top?++n:n=0Sie verwenden können , ++n||(n=0)oder ++n?n:n=0oder n=++n||0oder n=1+n||0die alle nutzen die falsiness von NaNder erzeugt wird durch Erhöhenundefined
Bergi
1
o=_=>('o='+o).charCodeAt((o.n=1+o.n|0)/8)>>(~o.n&7)&1
TSH
2

q / kdb + 45 Bytes

Lösung:

a:-1;f:{((,/)0b vs'4h$"a:-1;f:",($).z.s)a+:1}

Beispiel:

q)f[] / call function f with no parameters
0b   
q)f[]
1b   
q)f[]
1b   
q)f[]
0b   
q)f[]
0b   
q)f[]
0b   
q)f[]
0b   
q)f[]
1b   
q)f[]  
q)"c"$0b sv 01100001b / join back to a byte and cast to a character
"a"

Erläuterung:

Ich glaube, ich habe den Auftrag verstanden.

Richten Sie zuerst eine globale Variable amit dem Startwert von ein -1. Function erstellt fdie Binärdarstellung der Zeichenfolgendarstellung der Funktion (einschließlich der {}), der der a:-1;f:Junk vorangestellt ist , und indiziert diese Binärliste bei Index a (der bei jedem Aufruf inkrementiert wird).

a:-1;f:{(raze 0b vs'4h$"a:-1;f:",string .z.s)a+:1} / ungolfed solution
a:-1;                                              / stick -1 in variable a
     f:{                                         } / define function f
                                             a+:1  / increment a by 1 (:: is required as a is a global variable), indexes into the left
        (                                   )      / do all this together
                                 string .z.s       / z.s is the function, string converts it to a string
                       "a:-1;f:",                  / prepend "a:-1;f:" to the start
                    4h$                            / cast to bytes
              0b vs'                               / convert each byte to binary
         raze                                      / flatten binary into long list
Streetster
quelle
2

Python 2 , 164 Bytes

lambda s='lambda s=%r,i=[]:i.append(1)or"{:08b}".format(ord((s%%s)[~-len(i)/8]))[~-len(i)%%8]',i=[]:i.append(1)or"{:08b}".format(ord((s%s)[~-len(i)/8]))[~-len(i)%8]

Probieren Sie es online!

Erläuterung

Beginnen wir mit einem Standard-Python-2-Quine.

s = '...'; print s % s

Okay, das gibt es einfach so aus. Wir brauchen Binär!

s = '...'; print "\n".join("\n".join("{:08b}".format(ord(i))) for i in s % s)

Richtig, das wandelt einfach alles in Binär um. Aber der Titel sagt "Stück für Stück". Wir brauchen etwas, um durch mehrere Läufe zu bestehen. Ich weiß, machen wir es zu einer Funktion!

lambda s = '...': "\n".join("\n".join("{:08b}".format(ord(i))) for i in s % s)

Warten Sie, das hilft nicht ... Hmm, wie können wir den Index des Bits verfolgen, das ausgegeben werden soll? Oh, oh, lass uns eine ganze Zahl haben, um den Überblick zu behalten.

lambda s = '...', i = 0: "{:08b}".format(ord((s % s)[i / 8]))[i % 8]

Ähm ... das gibt immer das erste Bit aus. Oh, wir müssen den Tracker erhöhen! Oh Mist, Python erlaubt nicht, dass Ganzzahlen als Standardargumente geändert werden. Und Zuweisungen sind in Python keine Ausdrücke, also können Sie das nicht in einem Lambda tun. Welp, das ist unmöglich in Python, Fall geschlossen.

...Nicht ganz. Python tut Listen können als Standardargumente geändert werden. (Und es beißt Python-Programmierer die ganze Zeit.) Lassen Sie uns seine Länge verwenden!

lambda s = '...', i = []: "{:08b}".format(ord((s % s)[len(i) / 8]))[len(i) % 8]

Der Tracker wird trotzdem nicht verändert ... Wir können etwas anhängen, um seine Länge zu erhöhen ... Aber wie? Ah, na ja, wir haben list.append. lst.append(1)ist äquivalent zu lst += [1]. Groß!

lambda s = '...', i = []: i.append(1) and "{:08b}".format(ord((s % s)[len(i) / 8]))[len(i) % 8]

Whoops, dies überspringt das erste Bit, da die Länge des Trackers 1 ist, bevor das Bit ausgegeben wird. Wir müssen die Länge dort verringern, wo sie verwendet wird.

lambda s = '...', i = []: i.append(1) and "{:08b}".format(ord((s % s)[(len(i) - 1) / 8]))[(len(i) - 1) % 8]

Da ist es, Leute! Golf it und du hast meine Lösung!

total menschlich
quelle