Genelleştirilmiş Quine Generator


19

Meydan okuma

Bu zorlukta bir kaynak dil S ve bir hedef dil belirtirsiniz T. Göreviniz aşağıdaki programı Pdilde yazmaktır S. Geçerli bir programı varsa Qdilinde Tiçin girdi olarak verilir P, bu çıkış geçerli bir programı olacak Rdilinde Thiçbir giriş ve çıkışlarını sürer Q(R)olduğunu, programın Qkaynak koduna uygulanan R. Buna ek olarak , cevabınızda önemsiz olmayan bir örnek program Q(daha ilginç, daha iyi, bunun için puan kazanmasanız da ), ortaya çıkan program Rve çıktısını sunmalısınız R. Bu kod golf, yani Pkazanma için en kısa kod .

Başka bir deyişle, bu, keyfi genelleştirilmiş tırnak türleri oluşturabilen bir "evrensel kine yapıcısı" yazmakla ilgili bir sorundur.

Açıklamalar

  • Kaynak ve hedef dilleriniz aynı olabilir.
  • Program P, bir çıktıyı (STDIN veya eşdeğerinden) almalı ve bir çıktıyı (STDOUT veya eşdeğeri), her çıktı programında olduğu gibi almalıdır R.
  • Giriş programları Qda bir dizeyi başka bir dizeye dönüştürmelidir, ancak biçimleri daha esnektir: dizeden dizeye işlevler, belirli bir ada sahip bir değişkeni değiştiren kod parçacıkları, hedef dilinizse veri yığınını değiştiren parçacıklar olabilir Ayrıca Q, örneğin herhangi bir yorum içermeyebileceğini belirterek 's formunu daha da kısıtlayabilirsiniz . Ancak, herhangi bir hesaplanabilir dizeden dizeye işlevini bir giriş programı olarak uygulayabilmeniz Qve bunların nasıl çalıştığını ve bunlara ne gibi kısıtlamalar koyduğunuzu açıkça belirtmeniz gerekir .
  • Çıktı programı Rgerçekten (genelleştirilmiş) bir quine olmalıdır, bu yüzden bunu yapmadıkça herhangi bir girdi (kullanıcı girişi, dosyalar vb.) Okumamalıdır Q.
  • Standart boşluklara izin verilmez.

Bir örnek

Kaynak dilim olarak Python'u ve hedef dilim olarak Haskell'i seçtiğimi varsayalım. Ayrıca, giriş programının String -> Stringadlandırılmış bir işlevin tek satırlık bir tanım olması gerektiğini de varsayalım f. Eğer string-reversing programı verirsem

f x = reverse x

Python programıma girdi olarak P, başka bir Haskell programının kaynak kodunu çıktılar R. Bu program kaynak kodunun STDOUT'a yazdırılır R, ancak tersine çevrilir. Eğer Pkimlik işlevi verilir

f x = x

girdi olarak, çıktı programı Rbir kınnadır.

Yanıtlar:


7

Kaynak = Hedef = CJam, 19 17 16 bayt

{`"_~"+}`)q\"_~"

Bu, giriş programının Q(STDIN'de verilen) yığının üstünde bir dize bekleyen ve yığının üstünde başka bir dize bırakan bazı CJam snippet'i olduğunu varsayar .

Burada test edin.

Örnekler

  1. Kimlik sadece boş bir snippet olurdu, bu nedenle STDIN boş baskılar bırakır

    {`"_~"+}_~
    

    Hangi standart quine, bir ek ile +.

  2. CJam'de bir dizeyi tersine çevirmek için kullanabilirsiniz W%, böylece STDIN'e koymak, bu şu sonuçları verir:

    {`"_~"+W%}_~
    

    elde etmek için koşabileceğimiz

    ~_}%W+"~_"`{
    
  3. Üçüncü bir örnek olarak, boşluk içeren bir dize intersperses bir pasajı kullanmak ki: ' *. Koşu Pgirdi olarak bununla biz almak

    {`"_~"+' *}_~
    

    hangisi yazdırır

    { ` " _ ~ " + '   * } _ ~  
    
  4. Artık Qsatır sonları içeriyorsa da çalışır (CJam'da asla gerekli olmamasına rağmen). İşte, bir dizeden tüm satır sonlarını kaldıran (gereksiz yere kıvrık bir şekilde - satırlara bölün, sonra birleştirin) satır sonu olan bir program:

    N/
    ""
    *
    

    Bu, aşağıdakilerle sonuçlanır R:

    {`"_~"+N/
    ""
    *}_~
    

    hangisi yazdırır

    {`"_~"+N/""*}_~
    

açıklama

Önce üretilen çıktıya bakalım:

Standart CJam quine

{`"_~"}_~

