Mnożenie przez samodzielną modyfikację

33

... przynajmniej dla pewnej definicji „samodzielnej modyfikacji”.

Zadanie

W tym wyzwaniem, twoim zadaniem jest napisać trzy struny A, Bi Cktóre spełniają następujące właściwości.

  • Ciąg Bma długość co najmniej 1.

  • Dla każdego n ≥ 0ciąg jest prawidłowym programem (co oznacza pełną wersję programu lub definicji funkcji) w wybranym języku programowania. Powtórzenie oznacza Indeks górny, więc oznacza to, że ciągi , , , itd. Każdy program trwa jeden ciąg jako dane wejściowe i zwraca jeden ciąg jako wyjście.ABnCACABCABBCABBBC

  • Dla każdego m, n ≥ 0, jeśli program jest uruchamiany z wejściem , zwraca . W przypadku danych wejściowych nie w tym formularzu program może zrobić wszystko, w tym awarię.ABmCABnCABm*n+1C

Kilka przykładów w formacie 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

Zasady i punktacja

Twój wynik to łączna długość AiC , im niższy wynik, tym lepiej. Zauważ, że chociaż Bnie jest liczony do wyniku, musi on zostać wygenerowany przez Ai Cjak w pierwszym przykładzie.

Standardowe luki są niedozwolone. Programy nie mają bezpośredniego lub pośredniego dostępu do własnego kodu źródłowego (z wyjątkiem sytuacji, gdy podano go jako dane wejściowe). Które są wymagane do identyfikacji ciągi A, Ba Cw swojej odpowiedzi w jakiś sposób, i zachęcał, aby wyjaśnić swoje rozwiązanie.

Zgarb
źródło

Odpowiedzi:

16

CJam, 9 8 bajtów

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

Wypróbuj online w interpretatorze CJam .

Jak to działa

(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).
Dennis
źródło
12

CJam, 15 13 11 bajtów

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

Wypróbuj online w interpretatorze CJam .

Jak to działa

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.

Na końcu stos zawiera odczytany token r, wytworzone przez *niego miejsce, wypchnięte przez niego miejsce SNi linię oraz odczytany wiersz q. CJam drukuje je wszystkie automatycznie.

Dennis
źródło
Hah, fajne wykorzystanie cytatów: D
Optymalizator
9

Pyth, 10

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

Podzieliliśmy źródło na dwie linie. Pierwsza linia to A, druga linia to Bs. Ponieważ A znajduje się w pierwszej linii, pierwsza wpo prostu drukuje A - łatwe, gotowe.

W Pyth zera wiodące są oddzielnymi tokenami, więc tak [00)naprawdę jest [0, 0]. Zauważ, że pierwsza linia kończy się na l[, a druga linia składa się z 0000.... Tak więc l[faktycznie liczy liczbę Bs w tym programie. Drugi wodczytuje w drugim wierszu wejścia - jest to liczba Bs wejścia. Odtąd jest to proste pomnożenie, zwiększenie i wyprowadzenie tylu zer.

orlp
źródło
9

Siatkówka , 25 19 bajtów

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

<LF> stands for newline

Przykładowy ABCkod:

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

Kod ma dwa zastępcze kroki:

  • zmień dane wejściowe AB^mCna AB^(m*n)C, zmieniając każdy Bna B^n:

    • ]\]dopasowuje każdy Bna wejściu i nic więcej dzięki ucieczce w liniach wzoru
    • ]]...]] jest B^n
  • zmiana B^(m*n)do B^(m*n+1)przez

    • m`^]*$biorąc linię tylko ]„s
    • ]$0]dodanie do niego dodatkowej pary ]]w taki sposób, że ta linia nie pasuje do pierwszego wyrażenia regularnego

Dodałem 3 bajty do wyniku dla -sflagi wieloliniowej, która jest potrzebna, aby cały kod Retina mógł znajdować się w jednym pliku.

2 bajty zapisane dzięki @ MartinBüttner.

randomra
źródło
8

Python 3, 51 bajtów

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

Przykładowe użycie:

>>> 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:]'

Oblicza się czynności n*m+1z (1+len("xxx")*(len(s)-51))którym jest m xjest w ciągu ( xxxczęść jest B^m). Pomnożenie łańcucha "x"przez tę liczbę daje, B^(n*m+1)a funkcja pobiera Ai Cwyprowadza dane wejściowe i łączy je wszystkie, aby uzyskać AB^(n*m+1)C.

To samo podejście w J:

J, 35 bajtów

A: (19{.]),('x'#~1+(#'
B: x
C: ')*35-~#),_16{.]
randomra
źródło
5

CJam, 22

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

Przykładowy przebieg:

ABBC(ABC) -> ABBBC

co przekłada się na

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

z wejściem jako

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

co daje następujące dane wyjściowe:

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

Jak to działa :

Przyjrzyjmy się, jakie programy ACi ABCjak wyglądają:

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

Zauważamy, że C=B_~

Przyjrzyjmy się, co Brobi:

{])`\,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

Teraz zobaczmy, co ACzrobi bieganie bez żadnych danych wejściowych:

