Alıntı-Güvenli Quines


17

Göreviniz basittir: giriş almayan ve kaynak kodunu veren (veya döndüren) bir program (veya işlev) yazın. Yakalama, program "quotes"(Unicode karakter 34) içine sarıldığında , tekrar (şimdi alıntılanan) kaynak kodunu çıkarmasıdır.

Quines için standart kurallar geçerlidir. Bu , bu yüzden en kısa program (bayt cinsinden) kazanır.


8
@ATaco yaratıcı düşünün. Tırnak içinde kod normalde yürütülmez, ancak tüm programın tırnak içine alındığında bu bölümler vardır idam.
Pavel

1
Hmm, Güzel nokta.
ATaco

Bu, BF ile desteklenen uygulamalarda işe yarayabilir !...
Esolanging Fruit

1
Kullanmalı mısın "? Bazı diller iki veya üç tırnak karakterini destekler.
Neil

1
@tkellehe Meta: Uygun bir soru olarak sayılan nedir? Ben 1 baytlık quine anladığım kadarıyla, en yüksek oy alan yazı formüle formülü kod / veri gereksinimi ihlal.
Laikoni

Yanıtlar:


4

Erişte , 9 7 bayt

Bu sürüm diğeriyle aynı şekilde çalışıyor, sadece Noodel'in bir kez bir kod bloğu çalıştırmak için bir yolu olduğunu unuttum ve dili yaptım ...

Ḷ1ḥ-Ð1ḥ@€

ḷḥ-Ðḥ@ḅ

Dene:)


Nasıl çalışır

ḷḥ-Ðḥ@ḅ # Single statement that builds itself as a string.
ḷ       # Loop the following block of code unconditionally.
 ḥ-     # Push the string literal of the token preceding this one which pushes "ḷ" onto the stack.
   Ð    # Push the stack as an array to stdout (since is an array it is done by reference).
    ḥ@  # Push the string literal for this block of code which pushes "ḥ-Ðḥ@ḅ" onto the stack.
      ḅ # Break out of the given loop. (The stack is now ["ḷ", "ḥ-Ðḥ@ḅ"]).

        # The top of the stack is popped off and displayed which modifies the array to produce {["ḷ"], "ḥ-Ðḥ@ḅ"} in stdout.

Alıntı-Emniyet

Yerleştirme "önce ve çünkü program çalışır sonra karakteri Noodel ben dediğimiz adanmış karakter kümesi vardır Printables . Bunlar, kendileri yerleştirildiklerinde hemen dizgi değişmezleri olarak ayrıştırılırlar ve ekrana bir şeylerin kolayca yazdırılmasını sağlarlar. Bu nedenle, çoğu dilden farklı olarak, Noodel , baskıya layık görülen normal ASCII setini (boşluk ve satır besleme hariç), kodun alıntılanması yalnızca dizeleri itmek olarak görülür.

"ḷḥ-Ðḥ@ḅ"

"         # Pushes on the string literal "\"" onto the stack.

 ḷḥ-Ðḥ@ḅ  # Same execution as before, simply builds the Quine for this loop.
 ḷ        # Loop the following block of code unconditionally.
  ḥ-      # Push the string literal of the token preceding this one which pushes "ḷ" onto the stack.
    Ð     # Push the stack as an array to stdout (since is an array it is done by reference).
     ḥ@   # Push the string literal for this block of code which pushes "ḥ-Ðḥ@ḅ" onto the stack.
       ḅ  # Break out of the given loop. (The stack is now ["\"", "ḷ", "ḥ-Ðḥ@ḅ"]).

        " # Pushes on the string literal "\"" onto the stack.

          # The top of the stack is popped off and displayed which modifies the array to produce {["\"", "ḷ", "ḥ-Ðḥ@ḅ"], "\""} in stdout.

"Dene:)"


Parçacıklar

