Es gibt 95 druckbare ASCII- Zeichen:
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
In der Consolas-Schriftart (der Standardeinstellung für den Stack Exchange-Codeblock) haben einige der Zeichen Spiegel um eine vertikale Symmetrieachse:
- Diese Zeichenpaare sind Spiegelbilder voneinander:
()
[]
{}
<>
/\
- Diese Zeichen sind Spiegel ihrer selbst:
! "'*+-.8:=AHIMOTUVWXY^_ovwx|
(Beachten Sie, dass das Leerzeichen eins ist.) - Diese haben keine Spiegel:
#$%&,012345679;?@BCDEFGJKLNPQRSZ`abcdefghijklmnpqrstuyz~
( i
, l
, 0
, #
, Und wahrscheinlich auch andere Zeichen sind , ihr eigener Spiegel in einigen Schriften , sondern wir werden die Consolas Formen bleiben.)
Eine Zeichenfolge wird als Spiegel ihrer selbst bezeichnet, wenn sie nur aus 39 Spiegelzeichen besteht , die so angeordnet sind, dass die Zeichenfolge eine vertikale Symmetrie-Mittellinie aufweist. So ](A--A)[
ist ein Spiegel von sich selbst aber ](A--A(]
nicht.
Schreiben Sie ein einzeiliges Programm mit gerader Länge, das ein Spiegelbild seiner selbst ist. Wenn ihm N Kopien seiner linken Hälfte vorangestellt und N Kopien seiner rechten Hälfte angehängt wurden, sollte er N + 1 ausgeben. N ist eine nicht negative ganze Zahl.
Wenn zum Beispiel das Programm ](A--A)[
(linke Hälfte:, ](A-
rechte Hälfte:) war -A)[
, dann:
- Laufen
](A--A)[
sollte ausgeben1
. (N = 0) - Laufen
](A-](A--A)[-A)[
sollte ausgeben2
. (N = 1) - Laufen
](A-](A-](A--A)[-A)[-A)[
sollte ausgeben3
. (N = 2) - Laufen
](A-](A-](A-](A--A)[-A)[-A)[-A)[
sollte ausgeben4
. (N = 3) - . . .
- Laufen
](A-](A-](A-](A-](A-](A-](A-](A-](A-](A--A)[-A)[-A)[-A)[-A)[-A)[-A)[-A)[-A)[-A)[
sollte ausgeben10
. (N = 9) - etc.
Regeln
- Ausgabe auf stdout oder die nächstgelegene Alternative Ihrer Sprache. Es kann eine optionale nachgestellte Newline geben. Es sollten keine Eingaben gemacht werden.
- Der Prozess sollte theoretisch für N bis zu 2 15 -1 oder mehr funktionieren , vorausgesetzt, dass genügend Speicher und Rechenleistung vorhanden sind.
- Ein vollständiges Programm ist erforderlich, nicht nur ein REPL- Befehl.
Das kürzeste Anfangsprogramm (Fall N = 0) in Bytes gewinnt.
quelle
#
ist dies auch eine eigene Relektion, aber Sie haben Recht, nicht in Konsolen.Antworten:
Pip,
1284 BytesJetzt mit 66% weniger Bytes!
x
ist eine Variable, vorinitialisiert für""
. Im numerischen Kontext wird dies0
.+
ist Ausdruck der Formx+x+...+x
. Dies ist eine gültige Aussage, die nichts bewirkt.+
aus der ersten Hälfte, ist Ausdruck der Form++x+x+...+x
.++x
erhöht sichx
auf1
, und der Rest addiert sich N-mal. Da Ausdrücke in Pip von links nach rechts ausgewertet werden, wird das Inkrement garantiert zuerst ausgeführt und das Ergebnis entspricht der Anzahl der Spiegelebenen.Leider kann Pip große Ausdrücke nicht gut verarbeiten: Diese Lösung verursacht einen
maximum recursion depth exceeded
Fehler für N über 500 oder so. Hier ist eine frühere Lösung, die dies für 8 Bytes nicht tut :Mehr zu Pip
quelle
Fatal error: maximum recursion depth exceeded while calling a Python object
.x+x+...+x
Rekursionstiefe O (N) generiert wird. Vielleicht macht das diese Antwort ungültig. Ich werde eine Notiz hinzufügen.GolfScript, 10 Bytes
Probieren Sie es online mit Web Golfscript aus: N = 0 , N = 1 , N = 2 , N = 3 , N = 41
Web GolfScript ist auf 1024 Zeichen beschränkt, der Ruby-Interpreter verarbeitet N = 32767 jedoch perfekt:
Wie es funktioniert
Ohne Eingabe hat GolfScript zunächst eine leere Zeichenfolge auf dem Stapel.
In der ersten linken Hälfte passiert folgendes:
!
Wendet logisches NICHT auf die leere Zeichenfolge an. Das drängt1
.:{
speichert die ganze Zahl auf dem Stapel in der Variablen{
.Ja, das ist eine gültige ID, obwohl der gespeicherte Wert nicht abgerufen werden kann.
)
erhöht die Ganzzahl auf dem Stapel.:
ist eine unvollständige Anweisung.In den folgenden linken Hälften passiert Folgendes:
:!
(wo:
ist ein Rest von vorher) speichert die ganze Zahl auf dem Stapel in der Variablen!
.Ja, das ist auch eine gültige Kennung. Dadurch wird der
!
Befehl abgebrochen, aber wir verwenden ihn nicht mehr.:{
,)
Und:
arbeiten wie zuvor.In der ersten rechten Hälfte passiert folgendes:
::
(wo:
ist ein Rest von vorher) speichert die ganze Zahl auf dem Stapel in der Variablen:
.Ja, auch das ist eine gültige Kennung. Wie bei
{
gibt es keine Möglichkeit, den gespeicherten Wert abzurufen.(
dekrementiert die Ganzzahl auf dem Stapel und ergibt die Anzahl der linken Hälften.}
, da es nicht übereinstimmt und die Ausführung sofort beendet.Dies ist eine undokumentierte Funktion. Ich nenne sie Superkommentare .
Der verbleibende Code wird einfach ignoriert.
quelle
}
in einem Spiegelwettbewerb einen in der zweiten Hälfte Ihres Codes unerreichten Code zu haben ."\""/"
würden die vierten doppelten Anführungszeichen als auch unübertroffen, da die zweiten entgangen war.Z80 Maschinencode,
86 Bytes *<8ww8>
* Unter bestimmten Bedingungen von Amstrad BASIC eingebenA
ist anfangs 0, wenn von BASIC eingegeben. Es wirdA
n- mal inkrementiert und dann n- mal an denselben Speicherort geschrieben (der von BASIC auf einen leicht zufälligen Speicherort festgelegt wurde)! DieJR
Operation "Relativ springen" führt zu keinem Ergebnis, da dasC
Flag immer nicht gesetzt ist. Daher wird das folgende Byte "auskommentiert". Diese Version schummelt leicht, wenn bestimmte Einreisebedingungen vorausgesetzt werden, nämlich, dass die Einreise aus den BASIC-GarantienA
immer 0(HL)
ist. Der folgende Code ist viel robuster, weshalb er viel länger ist.Z80-Maschinencode, 30 Byte
Als ASCII:
o!.ww.!>A=o>{))((}<o=A<!.ww.!o
Grundsätzlich garantiert die erste Hälfte die Erzeugung eines Nullwerts und die zweite Hälfte erhöht ihn und schreibt ihn in den Speicher. In der erweiterten Version
##
bezeichnet unten Code, der in seiner Hälfte des Spiegels keinen Zweck erfüllt.Aufschlüsselung der erlaubten Anweisungen:
Von den 39 zulässigen Befehlen sind 28 Ladeoperationen (die Blöcke von 0x40 bis 0x7F sind alle Einzelbyte-
LD
Befehle), von denen die meisten hier keine Hilfe sind! Die einzige AnweisungLD (HL), A
zum Laden in den Speicher, die noch zulässig ist , bedeutet, dass ich den Wert in speichern mussA
. Da diesA
das einzige Register ist, in dem eineINC
Anweisung zulässig ist , ist dies praktisch.Ich kann nicht
A
mit 0x00 beginnen, da ASCII 0x00 kein zulässiges Zeichen ist! Alle verfügbaren Werte sind weit von 0 entfernt und alle mathematischen und logischen Anweisungen wurden nicht zugelassen! Außer ... ich kann immerADD HL, HL
noch 16-BitHL
zu sich selbst hinzufügen ! Abgesehen vom direkten Laden von Werten (hier keine Verwendung!), Dem InkrementierenA
und DekrementierenA
,L
oderHL
nur so kann ich den Wert eines Registers ändern! Es gibt tatsächlich eine spezielle Anweisung, die in der ersten Hälfte hilfreich sein könnte, aber in der zweiten Hälfte ein Problem, das umgangen werden muss, und eine ergänzende Anweisung, die hier fast nutzlos ist und nur Platz beansprucht.Also fand ich den nächsten Wert zu 0, den ich finden konnte: 0x41. Wie ist das nahe bei 0? In der Binärdatei ist es 0x01000001. Also dekrementiere ich es, lade es hinein
L
und mache esADD HL, HL
zweimal!L
ist jetzt null, in die ich wieder ladeA
! Leider für den ASCII - CodeADD HL, HL
ist)
so ich jetzt verwenden müssen(
zweimal. Zum Glück(
istJR Z, e
, woe
ist das nächste Byte. Also verschlingt es das zweite Byte und ich muss nur sicherstellen, dass es nichts tut, indem ich vorsichtig mit derZ
Flagge bin ! Die letzte Anweisung, die dasZ
Flag beeinflusste, warDEC A
(ADD HL, HL
nicht intuitiv zu ändern) und da ich weiß, dassA
es zu diesem Zeitpunkt 0x40 war, ist garantiert, dassZ
es nicht gesetzt ist.Die erste Anweisung in der zweiten Hälfte
JR Z, #28
wird die ersten 255-mal nichts tun, da das Z-Flag nur gesetzt werden kann, wenn A von 255 auf 0 übergelaufen ist. Danach ist die Ausgabe jedoch falsch, da ohnehin nur 8-Bit-Werte gespeichert werden sollte keine Rolle spielen. Der Code sollte nicht mehr als 255 Mal erweitert werden.Der Code muss als Snippet ausgeführt werden, da alle verfügbaren Methoden zur sauberen Rückgabe nicht zugelassen wurden. Alle RETurn-Befehle liegen über 0x80 und die wenigen erlaubten Sprungoperationen können nur zu einem positiven Offset springen, da auch alle negativen 8-Bit-Werte nicht erlaubt wurden!
quelle
A
Register ist immer 8 Bit, sonst wäre der Prozessor nicht mit dem Z80 kompatibel. Ich würde sagen, dass bei genügend Arbeitsspeicher und Rechenleistung hier abgedeckt wurde!A
Register mit etwas anderem als 8 Bits hat? Das Ändern in 16-Bit würde zum Beispiel einen Code unterbrechen, der sich auf 255 + 1 = 0 stützt . Sie müssten eine CPU erfinden, nennen wir sie die Z160, die ein Standard-16-Bit-Register verwendet, aber immer noch denselben 8-Bit-Befehlssatz wie die Z80 verwendet. Seltsam!J,
1614 BytesVerwendungen:
Erläuterung:
J wertet von rechts nach links aus.
(_=_)
Istinf equals inf
das, was wahr ist, hat einen Wert von1
, so wird der Ausdruck1+]...[+1
. ((8=8)
würde auch funktionieren aber das sieht cooler aus. :))[
und]
geben die Argumente left und right zurück, wenn sie 2 Argumente haben. Wenn sie nur 1 bekommen, geben sie das zurück.+
fügt die 2 Argumente hinzu. Wenn es nur 1 bekommt, gibt es das zurück.Bewerten wir nun einen Ausdruck der Ebene 3 (von rechts nach links):
Wie wir sehen, wird die rechte Hälfte der
1
's addiert und die linke Seite der1
' s weggelassen, was die gewünschte Ganzzahl ergibtN
, die Spiegelebene.Probieren Sie es hier online aus.
quelle
Haskell, 42 Bytes
Glücklicherweise
--
ist ein Zeilenkommentar in Haskell (-> ) spiegelbar und die Hälfte davon (->-
) ist eine gültige Funktion. Der Rest ist ein bisschen Mathe, um die Zahlen0
und zu bekommen1
. Grundsätzlich müssen wir bei jedem Schritt(0)-(-1)
einen Kommentar fürN=0
und voranstellen(0)-(-1)-
.Wenn Gleitkommazahlen für die Ausgabe erlaubt sind, können wir bauen
1
aus8/8
und kommen mit 26 Bytes:Haskell, 26 Bytes
Ausgänge
1.0
,2.0
usw.quelle
program.hs
und dann$ runhaskell program.hs
über die Befehlszeile ausführen und die Ausgabe sehen können. Ich kenne Haskell nicht und kann daher nicht genau sagen, was sich ändern muss.runhaskell
ist ein Shell-Skript, das eine Umgebung einrichtet und schließlichghc
den Haskell-Compiler aufruft . Sie können meinen Code direkt mit ausführenghc
:ghc -e "(8-8)-(-8/8)--(8\8-)-(8-8)"
. Dadurch wird gestartetghc
, der als Argument bereitgestellte Code ausgewertet, das Ergebnis gedruckt und beendet. Keine REPL, keine Interaktion. Dies würde natürlich +1 zur Byteanzahl für hinzufügen-e
.-e
in diesem Fall nicht zur Bewertung bei. Wir zählen keine Bytes fürperl -E
odergcc -std=c99
.CJam, 14 Bytes
Probieren Sie es online im CJam-Interpreter aus: N = 0 , N = 1 , N = 2 , N = 3 , N = 41
Beachten Sie, dass dieser Code mit einer Fehlermeldung endet. Mit dem Java-Interpreter kann diese Fehlermeldung unterdrückt werden, indem STDERR geschlossen oder umgeleitet wird. 1
Wie es funktioniert
In den linken Hälften passiert Folgendes:
]
Wickelt den gesamten Stapel in ein Array.X
hängt1
an dieses Array an.:+
berechnet die Summe aller Array-Elemente.Oo
druckt den Inhalt eines leeren Arrays (dh nichts).In der ersten rechten Hälfte passiert folgendes:
o
druckt die ganze Zahl auf den Stapel, die die gewünschte Ausgabe ist.O+
versucht, ein leeres Array an das oberste Element des Stapels anzuhängen.Der Stapel war jedoch vor dem Schieben leer
O
. Dies schlägt fehl und beendet die Ausführung des Programms.Der verbleibende Code wird einfach ignoriert.
1 Laut Meta-Umfrage sollten Einsendungen mit einem Fehler beendet werden dürfen? , das ist erlaubt.
quelle