এসকেআই সংকলক অনুকূলিতকরণ


22

স্কি ক্যালকুলাস ল্যামডা ক্যালকুলাস যে ল্যামডা এক্সপ্রেশন ব্যবহার করে না একটি বৈকল্পিক। পরিবর্তে, কেবলমাত্র অ্যাপ্লিকেশন এবং এস , কে , এবং আমি সংযুক্তকারীগুলি ব্যবহার করা হবে। এই চ্যালেঞ্জের মধ্যে আপনার কাজটি হ'ল এসকেআই পদকে ল্যাম্বডা শর্তগুলিতে সাধারণ আকারে অনুবাদ করা


ইনপুট স্পেসিফিকেশন

নিম্নলিখিত পাঠ্য উপস্থাপনায় ইনপুটটি একটি এসকেআই পদ। আপনি একটি alচ্ছিক ট্রেলিং নিউলাইনটি চয়ন করতে পারেন। ইনপুট অক্ষর গঠিত হয় S, K, I, (, এবং )সঙ্গে সন্তুষ্ট নিম্নলিখিত ব্যাকরণ (ABNF আকারে) stermশুরু প্রতীক হচ্ছে:

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

আউটপুট স্পেসিফিকেশন

আউটপুটটি একটি ল্যাম্বডা শব্দ যা নিম্নলিখিত পাঠ্য উপস্থাপনায় কোনও মুক্ত ভেরিয়েবল নেই। আপনি একটি বিকল্প ilingচ্ছিক নতুন লাইনের আউটপুট চয়ন করতে পারেন। আউটপুট ltermশুরুর প্রতীক হওয়ার সাথে সাথে নিম্নলিখিত ব্যাকরণটি ABNF আকারে পূরণ করবে :

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

সীমাবদ্ধতাসমূহ

আপনি ধরে নিতে পারেন যে ইনপুটটির একটি β স্বাভাবিক ফর্ম রয়েছে। আপনি ধরে নিতে পারেন যে form স্বাভাবিক ফর্মটি প্রায় 26 টি বিভিন্ন ভেরিয়েবল ব্যবহার করে। আপনি ধরে নিতে পারেন যে ইনপুট এবং আউটপুট উভয়ই characters৯ টি অক্ষরে প্রতিনিধিত্বযোগ্য।

নমুনা ইনপুট

এখানে নমুনা ইনপুট একটি দম্পতি দেওয়া হয়। প্রদত্ত ইনপুটটির জন্য আউটপুট সম্ভাব্য আউটপুট।

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

স্কোরিং

অক্টেটের মধ্যে সংক্ষিপ্ততম সমাধানটি জয়লাভ করে। সাধারণ লুফোলগুলি নিষিদ্ধ করা হয়।


7
+1 কারণ আমি ধরে নিই এটি একটি দুর্দান্ত চ্যালেঞ্জ; আমি এর একটি শব্দও বুঝতে পারিনি।
অ্যালেক্স এ

2
আহ, আমি আমার ski.aditsu.net :) গল্ফ করা উচিত :)
aditsu

আপনার সম্ভবত বলা উচিত যে উভয়ই stermএবং ltermবন্ধনীগুলি অনুপস্থিত থাকাকালীন বাম-সহযোগিতা ব্যবহার করুন।
পিটার টেলর

@ পিটারটেলর এইভাবে আরও ভাল?
FUZxxl

না, আমি মনে করি যে আসলে ভুল: নিম্নলিখিত পরিবর্তন ব্যাকরণ আমি পার্স হবে 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}

কাঁচা স্ট্রিংগুলিতে β-হ্রাস সম্পাদনের জন্য রেজেক্স বিকল্প ব্যবহার করা কিছু টনি-দ্য পোনি স্টাফ। তবুও, কমপক্ষে সহজ টেস্টকেসের জন্য এর আউটপুট সঠিক দেখাচ্ছে:

$ 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))))))))

আমি পেয়েছি: ski.rb: 4: in s gsub ': ভুল আর্গুমেন্ট টাইপ নীল (প্রত্যাশিত Regexp) (TypeError)' I 'উদাহরণ সহ
aditsu

এখনই ঠিক করা উচিত! আমি ইতিমধ্যে এটি স্থানীয়ভাবে সংশোধন করেছিলাম, তবে আমার পোস্টটি সম্পাদনা করতে ভুলে গিয়েছি।
লিন

