আমার রহস্যময় ভাষা জাম্পার জন্য একজন দোভাষী লিখুন


17

আমি গুপ্ত ভাষা জাম্পার চিন্তা করেছি। পরে আপনি দেখতে পাবেন কেন।

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

এখন, সবচেয়ে আকর্ষণীয় অংশ সিনট্যাক্স।

প্রোগ্রামে কমান্ড (অ্যানারি অপারেটর-উপসর্গ) এবং তাদের যুক্তি সমন্বিত থাকে। কমান্ড এবং যুক্তিগুলি ফাঁকা জায়গা বা নতুন লাইনের সাথে সীমিত করা যেতে পারে তবে প্রয়োজনীয় নয় not তবে যুক্তির অভ্যন্তরের স্থানগুলি অবৈধ, উদাহরণস্বরূপ, # 2 = 4বৈধ, তবে # 2 = 4 4তা নয়।
প্রোগ্রামের মধ্যে মন্তব্য থাকতে পারে ()। মন্তব্যগুলিতে নেস্ট করা যায় না - উদাহরণস্বরূপ, (abc(def)ghi)মন্তব্যটিতে (abc(def)। মন্তব্যগুলি যে কোনও জায়গায় রাখা যেতে পারে।

  • #123 র‌্যাম পয়েন্টারটিকে 123 এ সেট করে (কোনও ধনাত্মক দশমিক পূর্ণসংখ্যা বা শূন্য)।
  • >123 123 দ্বারা র‌্যাম পয়েন্টার বৃদ্ধি (কোনও ধনাত্মক দশমিক পূর্ণসংখ্যার) incre
  • <123 123 দ্বারা র‌্যাম পয়েন্টার হ্রাস (কোনও ধনাত্মক দশমিক পূর্ণসংখ্যার)।
  • =123 বর্তমান কক্ষে 123 (কোনও স্বাক্ষরযুক্ত 8-বিট দশমিক পূর্ণসংখ্যার) লিখেছেন।
  • +123 বর্তমান কক্ষে 123 (কোনও স্বাক্ষরযুক্ত 8-বিট দশমিক পূর্ণসংখ্যার) যোগ করা হয়েছে (256 মডেল))
  • -123 বর্তমান ঘর থেকে 123 (যেকোন স্বাক্ষরযুক্ত 8-বিট দশমিক পূর্ণসংখ্যার) বিয়োগফল (256 মডিউল)।
  • :123- "গোটো" - 123 কমান্ডে যায় (প্রথমটি 0)। আপনি কেবল গোটো দিয়েই আপনার প্রোগ্রামের প্রবাহকে নিয়ন্ত্রণ করতে পারেন - এটি লাফাতে হবে - এই কারণেই আমি এই ভাষাটিকে জাম্পার বলার সিদ্ধান্ত নিয়েছি।

যদি আর্গুমেন্টটি অনুপস্থিত থাকে - ><+-কমান্ডের জন্য এটি 1 বা #=:কমান্ডের জন্য 0 মনে করুন ।

এছাড়াও, কমান্ড সংশোধক রয়েছে - ?(কমান্ডের উপসর্গ), এটি পরবর্তী কমান্ডটি তখনই চালিত করে যদি বর্তমান ঘরটি শূন্য না হয়, অন্যথায় that আদেশটি এড়িয়ে যায়। যে কোনও কমান্ড প্রয়োগ করা যেতে পারে।
উদাহরণস্বরূপ, ?:17- বর্তমান ঘরটি শূন্য না হলে 17 কমান্ডে যায়।

প্রোগ্রামটি যদি অবৈধ হয় বা রানটাইমের সময় ত্রুটি দেখা দেয় তবে "ত্রুটি" বার্তা প্রদর্শিত হতে পারে। এর কারণে কোডগল্ফ, এরকম সংক্ষিপ্ত বার্তাটি ঠিক থাকবে।

তোমার কাজ

এই ভাষার জন্য সংক্ষিপ্ততম দোভাষী লিখুন।

কিছু পরীক্ষা প্রোগ্রাম

(prints "Hello world!" regardless of input)
=72>=101>=108>=108>=111>=32>=119>=111>=114>=108>=100>=33>=

(appends "!" to the end of input string)
?:2 :4 >1 :0 =33 >1 =0

আমি জাম্পারে কিছু সময় পরে নিজস্ব দোভাষী নিয়ে কিছু পরীক্ষা প্রোগ্রাম লিখব।
সোমনিয়াম

"প্রথম শূন্য বাইট বাদে" তাই যদি প্রথম শূন্য বাইটের পরে এখনও অন্য বাইট আসে তবে আমাদের সেগুলি আউটপুট করা উচিত নয়?
প্রোগ্রামফক্স

হ্যাঁ, আমাদের করা উচিত নয়। এটি সম্পূর্ণ ব্যবহৃত মেমরি পরিষ্কার না করার জন্য করা হয়, তবে কেবল আউটপুট অনুলিপি করতে শুরু করে।
সোমনিয়াম

5
আপনি কি আমাদের কিছু নমুনা প্রোগ্রাম এবং তাদের ফলাফল দিতে পারেন?
আর্শাজি

1
নেতিবাচক সূচকগুলির জন্য আপনি সঠিক ত্রুটি বার্তাটি নির্দিষ্ট করতে পারেন? আমি মনে করি বর্তমানে দুটি শীর্ষস্থানীয় উত্তরের মধ্যে পার্থক্যটি তাদের ত্রুটির বার্তাগুলির চেয়ে কম, সুতরাং আমার মনে হয় এটি সুনির্দিষ্টভাবে নির্দিষ্ট করা থাকলে এটি আরও সুন্দর হবে।
মার্টিন এন্ডার

উত্তর:


6

রুবি, 447 বাইট

