คุณสามารถ Meta Quine ได้ไหม?


25

คล้ายกับปริศนาตัวต่ออื่น (โดยเฉพาะตัวนี้ ) เขียนโปรแกรมที่สร้างแหล่งข้อมูลสำหรับตัวมันเอง

นี่คือการบิดใหม่:รหัสที่ผลิตไม่ควรเหมือนกันกับแหล่งที่มา แต่ควรส่งออกโปรแกรมอื่นที่จะสร้างโปรแกรมแรก

ความท้าทายที่เชื่อมโยงกับข้างต้นทำได้โดยการกระโดดระหว่างสองภาษา ฉันคิดว่าจะใช้ภาษานี้เพียงภาษาเดียวแต่แหล่งที่มาทั้งสอง (หรือมากกว่า) ควรจะแตกต่างกันอย่างมีนัยสำคัญ (ดูกฎด้านล่าง) ด้วยข้อ จำกัด นี้คำตอบเดียวของอักขระจะไม่ได้รับอนุญาต


กฎ

  1. รหัสของคุณจะต้องผลิตในภาษาเดียว (การส่งหลายรายการหนึ่งรายการสำหรับแต่ละภาษาเป็นที่ยอมรับอย่างสมบูรณ์)
  2. เวอร์ชันของรหัสที่แตกต่างกันของคุณจะต้องแตกต่างกันอย่างชัดเจน กล่าวอีกนัยหนึ่งถ้าคุณวาดแผนผังไวยากรณ์นามธรรมสำหรับโค้ดของคุณควรมีอย่างน้อยหนึ่งโหนดที่แตกต่างกัน
    • การจัดหาASTจะไม่จำเป็น แต่ถ้าคุณรู้สึกอยากจะจัดให้มีหนึ่งโปรแกรมสำหรับแต่ละโปรแกรมของคุณมันจะช่วยในการตัดสิน
  3. คุณสามารถทำซ้ำได้มากเท่าที่คุณต้องการตราบใดที่มันยังคงมีความแตกต่างทางวากยสัมพันธ์ (เพิ่มเติมจะช่วยให้คะแนนของคุณดูด้านล่าง)

SCORING

คะแนนสุดท้ายของคุณคือความยาวเฉลี่ยของโปรแกรมทั้งหมดหารด้วยจำนวนโปรแกรม

ตัวอย่างที่ 1:

A (แหล่งที่มาสำหรับ B) = 50 ตัวอักษร
B (แหล่งที่มาสำหรับ A) = 75 ตัวอักษร
คะแนนสุดท้าย = 31.25

ตัวอย่างที่ 2:

A (แหล่งที่มาสำหรับ B) = 50 ตัวอักษร
B (แหล่งที่มาสำหรับ C) = 75 ตัวอักษร
C (แหล่งที่มาสำหรับ A) = 100 ตัวอักษร
คะแนนสุดท้าย = 25


18
ฉันเมตาควินครั้งเดียว
mellamokb

1
@mellamokb har har ;-)
Gaffi

นี้เป็นจริงเพียงรุ่นทั่วไปมากขึ้นจากนี้ความท้าทายควินและคำตอบที่ให้มีการจะเป็นผู้ชนะที่นี่ด้วย
หยุดหมุนทวนเข็มนาฬิกาเมื่อ

@leftaroundabout ความต้องการความแตกต่างของประโยคทำให้โมฆะควอเตอร์หมุนได้ดังนั้นนี่จึงไม่ใช่เรื่องทั่วไป
บูธโดย

2
ไม่เคยเมตาควินฉันไม่ชอบ
Stack Tracer

คำตอบ:


35

Python, 0 (ขีด จำกัด (68 + 3 n ) / (16 n ))

ถ้าต้นไม้ไวยากรณ์นามธรรมสองต้นนั้นแตกต่างกันหากมีค่าคงที่ต่างกัน

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

มีโปรแกรมความยาว16 nโปรแกรมที่มากที่สุด 68 + 3n ให้คะแนน asymptotic 0