<div id="noodel" code='ḷḥ-Ðḥ@ḅ' input="" cols="10" rows="1"></div>
<script src="https://tkellehe.github.io/noodel/noodel-latest.js"></script>
<script src="https://tkellehe.github.io/noodel/ppcg.min.js"></script>


<div id="noodel" code='"ḷḥ-Ðḥ@ḅ"' input="" cols="10" rows="1"></div>
<script src="https://tkellehe.github.io/noodel/noodel-latest.js"></script>
<script src="https://tkellehe.github.io/noodel/ppcg.min.js"></script>


Kullanmanın egeçerli olduğunu düşünmüyorum . Soru, bayt 34 olarak kodlanan karakteri değil, Unicode 34 karakterini soruyor. Hangi kodlamayı kullanırsanız kullanın, sadece bir tane var:"
Dennis

@Dennis, söylediğinizi tahmin ediyorum, Unicode karakterine 34 atıfın herkesin aynı şeyi kullandığından emin olmak "mı? (Üzgünüm, sadece ne dediğini anladığımdan emin olmaya çalışıyorum) Ayrıca, cevabın içindeki tüm metni kaldırmaya emı başvurmalıyım ?
17'de tkellehe

1
Evet, binlerce kodlama var, ancak yalnızca bir Unicode karakter kümesi var. Yana "eserleri, sadece tartışma çıkarmak sadece kullanmayı tercih ediyorum ".
Dennis

11

Python 2 3, 181 152 130 124 122 bayt

""" """>" "or exec("oct=0");p='"""" """>" "or exec("oct=0");p=%r;a=oct==0;print(p[a:~a]%%p)#".';a=oct==0;print(p[a:~a]%p)#

Çevrimiçi deneyin! TIO, kininin geçerliliğini otomatik olarak test eden bir üstbilgi ve altbilgi ile birlikte gelir. Sadece kine çalıştırmak için onları temizleyebilirsiniz.

Bu kod, Python'daki üç tırnaklı dizeleri kullanarak çalışır. """ """eşittir ' 've """" """eşittir '" '.

Kod, execverileri yalnızca bir ifadenin içinden bir değişken ayarlamak için kod olarak yürütmenin "quiney olmayan" yolu için kullanmaz. execDüzgün de verilerde kodlanmıştır.

İlk ifade, dizeyi, büyük olasılıkla ekli bir alıntıyla karşılaştırır " "ve değişkeni octbuna göre ayarlar . (Değişken kısa bir yerleşik olabilirdi.)

Kodun geri kalanı, %rdize biçimlendirmesi kullanarak geleneksel Python ayracı uygular ve octdeğiştirilmezse fazladan tırnak işaretlerini ekleyen bazı ek kodlarla birlikte .

"Cheaty" kullanan alternatif bir sürüm exec, daha az tekrarlanan kodla 126 baytta gelir:

""" """>" "and exec("oct=0");s='"""" """>" "and exec("oct=0");s=%r;p=%r;exec(p)#".';p='a=oct!=0;print(s[a:~a]%(s,p))';exec(p)#

Çevrimiçi deneyin!


7

StandardML , 182176108 bayt

";str(chr 34)^it;(print(it^it);fn x=>print(x^it^x^it))";str(chr 34)^it;(print(it^it);fn x=>print(x^it^x^it))

Tırnaksız sürüm: Kodlama alanında deneyin.
Alıntılanan sürüm: Kodlama alanında deneyin.

Çıktının böyle bir şeye benzediğini unutmayın

> val it = "{some string}" : string
> val it = "{some string}" : string
{output to stdout}> val it = fn : string -> unit

çünkü kod bildirimi bildirimle (her biri ;bildirimi bitirir) yorumlanır ve her bildirimin değerini ve türünü gösterir.


Arka fon

SML'de formun bir örneği vardır <code>"<code in quotes>":

str(chr 34);(fn x=>print(x^it^x^it))"str(chr 34);(fn x=>print(x^it^x^it))" 

