मेरी गूढ़ भाषा जम्पर के लिए एक दुभाषिया लिखें


17

मैंने गूढ़ भाषा का जम्पर सोचा है। बाद में आप देखेंगे कि क्यों।

  • यह कोशिकाओं के रूप में बाइट्स के साथ यादृच्छिक-एक्सेस-मेमोरी के साथ संचालित होता है। रैम शून्य अनुक्रमित है और शुरू में शून्य से भरा है।
  • जब नकारात्मक अनुक्रमित त्रुटि के साथ एक्सेस कोशिकाओं की कोशिश की जानी चाहिए और कार्यक्रम को समाप्त कर दिया जाना चाहिए।
  • जब पिछले की तुलना में बड़े सूचकांक में पढ़ने की कोशिश की जाती है, तो शून्य वापस किया जाना चाहिए।
  • जब पिछले की तुलना में बड़े इंडेक्स पर लिखने की कोशिश की जाती है, तो RAM को 1024 से कई तक बढ़ा दिया जाना चाहिए और शून्य से भरी नई कोशिकाओं (तकनीकी रूप से आप RAM को 1024 से अधिक नहीं बढ़ा सकते हैं, इसका कारण प्रदर्शन को बढ़ावा देना था, इसलिए यदि यह आपके लिए बहुत सारे पात्रों का खर्च करता है यह 1024 के कई के लिए नहीं कर सकते हैं)।
  • कार्यक्रम में रैम में सेल का सूचक भी है जो शुरू में शून्य है
  • जब प्रोग्राम इनपुट स्ट्रिंग के लिए एक प्रॉम्प्ट को निष्पादित करना शुरू करता है, तो उसे प्रदर्शित किया जाना चाहिए (या कमांड लाइन के तर्कों से इनपुट लेना, यह आपके ऊपर है)। इनपुट स्ट्रिंग में शून्य वर्ण (शून्य बाइट) नहीं होना चाहिए। फिर इनपुट स्ट्रिंग को शून्य इंडेक्स पर शुरू होने वाली रैम को लिखा जाता है।
  • जब प्रोग्राम समाप्त होता है तो प्रोग्राम आउटपुट के साथ एक बॉक्स निष्पादित होता है - शून्य इंडेक्स से पहली शून्य बाइट को छोड़कर रैम की सामग्री।

अब, सबसे दिलचस्प हिस्सा, वाक्यविन्यास।

कार्यक्रम में कमांड (यूनिरी ऑपरेटर-उपसर्ग) और उनके तर्क शामिल हैं। कमांड और तर्क को रिक्त स्थान या नई लाइनों के साथ सीमांकित किया जा सकता है लेकिन आवश्यक नहीं है। हालाँकि, तर्कों के अंदर के स्थान अमान्य हैं, उदाहरण के लिए, # 2 = 4मान्य है, लेकिन # 2 = 4 4ऐसा नहीं है।
कार्यक्रम के बीच टिप्पणी हो सकती है ()। टिप्पणियाँ नेस्टेड नहीं हो सकती हैं - उदाहरण के लिए, (abc(def)ghi)टिप्पणी में (abc(def)। टिप्पणियां कहीं भी रखी जा सकती हैं।

  • #123 123 (किसी भी सकारात्मक दशमलव पूर्णांक या शून्य) के लिए रैम पॉइंटर सेट करता है।
  • >123 वेतन वृद्धि राम सूचक 123 (किसी भी सकारात्मक दशमलव पूर्णांक) द्वारा।
  • <123 123 (किसी भी सकारात्मक दशमलव पूर्णांक) द्वारा रैम सूचक को घटाया जाता है।
  • =123 वर्तमान सेल में 123 (कोई भी अहस्ताक्षरित 8-बिट दशमलव पूर्णांक) लिखता है।
  • +123 वर्तमान सेल (मॉडुलो 256) में 123 (कोई भी अहस्ताक्षरित 8-बिट दशमलव पूर्णांक) जोड़ता है।
  • -123 वर्तमान सेल (मॉडुलो 256) से 123 (कोई भी अहस्ताक्षरित 8-बिट दशमलव पूर्णांक) घटाता है।
  • :123- "गोटो" - कमांड नंबर 123 (पहले 0 है) पर जाता है। आप केवल गोटो के साथ अपने कार्यक्रम के प्रवाह को नियंत्रित कर सकते हैं - यह कूदना होगा - यही कारण है कि मैंने इस भाषा को जम्पर कहने का फैसला किया है।

यदि तर्क गायब है - तो इसके बारे में सोचें ><+-कमांड के लिए 1 या #=:कमांड के लिए 0 है ।

इसके अलावा, कमांड संशोधक है - ?(कमांड के लिए उपसर्ग), यह केवल अगले कमांड को निष्पादित करता है यदि वर्तमान सेल शून्य नहीं है, और कमांड को छोड़ देता है। किसी भी आदेश पर लागू किया जा सकता है।
उदाहरण के लिए, ?: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 बाइट्स की लागत पर कुछ सिंटैक्स के लिए कुछ बग्स को जोड़ा और समर्थन जोड़ा (जबकि कुछ अन्य अनुकूलन जोड़कर)।


बहुत अजीब। मेरा रूबी समाधान सिर्फ 447 अक्षरों में भी तौला गया। हालांकि मैं 400 के दशक के मध्य में शूटिंग कर रहा था, ठीक उसी बाइट की गिनती एक सुपरराइज थी।
स्कॉट लेडले

@ScottLeadley हा, यह एक दिलचस्प टाई है। ^ ^ अगर मैं पहले से ही ऐसा नहीं करता तो मैं आपको एक अपवोट देता। ;)
मार्टिन एंडर

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]

