APL (158 karakter, puan = 4)
'''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0
Burada Dyalog APL kullanıyorum. Döngü sayısı 0
, ifadenin sonuna ve dizgenin sonuna (önce '''
) eklenerek (0 boşluk bırakılarak) bir artırılabilir . Döngü uzunluğu (# 0's) + 1
ve ifadenin uzunluğu 150 + 4*(cycle length))
. Sonsuza sıfırları ekleyerek devam varsayarsak, puanıdır Limit[(150 + 4*n)/(n - 1), n -> Infinity] = 4
, nerede n
döngüsü uzunluğudur.
İşte döngü uzunluğu = 6 olan bir örnek:
'''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0
0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0
0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0
0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0
0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0
0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0
0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0
0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0
0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0
0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1
0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1
'''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0
192 karakter, puan = 2
'''{2≠⍴⍺:¯3⌽(2×1+⍴⍺)⍴(1+⍴⍺)⍴⍺ ⋄ a←⊃2⌷⍺ ⋄ ⍵=0:¯2⌽(2×1+⍴a)⍴(1+⍴a)⍴a⋄(-4+⌊10⍟⊃⍺)⌽(2×1+⍴a)⍴(1+⍴a)⍴a}01'''{2≠⍴⍺:¯3⌽(2×1+⍴⍺)⍴(1+⍴⍺)⍴⍺⋄a←⊃2⌷⍺⋄⍵=0:¯2⌽(2×1+⍴a)⍴(1+⍴a)⍴a⋄(-4+⌊10⍟⊃⍺)⌽(2×1+⍴a)⍴(1+⍴a)⍴a}01
Uygulamaya bağlı olarak, bir başarısızlık noktası dizgeye önceden verilen tam sayı çok büyük olduğunda olabilir. Teorik olarak, iki karakter ekleyerek bir döngü ekleyebiliriz - a 1
dize sonunda (önce '''
) ve a 1
satırın sonunda.
200 karakter, puan = 1
'''{a←{2=⍴⍵:⊃2⌷⍵⋄⍵}⍺⋄(⍺{⍵=9:⍬⋄⍕1+{2=⍴⍵:10×⊃⍵⋄0}⍺}⍵),(¯2⌽(2×1+⍴a)⍴(1+⍴a)⍴a),⍺{⍵=9:(⍕9),⍕⊃⍺⋄⍕⌊⍵÷10}⍵}'''{a←{2=⍴⍵:⊃2⌷⍵⋄⍵}⍺⋄(⍺{⍵=9:⍬⋄⍕1+{2=⍴⍵:10×⊃⍵⋄0}⍺}⍵),(¯2⌽(2×1+⍴a)⍴(1+⍴a)⍴a),⍺{⍵=9:(⍕9),⍕⊃⍺⋄⍕⌊⍵÷10}⍵}91
APL uygulamamın varsayılan olarak sınırsız hassas tamsayıları yoktur, bu nedenle tamsayı, çıkışın yanlış olmasına neden olacak şekilde çok büyük olduğunda bir kayan noktaya dönüştürülür. Yani bu en titiz, ancak teorik olarak (elle ya da farklı bir APL yorumlayıcısıyla), 1 puanına sahip olmalıdır 1
.
Genel bakış (daha kısa quine ile)
İlk versiyonun bir özetini vereceğim, çünkü en kolay anlaşılması en kolay şey bence. Bununla birlikte, bu versiyonla mücadele etmeden önce, APL'de basit bir quine düşüneceğiz :
1⌽22⍴11⍴'''1⌽22⍴11⍴'''
Bazı APL ifadelerini anlamanın en iyi yollarından birinin, operatör / fonksiyon dizisi boyunca çıktıya bakmak olduğunu buldum. APL'deki tüm operatörler ve fonksiyonlar sağdan ilişkilidir ve aynı önceliğe sahiptir, bu yüzden işte, sağdan sola:
'''1⌽22⍴11⍴'''
: Bu sadece bir dize değişmezi (bir karakter listesi). ''
Tekli alıntı işaretlerinden kaçan APL yoludur. Çıktı: '1⌽22⍴11⍴'
.
11⍴'''1⌽22⍴11⍴'''
: Burada, ⍴
uzunluğa sahip olan dizgiyi reshape ( ) yapıyoruz 11
. İpin uzunluğu 11'in altında olduğu için tekrar edilir (yani 5⍴'abc'
verim 'abcab'
). Çıktı: '1⌽22⍴11⍴''
. Şimdi sonunda iki tırnak işaretimiz var - bir yerlere geliyoruz!
22⍴11⍴'''1⌽22⍴11⍴'''
: Benzer şekilde, şimdi eski çıktımızı uzunluk olarak yeniden şekillendiriyoruz 22
. Çıktı: '1⌽22⍴11⍴'''1⌽22⍴11⍴''
. Neredeyse ordayız - ilk teklifi tek tek sonlandırmamız gerekiyor.
1⌽22⍴11⍴'''1⌽22⍴11⍴'''
: Burada, ⌽
karakter listesini döndürerek ( ) döndürüyoruz 1
. Bu, dizenin ilk karakterini sonuna kadar hareket ettirir. Başka bir örnek olarak, 2⌽'abcdef'
döner 'cdefab'
. Çıktı: 1⌽22⍴11⍴'''1⌽22⍴11⍴'''
.
Dönen quine
Bu kısa yüzgeç, dönen yüzüğümüzün temel dayanağıdır. Şimdi, bunu aklımızda tutarak, sıranıza bir göz atalım:
'''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0
{ ... }
İşi yapacağımız yerin adı belli olmayan bir işlev tanımlar. APL'deki işlevlerin, işaretiyle gösterilen bir argüman ve işaretiyle gösterilen ⍵
isteğe bağlı bir sol argüman aldığını unutmayın ⍺
(eki düşün). Bu işlevi hem sıra dizgemizi hem de rasgele sayıda döngü oluşturmamıza yardımcı olacak bir şeyi beslemek istiyoruz. Kendimizi daha kolay hale getirmek için (ve döngü eklemek isteyen herkes), quine dizesini sol argüman haline getirdik. Öyleyse doğru argüman, döngü listemizi koyduğumuz yerdir. Bir boşlukla ayrılmış 2 veya daha fazla öğe bir liste oluşturur, bu nedenle bu örnekte a 1
ve a'dan oluşan 2 elementli bir listeye sahibiz 0
.
İşlevin öncekinden sıfıra benzer olduğunu görüyoruz. Daha önce de aynı ...⌽...⍴...⍴...
formdayız. Yani bu iyi - en azından bu kadarını anlıyoruz! En son sonraki her şeyi ile başlayan, elips derinliklerine defterleri edelim ⍴
: ⊃,/(~^/¨⍺=0)/⍺
.
- Yukarıdaki örneğe bakarak görebileceğiniz gibi, her bir yinelemeye bir tane ekleyerek, sağ taraftaki 0'lı dizeyi önek olarak ekleriz; ama şu an onları umursamıyoruz. Sadece ipi istiyoruz!
- İlk önce parantez içinde ne olduğunu düşünün. (Bu arada diğer birçok dilde olduğu gibi gruplaşırlar.)
⍺=0
aynı şekle sahip, bu durumda, bir listesini verir ⍺
her eleman, ⍺
bir ile değiştirildiği 1
bu eşit ise 0
ve 0
aksi. Bu özyinelemeli bir şekilde gerçekleştirilir; bu nedenle, bir karakter listesinin bir listesine sahipsek, bireysel karakterler 0'a karşı test edilir ve bir ikili değerler listesinin listesini geri alırsınız.
- Yani
⍺
sadece dizgemizden oluşuyorsa, 0'ların listesini geri alırız. Aksi halde, sol argümanımıza önceden eklenmiş bazı 0'lar vardır (örneğin, 0 0 0 'quinestring'
), bu nedenle dizgimizden 0'lardan ve başka bir listeden oluşan bir listedir. O zaman çıktılarımız şuna benziyor 1 1 1 <sub-list of zeros>
.
^/¨⍺=0
: Mantıksal AND ( ) işlevini kullanarak ( ) değerini ^/
azaltan türetilmiş işlevi her bir ( ) öğeye uygularız . Bu, sıfırın alt listesini düzleştirerek quine dizesini bir ikili değer olarak düşünebiliriz. Önceki örnek göz önüne alındığında, çıkış olacaktır ./
^
¨
⍺=0
1 1 1 0
~
: Önümüzdeki değerlerin her birini ikili DEĞİLDİR (örneğin, dönen 0 0 0 1
).
(~^/¨⍺=0)/⍺
: İçindeki her eleman için ⍺
, /
sol argümanda karşılık gelen eleman tarafından verilen sayıyı ( ) çoğaltırız . Bu, tüm 0'ları ortadan kaldırarak bizi sadece quine dizemizle birlikte bırakır.
⊃,/
Sonuç birleştirme işleviyle ( ,
) azaltılarak düzleştirilmiş bir karakter listesini geri almamızı sağlayan gerekli evraklardır . Girdi zaten düzleştirilmiş bir liste ise (yani, ana işlevimizin sol argümanı yalnızca dizedir), bu listeyi içeren 1 öğeli bir liste alırız. Diğer durumda, dize için bir alt listeden oluşan bir listemiz olduğunda, aynı şeyi geri alırız (bir alt listeye sahip bir liste). Daha sonra bu ( ⊃
) karakterini açarak bize yalnızca listenin ilk elemanını (yani karakterlerin alt listesini) veriyoruz. Bu gereksiz görünebilir, ancak aksi halde 1 elemanlı bir listeyi yeniden şekillendirmeye çalışıyor oluruz!
Sonra, parantez içinde ilk yeniden şekillendirme için verilen uzunluğa bakarız:
⍺,⍵
: Doğru argümanı ilk argümanla birleştiriyoruz
⊃,/⍺,⍵
: Önceki ile aynı - listeyi düzleştirin.
+/0=⊃,/⍺,⍵
: Listedeki sıfıra, include /
( +
) işlevini kullanarak ( ) yaparak ekleyin .
2×+/0=⊃,/⍺,⍵
: Bu sayıyı iki ile çarpın.
z←2×+/0=⊃,/⍺,⍵
: Sonucu ←
değişkene atayın ( ) z
. Özetlemek gerekirse z
, şimdi hem sol hem de sağ argümanlarda bulunan sıfır sayısının iki katı.
77+z←2×+/0=⊃,/⍺,⍵
: Ardından 77
, quine dizesindeki karakterler için, boşluktan sonra her şeyi göz ardı ederek ekledik 1
. İlk quine örneğinde olduğu gibi, başka bir tek teklif almak için dizenin uzunluğuna 1 ekleriz.
- Bu yeniden şekillendirmenin çıktısı, bu örnekte:
'{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 ''
Takip eden yeniden şekillendirme argümanı basittir ve kısa quine (ilk yeniden şekillendirme için uzunluğun 2 katı) yansıtır. Şimdi çıktılarımız:
'{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 ''
Şimdi son adım için çıktı dizesini ne kadar döndüreceğinizi hesapladığımız yer:
- Önceki çıktıya bakarak görebileceğiniz gibi, son 2 alıntıyı başa getirmek için geri döndürmek (negatif bir miktar) istiyoruz. Çünkü biz
0
(ve başka bir boşluğun) en başa hareket etmesini istiyoruz, onu 3 karakter daha geri döndürmek istiyoruz.
+/+/¨⍺=0
: Soldaki bağımsız değişkene sıfır sayısını ekleyin . Birincisi (sağdan), +/¨
her bir öğenin sayımını (yani bir alt +/
liste veya sadece bir tamsayı) toplar ve ikincisi bize sonuçta ortaya çıkan listenin toplamını verir.
5+2×+/+/¨⍺=0
: İki ile çarp (boşlukları da döndürmek için) ve 5 (daha önce bulduğumuz sonuç) ekleyin.
- Şimdi,
-
döngünün sonuna geldiğimizde durumu ele almak için önceki değeri soldaki argümandan çıkardık:
(3+z)×^/⍵
: AND, argümandaki tüm öğelerin bir araya gelip gelmediğini görmek için birlikte ( 1
), ve bunu çarpınız 3+z
.
Ve biz bitti!