Multiplikation durch Selbstmodifikation


33

... zumindest für eine Definition von "Selbstmodifikation".

Die Aufgabe

In dieser Herausforderung ist Ihre Aufgabe , drei Saiten zu schreiben A, Bund Cdass die folgenden Eigenschaften erfüllen.

  • Die Zeichenfolge Bhat eine Länge von mindestens 1.

  • Für jeden n ≥ 0ist der String ein gültiges Programm (dh ein voll lauffähiges Programm oder eine Funktionsdefinition) in der Programmiersprache Ihrer Wahl. Die hochgestellte Index Bezeichnet Wiederholung, so dass diese Mittel die Saiten , , , usw. Jedes Programm nimmt eine Zeichenkette als Eingabe und gibt einen String als Ausgabe.ABnCACABCABBCABBBC

  • Für alle m, n ≥ 0, wenn das Programm mit Eingabe ausgeführt wird , gibt es . Für Eingaben, die nicht in dieser Form vorliegen, kann das Programm alles tun, einschließlich Absturz.ABmCABnCABm*n+1C

Einige Beispiele im Format program(input) -> output:

AC(AC) -> ABC
ABC(AC) -> ABC
ABBBBBC(AC) -> ABC
AC(ABC) -> ABC
AC(ABBBBC) -> ABC
ABC(ABC) -> ABBC
ABBC(ABC) -> ABBBC
ABBBBC(ABBBC) -> ABBBBBBBBBBBBBC
ABBBC(ABBBBBBC) -> ABBBBBBBBBBBBBBBBBBBC

Regeln und Wertung

Ihre Punktzahl ist die Gesamtlänge von AundC , wobei eine niedrigere Punktzahl besser ist. Beachten Sie, dass während Bnicht auf die Partitur angerechnet wird, es von Aund Cwie im ersten Beispiel produziert werden muss .

Standardlücken sind nicht zulässig. Die Programme dürfen weder direkt noch indirekt auf ihren eigenen Quellcode zugreifen (es sei denn, sie erhalten ihn als Eingabe). Sie sind verpflichtet , die Saiten zu identifizieren A, Bund Cin Ihrer Antwort in irgendeiner Weise, und ermutigt Ihre Lösung zu erklären.

Antworten:


16

CJam, 9 8 Bytes

A: 1
B: 0
C:  r,(#0q

Probieren Sie es online im CJam-Interpreter aus .

Wie es funktioniert

(ABcode) e# Push the integer 10 ** len(Bcode).
<SP>     e# Noop. Separates (AB) and C for input reading.
r        e# Read the first whitespace-separated token from STDIN (ABinput).
,(       e# Push the string length minus 1: len(Binput)
#        e# Power operator: 10 ** len(Bcode) len(Binput) # ->
         e#   (10 ** len(Bcode)) ** len(Binput) = 10 ** (len(Bcode) * len(Binput))
0        e# Push an additional 0 to complete len(Bcode) * len(Binput) + 1 zeroes.
q        e# Read the remaining input (C).

12

CJam, 15 13 11 Bytes

A: rl"
B: <SP>
C: <LF>",(*SNq

Probieren Sie es online im CJam-Interpreter aus .

Wie es funktioniert

e# A

r     e# Read a whitespace-separated token from STDIN.
      e# This reads the input up to the first space, but does not consume it.
l     e# Read the rest of the first line from STDIN.
      e# This reads up to the first linefeed and consumes it.

"     e# Initiate a string.

e# B

<SP>  e# Fill the string with as many spaces as there are copies of B.

e# C

<LF>" e# Terminate the string with a linefeed.
      e# This serves as a delimiter for the `l' command.
,(    e# Compute the length of the string minus 1 (to account for the LF).
*     e# Repeat the string read by `l' that many times.
SN    e# Push a space and a linefeed.
q     e# Read the remaining input (i.e., the second line) from STDIN.

Am Ende enthält der Stapel das Token, von dem gelesen wurde r, den von *, das Leerzeichen und den Zeilenvorschub, die von SNund die von gelesene Zeile q. CJam druckt alle diese automatisch.


Hah, schöne Verwendung von Zitaten gibt: D
Optimizer

9

Pyth, 10

A: w*\0hl*w[<newline>
B: 0
C: <empty>

Wir teilen die Quelle in zwei Zeilen auf. Die erste Zeile ist A, die zweite Zeile sind die Bs. Da A in der ersten Zeile steht, wdruckt das erste nur A - einfach, fertig.

In Pyth führende Nullen sind separate Token, also [00)eigentlich ist [0, 0]. Beachten Sie, dass die erste Zeile mit endet l[und die zweite Zeile aus besteht 0000.... l[Zählt also tatsächlich die Anzahl der Bs in diesem Programm. Die Sekunde wliest die zweite Zeile der Eingabe ein - dies ist die Anzahl Bs der Eingabe. Ab hier ist es ein einfaches Multiplizieren, Inkrementieren und Ausgeben von so vielen Nullen.


9

Netzhaut , 25 bis 19 Bytes

A: ]\]<LF>
B: ]]
C: <LF>m`^]*$<LF>]$0]

<LF> stands for newline

Beispielcode ABC:

]\]
]]
m`^]*$
]$0]