ve biri şu şekildedir "<code in quotes>"<code>:

";str(chr 34)^it;print(it^it)";str(chr 34)^it;print(it^it)

Her ikisi de, <code>-part'ın tırnak içermediğine güvenir ve bu nedenle herhangi bir şeyden kaçma ihtiyacı olmadan alıntılanabilir," çıktısı için gerekli str(chr 34).

Ayrıca, örtük tanımlayıcıya da büyük ölçüde güvenirler. it , bir bildirimde açık bir tanımlayıcı verilmediğinde kullanılan .

İlk quine içeren dizeye str(chr 34);bağlanır , bir argüman alarak anonim bir işlevi başlatır , sonra sonuçta oluşan dizeyi birleştirir ve yazdırır. Bu anonim işlev doğrudan program kodunu içeren bir dizeye uygulanır, böylece birleştirme sağlarit"fn x=>xx^it^x^itx^it^x^it<code>"<code>" .

İkinci quine dizesi olarak sadece program kodu ile başlar ";str(chr 34)^it;print(it^it)";bağlıdır it. Daha sonra str(chr 34)^it;bir dizginin başlangıcına bir teklif birleştirir ve yine açık bir tanımlayıcı verilmediği için, elde edilen dize "<code>bağlanır it. Sonunda print(it^it)dizeyi "<code>"<code>, daha sonra yazdırılan kendisi ile birleştirir .


açıklama

Düzenleme: Artık 108 baytlık sürümle güncel değil, ancak bu açıklamayı okuduktan sonra da anlayabilirsiniz.

Alıntı güvenli quine yukarıdaki yaklaşımların her ikisini de birleştirir ve formun kendisidir "<code>"<code>. Bunu tekrar tırnak içine almak getirisi""<code>"<code>" almak, böylece boş bir dize ve daha sonra diğer formun bir quine elde ederiz.

Bu, programın ya "<code>tanımlayıcı tarafından kendi kaynağında verildiği itya itda sadece "ve bizim kaynağımızın <code>argüman olarak verildiği ve bu nedenle böyle bir argümanı işleyen bir işlev olması gerektiği anlamına gelir.

(if size it>1then(print(it^it);fn _=>())else fn x=>print(it^it^x^it^x^it))

Hangi durumda olduğumuzu belirlemek için, boyutunun it1'den büyük olup olmadığını kontrol ederiz . Değilse o zaman itöyle "ve ikinci durumdayız, bu nedenle else-part fn x=>print(it^it^x^it^x^it), daha sonra çağrıldığı için anonim bir işlev döndürür; . Liderliğe dikkat edinit^it^ programın başında boş dize için gereklidir.

Eğer size itiçinde bulunduğumuz 1'den büyüktür then-bölümüne ve sadece gerçekleştirmek print(it^it), hakkını? Tam olarak değil, çünkü size SML'nin güçlü bir şekilde yazıldığını söylemeyi ihmal ettim, bu da bir koşulun if <cond> then <exp_1> else <exp_2>her zaman aynı türe sahip olması gerektiği anlamına gelir, bu da ifadelerin <exp_1>ve <exp_2>aynı tipte olması gerektiği anlamına gelir . Parçanın türünü zaten biliyoruz else: Bir dize alan ve daha sonra çağrı yapan anonim bir fonksiyonun printtürü vardır string -> <return type of print>ve printtürü vardır string -> unit( unitbir şekilde voiddiğer dillerde benzer ), bu nedenle ortaya çıkan tür tekrar olur string -> unit.

Yani thenparça sadece print(it^it)türü olan unitolsaydı, bir tür uyumsuzluğu hatası alırdık. Peki nasıl fn _=>print(it^it)? ( _Kendi başına Bu anonim fonksiyonu türünü etti kullanılmayan bir argüman için joker karakterdir) öylesine bir zorlar koşullu bağlamında, keyfi bir tipine karşılık gelmektedir bu işe yarar türü. (Type değişkeni type ile somutlaştırılır .) Ancak, bu durumda anonim işlev asla çağrılmadığından hiçbir şey basmazdık! Biz giderken Unutmayın genel kodudur -bölümüne nedenle, bu onun aramadı sonra hiçbir şey geliyor gibi bir işleve -part değerlendirir ama.'a -> unit'astring -> unit'astringthen"<code>"<code><code>

