একটি শিফট ইন্টারপ্রেটার লিখুন


10

সম্পাদনা: আপনারা কেউ কেউ সন্দেহ করেছেন, সরকারী দোভাষীতে একটি বাগ ছিল: এর মধ্যে রচনার .ক্রমটি বিপরীত হয়েছিল। আমার দোভাষীর দুটি সংস্করণ ছিল এবং আমি এখানে ভুলটি ব্যবহার করেছি। উদাহরণগুলিও এই ভুল সংস্করণের জন্য লেখা হয়েছিল। আমি ভান্ডারটিতে দোভাষী এবং নীচের উদাহরণগুলি স্থির করেছি। বর্ণনাটিও >কিছুটা অস্পষ্ট ছিল, তাই আমি এটি স্থির করেছি। এছাড়াও, এত দীর্ঘ সময় নেওয়ার জন্য ক্ষমা প্রার্থনা করে, আমি কিছু বাস্তব জীবনের জিনিসপত্রের মধ্যে পড়েছিলাম।

সম্পাদনা 2: আমার দোভাষীর প্রয়োগে একটি বাগ .ছিল যার উদাহরণগুলিতে প্রতিফলিত হয়েছিল (তারা অপরিবর্তিত আচরণের উপর নির্ভর করেছিল)। বিষয়টি এখন ঠিক হয়ে গেছে।

ভূমিকা

শিফট হ'ল বেশ কয়েক বছর আগে তৈরি করা তবে আজ প্রকাশিত। এটি স্ট্যাক-ভিত্তিক, তবে হাস্কেলের মতো স্বয়ংক্রিয়ভাবে কার্চিংও রয়েছে।

সবিস্তার বিবরণী

শিফটে দুটি ডেটাটাইপ রয়েছে:

  • কার্যাবলী, যা একটি স্বেচ্ছাসেবী ইতিবাচক আর্গুমেন্ট (ইনপুট সংখ্যা), এবং যা আউটপুট একটি তালিকা ফিরে। উদাহরণস্বরূপ, এমন একটি ফাংশন যা এর একমাত্র ইনপুটটির সদৃশ হয় সেটির আরতি 1 থাকে এবং এমন একটি ফাংশন যা তার দুটি ইনপুটগুলিকে অদলবদল করে আর্টি 2 থাকে।
  • ফাঁকা, যা সবগুলি অভিন্ন এবং ফাংশন না হওয়া ছাড়া অন্য কোনও উদ্দেশ্য নেই।

একটি শিফট প্রোগ্রামে শূন্য বা ততোধিক কমান্ড থাকে, যার প্রতিটিই একক ASCII অক্ষর। মোট 8 টি কমান্ড রয়েছে:

  • !( প্রযোজ্য ) একটি ফাংশন পপ fএবং একটি মান xস্ট্যাক থেকে, এবং প্রযোজ্য fকরার x। তাহলে farity 1 আছে, তালিকা f(x)স্ট্যাক সামনে যোগ করা হয়। যদি এর অভেদ্যতা থাকে তবে n > 1একটি নতুন- (n-1)তদন্ত ফাংশনটি gস্ট্যাকের দিকে ঠেলে দেওয়া হয়। এটি ইনপুট এবং রিটার্ন নেয় ।x1,x2,...,xn-1f(x,x1,x2,...,xn-1)
  • ?( ফাঁকা ) স্ট্যাকের একটি ফাঁকা ঠেলাঠেলি করে।
  • +( ক্লোন ) স্ট্যাকের দিকে ধাক্কা দেয় এমন একটি আনারি ফাংশন যা এর ইনপুটটিকে নকল করে তোলে: কোনও মান xম্যাপ করা হয় [x,x]
  • >( শিফট ) স্ট্যাক করার জন্য একটি ইউনারী ফাংশন যা একটি লাগে পাহাড় জমে n-ary ফাংশন f, এবং একটি ফেরৎ (n+1)-ary ফাংশন gযে তার প্রথম আর্গুমেন্ট উপেক্ষা করে xকল fঅবশিষ্ট বেশী, এবং tacks xফলাফলের সামনে। উদাহরণস্বরূপ, shift(clone)একটি বাইনারি ফাংশন যা ইনপুট নেয় a,bএবং ফেরত দেয় [a,b,b]
  • /( কাঁটাচামচ ) স্ট্যাকে একটি তিন ফাংশন যা তিন ইনপুট নেয় পাহাড় জমে a,b,c, এবং আয় [b]যদি aএকটি ফাঁকা, এবং [c]অন্যথায়।
  • $( কল ) স্ট্যাকে push কর্মের একটি বাইনারি ফাংশন একটি ফাংশন পপ যে fএবং একটি মান x, এবং প্রযোজ্য fকরার xঠিক হিসাবে !আছে।
  • .( চেইন ) একটি বাইনারি ফাংশন স্ট্যাকের দিকে ধাক্কা দেয় যা দুটি ফাংশন পপ করে fএবং gতাদের রচনাটি ফিরিয়ে দেয়: একটি ফাংশন hযা একই ধরণের arity থাকে fএবং যা সাধারণত ইনপুটগুলি গ্রহণ fকরে, তাদের জন্য প্রযোজ্য , এবং তারপরে ফলাফলের জন্য পুরোপুরি প্রয়োগ gহয় (কলগুলি) এটি এর আধ্যাত্মিকতা হিসাবে যতবার নির্ধারিত হয়) fএর ফলাফলের অবশিষ্টাংশের আউটপুট থেকে অব্যবহৃত আইটেমগুলি সহ h। উদাহরণস্বরূপ, অনুমান যে fএকটি বাইনারি ফাংশন যে তার দ্বিতীয় যুক্তি ক্লোনস, এবং gহয় কল । যদি স্ট্যাকটি থাকে [f,g,a,b,c]এবং আমরা তা করি .!!, তবে এটিতে রয়েছে [chain(f,g),a,b,c]; আমরা যদি !!পরবর্তী কাজ করি, তবে fপ্রথমে a,bউত্পাদন করা হয় ,[a,b,b]এর পরে gএর প্রথম দুটি উপাদানগুলিতে প্রয়োগ করা হয় কারণ এর উদারতা 2 হয়, উত্পাদন হয় [a(b),b]এবং স্ট্যাকটি শেষ পর্যন্ত হবে [a(b),b,c]
  • @( বলুন ) একটি অবিচ্ছিন্ন ফাংশন ঠেলে দেয় যা কেবল তার ইনপুট দেয় এবং প্রিন্ট করে 0যে এটি ফাঁকা থাকলে, এবং 1যদি এটি কোনও ফাংশন ছিল।

