एसकेआई संकलक का अनुकूलन


22

स्की पथरी लैम्ब्डा पथरी कि लैम्ब्डा भाव का उपयोग नहीं करता का एक संस्करण है। इसके बजाय, केवल आवेदन और कॉम्बिनेटर एस , के , और मेरा उपयोग किया जाता है। इस चुनौती में, आपका काम SKI शब्दों को लैम्ब्डा शब्दों में सामान्य रूप में अनुवाद करना है


इनपुट विशिष्टता

इनपुट निम्नलिखित पाठ प्रतिनिधित्व में एक SKI शब्द है। आप एक वैकल्पिक अनुगामी न्यूलाइन प्राप्त करना चुन सकते हैं। इनपुट पात्रों से बना है S, K, I, (, और )और साथ संतुष्ट निम्नलिखित व्याकरण (ABNF रूप में) stermशुरू प्रतीक होने:

sterm = sterm combinator     ; application
sterm = combinator           ;
sterm = '(' sterm ')'        ; grouping
combinator = 'S' | 'K' | 'I' ; primitives

आउटपुट विशिष्टता

आउटपुट एक लैम्ब्डा शब्द है जिसमें निम्नलिखित टेक्स्ट प्रतिनिधित्व में कोई मुफ्त चर नहीं है। आप एक वैकल्पिक अनुगामी न्यूलाइन आउटपुट के लिए चुन सकते हैं। उत्पादन ltermप्रारंभिक प्रतीक होने के साथ एबीएनएफ फॉर्म में निम्नलिखित व्याकरण को संतुष्ट करेगा :

lterm   = lterm operand     ; application
lterm   = ALPHA '.' lterm   ; lambda
lterm   = operand
operand = '(' lterm ')'     ; grouping
operand = ALPHA             ; variable (a letter)

प्रतिबन्ध

आप मान सकते हैं कि इनपुट में input सामान्य रूप है। आप मान सकते हैं कि form सामान्य रूप का उपयोग अधिकांश 26 विभिन्न चर में किया जाता है। आप मान सकते हैं कि इनपुट और आउटपुट दोनों 79 वर्णों में प्रतिनिधित्व करने योग्य हैं।

नमूना इनपुट

यहाँ नमूना इनपुट के एक जोड़े हैं। दिए गए इनपुट के लिए आउटपुट एक संभव आउटपुट है।

input                        output
I                            a.a
SKK                          a.a
KSK                          a.b.c.ac(bc)
SII                          a.aa

स्कोरिंग

ऑक्टेट्स में सबसे छोटा समाधान जीतता है। सामान्य खामियों पर रोक है।


7
+1 क्योंकि मैं मानता हूं कि यह एक अच्छी चुनौती है; मुझे इसका एक शब्द समझ नहीं आया।
एलेक्स ए।

2
आह, मुझे अपना स्की.डाइट्स.नेट बनाना चाहिए :)

आप शायद राज्य दोनों कि ऐसा करना चाहिए stermऔर ltermउपयोग बाएँ संबद्धता जब कोष्ठक याद कर रहे हैं।
पीटर टेलर

@PeterTaylor इस तरह से बेहतर?
फ़ूजएक्सएक्सएल जूल 16'15

नहीं, मुझे लगता है कि वास्तव में गलत क्या है: निम्नलिखित है कि बदली हुई व्याकरण मैं पार्स हैं SKIके रूप में S(KI)
पीटर टेलर

जवाबों:


3

हास्केल , 232 बाइट्स

data T s=T{a::T s->T s,(%)::s}
i d=T(i. \x v->d v++'(':x%v++")")d
l f=f`T`\v->v:'.':f(i(\_->[v]))%succ v
b"S"x=l$l.(a.a x<*>).a
b"K"x=l(\_->x)
b"I"x=x
p?'('=l id:p
(p:q:r)?')'=a q p:r
(p:q)?v=a p(l$b[v]):q
((%'a')=<<).foldl(?)[l id]

इसे ऑनलाइन आज़माएं!

यह काम किस प्रकार करता है