หากคุณต้องการโปรแกรมที่มีโครงสร้างตัวแปรเราสามารถใช้ไบนารี adder บนn bits ที่นี่มี 2 nโปรแกรมของความยาวO ( n 2 ) ไปในรอบเนื่องจากบิตพกพาลดลง

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]

ฉันอาจจะสับสน? ดูเหมือนว่าเอาต์พุตจะเหมือนกับแหล่งที่มา (ไม่ใช่วัตถุประสงค์ของการท้าทายนี้)
Gaffi

ดูในบล็อกที่ซ้อนกัน passจะเปลี่ยนไปt=n(t)และกลับในชุดค่าผสมทั้งหมด 2 ^ n
บูธโดย

ฉันเห็นตอนนี้แล้ว คุณทำให้ฉันสับสนด้วยการพูดซ้ำ ๆ ทั้งหมด!
Gaffi

22
ด้วยเหตุผลบางอย่างฉันชอบโซลูชั่นกอล์ฟที่ยาวมากและมีคะแนนน้อยมาก
บูธตาม

ว้าวคุณเป็นเจ้าของอย่างสมบูรณ์! ดีมาก.
Claudiu

4

Perl, คะแนน 110.25

ฉันต้องยอมรับว่าฉันไม่ค่อยเก่งกับควินิน ฉันมั่นใจ 100% ว่ามีห้องพักสำหรับการปรับปรุง การแก้ปัญหานั้นใช้หลักการเดียวกับการแก้ปัญหาองค์ประกอบด้านล่าง

โปรแกรมแรกคือ 264 ตัวอักษร

$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"}

โปรแกรมที่สองคือ 177 ตัวอักษร

$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"}

ฉันกำลังทำงานกับ AST สำหรับรายการนี้ (และรายการองค์ประกอบ)


องค์ประกอบคะแนน 47.25

โปรแกรมแรกคือ 105 ตัวอักษร

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

โปรแกรมที่สองคือ 84 ตัวอักษร

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

ฉันแน่ใจว่ามีห้องพักมากมายสำหรับการปรับปรุง

ในโปรแกรมแรกมีหนึ่งสตริง (ซึ่งตัวละครทุกตัวถูกหลบหนีแม้จะมีความซ้ำซ้อนมาก) ตามด้วยส่วนปฏิบัติการ A และ B ส่วน A ทำหลายสิ่ง: พิมพ์สตริงและหนีออกจากตัวละครทุกตัวพิมพ์ครึ่งหลัง ของสตริง (ซึ่งเป็นแหล่งข้อมูลสำหรับส่วน B) จากนั้นป้องกันส่วน B ที่ตามมาไม่ให้ทำอะไร

โปรแกรมที่สองคือสตริงเดียวกันตามด้วยส่วน B ส่วน B อิงจาก quine แบบง่าย มันพิมพ์สตริงนำหน้าด้วยรุ่นที่หลบหนีของมัน ซึ่งหมายความว่ามันจะพิมพ์สตริงและทั้งสองส่วน A และ B


ฉันคิดว่าสิ่งนี้แตกต่างไม่ต้องสงสัยเลยพิสูจน์ความถูกต้องขององค์ประกอบเป็นภาษาการเขียนโปรแกรม มันง่ายมากที่จะใช้ฉันที่ไม่มีประสบการณ์ดังนั้นฉันจึงสามารถเขียนล่ามที่สมบูรณ์สำหรับ Element ได้เพียงหนึ่งเดียวเท่านั้นที่สามารถตอบคำถามนี้ต่อหน้าคนอื่น ๆ บนโลกใบนี้ได้ถึง 7,000,000,000 คน กระบวนทัศน์ "หนึ่งตัวอักษรหนึ่งฟังก์ชั่นตลอดเวลา" ขององค์ประกอบหมายความว่าโค้ดทั้งหมดไม่มีความกำกวมอย่างสมบูรณ์ ภาษามีหลากหลาย: ยกเว้น[]{}คำสั่งใด ๆ สามารถวางที่ใดก็ได้ในโปรแกรมทั้งหมดโดยไม่ทำให้เกิดข้อผิดพลาดทางไวยากรณ์ มันสมบูรณ์แบบ.
PhiNotPi

4
เราลำเอียงใช่ไหม? ;-)
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