মনে রাখবেন যে সমস্ত কমান্ডগুলি !কেবল স্ট্যাকের জন্য একটি মানকে চাপ দেয়, ইনপুট সঞ্চালনের কোনও উপায় নেই এবং যে কোনও কিছুই আউটপুট দেওয়ার একমাত্র উপায় ব্যবহার করা হয় @। একটি প্রোগ্রাম কমান্ডগুলি একে একে মূল্যায়ন করে, 0এস বা 1এস মুদ্রণ করে যখনই "বলুন" ডাকা হয় এবং বেরিয়ে আসে। এখানে বর্ণিত কোনও আচরণ (একটি ফাঁকা প্রয়োগ, দৈর্ঘ্যের 0 বা 1 স্ট্যাক প্রয়োগ করা, ফাঁকা জায়গায় "চেইন" কল করা ইত্যাদি) সংজ্ঞায়িত নয়: দোভাষী তার বিপর্যয় ঘটতে পারে, নিঃশব্দে ব্যর্থ হতে পারে, ইনপুট চাইতে বা যা কিছু করতে পারে whatever

কাজটি

আপনার কাজ হ'ল শিফ্টের জন্য দোভাষী লিখুন। এটি STDIN, কমান্ড লাইন, বা ফাংশন আর্গুমেন্ট থেকে একটি শিফ্ট প্রোগ্রামকে ব্যাখ্যা করার জন্য নেওয়া উচিত এবং STDOUT এ মুদ্রণ করা উচিত বা 0এর এবং 1এর ফলাফল (সম্ভবত অসীম) আউটপুট ফিরিয়ে আনতে হবে । যদি আপনি কোনও ফাংশন লিখেন তবে আপনাকে অবশ্যই কোনও উপায়ে অসীম দৈর্ঘ্যের আউটপুটগুলি অ্যাক্সেস করতে সক্ষম হতে হবে (পাইথনে জেনারেটর, হাস্কেলের অলস তালিকা ইত্যাদি)। বিকল্পভাবে, আপনি অন্য ইনপুট, একটি সংখ্যা নিতে পারেন nএবং nআউটপুটটির কমপক্ষে অক্ষরগুলি যদি এটির চেয়ে দীর্ঘ হয় তবে ফিরে আসতে পারেন n

সর্বনিম্ন বাইট গণনা জয়, এবং মান লুফোলগুলি অনুমোদিত নয়।

পরীক্ষার কেস

এই শিফট প্রোগ্রামটি মুদ্রণ করে 01:

?@!@@!

বাম থেকে শুরু করে: একটি ফাঁকা ধাক্কা ধাক্কা বলে , তারপর আবেদন বলে ফাঁকা করতে। এই ফলাফল 0। তারপর, ধাক্কা বলে দুইবার, এবং দ্বিতীয় আবেদন বলে প্রথম। এই ফলাফল 1

এই প্রোগ্রামটি চিরতরে লুপ করে, কোনও আউটপুট উত্পাদন করে না:

$+.!!+!!

কল এবং ক্লোন পুশ করুন , তারপরে তাদের কাছে চেইন প্রয়োগ করুন ( চেইন একটি বাইনারি ফাংশন হওয়ায় আমাদের দুটি !সেকেন্ড দরকার )। এখন স্ট্যাকটিতে একটি ফাংশন রয়েছে যা একটি যুক্তি নেয়, এটি সদৃশ করে এবং দ্বিতীয়টিতে প্রথম অনুলিপিটি কল করে। এর সাথে , আমরা এই ফাংশনটির সদৃশ এবং এটিকে নিজে কল করি।+!!

এই প্রোগ্রামটি মুদ্রণ 0010:

?@$.++>!.!!.!!.!!!!+?/!!!@!@>!!!

একটি ফাঁকা ঠেলা এবং বলুন । তারপরে, একটি বাইনারি ফাংশন রচনা করুন যা তার দ্বিতীয় যুক্তিকে bঅনুলিপি করে, তারপরে প্রথমটি অনুলিপি করে aএবং এটি নিজের সাথে রচনা করে, তারপরে b, ফিরে আসার অনুলিপিটিতে রচনাটি প্রয়োগ করে [a(a(b)),b]। এটি বলার জন্য এবং ফাঁকাতে প্রয়োগ করুন , তারপরে স্ট্যাকের মধ্যে থাকা দুটি উপাদানকে বলুন

এই প্রোগ্রাম প্রিন্ট 0। আপনি এতে যুক্ত হওয়া প্রতিটিটির !!!জন্য এটি একটি অতিরিক্ত প্রিন্ট করে 0

