Tulis a ~ ATH Interpreter


12

Homestuck webcomic populer menggunakan bahasa pemrograman yang disebut ~ATHuntuk menghancurkan alam semesta. Walaupun tantangan golf kode ini bukan untuk menulis program untuk memusnahkan keberadaan kita, kita akan menghancurkan entitas yang lebih jinak (meskipun kurang menarik): variabel

~ATH(diucapkan "til death," perhatikan bagaimana ~ath"tilde ath") bekerja dengan membuat variabel yang dipanggil THIS, menjalankan perintah dengan EXECUTE, dan menyelesaikan program dengan THIS.DIE(). Halaman wiki untuk penggunaan bahasa di Homestuck dapat ditemukan di sini . Tujuan dari tantangan ini adalah menciptakan ~ATHjuru bahasa.

Demi tantangan, saya akan membuat beberapa detail ~ATHyang tidak benar-benar ada tetapi membuatnya (agak) berguna.

  • Bahasa hanya akan bekerja dengan bilangan bulat, yang dideklarasikan dengan import <variable name>;. Variabel akan secara otomatis ditetapkan ke nilai 0. Hanya satu variabel pada satu waktu yang dapat diimpor.
  • Suatu variabel xdapat disalin dengan menulis bifurcate x[y,z];, yang akan menghapus variabel xdan menggantinya dengan variabel yang identik ydan z. Perhatikan bahwa itu tidak dapat membuat variabel dengan nama yang sama dengan yang dihapus. Pada dasarnya, variabel diubah namanya, kemudian salinan variabel dengan nama yang berbeda dibuat. Hal ini tampaknya seperti fitur bodoh, tapi kebodohan sangat mendalam tertanam di Homestuck.
  • Sintaks untuk menulis program yang mengeksekusi kode xadalah ~ATH(x){EXECUTE(<code>)}. Jika Anda ingin mengeksekusi kode pada dua variabel secara bersamaan, kode menjadi bersarang, seperti ini: ~ATH(x){~ATH(y){EXECUTE(<code>)}}. Semua perintah di <code>akan dieksekusi pada keduanya xdan y.
  • Sekarang mari kita beralih ke perintah. +menambah variabel yang relevan dengan 1 dan -menurunkannya dengan 1. Dan ... itu saja.
  • Fitur terakhir ~ATHadalah bahwa ia membunuh apa pun yang bekerja dengannya. Variabel dicetak dalam format <name>=<value>(diikuti oleh baris baru) pada perintah [<name>].DIE();. Setelah itu, program mencetak kata DIE <name>dan baris baru beberapa kali sama dengan nilai absolut dari nilai variabel. Ketika variabel terbunuh secara bersamaan dengan [<name1>,<name2>].DIE();(Anda dapat memiliki banyak variabel terbunuh seperti yang Anda inginkan, selama mereka ada), DIE()perintah dieksekusi pada variabel secara berurutan.

Contoh program

Program 1:

import sollux;                  //calls variable "sollux"
import eridan;                  //calls variable "eridan"
~ATH(sollux){EXECUTE(--)}       //sets the value of "sollux" to -2
~ATH(eridan){EXECUTE(+++++)}    //sets the value of "eridan" to 5
[sollux].DIE();                 //kills "sollux", prints "DIE sollux" twice
~ATH(eridan){EXECUTE(+)}        //sets the value of "eridan" to 6
[eridan].DIE();                 //kills "eridan", prints "DIE eridan" 6 times

Keluaran:

sollux=-2
DIE sollux
DIE sollux
eridan=6
DIE eridan
DIE eridan
DIE eridan
DIE eridan
DIE eridan
DIE eridan

Program 2:

import THIS;                    //calls variable "THIS"
~ATH(THIS){EXECUTE(++++)}       //sets the value of "THIS" to 4
bifurcate THIS[THIS1,THIS2];    //deletes "THIS", creates variables "THIS1" and "THIS2" both equal to 4
~ATH(THIS1){EXECUTE(++)}        //sets the value of "THIS1" to 6
[THIS1,THIS2].DIE();            //kills "THIS1" and "THIS2", prints "DIE THIS1" 6 times then "DIE THIS2" 4 times

import THAT;                                         //calls variable "THAT"
bifurcate THAT[THESE,THOSE];                         //deletes "THAT", creates variables "THESE" and "THOSE"
~ATH(THESE){~ATH(THOSE){EXECUTE(+++)}EXECUTE(++)}    //sets the value of "THESE" and "THOSE" to 3, then sets the value of "THESE" to 5
[THESE,THOSE].DIE();                                 //kills "THESE" and "THOSE", prints "DIE THESE" 5 times then "DIE THOSE" 3 times

Keluaran:

