จำลองเครื่องลงทะเบียน Minsky (II)


11

นี้เป็นส่วนขยายของจำลองมินสกีลงทะเบียนเครื่อง (I) ฉันจะไม่ทำซ้ำคำอธิบายทั้งหมดที่นั่นดังนั้นโปรดอ่านคำอธิบายปัญหาก่อน

ไวยากรณ์ในส่วน (I) นั้นเรียบง่ายที่สุดเท่าที่จะเป็นไปได้ แต่ให้ผลลัพธ์ในโปรแกรมที่ค่อนข้างยาว เนื่องจากนี่คือไซต์รหัสกอล์ฟเราควรมีไวยากรณ์กอล์ฟใช่มั้ย

ในระดับสูงการเปลี่ยนแปลงจากไวยากรณ์ดั้งเดิมมีดังนี้:

  • ฉลากในบรรทัดแรกเป็นตัวเลือก
  • ช่องว่างเป็นทางเลือกยกเว้นในกรณีที่จำเป็นต้องแยกตัวระบุสองตัวที่ติดกัน
  • รัฐสามารถ inlined เพื่อให้แน่ใจว่าการวิเคราะห์คำที่ไม่กำกวมไม่ชัดเจนหากสถานะแรกของการดำเนินการลดทอนเป็นสถานะอินไลน์มันจะต้องอยู่ในวงเล็บ ซึ่งหมายความว่าโปรแกรมใด ๆ ที่สามารถเล่นกอล์ฟเป็นแบบหนึ่งเส้นได้

ตัวอย่างเช่นในกรณีทดสอบต้นฉบับเรามี:

b + = a, t = 0

init : t - init d0
d0 : a - d1 a0
d1 : b + d2
d2 : t + d0
a0 : t - a1 "Ok"
a1 : a + a0
a=3 b=4

ในไวยากรณ์ golfed นี้อาจสั้นลงไป:

init:t-init d
d:a-(b+t+d)a
a:t-(a+a)"Ok"
a=3 b=4

หรือแม้กระทั่ง:

init:t-init d:a-(b+t+d)a:t-(a+a)"Ok"
a=3 b=4

BNF ใหม่สำหรับบรรทัด "โปรแกรม" (ตรงข้ามกับบรรทัดสุดท้ายซึ่งเป็นข้อมูล) คือ:

program    ::= first_line (newline line)*
first_line ::= cmd
line       ::= named_cmd
state      ::= state_name
             | cmd
             | '"' message '"'
delim_state::= '(' cmd ')'
             | '"' message '"'
cmd        ::= raw_cmd
             | named_cmd
named_cmd  ::= state_name ' '* ':' ' '* raw_cmd
raw_cmd    ::= inc_cmd
             | dec_cmd
inc_cmd    ::= reg_name ' '* '+' ' '* state
dec_cmd    ::= reg_name ' '* '-' ' '* delim_state ' '* state
             | reg_name ' '* '-' ' '* state_name ' '* delim_state
             | reg_name ' '* '-' ' '* state_name ' '+ state
state_name ::= identifier
reg_name   ::= identifier

ตัวระบุและข้อความมีความยืดหยุ่นเช่นเดียวกับในความท้าทายที่ผ่านมา


กรณีทดสอบทั้งหมดจากความท้าทายก่อนหน้านี้ยังคงมีผลบังคับใช้ นอกจากนี้โซลูชัน Josephus ที่ได้ตีกอล์ฟต่อไปนี้ควรใช้ไวยากรณ์ส่วนใหญ่:

in:k-(r+t+in)in2:t-(k+in2)r-(i+n-0"ERROR n is 0")"ERROR k is 0"
0:n-(i+2:k-(r+t+2)5:t-(k+5)7:i-(r-(t+7)c:t-(i+r+c)i+0)a:t-(i+a)7)"Ok"
n=40 k=3

ผลลัพธ์ที่คาดหวัง:

Ok
i=40 k=3 n=0 r=27 t=0

และฉันคิดว่านี่ครอบคลุมกรณีที่เหลืออยู่:

k+k-"nop""assert false"
k=3

ผลลัพธ์ที่คาดหวัง:

nop
k=3

คุณอาจสันนิษฐานว่าทุกโปรแกรมจะมีความหมายที่สมเหตุสมผล โดยเฉพาะอย่างยิ่งพวกเขาจะมีอย่างน้อยหนึ่งรัฐและจะไม่กำหนดรัฐ อย่างไรก็ตามก่อนหน้านี้อาจมีการใช้สถานะก่อนที่จะถูกกำหนด

การให้คะแนนเป็นตัวแปรในการตีกอล์ฟ คุณสามารถเขียนโปรแกรมที่มีในตัวเองและมันจะทำคะแนนตามความยาวของโปรแกรมเป็นไบต์หลังจากการเข้ารหัส UTF-8 อีกทางเลือกหนึ่งเนื่องจากการใช้รหัสซ้ำเป็นสิ่งที่ดีหากคุณติดตั้งส่วน (I) เป็นn1ไบต์คุณสามารถเขียนโปรแกรมที่เปลี่ยนโปรแกรมส่วนหนึ่ง (II) เป็นโปรแกรมส่วนหนึ่ง (I) พร้อมที่จะส่งไปยังต้นฉบับ คะแนนของคุณจะเป็นความยาวของโปรแกรมการแปลงบวกของceil(n1 / 2)คุณ

หมายเหตุถ้าคุณเลือกที่จะแปลงคุณจะต้องสร้างชื่อสำหรับรัฐนิรนามในแบบที่คุณรับประกันว่าพวกเขาจะไม่ขัดแย้งกับรัฐที่มีชื่อ

คำตอบ:


6

Haskell, 552 499 493 ตัวอักษร

import Control.Monad.RWS
import Data.Map
main=interact$z.lines
z x=let(s:_,w)=evalRWS(mapM(q.t)x)w[]in s.f.i.t$last x 
p=get>>=q
q(l:":":x)=x%do a<-p;tell$f[(l,a)];r a
q(v:"+":x)=x%fmap(.a v 1)p
q(v:"-":x)=x%liftM2(d v)p p
q(('"':s):x)=x%r(\w->unlines[init s,do(v,x)<-assocs w;v++'=':show x++" "])
q(n:x)|n<"*"=x%p|1<3=x%asks(!n)
d v p n w|member v w&&w!v>0=p$a v(-1)w|1<3=n w
t[]=[];t x=lex x>>= \(y,x)->y:t x
i(v:_:x:t)=(v,read x):i t;i[]=[]
x%m=put x>>m;r=return;a=insertWith(+);f=fromList

ทำมากหรือน้อยเขียนใหม่ทั้งหมด แทนที่ CPS ด้วย RWS monad ซึ่งอ่านเอาต์พุตของตัวเองเพื่อค้นหาสถานะมันยังไม่ได้แยกวิเคราะห์ (yay for laziness!) รวมถึงการปรับแต่งอื่น ๆ

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