2
ঠিক আছে, এটি ........ l ....................... ও ........... ডাব্লু, তবে এটি কাজ করছে বলে মনে হচ্ছে .... শেষ পর্যন্ত :) আমি মনে করি এস (কে (এসআই)) কে এর ফলাফল যদিও সঠিক নয়।
অদিতসু

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/ এর পেছনের কোড যা অজগরকে অনুবাদ করা হয়েছে, খুব সরল ও ভারীভাবে গল্ফ হয়েছে।

তথ্যসূত্র: (কোডটি সংকুচিত করা হওয়ায় এটি সম্ভবত কম কার্যকর)

ভি = ভেরিয়েবল টার্ম
এ = অ্যাপ্লিকেশন টার্ম
এল = ল্যাম্বডা টার্ম
সি = ভেরিয়েবল কাউন্টার
পি = টার্মের সাথে প্রতিস্থাপন করুন
r = হ্রাস
এম = ফাইনাল ভেরিয়েবল রিম্বারিং
ইউ = অভ্যন্তরীণ ভেরিয়েবল রম্বারিং (ডুপ্লিকেটেড পদগুলির জন্য)
s = স্ট্রিং রূপান্তর
(প্যারামিটার এস = স্ব) আই, কে, এস
স্ট্রিং রূপান্তরকরণের জন্য সি = বিভাজক চরিত্র (গুলি)
: সংযুক্তকারী
E = পার্স

উদাহরণ:

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

(এটি expected হিসাবে প্রত্যাশিত কারণ SII(SII)অদলিত হয়)

একগুচ্ছ বাইটসকে মারতে সহায়তা করার জন্য মরিস এবং এসপি 3000 ধন্যবাদ


1
আমি প্রায় নিশ্চিত করুন যে আপনি চালু করতে পারেন আছি def m(a,b,c):return fooমধ্যে m=lambda a,b,c:fooএমনকি ভিতরে ক্লাস, যা আপনি বাইট প্রচুর বাঁচাতে পারি।
লিন

@ মরিস টিপটির জন্য ধন্যবাদ :)
আদিতু

আমি a.b.c.a(c)(b(c))একটি বৈধ ল্যাম্বডা এক্সপ্রেশন হিসাবে পড়তে ব্যর্থ : কি (c)?
coredump

@ কর্ড্প্প এটি অপ্রয়োজনীয় দলবদ্ধকরণের একটি অপারেন্ড ... এবং আপনি ঠিক বলেছেন, এটি ওপি'র ব্যাকরণের নিয়মের সাথে ঠিক মেলে না। আমি ভাবছি এটি কতটা গুরুত্বপূর্ণ; আমি জিজ্ঞেস করবো.
অদিতসু

@ কর্ডম্প্প আপডেট ব্যাকরণ দিয়ে এখন ঠিক করা উচিত।
অদিতসু

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.      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))
  • সম্পাদনা আমি অনুক্রমে হিসাবে একই গোষ্ঠী আচরণ আছে আমার উত্তর আপডেট aditsu এর উত্তর কারণ এটি লিখতে কম বাইট খরচ।
  • অবশিষ্ট পার্থক্য পরীক্ষার 6 এবং 8 এর জন্য দেখা যেতে পারে ফলাফলের a.a.a.a.a.b.aসঠিক এবং পাইথন উত্তর যতটা অক্ষর, যেখানে বাইন্ডিং যেমন ব্যবহার করে না a, b, cএবং dরেফারেন্সড নেই।

কর্মক্ষমতা

উপরের 7 টি উত্তীর্ণ পরীক্ষার উপরে লুপিং এবং ফলাফল সংগ্রহ করা অবিলম্বে (এসবিসিএল আউটপুট):

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

একই পরীক্ষা কয়েকশো বার করা থেকে শুরু করে ... বিশেষ ভেরিয়েবল সম্পর্কিত একটি সীমাবদ্ধতার কারণে এসবিসিএলে "থ্রেড লোকাল স্টোরেজ ক্লান্ত" । সিসিএল সহ, একই পরীক্ষার স্যুটকে 10000 বার কল করতে ৩.৩৩ সেকেন্ড সময় লাগে।


এটি একটি ঝরঝরে সমাধান!
FUZxxl

@FUZxxl ধন্যবাদ!
22:55
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.