यह " अनकैप्ड लैम्ब्डा कैलकुलस के लिए एक दुभाषिया लिखें" के लिए मेरे उत्तर के लिए एक अलग पार्सर सीमांत है , जिसमें प्रलेखन के साथ एक असंगठित संस्करण भी है ।

संक्षेप में, Term = T (Char -> String)लैम्ब्डा कैलकुलस शब्द का प्रकार है, जो जानता है कि खुद को अन्य शर्तों पर कैसे लागू किया जाए ( a :: Term -> Term -> Term) और खुद को एक String( (%) :: Term -> Char -> String) के रूप में कैसे प्रदर्शित किया जाए , एक प्रारंभिक ताजा चर दिया Char। हम किसी फ़ंक्शन को शब्द के साथ शब्द में परिवर्तित कर सकते हैं l :: (Term -> Term) -> Term, और क्योंकि परिणामी शब्द के अनुप्रयोग को केवल फ़ंक्शन ( a (l f) == f) कहते हैं, प्रदर्शित होने पर शब्द स्वचालित रूप से सामान्य रूप में कम हो जाते हैं।


9

रूबी, 323 बाइट्स

मैं विश्वास नहीं कर सकता बकवास का यह टुकड़ा काम करता है:

h={};f=96;z=gets.chop
{?S=>'s0.t0.u0.s0u0(t0u0)',?K=>'k0.l0.k0',?I=>'i0.i0'}.each{|k,v|z.gsub!k,?(+v+?)}
loop{z=~/\((?<V>\w1*0)\.(?<A>(?<B>\w1*0|[^()]|\(\g<B>+\))+)\)(?<X>\g<B>)/
s=$`;t=$';abort z.gsub(/\w1*0/){|x|h[x]=h[x]||(f+=1).chr}if !t
z=$`+?(+$~[?A].gsub($~[?V],$~[?X].gsub(/\w1*0/){|a|s[a]?a:a.gsub(?0,'10')})+?)+t}

कच्चे तार पर ge-कटौती करने के लिए रेगेक्स प्रतिस्थापन का उपयोग करना कुछ टोनी-द-पोनी सामान है। फिर भी, इसका उत्पादन आसान परीक्षण के लिए कम से कम सही लगता है:

$ echo 'I' | ruby ski.rb
(a.a)
$ echo 'SKK' | ruby ski.rb
(a.(a))
$ echo 'KSK' | ruby ski.rb
((a.b.c.ac(bc)))
$ echo 'SII' | ruby ski.rb
(a.(a)((a)))

यहाँ यह K(K(K(KK)))कुछ डिबग आउटपुट के साथ काम कर रहा है, जो मेरे लैपटॉप पर लगभग 7 सेकंड लेता है, क्योंकि नियमित अभिव्यक्ति पुनरावृत्ति धीमा है । आप कार्रवाई में इसके α- रूपांतरण देख सकते हैं!

$ echo 'K(K(K(KK)))' | ruby ski.rb
"(l0.((k10.l10.k10)((k10.l10.k10)((k10.l10.k10)(k10.l10.k10)))))"
"(l0.((l10.((k110.l110.k110)((k110.l110.k110)(k110.l110.k110))))))"
"(l0.((l10.((l110.((k1110.l1110.k1110)(k1110.l1110.k1110)))))))"
"(l0.((l10.((l110.((l1110.(k11110.l11110.k11110))))))))"
(a.((b.((c.((d.(e.f.e))))))))

मुझे मिलता है: स्की.rb: 4: इन 'gsub': गलत तर्क प्रकार nil (अपेक्षित Regexp) (TypeError) 'I' उदाहरण के साथ
aditsu

अब तय होना चाहिए! मैंने पहले ही इसे स्थानीय रूप से ठीक कर लिया था, लेकिन अपनी पोस्ट को संपादित करना भूल गया।
लिन

2
ठीक है, यह s ........ l ....................... o ........... w, लेकिन यह काम करने लगता है .... अंततः :) मुझे लगता है कि एस (के (एसआई)) के लिए परिणाम सही नहीं है।
एडिट्स