?@+$>!>!+>!///!!>!>!.!!.!!.!!+!!!!

একটি ফাঁকা ঠেলা এবং বলুন । তারপরে, একটি বার্ষিক ফাংশন রচনা করুন যা f,g,xইনপুট এবং রিটার্ন হিসাবে গ্রহণ করে [f,f,g,g(x)]। সেই ফাংশনটি ক্লোন করুন এবং এটিকে নিজেই বলুন , এবং ফাঁকা করুন। এই অ্যাপ্লিকেশনটি স্ট্যাক পরিবর্তন করে না, তাই আমরা যতবার চাই ফাংশনটি আবারও প্রয়োগ করতে পারি।

এই প্রোগ্রামটি অসীম অনুক্রমকে মুদ্রণ করে 001011011101111..., যেখানে 1সর্বদা এর সংখ্যা সর্বদা এক দ্বারা বৃদ্ধি পায়:

@?/!@>!??/!!>!+.!!.!!.!!.+>!.!!$$$$+$>!>!$>!>!+>!$>!>!>!+>!>!///!!>!>!>!.!!.!!.!!.!!.!!.!!.!!.!!.!!.!!+!!!!!

ভান্ডারটিতে একটি টীকাযুক্ত সংস্করণ রয়েছে।


আমি এখানে একটু বিভ্রান্ত। আপনি যখন শিফ্ট কমান্ডের মতো "টিস ইন" লিখেন, আপনি পপগুলি বোঝাতে চান বা প্রয়োগ আদেশ দ্বারা প্রয়োগ করা মানে?
tecywiz121

1
এছাড়াও, আমি আপনার চেক থেকে সত্যই নিশ্চিত নই যে চেইন কীভাবে কাজ করবে বলে মনে করা হচ্ছে। আপনি একটি উদাহরণ দিয়ে এটি পরিষ্কার করতে পারেন দয়া করে?
tecywiz121

@ tecywiz121 এটি আমি এটি বুঝতে পারি: বলুন স্ট্যাকের শীর্ষে দুটি ফাংশন পেয়েছেন f(x1, x2, ..., xn)এবং g(y1, y2, ..., ym)। কলিং .উভয়কে পপ করে এবং একটি ফাংশনকে ধাক্কা দেয় h(z1, z2, ..., zn)। এখন আপনি ধীরে ধীরে এটি দিয়ে কারি করে এই সমস্ত যুক্তিগুলি খেয়ে ফেলতে পারেন !। এই nধরনের অ্যাপ্লিকেশনগুলির পরে , বাকী ফাংশনটির কেবল একটি যুক্তি ছিল, এবং সেই সময়ে এটি গণনা করে f(z1, z2, ..., zn)(অর্থাত্ fআপনি যে সমস্ত যুক্তি দিয়েছিলেন সেগুলি প্রয়োগ করা হয়েছে), যা কিছু নতুন মানকে ঠেলে দেয় এবং তারপরে অবিলম্বে mস্ট্যাক থেকে মানগুলি গ্রহণ করে এবং gতাদেরকে কল করে।
মার্টিন ইন্ডার

@ মার্টিনব্যাটনার যদি জগারব মনে করেন এটি নিয়মের সাথে সামঞ্জস্যপূর্ণ তবে আপনি আউটপুট সর্বাধিক আকার নির্ধারণ করে একটি দ্বিতীয় ইনপুট প্যারামিটার ব্যবহার করতে পারেন। এটি অলস মূল্যায়ন ইস্যুটির সমাধানও হবে।
এলোমেলো

@ টেকিভিজ 121 .মার্টিন বর্ণিত ঠিক তেমনভাবে কাজ করে, মান ব্যতীত যদি fকম তালিকার একটি তালিকা ফেরত দেয় mতবে ফলাফলটি সংজ্ঞায়িত হয় (রচনাটি সার্থকতা রাখে n, তাই এটি স্ট্যাক থেকে আরও যুক্তি খেতে পারে না)। মূলত, এর আউটপুটটি fএকটি অস্থায়ী স্ট্যাক হিসাবে ব্যবহৃত হয়, যার উপর ব্যবহারের সময় gধাক্কা দেওয়া হয় এবং প্রয়োগ করা হয় এবং এর ফলাফলটি মূল স্ট্যাকটিতে যুক্ত হয়। m!
Zgarb

উত্তর:


12

পাইথন 2, 752 667 534 506 445 436 427 404 398 393 বাইট

এটি কোনওভাবেই সংক্ষিপ্ত নয় ... তবে আমি যথাসাধ্য চেষ্টা করেছি। কোনও গল্ফিং পরামর্শ খুব প্রশংসা করা হবে ...

সম্পাদনা 6: এটি এখন কোনও ফাংশনের পরিবর্তে একটি স্ক্রিপ্ট। এটি একটি ফাইলে সংরক্ষণ করুন (shift.py, forex), তারপরে এটি চালান $ python shift.py '<my_input>'। একক উদ্ধৃতিতে ইনপুট রাখার বিষয়টি নিশ্চিত করুন, বা ইনপুট অক্ষরের সাথে বাশ পাগল হবে।

সম্পাদনা 7: আআআআআআ্যান্ড ... এটি আর পঠনযোগ্য নয়। তবে আমি আরও 23 টি বাইটের হাত থেকে মুক্তি পেয়েছি, তাই এটি আমার পক্ষে ভাল? আমি একটি কদর্য সংস্করণও পোস্ট করব।

সম্পাদনা 8: আরও একটি গল্ফ, @ জগারবকে ধন্যবাদ।