THIS1=6
DIE THIS1
DIE THIS1
DIE THIS1
DIE THIS1
DIE THIS1
DIE THIS1
THIS2=4
DIE THIS2
DIE THIS2
DIE THIS2
DIE THIS2
THESE=5
DIE THESE
DIE THESE
DIE THESE
DIE THESE
DIE THESE
THOSE=3
DIE THOSE
DIE THOSE
DIE THOSE

Ini kode golf, jadi aturan standar berlaku. Kode terpendek dalam byte menang.


2
Sampai mati. Saya melihat apa yang Anda lakukan di sana.
Digital Trauma

3
@DigitalTrauma Saya harus memberikan kredit kepada Andrew Hussie (lelaki yang menulis Homestuck) karena membuat nama itu.
Arcturus

1
@sysreq ~ATHmenggunakan titik koma sebagai line-akhiran untuk import, bifurcatedan DIEperintah. Baik REPL dan file baik-baik saja. Sensitivitas kasus diperlukan baik dalam input maupun output (Saya mencoba mencocokkan yang sebenarnya ~ATHsebanyak mungkin).
Arcturus

1
@sysreq Saya harus mengubah beberapa hal sehingga bahasa akan benar - benar melakukan sesuatu dalam kehidupan nyata, Pecs saya jelaskan baik-baik saja.
Arcturus

2
Saya benar-benar terkejut pertanyaan ini belum mendapat tanggapan lebih banyak, dan bahkan lebih terkejut lagi tidak ada gerombolan penyihir Perl yang dipersenjatai dengan tongkat sihir regexy
kucing

Jawaban:


3

Python 2.7.6, 1244 1308 1265 1253 1073 1072 1071 1065 1064 1063 byte

Baiklah, saya tidak memecahkan catatan apa pun di sini tapi ini tentang Python terkecil akan pergi sejauh membaca input sekaligus dari file daripada secara berurutan dari waktu ke waktu. Saya akan mencoba untuk memperbaruinya nanti dalam bahasa yang berbeda (dan penerjemah, bukan hanya pengurai). Sampai saat itu, nikmati keburukan mengerikan yang menjijikkan.

Catatan : membuka file yang disebut tdi direktori kerja. Untuk membuatnya membuka argumen baris perintah, tambahkan import syske bagian atas file dan ubah 't'kesys.argv[1]

n=s='\n';m=',';X='[';Y=']';c=';';A='~ATH';D='import';b,g,k=[],[],[];r=range;l=len;f=open('t','r').read().split(n)
def d(j,u):
 p=[]
 for e in j:
  if e!=u:p.append(e)
 return''.join(p)
for h in r(l(f)):f[h]=f[h].split('//')[0].split()
while[]in f:f.remove([])
for h in r(l(f)):
 i=f[h]
 if i[0]==D and l(i)==2and i[1][l(i[1])-1]==c and d(i[1],c)not in b:g.append(0);b.append(d(i[1],c))
 elif i[0].startswith(A):
  i=i[0].split('){')
  for e in r(l(i)):
   if i[e].startswith(A):
    i[e]=i[e].split('(')
    if i[0][1]in b:g[b.index(i[0][1])]+=(i[1].count('+')-i[1].count('-'))
 elif i[0].startswith('bifurcate')and l(i)==2and i[1][l(i[1])-1]==c:
  i=i[1].split(X)
  if i[0] in b:
   z=d(d(i[1],c),Y).split(m)
   for e in r(l(z)):g.append(g[b.index(i[0])]);b.append(z[e])
   g.remove(g[b.index(i[0])]);b.remove(i[0])
 elif i[0].startswith(X)and i[0].endswith('.DIE();')and l(i)==1:
  z=d(i[0],X).split(Y)[0].split(m)
  for e in r(l(z)):
   k.append((z[e],g[b.index(z[e])]))
for e in r(l(k)):k0=k[e][0];k1=k[e][1];s+=k0+'='+str(k1)+n+('DIE '+k0+n)*abs(k1)
print s

2

Python 2, 447 475 463 443 byte

exec("eNp1UUtrAjEQvu+vCEshiYnrxl7KbqOUVmjvCoUkxUdiG7BRkpW2iP3tTVwrReppMsx8r4l936x9A8JXoN5kmu/2WeCxK0KjrSu8mWmEs0Ad96YI27lDPu/1is7wKqcQ0kBLenM+ty0nilu4zqnPtYCSQcXL2P2LmNvl1i9mjWlBUhwKbRt14uhHjlSvjzVy1tqswO/7AjsSpKtwIpGvt2zALqyNnkf3k/FIolb2ACjlpe2jR6lk8fAUQbKNulx7YIF1IDkqwmZlGwQpxNXGW9cASyCHZKqFVVOCoJQOEhjxABKLO7N5QGmET5qOs/Qfoqq6TGUfb3ZlgKvOnOxTwJKpDq6HSLzsVfK1k7g1iB7Hd9/JWh3T9wclkYwTlY4odP0nnvk0C3RUwj95/ZUq".decode('base64').decode('zip'))