Der Code hat zwei Ersatzschritte:

  • Ändern Sie den Eingang AB^mCin AB^(m*n)Cvon jedem Wechsel Bzu B^n:

    • ]\]Entspricht allen BEingaben und sonst nichts, da die Musterzeilen ausgeblendet werden
    • ]]...]] ist B^n
  • wechseln B^(m*n)zu B^(m*n+1)von

    • m`^]*$wobei die Leitung mit nur ]‚s
    • ]$0]Hinzufügen eines zusätzlichen Paares ]]davon in einer Weise, dass diese Zeile nicht mit dem ersten regulären Ausdruck übereinstimmt

Ich habe der Punktzahl für das -smehrzeilige Flag 3 Bytes hinzugefügt, die erforderlich sind, damit der gesamte Retina-Code in einer Datei gespeichert werden kann.

2 Bytes gespart dank @ MartinBüttner.


8

Python 3, 51 Bytes

A: lambda s:s[:28]+"x"*(1+len("
B: x
C: ")*(len(s)-51))+s[-23:]

Anwendungsbeispiel:

>>> f=lambda s:s[:28]+"x"*(1+len("xx")*(len(s)-51))+s[-23:]
>>> f('lambda s:s[:28]+"x"*(1+len("xxx")*(len(s)-51))+s[-23:]')
'lambda s:s[:28]+"x"*(1+len("xxxxxxx")*(len(s)-51))+s[-23:]'

Die Funktion berechnet n*m+1mit (1+len("xxx")*(len(s)-51))denen es m xist in der Zeichenfolge ( xxxTeil der B^m). Das Multiplizieren der Zeichenkette "x"mit dieser Zahl gibt B^(n*m+1)und die Funktion nimmt Aund Caus der Eingabe und verkettet all diese, um zu erhalten AB^(n*m+1)C.

Der gleiche Ansatz in J:

J, 35 Bytes

A: (19{.]),('x'#~1+(#'
B: x
C: ')*35-~#),_16{.]

5

CJam, 22

A:<empty>
B:{])`\,q,K/(*))*"_~"}
C:{])`\,q,K/(*))*"_~"}_~

Beispiellauf:

ABBC(ABC) -> ABBBC

was übersetzt zu

{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

mit Eingabe als

{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

was die folgende Ausgabe ergibt:

{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

Wie es funktioniert :

Lässt an , welche Programme einen Blick darauf werfen ACund ABCwie folgt aussehen:

AC :{])`\,q,K/(*))*"_~"}_~
ABC:{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

Wir bemerken, dass C=B_~

Schauen Bwir uns an, was passiert:

{])`\,q,K/(*))*"_~"}

{                  }    e# This is a code block. Alone, this does nothing except
                        e# pushing this block to stack as is
 ]                      e# Wrap everything on stack in an array
  )`                    e# Take out the last part and convert it to its string representation
    \,                  e# Take length of remaining array
      q,K/              e# Read the input, take its length and int divide by K (i.e. 20)
          (*            e# Decrement and multiply by the array length on stack
            ))          e# Add two to the product
              *         e# Repeat the string representation on stack that many times
               "_~"     e# Put this string on stack