k,d=[],[]
u=k.append
def z(f,a=1):f.a=a;return f
exec "i=!x:x(*map(k.pop,[-1]*x.a)));e=dict(zip('?+>/$.@',[0,!x:u(x)<u(x)),!x:u(!a,*_:x(*_)<u(a),x.a+1))),!x,y,z:u((z,y)[x<1]),3),!x,y:u(!*_:x(y,*_),x.a-1))if x.a>1 else x(y),2),!x,y:u(!*_:x(*_)<i(y),x.a)),2),!x:d.append(`+(x>0)`)<u(x))]))".replace('!',"z(lambda ")
for _ in raw_input():
 try:[i,u][_ in e](e.get(_,e['$']))
 except:break
print d

সম্পাদনা: গল্ফিং সাহায্যের জন্য @DLosc ধন্যবাদ! এটি 85 বাইট দ্বারা কমাতে পরিচালিত।

সম্পাদনা 2: এক টন অপ্রয়োজনীয় মোড়কে কেটে অন্য 133 বাইটে নামিয়ে দিন!

EDIT3: ... এবং 28 আরও চ্যাটে @ Sp3000 এবং @orlp কে ধন্যবাদ!

EDIT4: @orlp এবং @ Sp3000 এর সহায়তায় সমস্ত সজ্জা সরিয়ে ফেলেছে এবং এখন এটি 61 বাইট সংক্ষিপ্ত।

এডিআইটি 5: আমাকে সাহায্য করুন, আমি এটি গল্ফ করা বন্ধ করতে পারি না .... আরও 9 টি বাইট গেছে। চূড়ান্ত মুদ্রণ বিবৃতিটি পরিত্রাণ পেতে অন্য 7 টি সাশ্রয় হবে, তবে তারপরে আপনি যদি একটি লুপে এম () চালান, সমস্ত আউটপুট একই লাইনে থাকবে ... ঠিক আছে কি?

এখানে একটি অবারিত সংস্করণ:

stack = []
push = stack.append

def arity(func,a=1): #give each of our functions an arity
    func.arity = a
    return func

def do(func): ##pop the args off the stack, then call the function
    args = map(stack.pop,[-1]*func.arity)
    func(*args)

def call(func,arg): #apply is just do(call)
    if func.arity == 1:
        func(arg)
    else:
        def curried(*a): #a quick little currier
            func(arg, *a)
        curried = arity(curried, func.arity - 1)
        push(curried)

def clone(arg):
    push(arg)
    push(arg)

def shift(func):
    def shifted(a, *arg):
        func(*arg)
        push(a)
    shifted = arity(shifted, func.arity + 1)
    push(shifted)

def fork(a, b, c):
    if a == 0:
        push(b)
    else:
        push(c)

def chain(func, gunc):
    def composition(*args):
        func(*args)
        do(gunc)
    composition = arity(composition, func.arity)
    push(composition)

def say(arg):
    print '10'[arg == 0],
    push(arg)

commands = {'?': 0,
            '+': arity(clone),
            '>': arity(shift),
            '/': arity(fork, 3),
            '$': arity(call, 2),
            '.': arity(chain, 2),
            '@': arity(say)}

def interpret(input_string):
    for command in input_string:
        try:
            if command == '!':
                do(call)
            else:
                push(commands[command])
        except RuntimeError: #this handles max recursion depth errors
            break            # for infinite programs
    print

if __name__ == "__main__":
    interpret(raw_input())

মূল ধারণাটি হ'ল পাইথন তালিকাগুলি স্ট্যাক হিসাবে খুব সুন্দরভাবে কাজ করে এবং সংরক্ষণ করে u=k.appendকেবল অক্ষরগুলিই সংরক্ষণ করি না@u , তবে ধাক্কা ফাংশনগুলির জন্য ডেকরেটার হিসাবেও ব্যবহার করতে পারি (আর নয়!)।

যেহেতু n-arity এর ফাংশনগুলিতে কাজ করে এমন দু'টি কার্যকারিতা একটি স্বেচ্ছাসেবী যুক্তিগুলি গ্রহণ করতে সক্ষম হওয়া দরকার, তাই আমাকে ব্যবহার করতে হয়েছিল *argsযার অর্থ f.func_code.co_argcount আমার ট্র্যাকিংয়ের মূল পরিকল্পনাটি একটি আরটি দ্বারা প্রতিস্থাপন করতে হয়েছিল শোভাকর বৈশিষ্ট্য।

অসীম প্রোগ্রামগুলি পরিচালনা করার ক্ষেত্রে, দোভাষা যতক্ষণ না এটি সর্বাধিক পুনরাবৃত্ত গভীরতায় আঘাত না করে; নীচের দিকে রানটাইমরিয়ার হ্যান্ডলারটি এ পর্যায়ে এটি নিঃশব্দে প্রস্থান করেছে এবং এটি বর্তমান আউটপুট স্ট্রিংটি মুদ্রণ করে।

পরীক্ষার কেস:

>>> tests
['?@!@@!', '$+.!!+!!', '?@$..!!+.!!+>!.!!!!+?/!!!@!@>!!!', '?@+$>!>!.!!+>!.!!///!!>!>!.!!+!!!!', '?@+$>!>!.!!+>!.!!///!!>!>!.!!+!!!!!!!', '?@+$>!>!.!!+>!.!!///!!>!>!.!!+!!!!!!!!!!', '?@+$>!>!.!!+>!.!!///!!>!>!.!!+!!!!!!!!!!!!!', '@?/!@>!.!!??/!!>!.!!+.!!.+>!.!!$$.!!$.!!$.!!+.!!$>!>!.!!$>!>!.!!+>!.!!$>!>!>!.!!+>!>!.!!///!!>!>!>!.!!+!!!!!']
>>> for t in tests: m(t)
0 1