Ternyata zip dan pengkodean program base64 masih menyimpan byte lebih dari versi normal. Sebagai perbandingan, inilah yang normal:

import sys,re
d={}
s=sys.stdin.read()
s,n=re.subn(r"//.*?$",'',s,0,8)
s,n=re.subn(r"import (.*?);",r"d['\1']=0;",s,0,8)
s,n=re.subn(r"bifurcate (.*?)\[(.*?),(.*?)\];",r"d['\2']=d['\3']=d['\1'];del d['\1'];",s,0,8)
s,n=re.subn(r"([+-])",r"\g<1>1",s,0,8)
s,n=re.subn(r"EXECUTE\((.*?)\)",r"0\1",s,0,8)
s,n=re.subn(r"\[(.*?)\]\.DIE\(\);",r"for i in '\1'.split(','):print i+'='+`d[i]`+('\\n'+'DIE '+i)*abs(d[i])",s,0,8)
n=1
s=s[::-1]
while n:s,n=re.subn(r"\}([+-01]*);?([^}]*?)\{\)(.*?)\(HTA~",r";\g<2>0+\1=+]'\3'[d;\1",s,0,8)
exec(s[::-1])

Pada dasarnya solusi "tongkat sihir sihir" yang diinginkan. Membaca seluruh program dari stdin sebagai string tunggal, menggantikan ~ ATH ekspresi dengan ekspresi Python yang melakukan semantik yang dijelaskan, dan exec () adalah string yang dihasilkan.

Untuk melihat apa yang dilakukannya, lihat program python yang program uji yang disediakan kedua diterjemahkan ke:

d['THIS']=0;                    
0+1+1+1+1;d['THIS']+=0+1+1+1+1+0;       
d['THIS1']=d['THIS2']=d['THIS'];del d['THIS'];    
0+1+1;d['THIS1']+=0+1+1+0;        
for i in 'THIS1,THIS2'.split(','):print i+'='+`d[i]`+('\n'+'DIE '+i)*abs(d[i])            

d['THAT']=0;                                         
d['THESE']=d['THOSE']=d['THAT'];del d['THAT'];                         
0+1+1;d['THESE']+=0+1+1+00+1+1+1;d['THOSE']+=0+1+1+1+0;    
for i in 'THESE,THOSE'.split(','):print i+'='+`d[i]`+('\n'+'DIE '+i)*abs(d[i])                                 

Itu hal yang baik bahwa 00 == 0: P

Jelas, beberapa byte bisa diselamatkan dengan mengeksploitasi ambiguitas dalam aturan. Misalnya, tidak dikatakan apa yang harus terjadi jika seseorang mencoba DIE()variabel yang belum importdiedit, atau yang sudah bifurcated. Dugaan saya berdasarkan deskripsi adalah bahwa harus ada kesalahan. Jika tidak ada kesalahan yang diperlukan, saya bisa menghapus delpernyataan itu.

EDIT: Memperbaiki bug yang tidak diuji oleh test case. Yaitu, seperti itu, setiap ~ATHblok mereset variabel ke nol sebelum menambahkannya. Harganya 28 byte untuk memperbaikinya. Jika ada yang melihat cara yang lebih baik untuk mengganti ~ATHbalok, saya ingin mengetahuinya.

EDIT 2: Menyimpan 12 byte dengan membuka gulungan loop regex, menjadikan semuanya subns dan membiarkan kompresi menangani pengulangan.

EDIT 3: Menyimpan 20 byte lebih banyak dengan mengganti forloop dalam dengan perkalian string.


Hei, akhirnya tongkat sihir regexy! Saya tidak akan bisa mengalahkan ini tetapi dilakukan dengan baik!
kucing

Implementasi saya sepenuhnya mengabaikan hal-hal yang tidak secara eksplisit dicakup oleh aturan, yang berarti tidak apa-apa bagi Anda untuk tidak melakukan kesalahan dan mengabaikan kasus-kasus itu juga.
kucing

Anda bisa menghemat beberapa byte dengan melakukan import sys,redaripadaimport sys;import re
cat

1
penyorotan sintaks membuat ini lebih mudah dibaca
cat

1
@cat maaf saya lupa menjawab Anda sejak lama. Anda menjalankannya dari baris perintah dan menyalurkan input ke dalam file:python ~ath.py < program.~ath
quintopia
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.