9

अजगर 2, 674

exec u"""import sys
$ V#):%=V.c;V.c+=1
 c=97;p!,v,t:[s,t.u({})][v==s];r!:s;u!,d:d.get(s,s);s!:chr(%)
 def m(s,x):%=min(%,x);-(%==x)+x
$ A#,*x):%,&=x
 C='()';p!,x,y:s.__$__(%.p/,&.p/);m!,x:&.m(%.m(x));u!,d:A(%.u(d),&.u(d));s!:%.s()+s.C[0]+&.s()+s.C[1:]
 def r(s):x=%.r();y=&.r();-x.b.p(x.a,y).r()if'L'in`x`else s.__$__/
$ L(A):C='.';u!,d:L(d.setdefault(%,V()),&.u(d))
x=V();y=V();z=V()
I=L(x,x)
K=L(y,L/)
S=L(x,L(z,L(y,A(A/,A(z,y)))))
def E():
 t=I
 while 1:
    q=sys.stdin.read(1)
    if q in')\\n':-t
    t=A(t,eval(max(q,'E()')).u({}))
t=E().r()
t.m(97)
print t.s()""".translate({33:u'=lambda s',35:u':\n def __init__(s',36:u'class',37:u's.a',38:u's.b',45:u'return ',47:u'(x,y)'})

नोट: के बाद while 1: 3 लाइनों के , एक टैब वर्ण के साथ इंडेंट किया जाता है।

यह मूल रूप से http://ski.aditsu.net/ के पीछे का कोड है , जिसका अनुवाद अजगर से किया गया है, जो बहुत ही सरलीकृत और भारी गोल्फ है।

संदर्भ: (यह शायद अब कम उपयोगी है कि कोड संकुचित है)

V = वेरिएबल टर्म
ए = एप्लीकेशन टर्म
एल = लैम्ब्डा टर्म
सी = वेरिएबल काउंटर
पी = टर्म वेरिएबल विथ टर्म
आर = कम
मी = फाइनल वेरिएबल रीन्युबेरिंग
यू = इंटरनल वेरिएबल रिन्युबेरिंग (डुप्लीकेट टर्म्स के लिए)
s = स्ट्रिंग कन्वर्जन
(पैरामीटर s = self)
स्ट्रिंग रूपांतरण
I, K, S: combinators
E = parse के लिए C = विभाजक चरित्र

उदाहरण:

python ski.py <<< "KSK"
a.b.c.a(c)(b(c))
python ski.py <<< "SII"        
a.a(a)
python ski.py <<< "SS(SS)(SS)"
a.b.a(b)(c.b(c)(a(b)(c)))(a(d.a(d)(e.d(e)(a(d)(e))))(b))
python ski.py <<< "S(K(SI))K" 
a.b.b(a)
python ski.py <<< "S(S(KS)K)I"                   
a.b.a(a(b))
python ski.py <<< "S(S(KS)K)(S(S(KS)K)I)"        
a.b.a(a(a(b)))
python ski.py <<< "K(K(K(KK)))"
a.b.c.d.e.f.e
python ski.py <<< "SII(SII)"
[...]
RuntimeError: maximum recursion depth exceeded

(यह this अपेक्षित है क्योंकि SII(SII)यह अप्रासंगिक है)

धन्यवाद बरीस और Sp3000 बाइट्स का एक गुच्छा को मारने में मदद करने के लिए :)


1
मुझे पूरा यकीन है कि आप यहां तक ​​कि कक्षाओं def m(a,b,c):return fooमें m=lambda a,b,c:fooभी बदल सकते हैं , जो आपको बहुत सारे बाइट बचा सकता है।
लिन

@ मॉरिस टिप के लिए धन्यवाद :)
aditsu

मैं a.b.c.a(c)(b(c))एक मान्य लंबोदर अभिव्यक्ति के रूप में पढ़ने में असफल रहा : क्या है (c)?
coredump

