Kendi Kendini Değiştirme ile Çarpma


33

... en azından bazı "kendini değiştirme" tanımı için.

Görev

Bu meydan okuma olarak, görev üç dizeleri yazmaktır A, Bve Co aşağıdaki özellikleri karşılamaktadır.

  • Dize Buzunluğu en az 1'dir.

  • Her biri için n ≥ 0, dize seçtiğiniz programlama dilinizde geçerli bir programdır (tam çalıştırılabilir program veya işlev tanımı anlamına gelir). Üstindis O anlamına gelir tekrarlama, bu yollarla böylece dizeleri , , , vb Her program girdi olarak bir dize alır ve döner çıktı olarak tek bir dize.ABnCACABCABBCABBBC

  • Herhangi biri m, n ≥ 0için program girişle çalışıyorsa , döndürür . Bu formda olmayan girdiler için, program çökme dahil her şeyi yapabilir.ABmCABnCABm*n+1C

Formattaki bazı örnekler 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

Kurallar ve Puanlama

Puanınız toplam uzunluğu AveC düşük puanın daha iyi olması. İse bu Not Bpuanı doğru sayılmaz, bu üretilebilir olmalıdır Ave Cbirinci örnekte olduğu gibi.

Standart boşluklara izin verilmez. Programların doğrudan veya dolaylı olarak kendi kaynak kodlarına erişmelerine izin verilmez (girdi olarak verilmediklerinde hariç). Sen dizeleri tanımlamak için gerekli olan A, Bve Cbir şekilde Yanıtınızda ve çözümünüzü açıklamaya teşvik etti.

Yanıtlar:


16

CJam, 9 8 bayt

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

CJam tercümanında çevrimiçi olarak deneyin .

Nasıl çalışır

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

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

CJam tercümanında çevrimiçi olarak deneyin .

Nasıl çalışır

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.

Sonunda, yığında okunan token r, tarafından üretilen alan *, itilen alan ve satır beslemesi ve satır tarafından SNokunan satır bulunur q. CJam tüm bunları otomatik olarak yazdırır.


Hah, orada tırnak güzel kullanımı: D
Doktor

9

Pyth, 10

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

Kaynağı iki satıra bölüyoruz. İlk satır A, ikinci satır Bs. A ilk sırada olduğundan, ilkw A yazdırır - kolay, yapılır.

Pyth lider sıfır yani ayrı jetonladır [00)aslında [0, 0]. İlk satırın sona erdiğini l[ve ikinci satırın oluştuğunu unutmayın 0000.... Yani l[aslında bu programdaki Bs sayısını sayar. İkinciw girişin ikinci satırında okur - bu girişin Bs sayısıdır. Buradan basit bir çarpma, artan ve artan bu sıfırlar.


9

Retina , 25 19 bayt

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

<LF> stands for newline

Örnek ABCkod:

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

Kodun iki yedek adımı vardır:

  • girişini değiştirmek AB^mCiçine AB^(m*n)Cher değiştirerek Biçin B^n:

    • ]\] her biriyle eşleşir BDesen çizgilerinde kaçış sayesinde girdi içindeki şey ile
    • ]]...]] olduğu B^n
  • değişim B^(m*n)içinB^(m*n+1) tarafından

    • m`^]*$ sadece çizgiyi alarak ] 's
    • ]$0]]]bu çizginin ilk regex ile eşleşmeyeceği şekilde ona fazladan bir çift eklemek

İçin puanına 3 bayt ekledim -sTüm Retina kodunun tek bir dosyada olabilmesi için gereken çok hatlı bayrak .

@ MartinBüttner sayesinde 2 bayt kaydedildi.


8

Python 3, 51 bayt

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

Örnek kullanım:

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

Fonksiyon değerlerini hesaplar n*m+1ile (1+len("xxx")*(len(s)-51))olduğu yerde m xdizede 'ın ( xxxkısmıdır B^m). Dizenin "x"bu sayıyla çarpılması B^(n*m+1)işlevi verir ve işlev girdiyi alır Ave Cçıkarır ve bunları almak için birleştirir AB^(n*m+1)C.

J de aynı yaklaşım:

J, 35 bayt

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

5

CJam, 22

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

Örnek çalışma:

ABBC(ABC) -> ABBBC

hangi çevirir

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

girişi olan

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

aşağıdaki çıktıyı verir:

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

Nasıl çalışır :

Ne programlara bir göz atın sağlar ACve ABCbenzeri bir görünüm:

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

Bunu fark ettik C=B_~

Ne Byaptığına bakalım :

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

Şimdi ACherhangi bir girdi olmadan çalışmanın ne yapacağını görelim :

{])`\,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/(*))*"_~"}_~

Vay, çıktı ABC.