p,i=$*
l=(i||'').length
r=[0]*l
l.times{|j|r[j]=i[j].ord}
i=j=0
s=p.gsub(/\(.*?\)|\s/,'')
q=s.scan(/(\?)?([#<>=+:-])(\d*)/)
e=->{abort"Error"}
p[/\d\s+\d/]||q*''!=s ?e[]:(r+=[0]until i+1<r.length
c=q[j]
j+=1
f=c[1]
c[0]&&r[i]==0?next: a=c[2]==''? '><+-'[f]?1:0:c[2].to_i
'=+-'[f]&&a>255?e[]: f==?#?i=a :f==?>?i+=a :f==?<?i-=a :f==?=?r[i]=a :f==?+?r[i]+=a :f==?-?r[i]-=a :j=a
i<0?e[]:r[i]%=256)while j<q.length
puts r.first(r.index 0).map(&:chr)*''

কমান্ড লাইন আর্গুমেন্টের মাধ্যমে প্রোগ্রাম এবং ইনপুট উভয়ই গ্রহণ করে।

সম্পাদনা: কয়েকটি বাগ স্থির করা হয়েছে, এবং 40 বাইটের ব্যয়ে অবৈধ সিনট্যাক্সের জন্য সমর্থন যোগ করা হয়েছে (কয়েকটি অন্যান্য অপ্টিমাইজেশন যোগ করার সময়)।


খুবই হাস্যকর. আমার রুবি সলিউশনটির ওজনও ছিল ৪7 characters অক্ষর। যদিও আমি ৪০০-এর দশকের মাঝামাঝি সময়ে শুটিং করছিলাম, ঠিক একই বাইট গণনাটি হতবাক হয়েছিল।
স্কট লিডলি

@ স্কটলিডলি হা, এটি একটি আকর্ষণীয় টাই। I আমি যদি ইতিমধ্যে এটি না করে থাকি তবে আপনাকে একটি উত্সাহ দিতে পারতাম। ;)
মার্টিন ইন্ডার

5

পাইথন (729)

import re,sys
R,p,i,T,q,g=[0]*1024,0,0,re.findall(r'\d+|[()#><=+:?-]',sys.argv[1]),lambda i:0<=i<len(T),lambda i,d:int(T[i])if q(i)and T[i].isdigit()else d
def z(p):
 global R;assert p>=0
 if p>=len(R):R+=[0]*1024
s=sys.argv[2]
R[0:len(s)]=map(ord,s)
while i<len(T):
 t=T[i]
 if t=='(': 
  while T[i]!=')':i+=1
  i+=1
  if not q(i):break
  t=T[i]
 i+=1
 if t=='#':p=g(i,0)
 if t=='>':p+=g(i,1)
 if t=='<':p-=g(i,1)
 if t=='=':z(p);R[p]=g(i,0)
 if t=='+':z(p);R[p]+=g(i,1);R[p]%=256
 if t=='-':z(p);R[p]-=g(i,1);R[p]%=256
 if t==':':
  v=int(T[i])
  i,c=-1,-1
  while c!=v:i+=1;c+=T[i]in'#><=+-:'
 if t=='?':
  assert p>=0
  if p<len(R)and R[p]==0:i+=1
 i+=q(i)and T[i].isdigit()
print''.join(chr(int(c))for c in R).split('\0')[0]

প্রোগ্রাম চলমান হিসাবে:

  • প্রথম যুক্তি: জাম্পার কোড
  • ২ য় তর্ক: আরম্ভের স্ট্রিং

উদাহরণ:

$ python jumper.py "=97>>(this is a comment)=98>2=99#" "xyz123"
ayb1c3

আমি সম্ভবত কিছু বিষয় অগ্রাহ্য করেছি, সুতরাং আপনার যদি এমন কিছু কাজ করার চেষ্টা করা হয় যা না হয় তবে চেষ্টা করে যদি একটি মন্তব্য দিন leave দ্রষ্টব্য যে এটি পাইথন 2.x কোডে লিখিত হয়েছে।


আপনি কীভাবে এটিকে ইনপুট দিবেন?
ক্লদিউ

@ ক্লডিউ উদাহরণ দেখুন। এটি একটি কমান্ড-লাইনের যুক্তি।
আর্শাজি

এই প্রোগ্রাম। তবে 7 ম বুলেট পয়েন্ট দেখুন। আপনি স্ট্যান্ডিন বা একটি যুক্তির মাধ্যমে "হ্যালো" বলে প্রাথমিক র‌্যাম অ্যারেটি শুরু করতে সক্ষম হবেন
ক্লাদিউ

আমার ভুল, এটি 6th ষ্ঠ বুলেট: "যখন প্রোগ্রামটি ইনপুট স্ট্রিংয়ের জন্য একটি প্রম্পট কার্যকর করা শুরু করা উচিত (বা কমান্ড লাইন আর্গুমেন্টগুলি থেকে ইনপুট গ্রহণ করা এটি আপনার উপর নির্ভর করে) In ইনপুট স্ট্রিংটিতে নাল অক্ষর (শূন্য বাইট) না থাকা উচিত Then তারপরে ইনপুট স্ট্রিং র‌্যামে শূন্য সূচক থেকে শুরু করে লেখা হয়।
ক্লাদিউ

@ ক্লডিউ আহ, আমি জানতাম আমি কিছু উপেক্ষা করেছি, ধন্যবাদ। এখন, প্রোগ্রামটি চালানোর পরে, আপনি ইনপ্রেড স্ট্রিং বলতে পারেন।
আর্শাজি

4

রুবি 2 - 540 447 420 টি অক্ষর

"রুবি 2.0 জাম্পার.আরবি 'নির্দেশাবলী' 'আরম্ভের ডেটা'" হিসাবে চালান। 1.x রুবি কাজ করবে না (স্ট্রিং.বাইটস পদ্ধতি নেই)।


মাল্টি-লাইন কমান্ড এবং মন্তব্য যুক্ত করেছে এবং আমার রাখার উন্নতি করেছে।


i=$*[0].gsub(/\([^)]*\)/m,' ').scan(/(\??)\s*([#=:><+-])\s*(\d*)/m).map{|a|[a[0]!='?',a[1],a[2]==''?/[#=:]/=~a[1]?0:1:a[2].to_i]}
N=i.size
d=$*[1].bytes
r=p=0
while p<N
u,o,x=i[p]
p+=1
d[r]=0 if d[r].nil?
case o
when'#';r=x
when'>';r+=x
when'<';r-=x
when/[=+-]/;eval "d[r]#{o.tr'=',''}=x";d[r]%=256
when':';p=x;abort'Error'if p>=N
end if u||d[r]>0
abort'Error'if r<0
end
printf"%s\n",d.take_while{|v|v&&v!=0}.pack('C*')

কিছু স্কেটার-শট পরীক্ষার সাথে একটি পরীক্ষার স্যুট এখানে। এটি ব্যবহারের সবচেয়ে সহজ উপায় হ'ল কোডটি টি / জাম্পার.টিতে স্টাফ করা এবং "পার্ল টি / জাম্পার.টি" চালানো।


#/usr/bin/perl
use strict;
use warnings;
#       timestamp: 2014 August 3, 19:00
#
# - Assume program takes machine code and initialization string as command
#       line options.
# - Assume all required errors reported as "Error\n".
# - Go with the flow and suffix output with \n. Merged terminal newlines are
#       unacceptable [I'm talkin' to YOU Ruby puts()!].
# - As per OP - jumping to > end-of-program must be an error.

use Test::More qw(no_plan);
# use Test::More tests => 4;

my $jumper = "jumper.rb";
#
#       "happy" path
#
# starter tests provided by OP
is( `$jumper '=72>=101>=108>=108>=111>=32>=119>=111>=114>=108>=100>=33>=' '' 2>&1`, "Hello world!\n", "hello world (from user2992539)");
is( `$jumper '?:2 :4 >1 :0 =33 >1 =0' 'a' 2>&1`, "a!\n", 'append !, #1 (from user2992539)');

# simple variations
is( `$jumper '?:2 :4 >1 :0 =33 >1 =0' '' 2>&1`, "!\n", 'append !, #2');
is( `$jumper '?:2 :4 >1 :0 =33' '' 2>&1`, "!\n", 'append !, #3, no NUL');

# comment delimiters don't nest
is( `$jumper "(()=" 'oops' 2>&1`, "\n", "() don't nest");
# comments and termination
is( `$jumper '(start with a comment)?(comment w/ trailing sp) # (comment w/ surrounding sp) 1 =98' 'a' 2>&1`, "ab\n", 'walk to exit');
is( `$jumper '(start with a comment)? (comment w/ leading sp)= (comment w/ surrounding sp) 97()' '' 2>&1`, "\n", 'skip to exit');
is( `$jumper '#1=0 (actually two instructions, but it scans well) :5 #=(truncate further if not jumped over)' 'a b' 2>&1`, "Error\n", 'truncate & jump to exit');

# is RAM pointer initialized to 0?
is( `$jumper '-103(g-g) ?:1025(exit) =103 #4=10' 'good' 2>&1`, "good\n\n", 'intial string in right place?');

# TBD, do jumps work?
# TBD, do conditional jumps work?
# jump right to a harder case, copy byte 0 to byte 3 and format, e.g. input="Y" output="Y=>Y"
is( `$jumper '#1=61#2=62#4=0#3=#10=#(11:)?:13:20(13:)#3+#10+#0-:11(20:)#10(21:)?:23:28(23:)#0+#10-:21(28:)#' 'Y' 2>&1`, "Y=>Y\n", 'copy a byte');


# test memory allocation by dropping 255s at increasingly large intervals
is( `$jumper '#16=511 #64=511 #256=511 #1024=511 #4096=511 #16384=511 #65536=511 #262144=511 #1048576=511 #65536-255 (20:)?:23(exit) #=' 'wrong' 2>&1`, "\n", 'test alloc()');

# upcase by subtraction
is( `$jumper '-32' 't' 2>&1`, "T\n", 'upcase via subtraction');
# 2 nested loops to upcase a character, like so: #0=2; do { #0--; #1=16; do { #1--; #2--; } while (#1); } while (#0);
is( `$jumper '#=2 (2:)#- #1=16 (6:)#1- #2- #1?:6 #0?:2 #=32 #1=32' '  t' 2>&1`, "  T\n", 'upcase via loops');
# downcase by addition
is( `$jumper '+32' 'B' 2>&1`, "b\n", 'downcase via addition');
# same thing with a loop, adjusted to walk the plank instead of jumping off it
is( `$jumper '#1 ?:3 :7 -<+ :0 #' 'B ' 2>&1`, "b\n", 'downcase via adder (from  Sieg)');
# base 10 adder with carry
is( `$jumper '#0-48#10=9#11=#5=#0(9:)?:11:22(11:)#10?:14:22(14:)-#11+#5+#0-:9(22:)#0?:110#11(25:)?:27:32(27:)#0+#11-:25(32:)#0+48>-43?:110=43>-48#10=9#11=#2(45:)?:47:58(47:)#10?:50:58(50:)-#11+#5+#2-:45(58:)#2?:110#11(61:)?:63:68(63:)#2+#11-:61(68:)#2+48>-61?:110=61>?:110=32#10=9#11=#5-10(83:)?:85:94(85:)#10?:88:94(88:)-#11+#5-:83(94:)#5?:99#4=49:100(99:)+10(100:)#11(101:)?:103:108(103:)#5+#11-:101(108:)#5+48' '1+1=' 2>&1`, "1+1= 2\n", 'base 10 adder, #1');
is( `$jumper '#0-48#10=9#11=#5=#0(9:)?:11:22(11:)#10?:14:22(14:)-#11+#5+#0-:9(22:)#0?:110#11(25:)?:27:32(27:)#0+#11-:25(32:)#0+48>-43?:110=43>-48#10=9#11=#2(45:)?:47:58(47:)#10?:50:58(50:)-#11+#5+#2-:45(58:)#2?:110#11(61:)?:63:68(63:)#2+#11-:61(68:)#2+48>-61?:110=61>?:110=32#10=9#11=#5-10(83:)?:85:94(85:)#10?:88:94(88:)-#11+#5-:83(94:)#5?:99#4=49:100(99:)+10(100:)#11(101:)?:103:108(103:)#5+#11-:101(108:)#5+48' '9+9=' 2>&1`, "9+9=18\n", 'base 10 adder, #2');

# order of assignment shouldn't affect order of print
is( `$jumper '#1=98 #0=97' '' 2>&1`, "ab\n", 'print order != assignment order');

# are chars modulo 256?
is( `$jumper '#10(#10 defaults to 0) +255+(#10 += 256) ?#(skip if #10==0) =' 'good' 2>&1`, "good\n", 'memory values limited to 0<x<255');
# go for the cycle;
is( `$jumper '(0:)+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ (256:)#4=10' 'BCID' 2>&1`, "ACID\n\n", 'cycle character less 1, PC>255');
# same thing with a loop;
is( `$jumper '#4=255(#4 = 255) (2:)#1+(#1++) #4-(#4--) ?:2(loop 255 times) #4=10(#4 = NL)' 'ADID' 2>&1`, "ACID\n\n", 'cycle character less 1, PC>255');


#       Exercise the program counter.
# PC > 255;
is( `$jumper '(0:)= (1:)############################################################################################################################################################################################################################################################### (256:)?:259 (257:)+ (258:):1 (259:)=97#3=10' 'a==' 2>&1`, "a==\n\n", 'program counter range >255');


#
#       "sad" path
#
#       Error checking required by the specification.
#
# simplest test case of PC going out of bounds
is( `$jumper ':2' '' 2>&1`, "Error\n", 'program counter too big by 1');
is( `$jumper ':1024' '' 2>&1`, "Error\n", 'program counter in space');
is( `$jumper ':1073741824' '' 2>&1`, "Error\n", 'program counter in hyperspace');
# try to drive program counter negative, if 32-bit signed integer
is( `$jumper ':2147483648(exit)' 'ridiculous speed' 2>&1`, "Error\n", 'program counter goes negative?, #1');
# try to drive program counter negative, if 64-bit signed integer
is( `$jumper ':9223372036854775808 (exit)' 'ludicrous speed' 2>&1`, "Error\n", 'program counter goes negative?, #2');

# spaces not allowed in operand; error or silently ignore (my choice)
isnt(`$jumper '#= #= #= #= #= +1 4 ' 'aops' 2>&1`, "oops\n", 'do not accept spaces in operands');
# ditto w/ a comment ; error or silently ignore (my choice)
isnt(`$jumper '#= #= #= #= #= +1(not valid)4 ' 'aops' 2>&1`, "oops\n", 'do not accept spaces in operands');

# RAM pointer error-checking; "Error" or "" are OK
isnt( `$jumper '<>=' 'oops' 2>&1 | grep -v Error`, "oops\n", 'unused negative RAM pointer behavior unspecified');
# RAM pointer negative and use it
is( `$jumper '<=' '' 2>&1`, "Error\n", 'cannot use negative RAM pointer, #1');
# check for RAM pointer wrap-around
is( `$jumper '<=' '0123456789' 2>&1`, "Error\n", 'cannot use negative RAM pointer, #2');

# The way I read this
#       "Commands and arguments may be delimited with spaces or new lines but
#       not necessary."
# multi-line commands are legit.
is( `$jumper "#4#?\n=" 'oops' 2>&1`, "\n", 'multi-line commands allowed');

# Multi-line comments would be consistent with multi-line commands, but I can't
# find something I can translate into a "must" or "must not" requirement in
#       "Program can have comments between (). ... Comments can be placed
#       anywhere."
# Until uncertainty resolved, no test case.


#
#       "bad" path
#
#       These tests violate the assumption that the instruction stream is wellll-farmed.
#
# characters not in the language; error or (my choice) silently skip
isnt(`$jumper 'x =' 'oops' 2>&1`, "oops\n", 'opcode discrimination');
# is ? accepted as an operator (vs operation modifier); error or (my choice) silently skip
is(`$jumper '(bad 0, good 0:)??0 (bad 1, good 0:):3 (bad 2, good 1:)#0' '' 2>&1`, "Error\n", '? not accepted as an opcode');

exit 0;

উদার সংস্করণ


#
#       Turing Machine Mach 2.0.
#       Tape? Tape? We don't need no stinkin' tape! We gots RAM!
#
#       dM = data memory
#       iM = instruction memory
#       pC = program counter
#       rP = RAM pointer
#       u, o, x = current instruction being executed
#
#       N = number of instructions in instruction memory
#

#       instruction decoder
iM = $*[0].gsub(/\([^)]*\)/m,' ').scan(/(\??)\s*([#=:><+-])\s*(\d*)/m).map { |a|
    [
        a[0] != '?',
        a[1],
        (a[2] == '')  ?  (/[#=:]/ =~ a[1] ? 0 : 1)  :  a[2].to_i
    ]
}
pC = 0
N = iM.size

dM = $*[1].bytes
rP = 0

while pC < N do
    #   u, unconditional instruction,   execute if true || (dM[rP] > 0)
    #                                   skip if false && (dM[rP] == 0)
    #   o, operator
    #   x, operand
    (u, o, x) = iM[pC]
    pC += 1
    dM[rP] = 0  if dM[rP].nil?
    if u || (dM[rP] > 0)
        case o
        when '#'
            rP = x
        when '>'
            rP += x
        when '<'
            rP -= x
        when /[=+-]/
            eval "dM[rP]#{o.tr'=',''}=x"
            dM[rP] %= 256
        when ':'
            pC = x
            abort 'Error'  if pC >= N
        end
    end
    abort 'Error'  if rP < 0
end
printf "%s\n", dM.take_while{|v|v&&v!=0}.pack('C*')

একজন কুইকি প্রোটো-এসেম্বেলার


#
#       Jumper "assembler" - symbolic goto labels.
#
# what it does:
#       - translates labels/targets into absolute position
#               @label ?:good_exit
#               ...
#               :label
#
#       - a label is [a-zA-Z][a-zA-Z0-9_]*
#       - a target is @label
#       - one special label:
#               - "hyperspace" is last instruction index + 1
#       - strips out user comments
#               - everything from "//" to EOL is stripped
#               - jumper comments are stripped
#       - adds "label" comments of the form "(ddd:)"
# limitations & bugs:
#       - multi-line jumper comments aren't alway handled gracefully
#       - a target not followed by an instruction will reference
#               the previous instruction. this can only happen
#               at the end of the program. recommended idiom to
#               avoid this:
#                       @good_exit #
# what it doesn't do:
#       - TBD, simple error checking
#               - labels defined and not used
#       - TBD, symbolic memory names
#
# Example:
#
#   input -
#       (
#               adder from Sieg
#       )
#       @loop_head # 1  // while (*(1)) {
#       ?:continue
#       :good_exit
#
#       @continue -     //     *(1) -= 1;
#       <-           //     *(0) += 1;
#       +
#       :loop_head      // }
#       @good_exit #
#
#   output -
#       (0:) #1 ?:3 :7 (3:) - < + :0 (7:)#

rawSource = ARGF.map do |line|
  line.gsub(/\([^)]*\)/, ' ')   # eat intra-line jumper comments
    .gsub(/\/\/.*/, ' ')        # eat C99 comments
    .gsub(/^/, "#{$<.filename}@#{$<.file.lineno}\n") # add line ID
end.join
rawSource.gsub! /\([^)]*\)/m, '' # eat multi-line jumper comments
#
# Using example from above
#
# rawSource =
#       "sieg.ja@1\n \n" +
#       "sieg.ja@4\n@loop_head # 1\n"
#       ...
#       "sieg.ja@12\n@good_exit # \n"

instructionPattern = %r{
    (?<label> [[:alpha:]]\w* ){0}
    (?<operator> \??\s*[#=:><+-]) {0}
    (?<operand> \d+|[[:alpha:]]\w* ){0}

    \G\s*(@\g<label>\s*)?(\g<operator>\s*)?(\g<operand>)?
  }x
FAIL = [nil, nil, nil]
instructionOffset = 0
iStream = Array.new
target = Hash.new
targetComment = nil
for a in rawSource.lines.each_slice(2) do
  # only parse non-empty lines
  if /\S/ =~ a[1]
    m = nil
    catch( :parseError ) do
      chopped = a[1]
      while m = instructionPattern.match(chopped)
        if m.captures.eql?(FAIL) || (!m[:operator] && m[:operand])
          m = nil
          throw :parseError
        end
        if m[:label]
          if target.has_key?(m[:label].to_sym)
            printf $stderr, a[0].chomp + ": error: label '#{m[:label]}' is already defined"
            abort a[1]
          end
          target[ m[:label].to_sym ] = instructionOffset
          targetComment = "(#{instructionOffset}:)"
        end
        if m[:operator]
          iStream[instructionOffset] = [
              targetComment,
              m[:operator],
              /\A[[:alpha:]]/.match(m[:operand]) ? m[:operand].to_sym : m[:operand]
            ]
          targetComment = nil
          instructionOffset += 1
        end
        chopped = m.post_match
        if /\A\s*\Z/ =~ chopped
          # nothing parseable left
          break
        end
      end
    end
    if !m
      printf $stderr, a[0].chomp + ": error: parse failure"
      abort a[1]
    end
  end
end

# inject hyperspace label
target[:hyperspace] = instructionOffset

# replace operands that are labels
iStream.each do |instruction|
  if instruction[2]
    if !(/\A\d/ =~ instruction[2]) # its a label
      if target.has_key?(instruction[2])
        instruction[2] = target[instruction[2]]
      else
        abort "error: label '@#{instruction[2]}' is used but not defined"
      end
    end
  end
  puts instruction.join
end

2

ক্লোজার - 585 577 বাইট

Edit:   I forgot modulo 256, of course
Edit 2: Now supports whitespace and comments anywhere. (585 -> 578)

কোনও গল্ফিংয়ের বিশেষ কৌশল ব্যবহার করা হয়নি, কারণ আমি ক্লোজুরের জন্য কোনওটিই জানি না। দোভাষা বিশুদ্ধভাবে কার্যকরী। নেতিবাচক র‍্যাম ঠিকানার ক্ষেত্রে একটি দুর্দান্ত ত্রুটি বার্তা নিয়ে আসে (কোনও ত্রুটি আউটপুট হয় তবে কোনও ব্যতিক্রম বা ত্রুটি নিক্ষেপ করা হয় না)।

(defn j[o i](let[o(re-seq #"\??[#<>=+:-]\d*"(clojure.string/replace o #"\(.*?\)|\s"""))r(loop[c 0 p 0 m(map int i)](if-let[f(nth o c nil)](let[[c p m]((fn r[t](let[f(first t)s(if(next t)(apply str(next t))(case f(\#\=\:)"0"(\>\<\+\-)"1"))v(read-string s)a(nth m p 0)](case f\?(if(=(nth m p 0)0)[c p m](r s))\#[c v m]\>[c(+ p v)m]\<[c(- p v)m]\:[(dec v)p m][c p(assoc(vec(concat m(repeat(- p(count m))0)))p(mod({\+(+ a v)\-(- a v)}f v)256))])))f)](if(< p 0)(str"Negative index "p" caused by "f)(recur(inc c)p m)))m))](if(string? r)r(apply str(map char(take-while #(> % 0)r))))))

উদাহরণ:

(j "=72>=101>=108>=108>=111>=32>=119>=111>=114>=108>=100>=33>=" "")
=> "Hello world!"
(j "?:2 :4 >1 :0 =33 >1 =0" "hi there")
=> "hi there!"
(j "#1 ?:3 :7 -<+ :0" "01") ; adder
=> "a"
(j "?:2 :4 >1 :0 =33 <10 =0" "hi there")
=> "Negative index -2 caused by <10"
(j "=72>=101>=108>=108>=111>=3(comment here <100)2>=119>=111>=114>=108>=100>=33>=" "")
=> "Hello world!"

আসল কিছুটা অবারিত কোড:

(defn memory
  ([]
    (vec (repeat 1024 0)))
  ([m i v]
    (assoc (vec (concat m (repeat (- i (+ -1024 (mod i 1024)) (count m)) 0)))
           i v)))

(defn parse [c p m t]
  (let [f (first t)
        s (if-let [v (next t)]
            (apply str v)
            (case f
              (\#\=\:) "0"
              (\>\<\+\-) "1"))
        v (read-string s)
        a (nth m p 0)]
    (case f
      \? (if (= (nth m p 0) 0) [c p m] (parse c p m s))
      \# [c v m]
      \> [c (+ p v) m]
      \< [c (- p v) m]
      \: [(dec v) p m]
      [c p (memory m p (mod ({\+ (+ a v) \- (- a v)} f v) 256))])))

(defn jumper [o i]
  (let [o (re-seq #"\??[#<>=+:-]\d*" (clojure.string/replace o #"\(.*?\)|\s" ""))
        r (loop [c 0
                 p 0
                 m (map int i)]
            (if-let [f (nth o c nil)]
              (let [[c p m] (parse c p m f)]
                (if (< p 0)
                  (str "Negative index " p " caused by " (nth o c))
                  (recur (inc c) p m))) m))]
    (if (string? r)
      r
      (apply str (map char (take-while #(> % 0) r))))))

জাম্পারে আমার প্রোগ্রাম যা একটি "যোগ করে!" কাজ করে! জাম্পারে প্রোগ্রাম করা কিছুটা কঠিন ..
সোমনিয়াম

এটি আপনার কাছে একটি ঝরঝরে ধারণা।
seequ

@ user2992539 আমি একটি সাধারণ অ্যাডারের উদাহরণ যুক্ত করেছি।
seequ

সাধারণত, এটি ব্রেইনফাকের মতো, তবে এটির লুপ নেই, গোটো রয়েছে এবং যদি এর পরিবর্তে এবং এর কমান্ড প্যারামিটার রয়েছে।
সোমনিয়াম

1
আপনি যদি -আপনার রেজেক্সের অক্ষর শ্রেণীর শেষে রাখেন, আপনাকে এড়াতে হবে না। -1 চরিত্র।
টমসডিং

2

কফিস্ক্রিপ্ট (465)

প্রথম প্রম্পট বাক্সটি প্রোগ্রামটির জন্য এবং দ্বিতীয় প্রম্পট বাক্সটি ইনপুট। এটি http://coffeescript.org এ পরীক্ষা করুন ।

মূল :

p=prompt().replace(/\(.*?\)|[\s\n\r]/g,"").match(/\??[^\d]\d*/g) ?[]
y=p[..]
i=prompt()
r=[].map.call i,(c)->c[0].charCodeAt()
n=0
m=[(d)->n=d
(d)->m[5] (r[n]+d)%%256
(d)->p=y[d..]
(d)->m[1] -d
(d)->n-=d
(d)->r[n]=d
(d)->n+=d]
while b=p.shift()
 if b[0]=="?"
  continue unless r[n]
  b=b[1..]
 d="><+-#=:".indexOf(b[0])//4
 ~d||throw "!badcmd '#{b[0]}'"
 m[b[0].charCodeAt()%7](+b[1..]||+!d)
 n<0&&throw "!ramdix<0"
alert String.fromCharCode(r...).replace(/\0.*/,"")

এটি এখনও গল্ফড, তবে মন্তব্য করেছে:

# Get program
p=prompt().replace(/\(.*?\)/g,"").match(/\??[^\s\d]\d*/g) ?[]
# Create a copy of the program (for goto)
y=p[..]
# Get input
i=prompt()
# Put the input in the ram
r=[].map.call i,(c)->c[0].charCodeAt()
# RAM pointer
n=0
# An array of commands
# Since each of "<>+-#=:" is a different
# value mod 7 (what a coincedence?!)
# So 0th value is "#" command because 
# "#".charCodeAt() % 7 === 0
m=[(d)->n=d
(d)->m[5] (r[n]+d)%%256
(d)->p=y[d..]
(d)->m[1] -d
(d)->n-=d
(d)->r[n]=d
(d)->n+=d]
# Iterate through commands
while b=p.shift()
 # If you find a "?" skip unless r[n] is > 0
 if b[0]=="?"
  continue unless r[n]
  b=b[1..]
 # Get the default value
 d="><+-#=:".indexOf(b[0])//4
 # If the command isn't good, throw an error
 throw "!badcmd '#{b[0]}'" if d==-1
 # Call the appropriate command
 # By computing the char code mod 7
 m[b[0].charCodeAt()%7](+b[1..]||+!d)
 # Make sure n is bigger than or equal to 0
 throw "!ramdix<0" if n<0
# Show output
alert String.fromCharCode(r...).replace(/\0.*/,"")

সম্পাদনা করুন : স্পেস যুক্ত করা আমার চেয়ে বেশি বাইট লাগল took এই দোভাষীটি অবৈধ সিনট্যাক্সে একটি ত্রুটি নিক্ষেপ করবে, অন্যটির অবৈধ সিনট্যাক্সে অনির্দিষ্ট আচরণ রয়েছে।

p=prompt().replace(/\(.*?\)/g,"").match(/\??[^\d\s\r\n]\s*\n*\r*\d*/g) ?[]
y=p[..]
i=prompt()
r=[].map.call i,(c)->c[0].charCodeAt()
n=0
m=[(d)->n=d
(d)->m[5] (r[n]+d)%%256
(d)->p=y[d..]
(d)->m[1] -d
(d)->n-=d
(d)->r[n]=d
(d)->n+=d]
while b=p.shift()?.replace /^(.)(\s\r\n)*/,"$1"
 if b[0]=="?"
  continue if !r[n]
  b=b[1..]
 d="><+-#=:".indexOf(b[0])//4
 ~d||throw "!badcmd"
 m[b[0].charCodeAt()%7](+b[1..]||+!d)
 n<0&&throw "!ramdix<0"
alert String.fromCharCode(r...).replace(/\0.*/,"")

দৃশ্যত এই কাজের জন্য নয় ?:2 :4 >1 :0 = 33 <10 =0(! Append- প্রোগ্রাম একটি অতিরিক্ত স্থান সহ)
seequ

@ সিগ এটি করা উচিত <1নয় <10
soktinpk

@ সাইগ কিছু মনে করবেন না, সময়
পেলে

@ সিয়েগ এখন কাজ করে, আমি আরও গল্ফিংয়ের কাজ করব
soktinpk

1
আমি "এটি ঘোষিত হয়নি, সুতরাং এটি অনির্দিষ্ট আচরণ" এর অবস্থান নিয়েছিলাম, সুতরাং আমি বলব এটি ঠিক আছে। তবে আবার আমি শক্তিশালী ব্যবহারকারী নই।
seequ

1

জাভাস্ক্রিপ্ট, 519

C=prompt().replace(/\(.*?\)/g,"").match(/\??[#><=+:-]\d*/g)
M=prompt().split("").map(function(c){return c.charCodeAt(0)})
R=0
f=function(I){T=I[0]
A=I.slice(1)
if(T=="?")return M[R]?f(A):P++
A=A==""?1:+A
if(T==">")R+=A
if(T=="<")R-=A
if("=+-".indexOf(T)+1){if(R<0)throw alert("ERR RAMidx<0")
while(R>=M.length)M.push(0)}
if(T=="+")M[R]=M[R]+A&255
if(T=="-")M[R]=M[R]-A&255
A=+I.slice(1)
if(T=="#")R=A
if(T=="=")M[R]=A
if(T==":")P=A;else++P}
for(P=0;C[P];)f(C[P])
alert(String.fromCharCode.apply(7,M).replace(/\0.*/,""))

এটি প্রম্পট বাক্সগুলির মাধ্যমে প্রোগ্রাম এবং ইনপুট পায়। আপনার ব্রাউজারের জাভাস্ক্রিপ্ট কনসোলে এটি আটকানো কাজ করবে, পাশাপাশি কোড <!DOCTYPE html>, নিউলাইন <html><head><script>এবং কোডের পরে আটকানো </script></head><body></body></html>এবং ফলাফলটি ফাইলটিকে "swagger.html" হিসাবে সংরক্ষণ করে কোনও ফাইলের মধ্যে ফেলে দেওয়া কাজ করবে ।

এটি এই জিনিসটিতে আমার প্রথম প্রচেষ্টা এবং আমি ইতিমধ্যে ভাষা পছন্দ করি। ধরণ. এটি বেসিক-স্টাইল নির্দেশিকা সূচক লেবেলের পরিবর্তে, যদিও এটিতে সত্যিই পাঠ্য লেবেলগুলির প্রয়োজন।

অবরুদ্ধ সংস্করণ (কিন্ডা):

var C,M,R,P,f;
C=prompt().replace(/\(.*?\)/g,"").match(/\??[#><=+:-]\d*/g); //Code
M=prompt().split("").map(function(c){return c.charCodeAt(0)}); //Memory
R=0; //RAM pointer
f=function(I){ //parser function, Instruction
    var T,A;
    T=I[0]; //Type
    A=I.slice(1); //Argument
    if(T=="?")return M[R]?f(A):P++;
    A=A==""?1:+A;
    if(T==">")R+=A;
    if(T=="<")R-=A;
    if("=+-".indexOf(T)+1){
        if(R<0)throw alert("ERR RAMidx<0");
        while(R>=M.length)M.push(0);
    }
    if(T=="+")M[R]=M[R]+A&255;
    if(T=="-")M[R]=M[R]-A&255;
    A=+I.slice(1);
    if(T=="#")R=A;
    if(T=="=")M[R]=A;
    if(T==":")P=A;else++P;
}
for(P=0;C[P];f(C[P])); //Program pointer
alert(String.fromCharCode.apply(7,M).replace(/\0.*/,""));

যদি শুধুমাত্র Clojure এর স্ট্রিং-প্রতিস্থাপন হবে নাclojure.string/replace
seequ

1
এছাড়াও, আমি লক্ষ্য করেছি এমন কিছু, আপনি যদি মেমরিটি 1024 বা
বহুগুণে

1
আমি মনে করি না যে আপনার স্ক্রিপ্টটি হ্যান্ডেল করতে পারে ?:2 :4 >1 :0 = 33 <10 =0(অতিরিক্ত স্থান সহ! সংযোজন!) যদিও পরীক্ষিত হয়নি।
seequ

@ সিগ এটি অবশ্যই পারবেন না। ইহা উচিত? প্রয়োজনে আমি কেবল সমস্ত হোয়াইট স্পেস ফিল্টার করতে পারি ...
টমসডিং করুন

1
"কমান্ড এবং আর্গুমেন্টগুলি ফাঁকা জায়গা বা নতুন লাইন দিয়ে সীমিত করা যেতে পারে তবে প্রয়োজনীয় নয় However তবে আর্গুমেন্টের অভ্যন্তরীণ স্থানগুলি অবৈধ" "যদি আমি সঠিকভাবে বুঝতে পারি তবে আর্গুমেন্টগুলি হোয়াইট স্পেসের আগে থাকতে পারে। @ user2992539 এই এক শব্দ পেয়েছেন?
seequ

1

সি 687 জিসিসি 4.9.0 এবং ভিজ্যুয়াল সি ++ 2013 (লাইন শেষগুলি 1 হিসাবে গণনা করা হয়)

সম্পাদনা করুন: ডেনিসকে ধন্যবাদ এটি এখন আরও খাটো (এবং বুট করার জন্য এটি জিসিসিতে কাজ করে)

গল্ফ সংস্করণ

#define S char*
#define Z (S)R
#define U unsigned char
#define M R=(U*)realloc(Z,r+1024),memset(Z+r,0,1024),r+=1024
#define J z<0?exit(puts("!")),0:z>r?
#define G J 0:R[z]
#define P(x)J M,R[z]=x:(R[z]=x);
#define O !*(C+1)?1:
#define V atoi(C+1)
#define I if(*C==
#define W while(*p&&*p<33)p++;
#define K (*q++=*p++)
#define Y return
U C[999][9];U*R=0;r=0,z=0,c=0;S T(S a){S p=a,*q=C[c++],*r;W if(K==63){W K;}W int i=strtol(p,&r,0);memcpy(q,p,r-p);q[r-p]=0;Y r;}int E(S C){I 63)Y G?E(C+1):0;I 35)z=V;I 62)z+=O V;I 60)z-=O V;I 61)P(V)I 43)P(G+O V-1)I 45)P(G-O V-1)I 58)c=V-1;}main(int u,S *v){M;u==3?strcpy(Z,v[2]):0;S X=v[1];while(*X)X=T(X);*C[c]=0;c=-1;while(*C[++c])E(C[c]);Y puts(Z);}

কিছুটা কম গল্ফযুক্ত সংস্করণ:

#include<stdlib.h>
#include<memory.h>
#include<string.h>
#include<stdio.h>
#define CHAR_STAR char*
#define CASTED_R (CHAR_STAR)RAM
#define UNSIGNED_CHAR unsigned char
#define INCREASE_MEMORY RAM=(UNSIGNED_CHAR*)realloc(CASTED_R,RAM_size+1024),memset(CASTED_R+RAM_size,0,1024),RAM_size+=1024
#define IF_ERROR current<0?exit(puts("!")),0:current>RAM_size?
#define GET_CELL IF_ERROR 0:RAM[current]
#define PUT_CELL(x) IF_ERROR INCREASE_MEMORY,RAM[current]=x:RAM[current]=x;
#define ONE_IF_EMPTY !*(command+1)?1:
#define VALUE atoi(command+1)
#define REMOVE_WHITESPACE while (*pointer&&*pointer<33)pointer++;
#define COPY_CHAR (*command++ = *pointer++)
#define RETURN return
char commands[999][9];
UNSIGNED_CHAR*RAM = 0;
int RAM_size = 0, current = 0, command_size = 0;
CHAR_STAR get_command(CHAR_STAR a)
{
    CHAR_STAR pointer = a, *command = commands[command_size++], *next;
    REMOVE_WHITESPACE
    if (COPY_CHAR == '?')
    {
        REMOVE_WHITESPACE
        COPY_CHAR;
    }
    REMOVE_WHITESPACE
    int i = strtol(pointer, &next, 0);
    memcpy(command, pointer, next - pointer);
    command[next - pointer] = 0;
    RETURN next;
}
void eval(CHAR_STAR command){
    if (*command == '?')RETURN GET_CELL ? eval(command + 1) : 0;
    if (*command == '#')current = VALUE;
    if (*command == '>')current += ONE_IF_EMPTY VALUE;
    if (*command == '<')current -= ONE_IF_EMPTY VALUE;
    if (*command == '=')PUT_CELL(VALUE)
    if (*command == '+')PUT_CELL(GET_CELL + ONE_IF_EMPTY VALUE - 1)
    if (*command == '-')PUT_CELL(GET_CELL - ONE_IF_EMPTY VALUE - 1)
    if (*command == ':')command_size = VALUE - 1;
}
int main(int argc, CHAR_STAR *argv)
{
    INCREASE_MEMORY;
    argc == 3 ? strcpy(CASTED_R, argv[2]) : 0;
    CHAR_STAR command = argv[1];
    while (*command) command = get_command(command);
    *commands[command_size] = 0; command_size = -1;
    while (*commands[++command_size]) eval(commands[command_size]);
    RETURN puts(CASTED_R);
}

1. আমি অন্যান্য সংকলক সম্পর্কে জানি না, তবে এটি জিসিসিতে সংকলন করবে না। এই দ্বিতীয় প্রতিস্থাপন সংশোধন করা যেতে পারে R[z]=xযে P(x)সঙ্গে (R[z]=x)। ২. জিসিসির কোনও বিবৃতি অন্তর্ভুক্ত করার দরকার নেই। 3. char C-> U C
ডেনিস

@ ডেনিস আমি এটি ভিজ্যুয়াল সি ++ 2013 দিয়ে পরীক্ষা করছিলাম I'll আমি আগামীকাল এটি জিসিসির সাথে পরীক্ষা করব।
জেরি যেরেমিয়া

0

গ্রোভি 582

অবারিত সংস্করণ:

আমি মনে করি মন্তব্যগুলির সাথে একটি ত্রুটি রয়েছে, যা সঠিকভাবে স্বীকৃত নয়, যা আমি ব্যবহার করা বোকামি রেজেক্সের কারণে হতে পারে, তবে 2 টি প্রোগ্রাম তাদের হওয়া উচিত হিসাবে চালিত হবে:

class P {
    def c = 0
    def p = 0
    def m = []

    P(i="") {
        m = i.chars.collect { it }
        m << 0
    }

    def set(v) { m[p] = v }
    def add(v) { m[p] += v }
    def sub(v) { m[p] -= v }

    def eval(i) {
        while(c < i.size()) {
            if (i[c].p && m[p] == 0) {c++} 
            else { i[c].f(this,i[c].v) }
        }
        return m
    }
}


def parse(s) {
    def ops = [
       '#' : [{p, v -> p.p = v; p.c++}, "0"],
       '>' : [{p, v -> p.p += v; p.c++}, "1"],
       '<' : [{p, v -> p.p -= v; p.c++}, "1"],
       '=' : [{p, v -> p.set(v); p.c++}, "0"],
       '+' : [{p, v -> p.add(v); p.c++}, "1"],
       '-' : [{p, v -> p.sub(v); p.c++}, "1"],
       ':' : [{p, v -> p.c = v}, "0"]
    ]

    (s =~ /\(.*\)/).each {
        s = s.replace(it, "")
    }

    (s =~ /(\?)?([#><=+-:])([0-9]*)?/).collect {        
        def op = ops[it[2]]
        [f : op[0], v : Integer.parseInt(it[3] ?: op[1]), p : it[1] != null ]
    }
}

0

হাস্কেল: চরিত্রগুলির একটি অদৃশ্য পরিমাণ

ঠিক আছে, এখনই এটি এমন কিছু যা খুব শীঘ্রই গল্ফ হতে পারে বা নাও হতে পারে। এটি প্রচুর পরিমাণে এবং প্রচুর opালু লিখিত কোড সহ (যা আমি হ্যাস্কেলকে ছুঁয়েছি এটি বেশ কিছুটা সময় ছিল) এটি যা যা তার জন্য freakishly বিশাল। তবে লিখতে মজা লাগছিল।

import Data.Char

parse [] p c a m i =
    if c == ' ' || c == '?' then
        []
    else
        (p ++ [(c, a, m)])

parse (h:t) p c a m i
    | i
        = parse t p c a m (h == ')')
    | isDigit h && a < 0
        = parse t p c (digitToInt h) m i
    | isDigit h
        = parse t p c (10 * a + (digitToInt h)) m i
    | elem h "#><=+-:?"
        = if c == ' ' || c == '?' then
            parse t p h a (c == '?') i
        else
            parse t (p ++ [(c, a, m)]) h (-1) False i
    | otherwise
        = case h of
            '(' -> parse t p c a m True
            ' ' -> parse t p c a m i
            _   -> []

run p pp r rp
    | pp >= length p
        = r
    | pp 0 || rp < 0
        = []
    | otherwise
        = if mr then
            case c of
                '#' -> run p (pp + 1) r pa
                '>' -> run p (pp + 1) r (rp + pa)
                '<' -> run p (pp + 1) r (rp - pa)
                '=' -> run p (pp + 1) (rh ++ ((chr pa) : rt)) rp
                '+' -> run p (pp + 1) (rh ++ (chr (mod ((ord h) + pa) 256) : rt)) rp
                '-' -> run p (pp + 1) (rh ++ (chr (mod ((ord h) - pa + 256) 256) : rt)) rp
                ':' -> run p pa r rp
        else
            run p (pp + 1) r rp
        where
            (c, a, m)
                = p !! pp
            (rh, h:rt)
                = splitAt rp r
            pa
                = if a < 0 then
                    if elem c "><+-" then
                        1
                    else
                        0
                else
                    a
            mr
                = ord (r !! rp) > 0 || not m

main = do
    p <- getLine
    let n = parse p [] ' ' (-1) False False
    if n == []
        then do
            putStrLn "Error"
        else do
            s <- getLine
            let r = run n 0 (s ++ (repeat (chr 0))) 0
            if r == []
                then do
                    putStrLn "Error"
                else do
                    putStrLn (takeWhile (/=(chr 0)) r)

0

হাস্কেল, 584

ইনপুট এবং জাম্পার প্রোগ্রাম স্টিডিন থেকে ইনপুট প্রথম দুটি লাইন হিসাবে সরবরাহ করা হয়।

a g(i,n,x)=(i+1,n,take n x++((g$x!!n)`mod`256):drop(n+1)x)
b g(i,n,x)=(i+1,g n,x)
c=b.q:a.(+):g:a.(-):b.(-):a.q:b.(+):c
d=(%['0'..'9'])
e=fromEnum
f=0>1
g n(_,x,y)=(n,x,y)
h(x:_)=d x;h _=f
i g p@(j,n,m)|x$m!!n=g p|t=(j+1,n,m)
j=0:1:0:1:1:0:1:j
k=takeWhile
l[]=[];l(x:y)|x%") \n"=l y|x%"("=l$u(/=')')y|t=x:l y
main=v>>=(\y->v>>=putStr.map toEnum.k x.r(0,0,map e y++z).p.l)
o n s|h s=(read$k d s,u d s)|t=(n,s)
p[]=[];p(x:y)|x%"?"=w$p y|t=(c!!e x)n:p m where(n,m)=o(j!!e x)y
q=const
r s@(i,n,m)p|i<length p=r((p!!i)s)p|t=m
t=0<1
u=dropWhile
v=getLine
w(m:n)=i m:n
x=(/=0)
z=0:z
(%)=elem

আমি পরে একটি নিরবচ্ছিন্ন সংস্করণ পোস্ট করব, কিন্তু এর মধ্যে আমি এটি পাঠকের ধাঁধা হিসাবে ছেড়ে যেতে চেয়েছিলাম:

'#' ইত্যাদির মতো জাম্পার কমান্ডগুলি কোথায়?

আনন্দ কর!

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