Meta Quine yapabilir misin?


25

Diğer quine bulmacalarına benzer şekilde (daha doğrusu bu ), kendisi için kaynak üreten bir program yazın.

İşte yeni bir dönüm: üretilen kod gerekir DEĞİL kaynağına aynı olması. Aksine, ilkini yaratacak farklı bir program çıkarmalıdır.

Yukarıya bağlanan zorluk, iki dil arasında atlayarak bunu başardı. Bunun sadece bir dilde yapıldığını düşünüyorum , ancak kaynağın iki (veya daha fazla) sürümü oldukça farklı olmalıdır (aşağıdaki kurallara bakınız). Bu kısıtlama ile, tek karakterli cevaplara izin verilmezdi, bu nedenle son bir sunum için biraz daha fazla düşünmeyi gerektirir.


KURALLAR

  1. Kodunuz sadece bir dilde üretilmelidir. (Birden fazla başvuru, her dil için bir tane mükemmel kabul edilebilir.)
  2. Farklı kod sürümleriniz sözdizimsel olarak farklı olmalıdır. Başka bir deyişle, kodunuz için soyut bir sözdizimi ağacı çizecekseniz, farklı en az bir düğüm olmalıdır.
    • Bir temini AST gerekli olmayacak, ancak her program için bir tane sağlamak üzere eğimli hissediyorum, eğer olur yargılarken yardımcı olur.
  3. Hepsi sözdizimsel olarak farklı kaldığı sürece dilediğiniz kadar yineleme yapabilirsiniz. (Daha fazlası puanınıza yardımcı olacaktır, aşağıya bakınız.)

PUANLAMA

Nihai puanınız, program sayısına bölünerek tüm programlarınızın ortalama uzunluğu olacaktır.

Örnek 1:

A (B için kaynak) = 50 karakter
B (A için kaynak) = 75 karakter
Son Puan = 31.25

Örnek 2:

A (B kaynağı) = 50 karakter
B (C ​​kaynağı) = 75 karakter
C (A kaynağı) = 100 karakter
Final Puanı = 25


18
Ben bir kere tereddüt ediyorum.
mellamokb

1
@mellamokb har har ;-)
Gaffi

Bu aslında bu quine mücadelesinin daha genel bir versiyonudur ve burada verilen cevaplar da kazanacaktır.
saat

@leftaroundabout'ta, sözdizimsel farklılıklara duyulan gereksinim bir 'dönen quine'i geçersiz kılar, bu yüzden bu daha genel değildir.
stand

2
Asla sevmediğim meta quine.
Stack Tracer

Yanıtlar:


35

Python, 0 ((68 + 3 n ) / (16 n ) sınırı )

İki soyut sözdizimi ağacı farklı ise, sabitleri farklıysa,

r='r=%r;n=(0x%XL+1)%%0x10...0L;print r%%(r,n)';n=(0xF...FL+1)%0x10...0L;print r%(r,n)

Asimptotik skoru 0 vererek, en fazla 68 + 3n'de 16 n uzunluğunda programlar vardır .

Değişken yapıya sahip programlar istiyorsanız, n bitlerine bir ikili toplayıcı uygulayabiliriz . Burada, 2 n uzunlukta O programları vardır ( n 2 ). Düşen taşıma biti nedeniyle bir döngüde gider.

s="""
print 's='+'"'+'"'+'"'+s+'"'+'"'+'"'
n=lambda m:reduce(lambda (s,c),y:(s+(c^y,),c&y),m,((),1))[0]
print s[:112]
t=n(t)
print "t=(%s,)+(0,)*%s"%(t[0],len(t)-1)
for i in range(len(t)-1):
    print i*' '+'for i in range(2):'
    print ' '+i*' '+['pass','t=n(t)'][t[i+1]]
print s[113:-1]
"""

print 's='+'"'+'"'+'"'+s+'"'+'"'+'"'
n=lambda m:reduce(lambda (s,c),y:(s+(c^y,),c&y),m,((),1))[0]
print s[:112]
t=(0,)+(0,)*10
for i in range(2):
 t=n(t)
 for i in range(2):
  t=n(t)
  for i in range(2):
   t=n(t)
   for i in range(2):
    t=n(t)
    for i in range(2):
     pass
     for i in range(2):
      t=n(t)
      for i in range(2):
       pass
       for i in range(2):
        pass
        for i in range(2):
         pass
         for i in range(2):
          t=n(t)
t=n(t)
print "t=(%s,)+(0,)*%s"%(t[0],len(t)-1)
for i in range(len(t)-1):
    print i*' '+'for i in range(2):'
    print ' '+i*' '+['pass','t=n(t)'][t[i+1]]
print s[113:-1]