Temel Bolarak kodda kaç tane bulunduğunu sayarız . Sonra girişte kaç tane var (uzunluk kullanarak). Bunları çarpın, iki kez artırın ( Caynı zamanda vardır B) ve _~elde etmek için ekleyin .C

Burada çevrimiçi deneyin


3

Haskell , 50 bayt

f bir işlevi alan ve geri dönen bir işlevdir. String .

B dizesi sadece tek bir boşluktur, C ise bir tane ile başlar.

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

Çevrimiçi deneyin!

  • _:b=" "atar tüm ama dize hazır bilgi için alanların ilk bprogramın bu eşit hale m B kopya.
  • sGiriş dizesidir. a:c<-words sonu boşlukla ayrılmış sözcüklere böler, böylece aA olur ve cC'yi içeren kelimelerin bir listesi haline gelir words.
  • drop 50sgirişdeki B kopya n sayısına eşit uzunlukta bir dizedir . drop 50s>>bbirçok kopyasını mn boşluk bvererek birleştiriyor .
  • unwords$a:(drop 50s>>b):ctüm telleri boşluklarla birlikte birleştirir. (drop 50s>>b)Listeye eklenmiş bir "kelime" olduğu için, + 1'i çarpıma otomatik olarak ekleyen fazladan bir birleştirme alanı da vardır.

2

Matlab, 85

İlk kez böylesine soyut bir meydan okuma yapmamı sağladı, bu yüzden benim için kod-golf mücadelesinden çok bir kodlama mücadelesiydi!

Üç karakter, tırnak işaretleri olmadan:

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

Nasıl çalışır: Ben girdi argümanını boşlukta bölerim, böylece ndize bölümlerinin sayısından belirlenebilir. B almak için bir çeşit sayaç gibi çalışır.m . Cevabı yeniden oluşturmak için A ve C'yi bölmeden kullanıyorum, B m * n + 1 kez tekrar ediyorum ve boşlukları ASCII değerlerini kullanarak yerleştiriyorum, böylece C'de istenmeyen bölmeler oluşmuyor.

EDIT: boğmaca, yanlışlıkla A + B olarak sayılır


1

C (gcc) , 81 bayt

Dizeleri belirleme zorunluluğu, tanımlayıcı ne gerektirdiğine dair gevşek standartlar olmadıkça, yasadışı girdi için keyfi davranışlara izin verilme ihtimalimiz gibi görünüyor. Doğal olarak, en çok baytı tutan yorumu aldım.

Çevrimiçi deneyin!

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

Tanım olarak sadece cevabınızın hangi kod parçacıklarının A , B ve C olduğu konusunda net olması gerektiğini kastettim . Program için bir gereklilik değil.
Zgarb

1

TI-Basic (83 serisi), 65 bayt

Segment A (33 bayt):

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

B Bölümü:

X

Segment C (32 bayt):

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

Bu quine benzeri mücadeleyi bulmak için gerçekten heyecanlıyım! Çoğu kuyruk TI-Basic'te en azından küçük bir hile yapmadan çalışmaz, çünkü "sembolden kaçmanın yolu yoktur . (Her iki anlamda da "kaçış" kelimesini kullanın.) Ama burada, Inputkomut aracılığıyla bir girdi dizgisi alıyoruz ve" oraya gayet iyi.

Buralarda çalışmak için hala bir miktar TI-Basic aptallığı var: boş bir dize geçersiz, bu nedenle dizeyi "XXX...XX"bir döngüye eklemek için naif bir çözüm n = 0 olduğunda çalışmaz. Bunun yerine, mn + 1'in değerini el ile hesaplıyoruz ve dizeyi "X"birçok kez ekliyoruz.

Sihirli sabitler 27ve 28programda biraz byte sayısı 33 ve 32 kapalı olduğu için Str1, sub(velength( sadece bir dizi uzunluğuna 1 katkıda bulunan iki baytlı simgeler bulunmaktadır.

Bunun yerine yeni satırlar kullanırsak, sondaki :tırnak işaretlerini bırakarak birkaç bayt ne zaman tasarruf edebileceğimize benziyor, ancak bu gerçekten işe yaramıyor. Öncelikle, newline karakterini bir dizgeye eklemeden önce bir hex editörüne ihtiyacınız vardır: sadece yazamazsınız, çünkü bir Inputkomut sırasında ENTER tuşuna basarsanız , girişi gönderir. Onaltılı editör yaklaşımını denediğimde, programımın içeriğini değiştiren tuhaf bir arabellek taşması hatası alıyorum, bu yüzden bunu evinizde pahalı hesap makinenizle denemeyin.


0

Java 11, 135 65 + 26 = 91 bayt

bir

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

B

B

C

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

Burada çevrimiçi deneyin (TIO'da henüz Java 11 yoktur, bu nedenle bunun yerine bir yardımcı yöntem kullanılır 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
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.