{])`\,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, wyjście jest ABC.

Zasadniczo liczymy, ile jest Bw kodzie. Następnie ile jest na wejściu (używając długości). Pomnóż je, zwiększ dwukrotnie (ponieważ Cma również B) i dołącz, _~aby uzyskaćC

Wypróbuj online tutaj

Optymalizator
źródło
3

Haskell , 50 bajtów

fjest funkcją przyjmującą i zwracającą a String.

Ciąg B jest tylko pojedynczą spacją, podczas gdy C zaczyna się od jednej.

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

Wypróbuj online!

  • _:b=" "przypisuje wszystkie ale pierwszy z pomieszczeń, w ciągu do dosłowny b, co czyni, że równa programu m kopii B.
  • sjest łańcuchem wejściowym. a:c<-words sdzieli go na słowa rozdzielone spacjami, tak że astaje się A i cstaje się listą słów zawierających C. Kopie B są ignorowane, ponieważ wordsściskają wiele spacji (których unika reszta programu).
  • drop 50sjest łańcuchem o długości równej liczbie n kopii B na wejściu. drop 50s>>bkonkatenuje tyle kopii b, dając mn odstępy.
  • unwords$a:(drop 50s>>b):cłączy wszystkie łańcuchy z powrotem ze spacjami. Ponieważ (drop 50s>>b)na liście znajduje się dodatkowe „słowo” , istnieje również dodatkowe miejsce łączenia, automatycznie dodając +1 do mnożenia.
Ørjan Johansen
źródło
2

Matlab, 85

Po raz pierwszy wykonałem tak abstrakcyjne wyzwanie, więc dla mnie było to raczej wyzwanie kodowania niż wyzwanie golfa!

Trzy ciągi znaków bez cudzysłowu:

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

Jak to działa: Podzielę argument wejściowy na białe znaki, więc nmożna je ustalić na podstawie liczby części łańcucha. B działa jak rodzaj licznika do zdobycia m. Aby zrekonstruować odpowiedź, używam A i C z podziału, powtarzam B m * n + 1 razy i wstawiam spacje, używając ich wartości ASCII, aby żadne niepożądane podziały nie występowały w C.

EDYCJA: ups, przypadkowo policzył A + B

Oebele
źródło
1

C (gcc) , 81 bajtów

Wymóg identyfikacji ciągów wydaje się być sprzeczny z naszym dozwolonym arbitralnym zachowaniem w przypadku nielegalnych danych wejściowych, chyba że mamy dość luźne standardy dotyczące tego, co oznacza identyfikacja. Oczywiście przyjęłam interpretację, która zrzuca najwięcej bajtów.

Wypróbuj 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);}
gastropner
źródło
Poprzez identyfikację Chodziło mi o to, że powinno być jasne, z odpowiedzi, które fragmenty kodu są A , B i C . To nie jest wymóg programu.
Zgarb
1

TI-Basic (seria 83), 65 bajtów

Segment A (33 bajty):

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

Segment B:

X

Segment C (32 bajty):

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

Jestem naprawdę podekscytowany znalezieniem tego quino-wyzwania! Większość quines nie działa w TI-Basic bez choćby odrobiny oszukiwania, ponieważ nie ma sposobu na ucieczkę od "symbolu. (W obu znaczeniach słowa „ucieczka”.) Ale tutaj otrzymujemy ciąg wejściowy za pomocą Inputpolecenia i wpisanie "tam jest całkowicie w porządku.

Wciąż jest tu trochę głupoty TI-Basic: pusty łańcuch jest nieprawidłowy, więc naiwne rozwiązanie wstawiania łańcucha "XXX...XX"w pętli nie zadziała, gdy n = 0. Zamiast tego ręcznie obliczamy wartość mn + 1 i wstawiamy ciąg "X"wiele razy.

Stałe magiczne 27i 28w programie są nieco off z liczbą bajtów 33 i 32, ponieważ Str1, sub(i length(są tokeny dwóch bajtów, że tylko 1 przyczyniają się do długości łańcucha.

Jeśli użyjemy nowego wiersza zamiast :, wygląda na to, że można zaoszczędzić kilka bajtów, pomijając końcowe cudzysłowy, ale tak naprawdę to nie działa. Przede wszystkim potrzebujesz edytora szesnastkowego, aby dodać znak nowej linii do łańcucha: nie możesz go po prostu wpisać, ponieważ jeśli naciśniesz ENTER podczas Inputpolecenia, przesyła on dane wejściowe. Kiedy wypróbowałem podejście do edytora szesnastkowego, otrzymałem dziwny błąd przepełnienia bufora, który zmodyfikował zawartość mojego programu, więc nie próbuj tego w domu z drogim kalkulatorem.

Misza Ławrow
źródło
0

Java 11, 135 65 + 26 = 91 bajtów

ZA

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

b

B

do

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

Wypróbuj online tutaj (TIO nie ma jeszcze Java 11, więc zamiast tego opiera się na metodzie pomocnika String::repeat()).

Nie golfowany:

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
}
OOBalance
źródło