कार्यक्रम चलाने के लिए:

  • पहला तर्क: जम्पर कोड
  • 2 तर्क: प्रारंभिक स्ट्रिंग

उदाहरण:

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

शायद कुछ चीजें हैं जिन्हें मैंने अनदेखा कर दिया है, इसलिए कृपया एक टिप्पणी छोड़ दें यदि आप ऐसा कुछ करने की कोशिश करते हैं जो काम करना चाहिए लेकिन नहीं करता है। ध्यान दें कि यह पायथन 2.x कोड में लिखा गया है।


आप इसे कैसे इनपुट देते हैं?
Claudiu

@ कोलियु उदाहरण देखें। यह एक कमांड-लाइन तर्क है।
अर्शजी

यही कार्यक्रम है। लेकिन 7 वीं गोली बिंदु को देखो। आपको आरंभिक रैम ऐरे को शुरू करने में सक्षम होना चाहिए, कहना चाहिए, "हेलो" स्टड या एक तर्क के माध्यम से
क्लोडिउ

मेरी गलती है, यह 6 वीं बुलेट है: "जब प्रोग्राम इनपुट स्ट्रिंग के लिए एक प्रॉम्प्ट पर अमल करना शुरू कर देता है (या कमांड लाइन तर्कों से इनपुट लेना चाहिए, यह आपके ऊपर है)। इनपुट स्ट्रिंग में शून्य वर्ण (शून्य बाइट) नहीं होना चाहिए। फिर इनपुट। स्ट्रिंग को शून्य सूचकांक पर शुरू होने वाली रैम को लिखा जाता है। "
क्लाउडीयू

@ कलुआडु आह, मुझे पता था कि मैंने कुछ अनदेखी की है, धन्यवाद। अब, प्रोग्राम को चलाने पर, आप स्ट्रिंग कह सकते हैं।
अर्शजी जू

4

रूबी 2 - 540 447 420 अक्षर

"ruby2.0 जम्पर.आरबी 'निर्देश' 'आरंभीकरण डेटा" के रूप में चलाते हैं। 1.x रूबी काम नहीं करेगा (कोई String.bytes विधि)।


मल्टी-लाइन कमांड और टिप्पणियों को जोड़ा और मेरे डालने में सुधार किया।


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*')

यहां कुछ बिखरे-शॉट परीक्षणों के साथ एक परीक्षण सूट है। इसका उपयोग करने का सबसे आसान तरीका कोड को t / jumper.t में भरना है और "perl t / jumper.t" चलाना है।


