एक Minsky रजिस्टर मशीन (II) का अनुकरण करें


11

यह एक Minsky Register Machine (I) का अनुकरण है । मैं वहां सभी विवरण दोहराने नहीं जा रहा हूं, इसलिए कृपया उस समस्या विवरण को पहले पढ़ें।

भाग (I) में व्याकरण जितना संभव हो उतना सरल था, लेकिन इसके बजाय लंबे कार्यक्रम थे। चूंकि यह एक कोड गोल्फ साइट है, इसलिए हमारे पास एक गोल्फ व्याकरण होगा, हम नहीं?

उच्च स्तर पर, मूल व्याकरण से परिवर्तन निम्नानुसार हैं:

  • पहली पंक्ति पर लेबल वैकल्पिक है
  • व्हॉट्सएप वैकल्पिक है जहां दो आसन्न पहचानकर्ताओं को अलग करने के लिए आवश्यक है
  • राज्यों का झुकाव हो सकता है। गैर-अस्पष्ट पार्सिंग सुनिश्चित करने के लिए, यदि एक विकृति ऑपरेशन की पहली स्थिति एक अंतर्निर्मित अवस्था है, तो इसे कोष्ठकों में संलग्न किया जाना चाहिए। इसका मतलब है कि किसी भी कार्यक्रम को एक-लाइनर में रखा जा सकता है।

उदाहरण के लिए, हमारे पास मूल परीक्षण मामलों में:

बी + = ए, टी = 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

गोल्फ व्याकरण में इसे छोटा किया जा सकता है:

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

"प्रोग्राम" लाइनों के लिए नया बीएनएफ (अंतिम पंक्ति के विपरीत, जो डेटा है):

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

पिछली चुनौती की तरह पहचानकर्ता और संदेश लचीले हैं।


पिछली चुनौती के सभी परीक्षण मामले अभी भी लागू हैं। इसके अलावा, निम्नलिखित गोल्फ वाले जोसेफस समाधान में सबसे अधिक व्याकरण का अभ्यास करना चाहिए:

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

आप मान सकते हैं कि सभी कार्यक्रमों में समझदार शब्दार्थ होंगे। विशेष रूप से, उनके पास कम से कम एक राज्य होगा और एक राज्य को फिर से परिभाषित नहीं करेगा। हालांकि, पहले की तरह, एक राज्य का उपयोग परिभाषित होने से पहले किया जा सकता है।

स्कोरिंग कोड-गोल्फ पर एक प्रकार है। आप एक स्व-निहित कार्यक्रम लिख सकते हैं और यह यूटीएफ-8-एन्कोडिंग के बाद बाइट्स में कार्यक्रम की लंबाई के रूप में स्कोर करेगा। वैकल्पिक रूप से, क्योंकि कोड का पुन: उपयोग करना एक अच्छी बात है, यदि आपने n1बाइट्स में भाग (I) को लागू किया है, तो आप एक प्रोग्राम (II) प्रोग्राम को एक पार्ट (I) प्रोग्राम में बदल सकते हैं, जो मूल में पाइपिंग के लिए तैयार है। आपका स्कोर तब आपके परिवर्तन कार्यक्रम प्लस की लंबाई होगी ceil(n1 / 2)

NB यदि आप परिवर्तन का विकल्प चुनते हैं, तो आपको अनाम राज्यों के लिए इस तरह से नाम उत्पन्न करने की आवश्यकता होगी कि आप गारंटी देते हैं कि वे नामित राज्यों से टकराते नहीं हैं।

जवाबों:


6

हास्केल, 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

कमोबेश एक पूर्ण पुनर्लेखन किया। एक आरडब्ल्यूएस मोनाड के साथ सीपीएस को बदल दिया गया, जो अपने स्वयं के आउटपुट को पढ़ने के लिए कहता है कि यह अभी तक पार्स नहीं किया गया है (आलस्य के लिए याय!), साथ ही कुछ अन्य ट्विक्स।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.