Kafam karışabilir mi? Çıktı kaynakla aynı gibi görünüyor (bu zorluğun amacı değil)?
Gaffi

İç içe bloğa bakın. Tüm 2 ^ n birleşimlerinde geri ve passsonra değişecektir t=n(t).
boothby

Bunu şimdi anlıyorum. Beni bütün tekrarlarla karıştırdın!
Gaffi

22
Nedense, küçük puanlar ile çok uzun golf çözümleri seviyorum.
stand

Vay canına, tamamen buna sahiptin! Çok hoş.
Claudiu

4

Perl, 110.25'in skoru

İtiraf etmeliyim ki, çok iyi değilim. % 100 gelişim için yer olduğundan eminim. Çözüm, aşağıdaki Element çözümünün aynı prensibine dayanmaktadır.

İlk program 264 karakterdir.

$s='$a=chr(39);print"\$s=$a$s$a;";$s=reverse$s;for(1..87){chop$s}$s=reverse$s;print$s;$f++;if($f==0){$a=chr(39);print"\$s=$a$s$a;$s"}';$a=chr(39);print"\$s=$a$s$a;";$s=reverse$s;for(1..87){chop$s}$s=reverse$s;print$s;$f++;if($f==0){$a=chr(39);print"\$s=$a$s$a;$s"}

İkinci program 177 karakterdir.

$s='$a=chr(39);print"\$s=$a$s$a;";$s=reverse$s;for(1..87){chop$s}$s=reverse$s;print$s;$f++;if($f==0){$a=chr(39);print"\$s=$a$s$a;$s"}';if($f==0){$a=chr(39);print"\$s=$a$s$a;$s"}

Bu giriş için AST üzerinde çalışıyorum (ve Element girişi).


Eleman , 47.25 puanı

İlk program 105 karakterdir.

\ \3\:\$\'\[\\\\\`\(\`\]\#\2\1\'\[\(\#\]\`\ \3\:\$\'\[\\\\\`\(\`\]\#\` 3:$'[\\`(`]#21'[(#]` 3:$'[\\`(`]#`

İkinci program 84 karakterdir.

\ \3\:\$\'\[\\\\\`\(\`\]\#\2\1\'\[\(\#\]\`\ \3\:\$\'\[\\\\\`\(\`\]\#\` 3:$'[\\`(`]#`

İyileştirme için çok yer olduğuna eminim.

İlk programda bir dizge (içinde fazlalık olmasına rağmen her karakterin kaçtığını) ve ardından A ve B çalıştırılabilir bölümleri var. Dize (bu bölüm B'nin kaynağıdır) ve ardından onu takip eden B bölümünün bir şey yapmasını önler.

İkinci program, B dizisi ile aynı dizgedir, B Bölümü basit bir kestaneye dayanır; çıkışlı sürümünden önce gelen bir dize yazdırır. Bu, dizeyi ve hem A hem de B bölümlerini yazdırdığı anlamına gelir.


Bunun kesin olarak, şüphesiz ötesinde, Element'in bir programlama dili olarak geçerliliğini kanıtladığını düşünüyorum. Kullanımı o kadar kolaydır ki, Öylesine deneyimsiz ki Element için sadece bir tercüman yazmayı başarabildim, bu soruyu 7.000.000.000 insanın tüm bu gezegenindeki herhangi bir insandan önce cevaplayabildim. Element'in "bir karakter, bir fonksiyon, her zaman" paradigması, tüm kodların tamamen açık olduğu anlamına gelir. Dil çok yönlüdür: hariç []{}, herhangi bir komut sözdizimi hatasına neden olmadan tüm programın herhangi bir yerine yerleştirilebilir. O mükemmel.
PhiNotPi

4
Biraz önyargılı mıyız? ;-)
Gaffi

3

VBA: (251 + 216) / 2/2 = 116.75

251

Sub a()
r=vbCrLf:c="If b.Lines(4, 4) = c Then"&r &"b.InsertLines 8, d"&r &"b.DeleteLines 4, 4"&r &"End If":d="b.InsertLines 6, c"&r &"b.DeleteLines 4, 2"
Set b=Modules("Q")
If b.Lines(4, 4) = c Then
b.InsertLines 8, d
b.DeleteLines 4, 4
End If
End Sub

216

Sub a()
r=vbCrLf:c="If b.Lines(4, 4) = c Then"&r &"b.InsertLines 8, d"&r &"b.DeleteLines 4, 4"&r &"End If":d="b.InsertLines 6, c"&r &"b.DeleteLines 4, 2"
Set b=Modules("Q")
b.InsertLines 6,c
b.DeleteLines 4,2
End Sub

Bu, nesneyi kullanmak için MSAccess'te çalıştırılır Module. Modül "Q"golf oynamak için adlandırılmıştır . Sözdizimindeki fark If ... Then, kısa versiyondaki eksiklikten kaynaklanmaktadır.