Nun ACwollen wir sehen, was das Ausführen ohne Eingabe bewirkt:

{])`\,q,K/(*))*"_~"}_~                      e# Copy the block and run it
{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}~   e# Block is copied, run it
{      ...         } ])                     e# Wrapped array has the block in it.
                       `\,                  e# Stringify it and take length of remaining = 0
                          q,K/              e# No input so 0
                              (*))          e# 0 * -1 = 0. 0 + 2 = 2
                                  *         e# Repeat the stringified block 2 times:
                                            e# "{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}"
                                   "_~"     e# Put this string. Program ends, so print stack:
                                            e# {])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

Wow, die Ausgabe ist ABC.

Wir zählen grundsätzlich, wie viele Bim Code vorhanden sind. Dann, wie viele sind in der Eingabe (mit Länge). Multipliziere sie, erhöhe sie zweimal (da Chat sie auch B) und hänge sie _~an, um sie zu erhaltenC

Probieren Sie es hier online aus


3

Haskell , 50 Bytes

fist eine Funktion, die a String.

Die Zeichenfolge B ist nur ein einzelnes Leerzeichen, während C mit eins beginnt.

A:_:b="
B: 
C: ";f s|a:c<-words s=unwords$a:(drop 50s>>b):c

Probieren Sie es online!

  • _:b=" "Weist alle Leerzeichen bis auf das erste im Zeichenfolgenliteral zu b, sodass dies den m B-Kopien des Programms entspricht .
  • sist die Eingabezeichenfolge. a:c<-words sTeilt es in durch Leerzeichen getrennte Wörter auf, so dass es azu A wird und ceine Liste der Wörter mit C wird. Die B-Kopien werden ignoriert, da wordsmehrere Leerzeichen gedrückt werden (was der Rest des Programms vermeidet).
  • drop 50sist eine Zeichenfolge mit einer Länge, die der Anzahl n von B Kopien in der Eingabe entspricht. drop 50s>>bverkettet so viele Kopien bmit mn Leerzeichen.
  • unwords$a:(drop 50s>>b):cVerbindet alle Zeichenfolgen mit Leerzeichen. Da (drop 50s>>b)in der Liste ein zusätzliches "Wort" eingefügt ist, gibt es auch ein zusätzliches Verknüpfungsfeld, bei dem der Multiplikation automatisch +1 hinzugefügt wird.

2

Matlab, 85

Für mich war es das erste Mal, dass ich eine solche abstrakte Herausforderung durchführte, also war es für mich eher eine Codierungsherausforderung als eine Codegolfherausforderung!

Die drei Zeichenfolgen sind ohne Anführungszeichen:

A:    "X=strsplit(input('','s'));m=0 "
B:    "+1 "
C:    ";[X{1},32,repmat(['+1',32],1,m*(length(X)-2)+1),X{end}]"

So funktioniert es: Ich teile das Eingabeargument auf Whitespace auf, nkann also aus der Anzahl der String-Teile ermittelt werden. B arbeitet als eine Art Zähler zu bekommen m. Um die Antwort zu rekonstruieren, benutze ich A und C aus dem Split, wiederhole B m * n + 1 und füge die Leerzeichen mit ihrem ASCII-Wert ein, damit in C keine unerwünschten Splits auftreten.

