7
\$\begingroup\$

"Counter" is a language I've created for the purpose of this question.

Rules

  • Commands are read from left to right from the first character.
  • Each command may be executed as it is read, or you may execute all commands together at the end.
  • In case of an error, all commands up till the error must be executed.
  • A program is written in exactly one line.
  • Data is stored in counters. At the start, there is exactly one counter. More can be created and deleted.
  • A counter holds an integer value between -100 and 100 (limits inclusive).
  • Exactly one counter is the selected counter at any point in time.
  • Counters are arranged in a 1d array, so one can move left (previous) or right (next) to change selected counter.

Commands

  • Any number between -100 and 100 - Set the currently selected counter to that value.
  • c - Create a counter immediately after the currently selected counter, make it the selected counter, and set it to 0.
  • d - Delete the currently selected counter, and make the previous one selected. If it is the first one, this is an error.
  • + - Make the next counter the selected one.
  • - - Make the previous counter the selected one. (Ensure that this command is not immediately followed by a number.)
  • o - Output the value in the selected counter, followed by a space.
  • ? - If the value in the selected counter is 0, apply the d command on it.
  • # - If the value in the selected counter is 0, ignore the next command.
  • (space) - No meaning, but is to be treated like a command, if preceded by a #. Used to demarcate numbers.

Errors

  • Going left of the leftmost counter, or right of the rightmost counter.
  • Deleting the first counter.
  • Encountering a # as the last command. (Of course, this means all commands will get executed anyways)
  • A command that does not exist.
  • A number that's too long.

Task

Create an interpreter in any language. Code will be in a file or given as input (your choice). Shortest code wins.

Lengthy example

Consider the code:

7cc--13 12do?+?#0#o3od-7o

Here is a breakdown of the program. [] indicates the selected counter.

Cmd   Memory    Output

7     [7]
c     7 [0]
c     7 0 [0]
-     7 [0] 0
-13   7 [-13] 0
      7 [-13] 0
12    7 [12] 0
d     [7] 0
o     [7] 0     7
?     [7] 0
+     7 [0]
?     [7]
#     [7]
0     [0]
#     [0]
o     [0]
3     [3]
o     [3]       3
d     This is an error. Program terminates here.

Total output 7 3

\$\endgroup\$
  • \$\begingroup\$ Oh, one thing you could still clarify is what exactly is allowed or required when an error is encountered. Clean termination of the program? Error message? Undefined behaviour as long as everything before the error works? \$\endgroup\$ – Martin Ender Dec 19 '15 at 10:18
  • 1
    \$\begingroup\$ @Martin Any undefined behaviour as long as the previous commands have been executed and output is still visible. \$\endgroup\$ – ghosts_in_the_code Dec 19 '15 at 11:56
  • \$\begingroup\$ When you say "deleting the first counter" is an error do you mean "deleting the only existing counter" or do you mean "deleting the first counter even if other ones exist and could become the selected counter" For example: c-d \$\endgroup\$ – Jerry Jeremiah Jan 13 '16 at 4:04
  • \$\begingroup\$ @Jerry The second case \$\endgroup\$ – ghosts_in_the_code Jan 13 '16 at 7:18
1
\$\begingroup\$

JavaScript (ES6) 228

s=>s.replace(/-?(\d+)|./g,(t,n)=>i?++i:C[k]&&(u='?-+# odc'.indexOf(t),n<101?C[k]=t:u>6?C[S='splice'](++k,0,'0'):u>5?C[S](k--,1):u>4?o+=C[k]+' ':u>2?+C[k]?0:i=-(u<4):u>1?k++:u>0?k--:~u?+C[k]||C[S](k--,1):i=1),i=o='',C=[k='0'])&&o

Less golfed

s=>(
  i=o='',
  C=[k='0'], // C: counters, k: current counter index
  s.replace(/-?(\d+)|./g,
    (t,n)=>( // tokenize, n is eventually the number, unsigned
      i?++i:C[k] && ( // i>0 or C[k] undefined -> error found
      u='?-+# odc'.indexOf(t),
      n<101?C[k]=t // n present and < 101 
      :u>6?C.splice(++k,0,'0') //c add counter
      :u>5?C.splice(k--,1) // d remove counter
      :u>4?o+=C[k]+' ' // o output
      :u>3?0 // space == NO OP
      :u>2?+C[k]?0:i=-1 // set i to -1 to skip the next command
      :u>1?k++
      :u>0?k--
      :~u?+C[k]||C.splice(k--,1) // ? conditional remove counter
      :i=1) // invalid command error
    )
  ),
  o // return output
)
\$\endgroup\$
1
\$\begingroup\$

Python3, 403 530 bytes

This is seriously golfable, but I can't think of how...

Thanks to @cat for 127 bytes!!! (I'm really bad at golfing in Python)

c=input()
a=[0]
s=0
i=0
def g(i,n):
 p=i
 if n:i+=1
 while c[i].isdigit():i+=1
 a[s]=int(c[p:i]);return i-1
def e():
 a.pop(s);s-=1
while i<len(c):
 d=c[i]
 if d.isdigit():i=g(i,0)
 elif d=='c':s+=1;a.insert(s,0)
 elif d=='d':e()
 elif d=='+':s+=1
 elif d=='-':
  if c[i+1].isdigit():i=g(i,1)
  else:s-=1
 elif d=='o':print(a[s],end=' ')
 elif d=='?':
  if a[s]==0:e()
 elif d=='#':
  if a[s]==0:i+=1
 i+=1
\$\endgroup\$
  • \$\begingroup\$ here's 406 \$\endgroup\$ – cat Jan 25 '16 at 0:13
0
\$\begingroup\$

JavaScript ES6, 300 bytes

Hey look, a nice round number!

x=>x.match(/-\d*|\d+|./g).map(c=>e?0:q?q--:c-101?Math.abs(c)>100?e++:s[p]=+c:c=="c"?s.splice(++p,0,0):c=="d"?s.length>1?s.splice(p--,1):e++:c=="o"?o+=s[p]+" ":c=="-"?--p<0&&e++:c=="+"?++p>=s.length&&e++:c=="?"?s[p]||(s.length>1?s.splice(p--,1):e++):c=="#"?s[p]||q++:c==" "?0:e++,s=[],e=p=q=0,o="")&&o

It doesn't error on # at the end of a program because that wouldn't affect anything at all. Let me know if I need to anyway.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.