นี่คือการทำงานในMSAccessเพื่อใช้ประโยชน์จากModuleวัตถุ โมดูลนี้มีชื่อ"Q"สำหรับการเล่นกอล์ฟ ความแตกต่างในไวยากรณ์มาจากการIf ... Thenหายไปจากรุ่นที่สั้นกว่า


คุณน่าจะเปลี่ยนvbCrLFไปเป็นvbCr
Taylor Scott

3

C ++, คะแนน 0.734194

ซอร์สโค้ดต่อไปนี้จะพิมพ์เมตาลำดับของ 999 ไปยังคอนโซล (คำอธิบายด้านล่าง):

#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<<")"; \
  })

บรรทัดเดียวที่เปลี่ยนแปลงคือบรรทัดแรก ค่าของXจะเท่ากับ 1,000, 999, 998, ... , 3, 2 จากนั้นจะเริ่มอีกครั้ง อย่างไรก็ตามเพื่อให้ได้ต้นไม้ไวยากรณ์ที่แตกต่างกันทุกครั้งXจะถูกแสดงในรูปแบบของการแยกตัวประกอบเฉพาะของมันซึ่งไพรม์ทั้งหมดถูกเขียนเป็นผลรวมของ1s AST นั้นแตกต่างกันเนื่องจากการแยกตัวประกอบเฉพาะของจำนวนเต็มแตกต่างกันสำหรับทุกค่า

โปรแกรมจะพิมพ์ตัวเองยกเว้นว่าบรรทัดแรกมีการเปลี่ยนแปลงและแบ็กสแลชการแบ่งบรรทัดและการเยื้องที่อยู่ภายในQ(...)จะถูกลบออก

โปรแกรมต่อไปนี้คำนวณคะแนนคำตอบของฉัน:

#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';
}

มันพิมพ์ 0.734194 ไปยังคอนโซล เห็นได้ชัดว่า 1,000 สามารถแทนที่ได้ด้วยจำนวนเต็มขนาดใหญ่และคะแนนจะเข้าใกล้ 0 เป็นขีด จำกัด การพิสูจน์ทางคณิตศาสตร์เกี่ยวข้องกับฟังก์ชันซีตาของ Riemann ค่อนข้างซับซ้อน ฉันปล่อยให้มันเป็นแบบฝึกหัดให้กับผู้อ่าน ;)


2

JavaScript, 84.5 64 61

สองโปรแกรมทั้งความยาว169 128 122

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

ก่อนที่ฉันจะตีกอล์ฟเพื่อความสุขในการรับชมของคุณ:

(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;
})();

ส่งคืนโปรแกรมใหม่และส่งออกส่วนปัจจุบัน! ฉันอาจทำให้มันสั้นลงโดยไม่ต้องฟังก์ชั่น regex แต่ ... ฉันไม่ต้องการ


ไม่พวกมันมีความแตกต่างทางวากยสัมพันธ์ เมื่อคุณเพิ่มบรรทัดใหม่นั่นคือ
Ry-

2

J - (24 + 30) / 2/2 = 13.5 แต้ม

โปรดทราบว่าสตริงใน J จะไม่ทับขวาหนี 'I can''t breathe!'แต่อ้างหนีàลาปาสคาล:

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

โปรแกรมที่ 1 มี AST noun verb hook nounและโปรแกรม 2 มี nounAST โปรแกรม 2 เป็นเวอร์ชันที่ยกมาของโปรแกรม 1 ซึ่งจะส่งคืนโปรแกรม 1 เมื่อทำงานดังนั้นวิธีนี้จึงไม่สามารถขยายเป็นสำเนาที่สามได้อย่างง่ายดาย: P

โปรแกรม 1 ดำเนินการโดยการคัดลอกส่วนรหัสของแหล่งที่มาพร้อมกับคำพูดต่อท้ายและเพิ่มห้าของคำพูดเหล่านั้นไปยังจุดสิ้นสุด ( (,5#{.)) จากนั้นมันจะใช้เวลา 30 ตัวอักษรจากสตริง 16 ตัวอักษรนี้ซึ่งจะทำให้โปรแกรม 2 เป็นผล

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.