Perkalian dengan Modifikasi-Diri


33

... setidaknya untuk beberapa definisi "modifikasi diri".

Tugas

Dalam tantangan ini, tugas Anda adalah menulis tiga string A, Bdan Citu memenuhi properti berikut.

  • String Bmemiliki panjang setidaknya 1.

  • Untuk setiap n ≥ 0, string adalah program yang valid (artinya program runnable penuh atau definisi fungsi) dalam bahasa pemrograman pilihan Anda. Menunjukan superscript pengulangan, jadi ini berarti string , , , dll Setiap program mengambil satu string sebagai masukan, dan kembali satu string sebagai output.ABnCACABCABBCABBBC

  • Untuk apa pun m, n ≥ 0, jika program dijalankan dengan input , ia kembali . Untuk input yang bukan dari formulir ini, program dapat melakukan apa saja, termasuk crash.ABmCABnCABm*n+1C

Beberapa contoh dalam 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

Aturan dan Penilaian

Skor Anda adalah total panjang AdanC , skor yang lebih rendah lebih baik. Perhatikan bahwa sementara Btidak dihitung ke arah skor, itu harus dihasilkan oleh Adan Cseperti pada contoh pertama.

Celah standar tidak diijinkan. Program-program tidak diperbolehkan untuk secara langsung atau tidak langsung mengakses kode sumber mereka sendiri (kecuali ketika mereka diberikan sebagai input). Anda diminta untuk mengidentifikasi string A, Bdan Cdalam jawaban Anda dalam beberapa cara, dan didorong untuk menjelaskan solusi Anda.

Jawaban:


16

CJam, 9 8 byte

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

Cobalah online di juru bahasa CJam .

Bagaimana itu bekerja