Aşağıdaki gibi çalışır:

  • Bloğu itin {`"_~"}.
  • İle çoğaltın _.
  • Kopyayı ile yürütün ~.
  • Şimdi bloğun içinde, `ilk bloğu dize olarak temsil eder.
  • "_~" kaynağın bloğun bir parçası olmayan iki karakterini iter (ve dolayısıyla dize gösteriminde eksiktir).
  • İki dizgi programın sonunda arka arkaya yazdırılır.

Temel satırda `gereksizdir, çünkü bloğu olduğu gibi bırakırsanız, programın sonunda aynı şekilde yazdırılır.

Programımın çıktısı Pbu snippet'in değiştirilmiş bir sürümüdür. İlk olarak, +tüm dizeyi içeren bir dizeye iki dizeyi birleştiren bloğa bir ekledim . Blok içinde ne yaparsam yapayım, bunun doğru olacağını unutmayın, çünkü bunların hepsi elde edilen dize gösterimine eklenecektir `. Şimdi, program / snippet'i Qbloktan sonra bloğun içine koyabilirim +, böylece yazdırılmadan önce kaynak dizgiyi değiştirebilir. Yine, Qbloğun içine girdiği için, söz konusu kaynak dizginin bir parçası olacaktır.

Özetle, Pbaskılar

{`"_~"+Q}_~

Şimdi, nasıl bu çıktı inşa hakkında gitmek için P:

{`"_~"+}         "Push the block without Q.";
        `        "Turn it into a string. This is shorter than writing a string right away,
                  because I'd have to escape the quotes, and I'd need two quotes instead of
                  one backtick.";
         )       "Pop off the last character (the brace) and push it on the stack.";
          q      "Read input Q.";
           \     "Swap Q with the brace.";
            "_~" "Push the final two characters.";

Dört karakter dizisi programın sonunda otomatik olarak (arka arkaya) yazdırılır.


1
Bu hızlıydı! Ve yenmek kesinlikle zor. Açıklama çok güzel.
Zgarb

W% 'nin tersine döndüğünü nereden öğrendin? dl.dropboxusercontent.com/u/15495351/cjam.pdf buna sahip değil
Faraz

Daha eksiksiz bir yöntem listesi var mı?
Faraz Masroor

@FarazMasroor sourceforge.net/p/cjam/wiki/Basic%20operators/#percent (no. 3) ... bu, GolfScript'ten ödünç alınan bir özellik ve bir noktada bana GolfScript'te nasıl çalıştığını söyledi. Öyle yaygın bir deyim gibi görünüyor ki, her CJam / GS kullanıcısının sahip olduğu ama aslında pek çok yerde açıklanmayan garip bir örtük bilgi. (Daha ayrıntılı olarak belgelenmemiş operatörler için bkz. Sourceforge.net/p/cjam/wiki/Operators )
Martin Ender

3

Haskell ifadeleri → Haskell ifadeleri, 41 bayt

((++)<*>show).('(':).(++")$(++)<*>show$")

Çevrimiçi deneyin!

Nasıl çalışır

P $ "Q"= ((++)<*>show).('(':).(++")$(++)<*>show$") $ "Q"Yapılar "R"tarafından

  1. (++")$(++)<*>show$"): dizgiyi ekleyerek ")$(++)<*>show$",
  2. ('(':): karakterin başına gelen '('ve
  3. (++)<*>show(= \x->x++show x): bunun alıntılanmış bir sürümünü ekleyerek,

sonuç "R"= "(Q)$(++)<*>show$\"(Q)$(++)<*>show$\"".

R= (Q)$(++)<*>show$"(Q)$(++)<*>show$"tarafından çalışır

  1. ipi alarak "(Q)$(++)<*>show$",
  2. (++)<*>show: bunun alıntılanmış bir versiyonunu ekleyerek,
  3. uygulayarak Qbuna,

sonuç Q "(Q)$(++)<*>show$\"(Q)$(++)<*>show$\""= Q "R".

(Etraftaki parensler Qgereklidir, çünkü olabildiğince kolay Qiçerebilir ve maalesef sağlayıcıdır.)$R$

gösteri

λ> putStrLn $ ((++)<*>show).('(':).(++")$(++)<*>show$") $ "id"
(id)$(++)<*>show$"(id)$(++)<*>show$"
λ> putStrLn $ (id)$(++)<*>show$"(id)$(++)<*>show$"
(id)$(++)<*>show$"(id)$(++)<*>show$"
λ> putStrLn $ ((++)<*>show).('(':).(++")$(++)<*>show$") $ "reverse"
(reverse)$(++)<*>show$"(reverse)$(++)<*>show$"
λ> putStrLn $ (reverse)$(++)<*>show$"(reverse)$(++)<*>show$"
"$wohs>*<)++($)esrever("$wohs>*<)++($)esrever(
λ> putStrLn $ ((++)<*>show).('(':).(++")$(++)<*>show$") $ "length"
(length)$(++)<*>show$"(length)$(++)<*>show$"
λ> print $ (length)$(++)<*>show$"(length)$(++)<*>show$"
44

Sadece $parantez ihtiyacı, aynı zamanda arka let, doveya lambda ifadeleri.
Ørjan Johansen

@ ØrjanJohansen Doğru, ama kendim yaymazsam, gizli olmayan lambda / let/ if/ case/ ' a izin vermeyen bir dil altkümesi tanımlayabilirdim do. Belki de benim yapmak zorunda olmadığım kadar iyi.
Anders Kaseorg

2

Kaynak = Hedef = JavaScript, 66

console.log("function a(){console.log("+prompt()+"(a+'a()'))}a()")

Q için Varsayımlar:

  • Q dizeden dizeye JavaScript anonim işlevi olmalıdır.

Örnekler:

  • Ters . Q =function(s) { return s.split('').reverse().join(''); }

Bu durumda, P(Q)(veya R): olacaktır function a(){console.log(function(s) { return s.split('').reverse().join(''); }(a+'a()'))}a()ve uygulayarak şunu elde edeceğiz: )(a}))')(a'+a(} ;)''(nioj.)(esrever.)''(tilps.s nruter { )s(noitcnuf(gol.elosnoc{)(a noitcnufki tam olarak aynıdır Q(R).

  • Kimlik . Q =function(s) { return s; }

bu durumda, P(Q)(veya R) şöyle olur: function a(){console.log(function(s) { return s; }(a+'a()'))}a()bu bir JavaScript Quine'dir . Söylemeye gerek yok Q(R), Q aynıdır çünkü Q Kimlik fonksiyonudur.


Bazı notlar:

JavaScript'teki STDIN geleneksel olarak prompt(), ancak alert()kopyala-yapıştır kullanarak bir çıktı olarak çalıştırma sürecini kolaylaştırmak için kendime STDOUT geleneğinden kaçınmasına izin verdim . (Ben yapabilirsiniz farkında mısın 12 karaktere kadar tasarruf etmek değiştirirken alert()).

Ayrıca ES6'da işleri daha kısa hale getirebilirim, ancak şimdilik Yerel JavaScript ile kalmak istiyorum. Gelecekte sadece deneyim için bir S = Scala, T = ECMA6 cevabı göndermeyi düşünüyorum.

Ayrıca JavaScript neredeyse dövmek asla fark CJam içinde , ama bu zorluk çekmek zorunda kaldı! Somurtkan eğlenceli biriydi.


Teşekkürler! Farklı kaynak ve hedef dillerle giriş yapmak gerçekten harika olurdu.
Zgarb

2

Jöle7 , 9 bayt

“ṚƓ^ṾṂ’³3

Çevrimiçi deneyin!

Q, 7 işlevdir (yani üst yığın öğesinin ötesine bakmaz ve yığın yoluyla G / Ç yapar) ve komut satırı bağımsız değişkeni olarak verilir.

açıklama

7 programı

Burada kullandığım 7'deki evrensel quine yapıcısı:

717162234430…3

Dikkat edilmesi gereken ilk şey, önde gelen 7'nin önde gelen boşluk ile eşdeğer olması ve program üzerinde herhangi bir etkisi olmamasıdır. Bunun tek sebebi, PPCG'nin sadece değişmez sorgulara karşı kurallarına uymaktır ( 1kendisinden ziyade programda ikincisi tarafından kodlanır ).

Programın geri kalanı, çalıştırıldığında aşağıdakileri yapan tek bir yığın öğesidir (dengeli 7s ve 6s'ye sahiptir):

717162234430…3
 1716           Push a stack element "7" onto the stack
     2          Copy it
      23        Pop and output one of the copies (selecting format 7)
        4430    Prepend it to the top of stack
             3  Output it

Başka bir deyişle, bu yığın öğesi, üstte 77, çıkış biçiminde ("tam anlamıyla kaynak kodu ile aynı kodlamayı kullanarak yazdırma" anlamına gelen) yığının üstünü yazdıran ve dolayısıyla açıkça en iyi kodlama olan bir programdır . quines). Burada, kelimenin tam anlamıyla 7iki amaç için (çıktı biçimi ve önde gelen beyaz alan) yeniden kullanabileceğimiz için şanslıyız . Açıkça, finalden hemen önce bir şey ekleyerek 3, çıktı almak yerine 7+ girdi işlevini çıktılayabiliriz 7. doğrudan giriş.

Bu yığın öğesi kendi kaynak kodunda nasıl bulunur? Peki, programın sonuna ulaşıldığında, evalvarsayılan olarak üst yığın elemanı 7 sn'dir. Ancak, işlemdeki yığından aslında atmaz, bu nedenle yönlendirilen yığın öğesi hazır bilgisi evalhala oradadır. (Başka bir deyişle, program kendi kaynağını okumuyor - 7programın başlangıcında, bir hazır bilginin parçası olmaktan ziyade bir yığın öğesi ayırıcısı olduğunu göremediği gerçeği ile - daha ziyade, çoğunlukla evalvarsayılan olarak yönlendirilen bir değişmez değerden oluşur .)

Jelly programı

Bu belki de yazdığım en az Jelly benzeri Jelly programlarından biri; üç nilads (oluşur “ṚƓ^ṾṂ’, ³, 3herhangi bir işlem üzerlerinde yapılır çünkü sırayla sadece çıkarılır). 3Sadece bir tamsayı sabiti olmak bariz yeterince vardır. ³Eğer Jelly biliyorsanız da basittir: o (Jelly genellikle kendi girdi alır nerede) ilk komut satırı argümanı için Jelly açık gösterimi var. Jelly programının geri kalanı 7 evrensel quine kurucumun büyük kısmını temsil ediyor: 7'deki tüm komutların ASCII basamakları kullanılarak temsil edilebileceği gerçeğini kullanarak yorumlayabiliriz.717162234430bir komut dizisi olarak değil, hatta sekizlik bir sayı olarak (kavramsal olarak olduğu gibi) değil, ondalık bir sayı olarak, yani çıktı için herhangi bir özel biçimlendirmeye ihtiyacımız olmadığı anlamına gelir. Bu ondalık sayı “ṚƓ^ṾṂ’Jelly'in sıkıştırılmış tamsayı gösteriminde olur.

Misal

Biz verirsek 24053programı Q, aşağıdaki çıktıyı alırsınız:

717162234430240533

Çevrimiçi deneyin!

2405 üst yığın öğesini kendine birleştirir:

2405   Stack   Explanation
       x
2      x|x     Duplicate top of stack
 4     x||x    Swap two stack elements, with an empty element between
  0    x|(X)   Escape the top stack element, then concatenate the top two
   5   xx      Execute the top stack element

(Son adım biraz kafa karıştırıcı görünebilir; bir yığın öğesinden kaçmak, içindeki her komutu "bu komutu çalıştır" dan "bu komutu yığının üstüne eklemek" e dönüştürür, böylece her komut kendisini orijinaline ekler üst yığın elemanını çalışır.)

Bu nedenle, sonuçtaki R programını çalıştırmak bize R'nin iki kopyasını verir:

7171622344302405371716223443024053

2

CJam → CJam, 13 bayt

{`"_~"+7}_~qt