büyük olasılıkla değişen kurtulabiliriz vbCrLFiçinvbCr
Taylor Scott

3

C ++, 0.734194 puanı

Aşağıdaki kaynak kodu, konsola 999 sıralı bir meta dizisi yazdırır (aşağıdaki açıklama):

#define X 1*(1+1)
#include<iostream>
#include<vector>
#define Q(S)auto q=#S;S
Q( \
  main() \
  { \
      using namespace std; \
      cout<<"#define X 1"; \
      int x=X==2?1000:X-1; \
      vector<int> factors; \
      for ( int p = 2; p <= x; ++p) \
      { \
        while ( x % p == 0 ) \
        { \
          factors.push_back( p ); \
          x /= p; \
        } \
      } \
      for ( int factor : factors ) \
      { \
        cout<<"*(1"; \
        for ( int i=1;i<factor;++i) \
          cout<<"+1"; \
        cout<<")"; \
      } \
      cout<<"\n#include<iostream>\n#include<vector>\n#define Q(S)auto q=#S;S\nQ("<<q<<")"; \
  })

Değişen tek çizgi ilk satırdır. Değeri X1000, 999, 998, ..., 3, 2 olacak ve sonra tekrar başlayacaktır. Bununla birlikte, her seferinde farklı sözdizimi ağaçları elde etmek için X, her bir başlığın bir toplamı olarak yazıldığı asal çarpanlara ayırma bakımından temsil edilir 1. AST'ler farklıdır, çünkü tamsayıların ana çarpanlara ayırması her değer için farklıdır.

Program, ilk satırın değişmesi ve ters eğik çizgiler, satır sonları ve içindeki girintilerin Q(...)kaldırılması dışında kendisini yazdırır .

Aşağıdaki program cevabımın puanını hesaplar:

#include <iostream>

const int n = 1000;

int getProgramLength( int n )
{
  int sum = 442;
  for ( int p = 2; p*p <= n; ++p )
  {
    while ( n % p == 0 )
    {
      sum += 2 * ( 1 + p );
      n /= p;
    }
  }
  if ( n > 1 )
    sum += 2 * ( 1 + n );
  return sum;
}

int main()
{
  int sum = 0;
  for ( int i = 2; i <= n; ++i )
    sum += getProgramLength( i );
  std::cout << (double)sum/(n-1)/(n-1) << '\n';
}

Konsola 0.734194 yazdırdı. Açıkçası, 1000 daha büyük tamsayılarla değiştirilebilir ve puan sınır olarak 0'a yaklaşır. Matematiksel kanıt Riemann'ın Zeta işlevini içerir ve biraz sarstı. Okuyucunun alıştırması olarak bırakıyorum. ;)


2

JavaScript, 84.5 64 61

İki program, her ikisi de uzunluk 169 128 122.

(function c(){alert(/*
2/*/1/**/);return ('('+c+')()').replace(/\/([/\*])/,function(m,a){return a=='*'?'/\/':'/\*'});
})()

Golfe başlamadan önce, izleme zevkiniz için:

(function c() {
    var r = /\/([/\*])/;
    var f = function(m, a) { return a === '*' ? '/\/' : '/\*' };
    var p = '(' + c + ')();';
    p = p.replace(r, f);
    /* This is just a comment!
    console.log('Quine, part two!'); /*/
    console.log('Quine, part one!'); /**/
    return p;
})();

Yeni programı döndürür ve mevcut kısmı çıkarır! İşlev regex olmadan kısaltabilirim, ama ... istemiyorum.


Hayır, sözdizimsel olarak farklılar. Yeni satırları ekledikten sonra, o kadar.
Ry-

2

J - (24 + 30) / 2/2 = 13,5 puan

J dizeleri ters eğik çizgi bulunan olmadıklarını Not fakat la Pascal à alıntı kaçtı: 'I can''t breathe!'.

30$(,5#{.)'''30$(,5#{.)'         NB. program 1, 24 char
'30$(,5#{.)''''''30$(,5#{.)'''   NB. program 2, 30 char

Program 1, AST'ye noun verb hook nounve program 2, AST'ye sahiptir noun. Program 2, çalıştırıldığında yalnızca program 1'i döndürecek program 1'in alıntı bir sürümüdür, bu nedenle bu yöntem kolayca üç kopyaya genişletilemez: P

Program 1, kaynağın kod kısmının bir kopyasını, önüne eklenmiş bir alıntı ile alarak ve sonuna bu alıntıların beşini ekleyerek çalışır ( (,5#{.)). Daha sonra, döngüsel olarak bu 16 karakterli dizgeden 30 karakter alır ve sonuç olarak tam olarak Program 2 verir.

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.