0 0 1 0
0
0 0
0 0 0
0 0 0 0
0 0 1 0 1 1 0 1 1 1 0 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

1
আমার প্রথম প্রতিক্রিয়া: @ _ @ মারাত্মকভাবে, যদিও দুর্দান্ত কাজ - স্ট্যাকের উপর প্রকৃত ফাংশনগুলি রাখা একটি ঝরঝরে সমাধান। কয়েকটি টিপস: 1) টার্নারি অপারেটরগুলি সাধারণত এক বা অন্য উপায়ে ছোট করা যায় । 2) আপনি ['1','0'][...]ঠিক সঙ্গে প্রতিস্থাপন করতে পারেন '10'[...]। 3) কেন x is 0এবং না x==0(বা x<1)? 4) নির্দিষ্ট করে বিরক্ত করবেন না RuntimeError, কেবল exceptকরবেন। 5) যেহেতু আপনি পাইথন 2 ব্যবহার করছেন তাই ট্যাব এবং স্পেসগুলি পৃথক ইনডেন্টেশন স্তর হিসাবে গণনা করা হয় - তবে, আপনাকে 25 ডলার বাইট সংরক্ষণ করতে হবে save
ডিএলসক

1
আপনি এটিতে কাটাতে সক্ষম হবেন - x.a==1and x(y)or u(a(x.a-1)(b.partial(x,y)))লজিকাল অপারেটরগুলি এখনও সংক্ষিপ্ত-সার্কিট, তবে ত্রিশের চেয়ে কম অক্ষর ব্যবহার করুন। তারপর ব্যবহার করার মাধ্যমে অন্যদের বাইট সংরক্ষণ x.a-1শর্ত (যদি 0 / মিথ্যা হিসাবে x1, অন্যথায় নয় অশূন্য / সত্য) এবং এক্সপ্রেশন 'আর' সোয়াপিং 'তারপর' এবং: x.a-1and u(a(x.a-1)(b.partial(x,y)))or x(y)। (গল্টা গল্ফ আমারে আরও কিছু হয়েছে যে আপনি আমাকে পাশ করেছেন ...; ^))
ডিএলসাস

1
আমার সাথে একই রকম সমস্যায় পড়ার পরে, আমি বুঝতে পারি যে এখন কী ব্যর্থ x.a==1হচ্ছে - যদি সত্য হয় তবে x(y)মিথ্যা কিছু দেয় তবে এটি মূল্যায়নের চেষ্টা করে u(...)। তবে দেখে মনে হচ্ছে আপনাকে যে মাইলি 3 বাইট দেয় সেগুলি সংরক্ষণ করার দরকার নেই! আমি সম্মতি জানাই, স্যার: আপনি আমাকে ছাড়িয়ে গেছেন।
DLosc

1
একটি মাত্র বাছাইযোগ্য: নির্দিষ্ট আউটপুট ফর্ম্যাটটিতে স্পেস নেই - আপনি বিভিন্ন কৌশল দ্বারা সমাধান করতে পারেন , কোনটি সবচেয়ে কম তা নিশ্চিত নয়। অবশ্যই, আপনার প্রোগ্রামটি হ্যান্ডলগুলি করার RuntimeErrorসময় আমার কেবল ব্যবহারকারীকে স্ট্যাডারকে পুনঃনির্দেশ করতে বলেছে ... সুতরাং আমরা সম্ভবত এমনকি বাচ্চাদের উপরও আছি। ;।)
DLosc

1
*_ল্যাম্বডাসের জন্য কী ?
mbomb007

4

প্রস্তুতকারী Ghostscript

এখনও গল্ফ করা হয়নি, যেহেতু এখনও পার্সিং ফাংশনটি আমার কাজ করা দরকার।

এই বাস্তবায়ন ব্যবহার করে _এবং :পরিবর্তে> এবং /, এবং এটি সমস্ত প্রোগ্রাম অক্ষর স্পেস দিয়ে পৃথক করা প্রয়োজন। এটি পোস্টস্ক্রিপ্টে বৈধ নাম না হওয়ার কারণে >এবং /অপারেটররা স্ব-সীমাবদ্ধ নয়, তবে আমি যখন পার্সার লিখব তখন এটি স্থির হবে।

কোডটির প্রথম অংশটি মোটামুটি স্বচ্ছ হওয়া উচিত, কারণ এটি কেবল অপারেটরের ক্রিয়াকলাপগুলির সংজ্ঞা পুনরাবৃত্তি করছে। সংজ্ঞায় যাদু ঘটে happens!

/switch {
    /y exch def
    /x exch def
    {x} {y} ifelse
} bind def

/unwrap {
    dup type (arraytype) eq {aload pop} if
} bind def

/! { % IN: <x> <f> OUT: <g>|<f(x)>
    [ 3 1 roll unwrap] cvx %prefix argument into function
    dup /fun exch def %bind

    [ count 1 roll ] { %run the function sandboxed so it can't take any additional args
        2 dict begin
        /=only {} def % suppress output
            {
                fun
            } stopped /err exch def clear err
        end
    } .runandhide


    exch {
        $error /errorname get
        (stackunderflow) ne {
            handleerror
        } if

        $error /newerror false put

        unwrap
    } {
        unwrap exec
    } ifelse
} def

/? 0 def
/+ {{dup}} def
/_ {{/f exch def pop f}} def % using _ instead of >
/: {{? ne 3 1 roll switch}} def % using : instead of /
/$ {{!}} def
/. {{/g exch def exec g}} def 
/@ {{dup ? eq {0}{1} ifelse =only}} def