Çevrimiçi deneyin!

Giriş Q, yığındaki tek dizeyi değiştiren bir kod snippet'i olmalıdır. Qstdin'den okunur.

Misal

Giriş:

S*W%

Her iki karakter arasına boşluk ekler ve dizeyi tersine çevirir.

Çıktı:

{`"_~"+S*W%}_~

Genelleştirilmiş kinin çıktısı:

~ _ } % W * S + " ~ _ " ` {

açıklama

{`"_~"+7}_~      e# Evaluate a generalized quine in CJam that only appends a 7.
q                e# Read the input.
t                e# Replace the 7th character (0-based) with the input.

Öncelikle kini değerlendirir, böylece gereksiz çift tırnak işaretleri olmadan dize temsilini alabiliriz. Ardından yükü girdiyle değiştirin.

Bu olabilir {`"_~"+ }_~7qtalan yükü tutucu olduğu. Ancak yükü değiştirmek 7bayt tasarrufu sağlar.


1

Odun kömürüPerl (5), 29 33 byte

A$_=q(αA);evalβαS"\α$_β\n";printβ

Çevrimiçi deneyin!

Perl programı Q, girişi sağ tarafına dize olarak alan ve değişkende çıktı sağlayan bir snippet döndürmelidir $_. (Rasgele Perl işlevleri, bu forma şu şekilde sarılarak dönüştürülebilir sub x {…}; $_=x. Çoğu durumda, Perl sözdizimi herhangi bir sarma gerekmediği anlamına gelir.)

açıklama

Perl

Evrensel Perl quine yapıcısının görünüşü:

$_=q(…"\$_=q($_);eval";print);eval

(Çoğu durumda bunu golf oynamak istersiniz $_=q(say…"\$_=q($_);eval");eval, ancak oraya rastgele Perl kodu sığdırabileceğinizden emin değilim .)

Başka bir deyişle, $_=q(…);evalbir dize atayan $_ve sonra değerlendiren bir dış sargıcımız var. Ambalajın içinde "\$_=q($_);eval", yani ambalajın içinde depoladığımız değeri $_artı kullanıcı tarafından belirtilen Q kodunu printkullanarak çıktıyı yazdırmak için içeriği ile birlikte yeniden oluşturulması bulunur . (Ne yazık ki kullanamayız say; bir satırsonu ekler ve bu da ayetlerle ilgilidir.)

Kömür

Bu cevabın "amacı" Perl'de genelleştirilmiş sorgular üretmekti, bu yüzden bunu yapmak için golf stratejisine sahip olduğumda (diğer birçok cevapta kullandığım), temelde sadece ikame edilen P programını yazmanın zamanı gelmişti. şablon içine bir dize. Burada istediğim sabit dizeleri (ideal olarak biraz sıkıştırmak) yazdırma ve bunlara kullanıcı girdisi enterpolasyonunda iyi olan bir dildi.

Birkaçını denedikten sonra, daha önce hiç kullanmadığım (ve bazı belgelerle gerçekten yapabilen) Kömür'e karar verdim; ASCII sanatı için tasarlanmıştır ancak bir boyutta dizeler yazabilir. ASCII karakterleri Kömür harfiyle tam anlamıyla yazdırılır, yani sabit dizelerin yazdırılması herhangi bir kazan plakası gerektirmez ve komutu kullanıcı girişinden programa alınan bir dizeyi enterpolasyonlamak için kullanabiliriz .

Yine de (biraz) daha kısa gitmek mümkündür. Perl üniversal kine yapıcısı oldukça uzun tekrarlanan iki bölüm içerir. Bu nedenle, bunları değişkenlere atamak için komutu kullanabiliriz (örneğin A…α, değişkene atar α) ve değişkenleri, adlarını kullanarak yazdırdığımız dizeye enterpole edebiliriz. Bu, dizeyi kelimenin tam anlamıyla yazmaya birkaç bayt kazandırır.

Ne yazık ki, Charcoal da programa yeni bir satır ekliyor, ancak bu çok büyük bir anlaşma değil; bu \nsatırsonu Q'nun girişine de eklemek iki bayta mal olur.

Misal

Girdiyi verirsek $_=reverse(dize tersine çevirir), aşağıdaki çıktıyı alırız:

$_=q($_=reverse"\$_=q($_);eval\n";print);eval

Çevrimiçi deneyin!

beklendiği gibi kaynağını geriye doğru yazdıran benzer.


1

JöleDüşük yük , 15 bayt

“(a(:^)*“S):^”j

Çevrimiçi deneyin!

Düşük yük fonksiyonu Q komutunu komut benzeri bir bağımsız değişken olarak alır. Q, daha derin yığın öğelerini (var olmayacakları gibi) incelemeye çalışmadan yığının girdisini almalı ve çıktıyı yığına itmelidir.

açıklama

Düşük Yük

Burada kullanılan Underload universal quine yapıcısı:

(a(:^)*…S):^

Programın çoğu tek bir değişmezdir. Biz tarafından o izleyin :^hangi kopya, o daha sonra bir kopya (yığın başka kopyasını bırakarak) değerlendirir.

Literal başlar değerlendirmesi yaparken, koşmak a(orijinal programa aynı forma geri getirir kaçış,) ve (:^)*(ekler hangi :^böylece tüm programın kaynak kodunu yeniden). Daha sonra bunu keyfi bir şekilde dönüştürmek için Q işlevini çalıştırabilir ve sonucu ile yazdırabiliriz S.

Jöle

Bu sefer Charcoal'ı kullanamıyorum çünkü program bir satırsonu ile bitiyorsa, programın sonunda geçerli bir Underload yorumlayıcısı çöküyor. (TIO'daki gibi bazı Düşük Yüklü tercümanlar bu kuralı uygulamamaktadır, ancak düzgün bir şekilde taşınabilir olmak istedim.) Ne yazık ki, Kömür doğal olarak çıkışına yeni satırlar ekliyor. Bunun yerine, böyle basit durumlarda neredeyse aynı olan Jelly'i kullandım; program iki elemanlı ( ““”) bir liste değişmezinden oluşur ve bunları girdi ( j) üzerine ekler , böylece kullanıcı girdisini programa enterpolasyona sokar.

Misal

Girdiyi kullanarak :S^(bir kopyasını yazdırın, ardından orijinali değerlendirin), aşağıdaki Underload programını elde ederiz:

(a(:^)*:S^S):^

Çevrimiçi deneyin!

Bu, kendini oldukça ilginç bir şekilde sonsuz kez yazdırır: normal quine davranışını yaptıktan sonra, evalçıktısının bir kopyası üzerinde çalışır . Bu, yeniden yapılandırılan tüm programın süresiz olarak tekrar çalışmasına neden olur (Düşük yük kuyruk yinelemelidir). Kendinizi sorgulamak ve an evalyapmak aslında Underload'da sonsuz bir döngü yapmanın tek yoludur.


Charcoal artık sondaki yeni satırları eklemiyor (yay)
sadece ASCII-sadece

1

RProgN 2 , 11 bayt

'{`{.%s}{'F

Program Açıklaması

'{`{.%s}{'F
'{`{.%s}{'  # Push the string "{`{.%s}{" to the stack.
          F # Format the input with the top of the stack as a template. Which produces {`{.<INPUT>}{

Quine Açıklaması

Üretilen quine basittir, ancak "Döngü" quine adı verilen kısa ve tatlı bir quine oluşturmak için RProgN2'deki eşsiz işlev işleyicilerinin işlevselliğini kullanır. Bir <> <kine ile şaşırtıcı derecede benzer bir kavram.

{`{.}{
{`{.}   # Push the function {`{.} to the stack.
     {  # Try to define a new function, fail, loop back to index 1. (Which in turn, skips the function definition.)
 `{     # Push the string "{" to the stack.
   .    # Concatenate the top two values of the stack, which stringifies the function, then appends { to it.
    }   # Try to terminate a function, fail quietly, and terminate the program.

Tabii ki, bu kininin yapısı nedeniyle, gerçek no-op'lar dışında herhangi bir şey (hangisi stringize edilmez) bitiştir işlevinden sonra yerleştirilebilir ve

Bazı sorular

  • {`{.i}{: Çıkışlar {}i.{`{. isadece "ters" fonksiyonudur, bu nedenle bu program kendisini tersine çevirir.
  • {`{.S§.}{: Çıkışlar ..S`{{{}§. Sdizgiyi bir karakter yığınına dönüştürür, §yığını sözcükbilimsel olarak sıralar, sonra .yeniden bir araya getirerek kendi kendini sıralar .

Çevrimiçi deneyin!

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.