#/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))))))

जम्पर में मेरा कार्यक्रम जो एक "जोड़ता है!" काम करता है! जम्पर में प्रोग्राम करना थोड़ा कठिन है ..
सोमनील

यह आपके पास एक स्वच्छ अवधारणा है।
21

@ user2992539 मैंने एक साधारण योजक का एक उदाहरण जोड़ा।
२२:२० बजे

आम तौर पर, यह ब्रेनफक के समान होता है, हालांकि इसमें लूप्स, गोटो और यदि की जगह नहीं है और कमांड पैरामीटर हैं।
सोमनि जूल 25'14

1
यदि आप -अपने रेगेक्स के चरित्र वर्ग के अंत में रखते हैं, तो आपको इससे बचने की आवश्यकता नहीं है। -1 चरित्र।
tomsmeding

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.*/,"")

संपादित करें : मेरे विचार से रिक्त स्थान जोड़ने से अधिक बाइट्स हुए। यह दुभाषिया अमान्य सिंटैक्स पर एक त्रुटि फेंक देगा, दूसरे में अमान्य सिंटैक्स पर अनिर्दिष्ट व्यवहार है।

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

@Sieg यह <1नहीं होना चाहिए <10
सोकटिनपैक

@ कोई बात नहीं, मैं इसे तब अपडेट करूंगा जब मेरे पास समय होगा
soktinpk

@Sieg अब काम करता है, मैं इसे आगे गोल्फिंग पर काम
करूंगा

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" के रूप में सहेजना होगा।

इस चीज पर यह मेरा पहला प्रयास है, और मुझे पहले से ही भाषा पसंद है। किंडा। हालांकि, इस बुनियादी शैली निर्देश सूचकांक लेबलिंग के बजाय इसे वास्तव में पाठ लेबल की आवश्यकता है।

Ungolfed संस्करण (थोड़े):

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.string/replace
रिप्ले

1
इसके अलावा, मैंने जो कुछ देखा है, उससे कोई फर्क नहीं पड़ता कि आप मेमोरी को 1024 के गुणक में
बढ़ाते हैं

1
मुझे नहीं लगता कि आपकी स्क्रिप्ट संभाल सकती है ?:2 :4 >1 :0 = 33 <10 =0(अपेंडेंट! - एक अतिरिक्त जगह के साथ) हालांकि परीक्षण नहीं किया गया।
२३:१३ बजे २३:१४

@ यह निश्चित रूप से नहीं कर सकते। इसे होना चाहिए? मैं बस जरूरत पड़ने पर सभी
व्हाट्सएप को

1
"कमानों और तर्कों को रिक्त स्थान या नई लाइनों के साथ सीमांकित किया जा सकता है लेकिन आवश्यक नहीं है। हालांकि तर्कों के अंदर रिक्त स्थान अमान्य हैं" यदि मैं समझता हूं कि सही ढंग से, तर्क व्हाट्सएप से पहले हो सकते हैं। @ 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को बदलकर इसे ठीक किया जा सकता है । 2. GCC में शामिल कथनों में से किसी की आवश्यकता नहीं है। 3. -> । P(x)(R[z]=x)char CU C
डेनिस

@ डेनिस I इसे विजुअल C ++ 2013 के साथ परीक्षण कर रहा था। मैं कल जीसीसी के साथ इसका परीक्षण करूंगा।
जेरी जेरेमिया

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

हास्केल: वर्णों की एक अस्पष्ट राशि

ठीक है, अभी यह कुछ ऐसा है जो शीघ्र ही हो सकता है या नहीं। यह बहुत अधिक है कि यह क्या है, बहुत से और बहुत से लिखे गए कोड के साथ (यह काफी समय था जब से मैंने आखिरी बार हास्केल को छुआ था)। लेकिन लिखना मजेदार था।

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

मैं बाद में एक ungolfed संस्करण पोस्ट करूंगा, लेकिन इस बीच मैं इसे पाठक के लिए एक पहेली के रूप में छोड़ना चाहता था:

जम्पर कमांड्स जैसे '#' आदि कहां हैं?

मज़े करो!

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