পথ !, প্রথম এটা যুক্তি যোগ করেছেন: কাজ সহজ xকরার জন্যf prefixing দ্বারা xবিষয়বস্তু থেকে f, এটা স্ট্যাক ফিরে ঠেলাঠেলি, এবং এর ফলে একটি কপি নামকরণ fun

এটি তখন অ্যারে হিসাবে পুরো স্ট্যাকটি গুটিয়ে রাখে। স্যান্ডবক্সযুক্ত কোড চালানোর জন্য .runandhideএকটি ঘোস্টস্ক্রিপ্ট এক্সটেনশন যা পূর্ববর্তী অ্যারের সামগ্রীগুলি চালিত হওয়ার প্রক্রিয়া থেকে এটি গোপন করে। dictকমান্ড অভি স্ট্যাক একটি নতুন অভিধান push কর্মের, যতক্ষণ না মধ্যে সংজ্ঞায়িত নাম পরিধি সংকীর্ণ endপপ এটি বন্ধ ব্যাক। এটিও প্রতিস্থাপন করে =only(আমার ব্যবহৃত আউটপুট অপারেটর)@ রান চলাকালীন আউটপুটকে দমন করে একটি ডামি একটি ) এর সাথে । অন্যান্য ভাষায় পাওয়া বিবৃতিটির stoppedপোস্টস্ক্রিপ্টের সমতুল্য try, এবং যদি এর পদ্ধতিতে কোনও ত্রুটি ছুঁড়ে দেওয়া হয় এবং এটি সমাপ্তিতে ছুটে যায় তবে এটি সত্য হয়।

একবার ট্রায়াল রান funসম্পূর্ণ হয়ে গেলে , প্রোগ্রামটি লুকানো অ্যারে থেকে মূল স্ট্যাকটি পুনরুদ্ধার করে এবং যদি funত্রুটি ছাড়াই সম্পন্ন হয়, তবে এটি আউটপুট রেখে, এটি বাস্তবের জন্য চালায়।


2

পাইথন 3, 685 670 634 633 বাইট

আমি নিশ্চিত যে এটি আমার মধ্যে দীর্ঘতম জিনিস g এটি কিছুটা পঠনযোগ্য হতে পেত, তবে @ সির্পারসিভালের পরামর্শ অনুসরণ করে সেই অসুবিধা দূর করেছে !

from re import*
E,*k="E"
P="e(k.pop(),k.pop())"
def H(a,b):global k;k+=list(a)+[N(b)];exec("k+=%s;"%P*Z(N(b)));return[]
def e(a,b):a=sub("(?<!\d)0",repr(N(b,1)).replace("\\",r"\\"),a,1);return Z(a)and[a]or list(eval(a))
D=list(zip("ilhydsSNZ",[3,2,2]+[1]*6,sub("A","N(a)",',b,c:[N([b,c][a>E])]|,b:e(A,N(b))|,b:["H(%s,%s)"%(A,repr(b))]|:print(0+(a>E),end="")or[A]|:[A]*2|:["S(0,%s)"%A]|,b:b+[A]|,b=-1:sub("\d+",lambda m:str(int(m.group())+b),a)|:len(split("\D0",a))-1').split("|")))
for n,r,f in D:exec(n+"=lambda a"+f)
F=dict(zip("/$.@+>?!",D))
for z in input():n,r,f=F[z];k+=z!="!"and[[n+"(%s)"%",".join("0"*r),E][z=="?"]]or eval(P)

kস্ট্যাক, যা স্ট্রিং হিসাবে প্রতিনিধিত্ব করে এমন ফাংশনগুলি অন্তর্ভুক্ত করে "h(0,0)"(যা সি এইচ এন )। একটি ফাংশন অন্য ফাংশন একটি আর্গুমেন্ট হিসাবে পাস করা হলে, তা পায় repr; 'd এবং সমস্ত সংখ্যার বৃদ্ধি: "h('h(1,1)',0)"। একবার সব0 ফাংশনগুলিতে প্রতিস্থাপন করা হলে পুরো জিনিসটি পাশ হয়ে যায় eval, যার ফলে যথাযথ পাইথন ফাংশনটিকে ডাকা হয় - যার বেশিরভাগ লম্বা ফাংশন যা লাইন by-এর লাইনে line লাইনে বড় স্ট্রিং থেকে উত্পন্ন হয় exec

নেস্টেড ফাংশনগুলির একাধিক স্তরের বর্ধিত হওয়া, উদ্ধৃত হওয়া এবং সঠিকভাবে পালানো সবচেয়ে বড় মাথা ব্যথা। আমি যদি রেজেক্স অপারেশনগুলিতে আরও কিছুটা বাঁচাতে পারি যদি আমি ধরে নিতে পারি যে ফাংশন নেস্টিং 9 স্তরের চেয়ে আরও গভীরতর হবে না, তবে মন্তব্যগুলিতে উল্লেখ করা হয়েছে এটি সম্ভবত নিরাপদ অনুমান নয়।

কোডটির পূর্ববর্তী সংস্করণটি রহিত করা:

from re import *
E="E"
stack=[]

clone=lambda a:[unnest(a)]*2
shift=lambda a:["shifted(0,%s)"%unnest(a)]
fork=lambda a,b,c:[unnest(c if a!=E else b)]
call=lambda a,b:apply(unnest(a),unnest(b))
chain=lambda a,b:["chained(%s,%s)"%(unnest(a),repr(b))]
def say(a):
 print(1 if a!=E else 0,end="")
 return [unnest(a)]

