Haskell , 3 quines, 1119 bayt
Quine 1, 51 bayt
IO
Doğrudan stdout'a yazdıran anonim bir işlem.
putStr`mappend`print`id`"putStr`mappend`print`id`"
Çevrimiçi deneyin!
Quine 2, 265 bayt
İşlev f
kukla bir argüman alır ve bir dize döndürür.
f c=[b=<<g]!!0++show g;b c=[[[show 9!!0,show 1!!0..]!!6..]!!c];g=[93,0,90,52,82,89,52,51,51,94,84,24,24,39,34,34,106,95,102,110,0,94,50,89,0,90,52,82,82,82,106,95,102,110,0,48,24,24,39,35,106,95,102,110,0,40,24,24,39,37,37,84,24,24,45,37,37,84,24,24,90,84,50,94,52]
Çevrimiçi deneyin!
Quine 3, 803 bayt
LANGUAGE
Pragma'dan sonraki her şey , sahte bir argüman alan ve bir ip döndüren muazzam bir fonksiyondur.
{-#LANGUAGE CPP#-}(\q(_:_:_:_:_:_:_:_:z)y(#)_->(y(\k x->'&':q:k:q:x)#y(\k x->'%':q:'\\':k:q:x)$y(:)#y(:)$ \x->x)z)'\''__TIME__(\(?)v k x->v$k?x)$ \(&)(%)v->v&'{'&'-'&'#'&'L'&'A'&'N'&'G'&'U'&'A'&'G'&'E'&' '&'C'&'P'&'P'&'#'&'-'&'}'&'('%'\\'&'q'&'('&'_'&':'&'_'&':'&'_'&':'&'_'&':'&'_'&':'&'_'&':'&'_'&':'&'_'&':'&'z'&')'&'y'&'('&'#'&')'&'_'&'-'&'>'&'('&'y'&'('%'\\'&'k'&' '&'x'&'-'&'>'%'\''&'&'%'\''&':'&'q'&':'&'k'&':'&'q'&':'&'x'&')'&'#'&'y'&'('%'\\'&'k'&' '&'x'&'-'&'>'%'\''&'%'%'\''&':'&'q'&':'%'\''%'\\'%'\\'%'\''&':'&'k'&':'&'q'&':'&'x'&')'&'$'&'y'&'('&':'&')'&'#'&'y'&'('&':'&')'&'$'&' '%'\\'&'x'&'-'&'>'&'x'&')'&'z'&')'%'\''%'\\'%'\''%'\''&'_'&'_'&'T'&'I'&'M'&'E'&'_'&'_'&'('%'\\'&'('&'?'&')'&'v'&' '&'k'&' '&'x'&'-'&'>'&'v'&'$'&'k'&'?'&'x'&')'&'$'&' '%'\\'&'('&'&'&')'&'('&'%'&')'&'v'&'-'&'>'&'v'
Çevrimiçi deneyin!
Karakterler
Quine 1:
"S`adeimnprtu
Quine 2:
!+,.0123456789;<=[]bcfghosw
Quine 3:
#$%&'()-:>?ACEGILMNPTU\_kqvxyz{}
Nasıl çalışır
Quine 1
putStr`mappend`print`id`"putStr`mappend`print`id`"
Quine 1 Benim son değiştirilmiş bir versiyonu Golf sana quine (H.PWiz tarafından geliştirmelerle) cevap:
- Tam programlar gerekli olmadığından,
main=
kaldırılmıştır.
<>
ve $
onların yakın eş anlamlıları mappend
ile değiştirilmiştir id
.
Bu , diğer karakterlerde hayati karakterleri =<>
ve yardımcı operatörü serbest bırakır $
.
Quine 2
f c=[b=<<g]!!0++show g;b c=[[[show 9!!0,show 1!!0..]!!6..]!!c];g=[93,0,......]
Quine 2, son Mutual Exclusive Exclusive Quines cevabımın 2 programını programlamak için biraz benzer yöntemler kullanıyor , ancak doğrudan kendi için quine ve özellikle de quin 3 için gerekli olan karakter değişmezlerini kullanmaktan kaçınmak için uyarlandı.show
fonksiyonun Şans eseri, henüz kullandığı hiçbir karaktere sahip değildi.
Bu quine boşluk yerine sekmeleri kullanıyor, ancak okunabilirlik için aşağıdaki boşlukları kullandım.
g
Kodun sonundaki tamsayıların listesi olarak quine verileridir. Her sayı, kodun geri kalanından bir karakter gösterir.
- Sayılar,
9
o sekme olacak şekilde kaydırılır 0
. Bu, fonksiyon için küçük harflerin ve değişken adlarının 2 basamağa sığmasına izin vererek kodlamayı biraz kısaltır.
b c=[[[show 9!!0,show 1!!0..]!!6..]!!c]
sayıyı karaktere dönüştürmek için kullanılan bir işlevdir (aslında bir karakterlik bir dize).
[[show 9!!0,show 1!!0..]!!6..]
ile dizine eklenmiş bir sekme karakteriyle başlayan bir karakter aralığıdır !!c
.
- Sekme karakterinin kendisi başka bir dizine indeksleyerek
[show 9!!0,show 1!!0..]
, rakam karakterleriyle başlayan '9'
ve '1'
8 adımda aşağı atlayarak üretilir .
- Rakam karakterleri
show
, karşılık gelen rakamın dizgisine indekslenerek üretilir .
f c=[b=<<g]!!0++show g
ana işlevidir. c
kukla bir argümandır.
b=<<g
kullandığı =<<
her sayı dönüştürmek için g
onun karakterine. ( =<<
Örneğin yerine map
, neden b
döndürülen karakterini bir listeye sarması gerektiğinin nedenidir .)
show g
g
'in listesinin string gösterimini verir ve ++
dizeleri birleştirir.
- Çünkü
=<<
daha düşük önceliğe sahip ++
, biraz parantez gerekli. Kullanmamak için ()
(3. [...]!!0
sıraya ayrılmıştır), bir element içeren bir listeye endekslenir.
Quine 3
Diğer kuyrukların tasarımına göre, 3. sıra hala parantez, lambda ifadeleri, karakter değişmezleri ve string / list yapıcısına erişebiliyor :
. Bu , quine kodunu bir dizeye hazırlayan bir fonksiyon oluşturmak için yeterli olacaktır .
Ne yazık ki, tüm küçük harfli ünlüler (bazen hariç y
) kullanılmış ve faydalı alfanümerik yerleşik işlevler bırakılmamış. Ayrıca []""
gitti. Bu , kodu gibi davranmaya başlamak için boş bir dize oluşturmak için normal bir yol bırakmaz.
Bununla birlikte, neredeyse tüm büyük harfler hala mevcuttur, bu nedenle LANGUAGE
dil uzatması için bir pragma mümkündür. Yine tam şans, CPP
(C önişlemcisini etkinleştir) yalnızca büyük harflerle adlandırılan tek dil uzantısıdır. CPP makroları genellikle büyük harf adlarına sahiptir.
Böylece, temel boş dizgiyi elde etmek için, quine , formun bir dizgisi sabiti elde etmek için makroyu CPP
kullanır (her zaman aynı uzunlukta olması uygun şekilde garanti edilir) ve desen üzerinde eşleşir.__TIME__
"??:??:??"
{-#LANGUAGE CPP#-}(\q(_:_:_:_:_:_:_:_:z)y(#)_->(y(\k x->'&':q:k:q:x)#y(\k x->'%':q:'\\':k:q:x)$y(:)#y(:)$ \x->x)z)'\''__TIME__(\(?)v k x->v$k?x)$ \(&)(%)v->v&'{'&'-'&......
Dil pragmasından sonra, quine, parametrelerini bu dört argümana bağlayan bir lambda ifadesinden oluşur ( _
daha sonra uygulanacak son bir boş parametre bırakarak ):
q
bağlı '\''
, tek bir alıntı karakteri vererek;
_:_:_:_:_:_:_:_:z
bağlı __TIME__
gibi bir dize aka "??:??:??"
böylece yapım z
boş bir dize;
y
bağlı olarak (\(?)v k x->v$k?x)
, quine verilerinin sol ilişkili ("katlama") 'dan sağ ilişkili ("katlama") forma dönüştürülmesine yardımcı olmak için kullanılan bir lambda birleştiricisi;
- Operatör
(#)
bağlı \(&)(%)v->v&'{'&'-'&...
quine verilerinin kendisi,.
Kesit verileri, kilitli kodlama şeklinde, parametreli bir lambda ifadesi şeklinde verilir (&)(%)v
.
- Örneğini oluşturmak için belirli değerlere ifade uygulayarak
(&)
, (%)
vev
bu kodlama Quine'ın çekirdek kodu oluşturmak için ya da quine veri temsilini kendisini yeniden halinde kullanılabilir.
- Haskell'in varsayılan sabitlik kuralı
&
ve %
lambda içinde solda ortak operatörler haline gelir. Böylece karakter parametreleri v
soldan başlayarak başlangıçta birleştirilir .
- Çoğu karakter
k
için bir karşılık vardır &'k'
.
- Karakter değişmezleri içinde kaçması gereken veya olduğunda
k
, bunun yerine kodlama yapılır .'
\
%'\k'
Veri kodlaması birleştirici bırakıldığından, ancak dizeler doğru ilişkilendirici bir şekilde oluşturulduğundan, birleştirici y = (\(?)v k x->v$k?x)
uyumsuzluğu köprülemek için tanıtılır.
y(...)
quine verileri (&)
ve (%)
operatörleri olarak kullanmak için uygun fonksiyonlar oluşturmak amaçlanmıştır .
v
dizgilerden dizgilere bir işlevdir (quine verilerinin amaçlanan v
örnekleridir).
k
karakter, x
bir dize ve ?
bunları yeni bir dizgede birleştiren bir işlecidir. (Çekirdek kod (?)=(:)
için,...... .Quine veri temsilini yeniden yapılandırmak için, daha karmaşıktır.
- Bu nedenle
y(?)v k = \x->v$k?x
, dizgilerden dizgelere başka bir işlevdir.
Bunun ilişkililiği nasıl değiştirdiğinin bir örneği olarak, eğer (&)=y(:)
:
(v&k1&k2&k3) x
= (((v&k1)&k2)&k3) x
= y(:)(y(:)(y(:)v k1)k2)k3 x
= y(:)(y(:)v k1)k2 (k3:x)
= y(:)v k1 (k2:(k3:x))
= v (k1:(k2:(k3:x)))
= v (k1:k2:k3:x)
Daha genel olarak, (#)
ince veri işlevi ne zaman ve f1,f2
karakterleri karakter dizileriyle birleştiren işlevlerdir:
(y(f1)#y(f2)$v) x
= (...(y(f1)(y(f1)v '{') '-')...) x
= v(f1 '{' (f1 '-' (... x)))
quine veri işlevini (&)=y(f1)
ve ile uygulamak (%)=y(f2)
ve bu, öngörülen f1
ve f2
quine verilerinin karakterlerini birleştirmek için kullanır x
ve sonra elde edilen dizgiyi iletir v
.
Ana lambda ifadesinin gövdesi bunu bir araya getirir:
(y(\k x->'&':q:k:q:x)#y(\k x->'%':q:'\\':k:q:x)$y(:)#y(:)$ \x->x)z
'&':q:k:q:x
Bir karakter için k
başa ekler &'k'
dize x
ise, '%':q:'\\':k:q:x
prepends %'\k'
orijinal quine veri formları,.
- Bu nedenle
y(\k x->'&':q:k:q:x)#y(\k x->'%':q:'\\':k:q:x
, son veriye z
(boş dize) hazırlanmış ve ardından aşağıdaki işleve geçirilen ince veri gösterimini yeniden oluşturmak için doğru parametrelerdir .
y(:)#y(:)
Quine'in çekirdek kodunu başka bir değişiklik yapmadan bir dizgeye hazırlamak için doğru parametrelerdir.
- Sonunda
\x->x
, döndürülen yapılı quine ile hiçbir şey yapmaz.