@coredump यह अनावश्यक समूहन के साथ एक ऑपरेंड है ... और आप सही हैं, यह ओपी के व्याकरण नियमों से बिल्कुल मेल नहीं खाता है। मुझे आश्चर्य है कि यह कितना महत्वपूर्ण है; मैं पूछता हूं।
aditsu

@coredump अद्यतन व्याकरण के साथ अब यह ठीक होना चाहिए।
aditsu

3

आम लिस्प, 560 बाइट्स

"अंत में, मुझे इसके लिए एक उपयोग मिला PROGV।"

(macrolet((w(S Z G #1=&optional(J Z))`(if(symbolp,S),Z(destructuring-bind(a b #1#c),S(if(eq a'L),G,J)))))(labels((r(S #1#(N 97))(w S(symbol-value s)(let((v(make-symbol(coerce`(,(code-char N))'string))))(progv`(,b,v)`(,v,v)`(L,v,(r c(1+ n)))))(let((F(r a N))(U(r b N)))(w F`(,F,U)(progv`(,b)`(,U)(r c N))))))(p()(do((c()(read-char()()#\)))q u)((eql c #\))u)(setf q(case c(#\S'(L x(L y(L z((x z)(y z))))))(#\K'(L x(L u x)))(#\I'(L a a))(#\((p)))u(if u`(,u,q)q))))(o(S)(w S(symbol-name S)(#2=format()"~A.~A"b(o c))(#2#()"~A(~A)"(o a)(o b)))))(lambda()(o(r(p))))))

Ungolfed

;; Bind S, K and I symbols to their lambda-calculus equivalent.
;;
;; L means lambda, and thus:
;;
;; -  (L x S) is variable binding, i.e. "x.S"
;; -  (F x)   is function application

(define-symbol-macro S '(L x (L y (L z ((x z) (y z))))))
(define-symbol-macro K '(L x (L u x)))
(define-symbol-macro I '(L x x))

;; helper macro: used twice in R and once in O

(defmacro w (S sf lf &optional(af sf))
  `(if (symbolp ,S) ,sf
       (destructuring-bind(a b &optional c) ,S
         (if (eq a 'L)
             ,lf
             ,af))))

;; R : beta-reduction

(defun r (S &optional (N 97))
  (w S
      (symbol-value s)
      (let ((v(make-symbol(make-string 1 :initial-element(code-char N)))))
        (progv`(,b,v)`(,v,v)
              `(L ,v ,(r c (1+ n)))))
      (let ((F (r a N))
            (U (r b N)))
        (w F`(,F,U)(progv`(,b)`(,U)(r c N))))))

;; P : parse from stream to lambda tree

(defun p (&optional (stream *standard-output*))
  (loop for c = (read-char stream nil #\))
        until (eql c #\))
        for q = (case c (#\S S) (#\K K) (#\I I) (#\( (p stream)))
        for u = q then `(,u ,q)
        finally (return u)))

;; O : output lambda forms as strings

(defun o (S)
  (w S
      (princ-to-string S)
      (format nil "~A.~A" b (o c))
      (format nil (w b "(~A~A)" "(~A(~A))") (o a) (o b))))

बीटा कमी

वेरिएबल्स PROGVका उपयोग करते हुए नए आम लिस्प प्रतीकों के साथ कमी के दौरान गतिशील रूप से बाध्य किया जाता है MAKE-SYMBOL। यह अच्छी तरह से नामकरण टकराव से बचने की अनुमति देता है (जैसे बाध्य चर की अवांछित छायांकन)। मैं इस्तेमाल कर सकता था GENSYM, लेकिन हम प्रतीकों के लिए उपयोगकर्ता के अनुकूल नाम रखना चाहते हैं। इसीलिए प्रतीकों aको z(प्रश्न द्वारा अनुमति के अनुसार) अक्षरों से नाम दिया गया है। Nमौजूदा दायरे में अगले उपलब्ध पत्र के चरित्र कोड का प्रतिनिधित्व करता है और 97 से शुरू होता है, उर्फa

यहाँ R( Wमैक्रो के बिना ) का अधिक पठनीय संस्करण है :

(defun beta-reduce (S &optional (N 97))
  (if (symbolp s)
      (symbol-value s)
      (if (eq (car s) 'L)
          ;; lambda
          (let ((v (make-symbol (make-string 1 :initial-element (code-char N)))))
            (progv (list (second s) v)(list v v)
              `(L ,v ,(beta-reduce (third s) (1+ n)))))
          (let ((fn (beta-reduce (first s) N))
                (arg (beta-reduce (second s) N)))
            (if (and(consp fn)(eq'L(car fn)))
                (progv (list (second fn)) (list arg)
                  (beta-reduce (third fn) N))
                `(,fn ,arg))))))

इंटरमीडिएट के परिणाम

स्ट्रिंग से पार्स:

CL-USER> (p (make-string-input-stream "K(K(K(KK)))"))
((L X (L U X)) ((L X (L U X)) ((L X (L U X)) ((L X (L U X)) (L X (L U X))))))

कम करें:

CL-USER> (r *)
(L #:|a| (L #:|a| (L #:|a| (L #:|a| (L #:|a| (L #:|b| #:|a|))))))

(निष्पादन का ट्रेस देखें)

सुंदर प्रिंट:

CL-USER> (o *)
"a.a.a.a.a.b.a"

टेस्ट

मैं पायथन जवाब के रूप में एक ही परीक्षण सूट का पुन: उपयोग करता हूं:

        Input                    Output              Python output (for comparison)

   1.   KSK                      a.b.c.a(c)(b(c))    a.b.c.a(c)(b(c))              
   2.   SII                      a.a(a)              a.a(a)                        
   3.   S(K(SI))K                a.b.b(a)            a.b.b(a)                      
   4.   S(S(KS)K)I               a.b.a(a(b))         a.b.a(a(b))                   
   5.   S(S(KS)K)(S(S(KS)K)I)    a.b.a(a(a(b)))      a.b.a(a(a(b)))                
   6.   K(K(K(KK)))              a.a.a.a.a.b.a       a.b.c.d.e.f.e 
   7.   SII(SII)                 ERROR               ERROR

8 वीं परीक्षा का उदाहरण ऊपर दी गई तालिका के लिए बहुत बड़ा है:

8.      SS(SS)(SS)
CL      a.b.a(b)(c.b(c)(a(b)(c)))(a(b.a(b)(c.b(c)(a(b)(c))))(b))      
Python  a.b.a(b)(c.b(c)(a(b)(c)))(a(d.a(d)(e.d(e)(a(d)(e))))(b))
  • EDIT I ने मेरे उत्तर को उसी तरह से समूहीकृत करने का व्यवहार किया है जैसा कि विज्ञापन के उत्तर में है , क्योंकि इसे लिखने के लिए कम बाइट खर्च होती है।
  • शेष अंतर परीक्षण 6 और 8 के लिए देखा जा सकता है परिणाम a.a.a.a.a.b.aसही है और अजगर जवाब के रूप में ज्यादा पत्र, जहां के लिए बाइंडिंग के रूप में उपयोग नहीं करता है a, b, cऔर dसंदर्भित नहीं हैं।

प्रदर्शन

ऊपर दिए गए 7 उत्तीर्ण परीक्षणों में लूपिंग और परिणाम एकत्र करना तत्काल (SBCL आउटपुट) है:

Evaluation took:
  0.000 seconds of real time
  0.000000 seconds of total run time (0.000000 user, 0.000000 system)
  100.00% CPU
  310,837 processor cycles
  129,792 bytes consed

एक ही परीक्षण के सौ बार नेतृत्व करने के लिए ... SBCL पर "थ्रेड लोकल स्टोरेज समाप्त हो गया", जो कि कुछ अन्य वैरिएबल के बारे में ज्ञात सीमा के कारण है । CCL के साथ, एक ही टेस्ट सूट को 10000 बार कॉल करने में 3.33 सेकंड लगते हैं।


यह एक साफ समाधान है!
फ़ूजएक्सएक्सएल

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