shifted=lambda a,b:b+[unnest(a)]
def chained(a,b):
 global stack
 stack+=list(a)+[unnest(b)]
 exec("stack+=apply(stack.pop(),stack.pop());"*zeros(unnest(b)))
 return []

nest=lambda a,direction:sub("\d+",lambda m:str(int(m.group())+direction),a)
unnest=lambda a:nest(a,-1)
zeros=lambda a:len(split("\D0",a))-1
def apply(a,b):
 a=sub("(?<!\d)0",repr(nest(b,1)).replace("\\",r"\\"),a,1)
 return [a] if zeros(a) else list(eval(a))

functions=dict(zip("+>/$.@",zip(["clone","shift","fork","call","chain","say"],[1,1,3,2,2,1])))

for cmd in input():
 if"!"==cmd:
  stack+=apply(stack.pop(),stack.pop())
 elif"?"==cmd:
  stack+=[E]
 else:
  name,arity=functions[cmd]
  stack+=[name+"(%s)"%",".join("0"*arity)]

এই বাস্তবায়নের এক সম্ভাব্য ত্রুটি এটি পুনরাবৃত্তি ব্যবহার করে, সুতরাং যে প্রোগ্রামগুলি অসীম হওয়া উচিত তাদের উচিত সর্বাধিক পুনরাবৃত্তির গভীরতাটিকে খুব দ্রুত hit (আপনি যখন অসীম প্রোগ্রামটি চালাবেন আপনি সম্ভবত স্টেডারকে পুনর্নির্দেশ করতে চান - অন্যথায় স্ট্যাক ট্রেসটি আসল আউটপুটকে জলাবদ্ধ করবে will) এটি ব্যতীত, সমস্ত কিছু কাজ করছে বলে মনে হচ্ছে।


আপনি কি এমন কোনও প্রোগ্রাম লিখতে পারবেন যা উপরের প্রোগ্রামটি উত্পন্ন করে এবং তারপরে তা কার্যকর করে? আপনার কাছে প্রচুর পুনরাবৃত্ত কোড রয়েছে যা সংকোচনের মতো lambda aএবং হওয়া উচিত k.pop()
mbomb007