(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 byte

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

Cobalah online di juru bahasa CJam .

Bagaimana itu bekerja

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.

Pada akhirnya, tumpukan berisi token yang dibaca r, ruang yang dihasilkan oleh *, ruang dan umpan baris didorong oleh SNdan baris dibaca oleh q. CJam mencetak semua ini secara otomatis.


Hah, penggunaan kutipan di sana: D
Optimizer

9

Pyth, 10

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

Kami membagi sumber menjadi dua baris. Baris pertama adalah A, baris kedua adalah B. Karena A ada di baris pertama, yang pertama wdicetak A - mudah, selesai.

Dalam Pyth nol nol adalah token yang terpisah, jadi [00)sebenarnya adalah [0, 0]. Perhatikan bahwa baris pertama berakhir l[, dan baris kedua terdiri dari 0000.... Jadi l[sebenarnya menghitung jumlah B dalam program ini. wBunyi kedua berbunyi di baris kedua input - ini adalah jumlah B dari input. Dari sini ini adalah perkalian sederhana, kenaikan dan keluaran yang banyak nol.


9

Retina , 25 19 byte

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

<LF> stands for newline

ABCKode contoh :

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

Kode memiliki dua langkah pengganti:

  • ubah input AB^mCmenjadi AB^(m*n)Cdengan mengubah setiapB menjadi B^n:

    • ]\] cocok setiap B di input dan tidak ada yang lain berkat lolos di garis pola
    • ]]...]] aku s B^n
  • ubah B^(m*n)keB^(m*n+1) dengan

    • m`^]*$ hanya mengambil garis ] 's
    • ]$0]menambahkan pasangan ekstra ]]untuk itu dengan cara yang baris ini tidak cocok dengan regex pertama

Saya telah menambahkan 3 byte ke skor untuk -s bendera multi-baris yang diperlukan agar seluruh kode Retina bisa dalam satu file.

2 byte disimpan berkat @ MartinBüttner.


8

Python 3, 51 byte

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

Contoh penggunaan:

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

Fungsi menghitung n*m+1dengan di (1+len("xxx")*(len(s)-51))mana ada m xdalam string ( xxxbagiannya adalah B^m). Mengalikan string "x"dengan angka ini memberi B^(n*m+1)dan fungsi mengambil Adan Ckeluar dari input dan menggabungkan semua ini untuk mendapatkan AB^(n*m+1)C.

Pendekatan yang sama dalam J:

J, 35 byte

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

5

CJam, 22

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

Contoh dijalankan:

ABBC(ABC) -> ABBBC

yang diterjemahkan menjadi

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

dengan input sebagai

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

yang memberikan output berikut:

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

Bagaimana itu bekerja :

Mari kita lihat program apa ACdan ABCterlihat seperti:

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

Kami perhatikan itu C =B_~

Mari kita lihat apa yang Bsedang dilakukan:

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

Sekarang mari kita lihat apa yang berjalan ACtanpa input akan dilakukan:

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

Kami pada dasarnya menghitung berapa banyak yang Bada dalam kode. Lalu berapa banyak yang di input (menggunakan panjang). Lipat gandakan, tambah dua kali (karena Cjuga sudah B) dan tambahkan _~untuk dapatkanC

Cobalah online di sini


3

Haskell , 50 byte

fadalah fungsi mengambil dan mengembalikan a String.

String B hanya satu ruang tunggal, sedangkan C dimulai dengan satu.

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

Cobalah online!

  • _:b=" "menugaskan semua kecuali yang pertama dari spasi dalam string literal ke b, menjadikannya sama dengan m program salinan B.
  • sadalah string input. a:c<-words smembaginya menjadi kata-kata yang dipisahkan oleh ruang, sehingga amenjadi A dan cmenjadi daftar kata-kata yang terdiri dari C. Salinan B diabaikan karenawords meremas beberapa spasi (yang tidak dapat dilakukan oleh sisa program).
  • drop 50sadalah string dengan panjang sama dengan jumlah n salinan B dalam input. drop 50s>>bmenyatukan bahwa banyak salinan b, memberikan mn ruang .
  • unwords$a:(drop 50s>>b):cbergabung dengan semua string kembali bersama dengan spasi. Karena ada "kata" tambahan yang (drop 50s>>b)dimasukkan dalam daftar, ada juga ruang penggabung tambahan, yang secara otomatis menambahkan +1 ke perkalian.

2

Matlab, 85

Pertama kali bagi saya untuk melakukan tantangan abstrak, jadi bagi saya itu lebih merupakan tantangan pengkodean daripada tantangan kode-golf!

Tiga string adalah, tanpa tanda kutip:

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

Cara kerjanya: Saya membagi argumen input pada spasi, sehingga ndapat ditentukan dari jumlah bagian string. B berfungsi sebagai semacam penghitung untuk didapatkanm . Untuk merekonstruksi jawaban saya menggunakan A dan C dari split, ulangi B m * n + 1 kali dan saya memasukkan spasi dengan menggunakan nilai ASCII mereka, sehingga tidak ada pemisahan yang tidak diinginkan terjadi dalam C.

EDIT: ups, tidak sengaja menghitung A + B


1

C (gcc) , 81 byte

Persyaratan untuk mengidentifikasi string tampaknya bertentangan dengan perilaku diizinkan kita yang sewenang-wenang untuk input ilegal, kecuali kita memiliki standar yang agak longgar tentang apa yang memerlukan identifikasi. Secara alami, saya mengambil interpretasi yang paling banyak menghilangkan byte.

Cobalah 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);}

Dengan identifikasi Aku hanya berarti bahwa itu harus jelas dari jawaban Anda yang potongan kode yang A , B dan C . Itu bukan persyaratan untuk program.
Zgarb

1

TI-Basic (83 series), 65 byte

Segmen A (33 byte):

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

Segmen B:

X

Segmen C (32 byte):

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

Saya sangat senang menemukan tantangan seperti ini! Kebanyakan quines tidak bekerja di TI-Basic tanpa setidaknya sedikit kecurangan, karena tidak ada cara untuk melarikan diri dari "simbol. (Dalam kedua arti kata "melarikan diri".) Tapi di sini, kita mendapatkan string input melalui Inputperintah, dan mengetikkan" sana baik-baik saja.

Masih ada sejumlah kekonyolan TI-Basic untuk bekerja di sini: string kosong tidak valid, sehingga solusi naif memasukkan string ke "XXX...XX"dalam sebuah loop tidak akan berfungsi ketika n = 0. Sebagai gantinya, kami menghitung nilai mn + 1 secara manual, dan menyisipkan string "X"itu berkali-kali.

Konstanta sihir 27dan 28dalam program ini adalah sedikit off dari jumlah byte 33 dan 32, karena Str1, sub(, danlength( dua-byte token yang hanya berkontribusi 1 dengan panjang string.

Jika kita menggunakan baris baru alih-alih :, sepertinya kapan dapat menyimpan beberapa byte dengan meninggalkan tanda kutip berakhir, tetapi ini sebenarnya tidak berhasil. Pertama-tama, Anda memerlukan hex editor sebelum Anda dapat menambahkan karakter baris baru ke dalam string: Anda tidak bisa mengetikkannya, karena jika Anda menekan ENTER saat Inputperintah, ia mengirimkan input. Ketika saya mencoba pendekatan hex editor, saya akhirnya mendapatkan kesalahan buffer overflow aneh yang mengubah isi program saya, jadi jangan coba ini di rumah dengan kalkulator mahal Anda.


0

Java 11, 135 65 + 26 = 91 byte

SEBUAH

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

B

B

C

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

Cobalah online sini (TIO belum memiliki Java 11, jadi ini bergantung pada metode penolong alih-alih String::repeat()).

Tidak Disatukan:

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
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.