Bunun yerine formu olan bir sequentialisation kullanmak için keyfi türleri ve türü olabilir bütün sequentialisation türünü sağlar. Değerleri bakış fonksiyonel açıdan etmek ifadeler yan etkileri olabilir bu yüzden sadece atılır, ancak SML da zorunlu yapıları destekler. Kısacası, -part olarak alırız , böylece önce yazdırırız ve sonra doğru tipe sahip işlevi döndürürüz .(<exp_1>; ...; <exp_n>)<exp_1><exp_n-1><exp_n><exp_1><exp_n-1>(print(it^it);print)thenprint


7

V , 27 , 23 bayt

éPñi"éP241"qpá"lxx|xÿ

Çevrimiçi deneyin!

Bu bazı yazdırılamayan karakterler içerdiğinden, okunabilir bir sürüm:

éPñi"éP<C-v>241<esc>"qpá"lxx|xÿ

ve burada bir hexdump var:

00000000: e950 f169 22e9 5016 3234 311b 2271 70e1  .P.i".P.241."qp.
00000010: 226c 7878 7c78 ff                        "lxx|x.

Yapmamız gereken ilk şey, ilk karakterin bir alıntı olup olmadığını belirlemektir. éPbir 'P' karakteri ekler, ancak "éPbir NOOP'dir. Bundan sonra, standart uzatılabilir kine üzerinde küçük bir değişiklik yaparız:

ñi<C-v>241<esc>"qpÿ

Yine de biraz farklı yapacağız. Öncelikle başlangıç ​​"éP" metnini eklememiz gerekiyor. Yani yapıyoruz

ñ                        " Start recording into register 'q'
 i                       " Enter insert mode
  "éP<C-v>241<esc>       " Enter the following text: '"éPñ'
                  "qp    " Paste the text in register 'q'
                     á"  " Append a '"'

Dallanma burada gerçekleşir. Şu anda arabellekte bulunan metin

"éPñi"éP<C-v>241<esc>"qpá"P
Cursor is here ----------^

Tırnak içine almazsak, bu durumda 'P' asla eklenmezdi ve tampon:

"éPñi"éP<C-v>241<esc>"qpá"
Cursor is here ----------^

Hala kaydettiğimiz için burada istediğimizi yapabiliriz ve "qpgerçekleştiğinde ara belleğe eklenir . Yani buradan şartlı olarak tırnak işaretlerini silmek oldukça kolaydır:

l           " Move one character to the right. If there is no character to the right, 
            " then this is effectively a "break" statement, stopping playback of the recording
 xx         " Delete two characters (the '"P')
   |        " Move to the first character on this line
    x       " Delete one character
     ÿ      " End the program

3

JavaScript (ES6), 239 237 bayt

Set=``;eval(";a='Set=``;eval(~;a=1;S=String.fromCharCode;q=S(34);r=Set&&q;s=S(39);alert(r+a.replace(/[^ -}]/g,q).replace(1,s+a+s)+r);~)';S=String.fromCharCode;q=S(34);r=Set&&q;s=S(39);alert(r+a.replace(/[^ -}]/g,q).replace(1,s+a+s)+r);")

Her sürümü yeni bir ortamda denemeye dikkat edin (örn. Yeni bir tarayıcı sekmesi)

Bunu basitleştirmenin en az bir yolu olmalı ...


1
Sanırım yerine için bir dizi kullanabilirsiniz: [x = "replace"]. Bir şeyleri kırabilir, quines konusunda çok tecrübeli değilim ...
Luke
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.