@ mbomb007 ... আমি মনে করি আমার মস্তিষ্ক বিস্ফোরিত হবে। (তবে সাম্প্রতিক সম্পাদনাটি দেখুন - k.pop()যাইহোক, পরিস্থিতিটিকে আমি একটু কম পুনরাবৃত্ত করে
তুলেছি

আপনি কি এই সমস্ত ল্যাম্বডাসের জন্য নির্বাহ / অনুবাদ কৌশল করতে পারেন? সব এক স্ট্রিং মধ্যে লাঠি?
sirpercival

অন্য একটি মন্তব্য: আমি সন্দেহ করি আপনি এই ভাষাটির সাথে <= 9 ফাংশন নেস্টিংয়ের উপর নির্ভর করতে পারেন
sirpercival

@ সির্পারসিভাল হ্যাঁ, আমি এটি চেষ্টা করার কথা ভাবছিলাম। এবং না, আমি মনে করি না। : ^ পি
ডিএলকস

1

সিলোন, 1167 1057 1031

মনো-টাইপড পাইথন সংস্করণ হিসাবে আমি এটি সংক্ষিপ্ত পাই না ...

import ceylon.language.meta.model{N=Function}import ceylon.collection{H=HashMap}interface D of F|b{}object b satisfies D{}class F(shared Integer a,[D+](D+)f,[D*]c=[])satisfies D{shared[D+]o(D i){[D+]s=[i].prepend(c);return a==1then f(*s)else[F(a-1,f,s)];}shared[D+]y([D+]i){return f(*i.prepend(c));}}F m<A>(N<[D+],A>f)given A satisfies[D+]=>F(f.parameterTypes.size,(D+i)=>f.apply(*i));[D,D]e(D x)=>[x,x];[F]t(F f){[D+]g(D+i){assert(is[D+]r=i.rest);return[i[0],*f.y(r)];}return[F(f.a+1,g)];}[D]k(D a,D d,D c)=>a==b then[d]else[c];[D+]l(F a,D x)=>a.o(x);[F]n(F f,F g){[D+]h(D+i){[D+]r=f.y(i);assert(is[D+]d=r[0:g.a]);return g.y(d).append(r[g.a...]);}return[F(f.a,h)];}[D]y(D x){process.write(x==b then"0"else"1");return[x];}class I(){variable D[]s=[];value c=H{'?'->b,'+'->m(`e`),'>'->m(`t`),'/'->m(`k`),'$'->m(`l`),'.'->m(`n`),'@'->m(`y`)};shared void r(Character i){if(i=='!'){assert(is F f=s[0],is D x=s[1]);s=f.o(x).append(s[2...]);}else{assert(is D d=c[i]);s=[d].append(s);}}}shared void z(){process.readLine()?.collect(I().r);}

এখানে একই কোডের একটি ফর্ম্যাট (এবং মন্তব্য করা) সংস্করণ রয়েছে (স্পেস / নিউলাইন / মন্তব্য সহ এটি 4867 বাইটে পরিণত হয়):

import ceylon.language.meta.model {
    N=Function
}
import ceylon.collection {
    H=HashMap
}
//↑ Import of stuff we need – with a shorter alias.
// (The comment is down here due to a bug in my comment and space
//  remover – it doesn't remove a comment if it is the first token
//  at all.)

// Our data items are either functions or blanks.
interface D of F | b {}

// There is no point in having many blanks – so here a singleton.
object b satisfies D {}

// The function class. Our functions take a number of data items,
// and return a number of data items.
// We know the arity a, and have also an actual function f, and a number
// or already collected arguments.
class F(shared Integer a, [D+](D+) f, [D*] c = [])
        satisfies D {
    // apply once (= collect one parameter). Returns either the result,
    // or a function with arity one less.
    shared [D+] o(D i) {
        [D+] s = [i].prepend(c);
        return a == 1 then f(*s) else [F(a - 1, f, s)];
    }
    // apply fully (= with all needed parameters).
    // The input size should equal the arity.
    shared [D+] y([D+] i) {
        // merge collected and input arguments.
        return f(*i.prepend(c));
    }
}
// creates a shift function from a ceylon function,
// deriving the arity using reflection.
F m<A>(N<[D+],A> f)
        given A satisfies [D+]
        => F(f.parameterTypes.size, (D+ i) => f.apply(*i));

//
// clone: a unary function that duplicates its input: any value x is mapped to [x,x].
//
[D, D] e(D x) => [x, x];

//
// shift: a unary function that takes in an n-ary function f, and returns an
// (n+1)-ary function g that ignores its first argument x, calls f on the
// remaining ones, and tacks x in front of the result. For example,
// shift(clone) is a binary function that takes inputs a,b and returns [a,b,b].
//
[F] t(F f) {
    [D+] g(D+ i) {
        assert (is [D+] r = i.rest);
        return [i[0], *f.y(r)];
    }
    return [F(f.a + 1, g)];
}

//
// fork: a ternary function that takes three inputs a,d,c, and returns [d] if a is a blank,
// and [c] otherwise.
//
[D] k(D a, D d, D c) => a == b then [d] else [c];

//
// call: a binary function that pops a function f and a value x,
//        and applies f to x exactly as ! does.
//
[D+] l(F a, D x) => a.o(x);

//
// chain:  a binary function that pops two functions f and g, and returns their composition:
//         a function h that has the same arity as f, and which takes its inputs normally, applies
//         f to them, and then fully applies g to the result (calls it as many times as its arity
//         dictates), with unused items from the output of f remaining in the result of h. For
//         example, suppose that f is a binary function that clones its second argument, and
//         g is call. If the stack contains [f,g,a,b,c] and we do .!!, then it contains
//         [chain(f,g),a,b,c]; if we do !! next, then f is first applied to a,b, producing
//         [a,b,b], then g is applied to the first two elements of that since its arity is 2,
//         producing [a(b),b], and the stack will finally be [a(b),b,c].
//
[F] n(F f, F g) {
    [D+] h(D+ i) {
        // call f, remember the results.
        [D+] r = f.y(i);
        // first some results from f are the arguments to g:
        assert (is [D+] d = r[0:g.a]);
        // remaining results from f are passed back directly, with the results from g.
        return g.y(d).append(r[g.a...]);
    }
    return [F(f.a, h)];
}

//
// say: a unary function that simply returns its input, and prints 0 if it was a blank,
//      and 1 if it was a function.
// 
[D] y(D x) {
    process.write(x == b then "0" else "1");
    return [x];
}

//
// Interpreter class, which manages the stack and interprets the commands.
// Just call the r method with the individual command characters.
//
class I() {
    // The stack. The only variable in the whole program.
    variable D[] s = [];

    // a hash map of items to be pushed by commands, most build using the m function.
    // The apply command is not here, this is handled separately by the interpreter. 
    value c = H {
        '?'->b,
        '+'->m(`e`),
        '>'->m(`t`),
        '/'->m(`k`),
        '$'->m(`l`),
        '.'->m(`n`),
        '@'->m(`y`)
    };

    // Interprets one command, indicated by a character.
    // Will throw an AssertionError for unknown commands.
    shared void r(Character i) {
        if (i == '!') {
            assert (
                is F f = s[0],
                is D x = s[1]);
            // apply f on x, push the result onto a shortened version of the stack.
            s = f.o(x).append(s[2...]);
        } else {
            assert (is D d = c[i]);
            // push d on top of the stack.
            s = [d].append(s);
        }
    }
}

shared void z() {
    process.readLine()?.collect(I().r);
}

ফাংশন ক্লোন e, শিফট t, কাঁটাচামচ k, কল l, বলতে yএবং চেইন nসংক্ষিপ্ত সংস্করণের জন্য নাম শেষ চিঠি ব্যবহার করেন, কারণ কম দুর্ঘটনায় দিলেন। : (তুচ্ছ বস্তু: কাঁটাচামচ মূলত এই ভাবে সংজ্ঞায়িত করা হয় [Data] fork(Data a, Data b, Data c) => a == blank then [b] else [c];যখন আমি নতুন নামকরণ - blankথেকে b, এই কপর্দকশূন্য, কারণ এটি এখন পরামিতি তুলনায় aএবং bপরিবর্তেa ফাঁকা দিয়ে আমাকে ডিবাগ করতে কিছু সময় নিয়েছে।।)

zকারণ আমার আইডিই যারা ফাংশন সঞ্চালিত হয় ফাংশন ভাগ করা হয় - কমান্ড লাইন টুল এছাড়াও অ ভাগ বেশী রান করতে পারেন।


লুপিং সংস্করণগুলি আসলে কোনও পর্যায়ে একটি স্ট্যাকওভারফ্লো এরির ফেলে দেবে, তারপরে শেষ হবে ing জেভিএমের কোন পুনরাবৃত্তি স্ট্যাক অপ্টিমাইজেশন নেই (বা কমপক্ষে এমন কোনও নয় যা আমার প্রোগ্রামের জন্য কাজ করবে)।
পাওলো ইবারম্যান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.