EDIT: whoops, versehentlich A + B gezählt


1

C (gcc) , 81 Bytes

Das Erfordernis, die Zeichenfolgen zu identifizieren, steht im Widerspruch zu unserem Willkürverhalten für illegale Eingaben, es sei denn, wir haben eher laxe Standards in Bezug auf die Identifizierung. Natürlich habe ich die Interpretation genommen, die die meisten Bytes vergießt.

Probieren Sie es online!

A: m;f(char*s){m=strrchr(s+66,32)-s-65;printf("%.66s%*s",s,m*strlen("
B: <SPACE>
C: ")+16,s+m+66);}

Mit Identifikation meine ich nur, dass es aus Ihrer Antwort klar werden sollte, welche Code-Schnipsel A , B und C sind . Es ist keine Voraussetzung für das Programm.
Zgarb

1

TI-Basic (Serie 83), 65 Byte

Segment A (33 Bytes):

Input Str1:sub(Str1,1,27:For(I,0,(length(Str1)-55)(length("

Segment B:

X

Segment C (32 Bytes):

Y")-1:Ans+"X":End:Ans+sub(Str1,length(Str1)-27,28

Ich freue mich riesig, diese quineartige Herausforderung zu finden! Die meisten Quines funktionieren in TI-Basic nicht ohne ein wenig Schummeln, da es keine Möglichkeit gibt, sich dem "Symbol zu entziehen . (In beiden Bedeutungen des Wortes "Escape".) Aber hier erhalten wir eine Eingabezeichenfolge über den InputBefehl, und die Eingabe von a "dort ist vollkommen in Ordnung.

Hier gibt es immer noch einiges an TI-Basic-Schwachsinn: Eine leere Zeichenfolge ist ungültig, sodass die naive Lösung, die Zeichenfolge "XXX...XX"in eine Schleife einzufügen, nicht funktioniert, wenn n = 0 ist. Stattdessen berechnen wir den Wert von mn + 1 manuell und fügen die Zeichenfolge "X"so oft ein.

Die magischen Konstanten 27und 28im Programm sind leicht aus von den Bytezähler 33 und 32, weil Str1, sub(und length(sind Zwei-Byte - Zeichen , die nur 1 auf die Länge einer Zeichenkette beizutragen.

Wenn wir stattdessen Zeilenumbrüche verwenden :, sieht es so aus, als könnten einige Bytes eingespart werden , indem endende Anführungszeichen weggelassen werden. Dies funktioniert jedoch nicht. Zuallererst benötigen Sie einen Hex-Editor, bevor Sie das Newline-Zeichen in eine Zeichenfolge einfügen können: Sie können es nicht einfach eingeben, denn wenn Sie während eines InputBefehls die EINGABETASTE drücken , wird die Eingabe gesendet . Als ich den Hex-Editor-Ansatz ausprobierte, kam es zu einem seltsamen Pufferüberlauffehler, der den Inhalt meines Programms veränderte. Versuchen Sie dies also nicht zu Hause mit Ihrem teuren Taschenrechner.


0

Java 11, 135 65 + 26 = 91 Bytes

EIN

s->{var p=s.split("\\(\"|\"\\.");return p[0]+"(\"B"+p[1].repeat("

B

B

C

".length())+'"'+'.'+p[2];}

Probieren Sie es hier online aus (TIO verfügt noch nicht über Java 11, daher wird stattdessen eine Hilfsmethode verwendet String::repeat()).

Ungolfed:

s -> { // lambda taking and returning a String
    var p = s.split("\\(\"|\"\\."); // split input into parts A, B^n, C (where n may be 0) at the "(\"" and "\"."
    return p[0] + "(\"B" + // put it back together: A plus the part the split shaved off, plus an extra B ...
    p[1].repeat("BBB".length()) + // ... plus B^(n*m)
    '"' + '.' + p[2]; // plus C, with the part the split shaved off reattached
}
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.