# Write an interpreter for simplified 33

33 is a simple esolang I created. You may have seen me use it in a few questions. You're not going to be writing a full interpreter. The interpreter you will be writing is for a simplified version of 33.

This simplified 33 has two numeric registers: the accumulator and the counter. The accumulator holds all the post-arithmetic values, the counter is where numbers in the program come from. Both registers are initialized to 0.

0-9 | Appends the digit to the counter
a   | Adds the counter to the accumulator
m   | Subtracts the counter from the accumulator
x   | Multiplies the accumulator by the counter
d   | Divides the accumulator by the counter
r   | Divides the accumulator by the counter, but stores the remainder in the accumulator
z   | Sets the counter to 0
c   | Swaps the accumulator and counter
-----
p   | Outputs the current value of the accumulator as an ASCII character
o   | Outputs the current value of the accumulator as a formatted decimal number
i   | Outputs a newline character (0x0a)
-----
P   | Stores the ASCII value of the next character read in the accumulator
O   | Stores the next integer read into the accumulator
-----
n   | Skips the next instruction if the accumulator is not 0
N   | Skips the next instruction if the accumulator is 0
g   | Skips the next instruction if the accumulator is less than or equal to 0
G   | Skips the next instruction if the accumulator is greater than 0
h   | Skips the next instruction if the accumulator is greater than or equal to 0
H   | Skips the next instruction if the accumulator is less than 0


## Test cases

Program / Input -> Output
2o          -> 0
25co        -> 25
1a0aoi      -> 11 (trailing newline)
Oo / 42     -> 42
Op / 42     -> *
1cNoo       -> 11
no          -> 0
Ogo / 2     -> 2
Ogoi / -4   -> (newline)
50a         -> (no output)
On12co / 12 -> 2


## Clarifications

• The input to your interpreter will be a valid simplified 33 program.
• The input may be given in any acceptable format.
• The output may be given in any acceptable format.
• When dividing, truncate any decimal places.
• A trailing newline is acceptable, but it must be consistent; as in, if there's an i at the end of the program, it should have two trailing newlines.
• The accumulator and counter must be able to hold at least a signed byte (-128 to 127)
• You may assume that the p instruction will never be given when the accumulator has an invalid ASCII character in it.
• You may assume the O instruction will never be given unless there is a valid integer string (such as 3, -54, +23) left in the input.
• How does O work? Sep 10, 2019 at 10:57
• @tsh Yes. I'll update that. Sep 10, 2019 at 10:59
• @EriktheOutgolfer It reads the integer in the same format that o outputs it Sep 10, 2019 at 11:01
• @TheOnlyMrCat If the remaining input is x-13, will O skip the x and read the -13? Or can we assume that there will always be an integer right where the O reads the input? Sep 10, 2019 at 11:02
• What is acceptable format for an integer input the interpreter must handle? Will +03 be valid input for integer?
– tsh
Sep 10, 2019 at 11:21

# JavaScript (Node.js), 264 bytes

S=>I=>[...S].map(s=>K?K=0:1/s?C=+(C+s):eval("A*=C;[A,C]=[C,A];K=!A;;K=A;K=A>0;A%=C;K=A<=0;A=A/C|0;I=I.replace(/-?\\d+/,n=>(A=+n,''));K=A>=0;O+=A;K=A<0;A+=C;C=0;;[A]=B(I),I=I.slice(1);O+=\n;O+=B([A]);A-=C".split;[B(s)*73%378%22]),A=C=K=0,O='',B=Buffer)&&O


Try it online!

Saved ~20 bytes, thanks to Arnauld's magic integer modulus.

• 253 bytes by converting the input to a buffer right away, re-using S as the result of the previous instruction and using a strict comparison with true. Sep 11, 2019 at 7:22

### Lua 5.3, 342 bytes

Code is provided as a cmdline argument, input is provided via stdin.

H=string.char R=io.read A=0 C=0 i=1 s=...while i<=#s do
b=s:byte(i)d=H(b)i=i+(({H=A<0,G=A>0,N=A==0,g=A<=0,h=A>=0,n=A~=0})[d]and 2or
1)io.write(({i='\n',o=A|0,p=H(A%255)})[d]or'')A,C=d=='O'and R'n'or d=='P'and
R(1):byte()or d=='d'and A//C or d=='r'and A%C or({a=A+C,c=C,m=A-C,x=A*C})[d]or
A,b>=48 and b<58 and b-48+C*10or({c=A,z=0})[d]or C end


# Julia 1.0, 355 bytes

p=print
function f(s,a=0,c=0,i=1)
for x=s
z=findfirst(==(x),"amxdrzcpoiPOnNgGhH0123456789")
y=z-9
i<1&&(i=1;continue)
z<6 ? a=(+,-,*,÷,%)[z](a,c) :
z<7 ? c=0 :
z<8 ? ((a,c)=(c,a)) :
z<9 ? p(Char(a)) :
y<1 ? p(a) :
y<2 ? p("\n") :
y<3 ? a=0+read(stdin,UInt8) :
y<4 ? a=parse(Int,readline()) :
y<10 ? (!=,==,<=,>,>=,<)[y-3](a,0)&&(i=0) :
c=10c+y-10
end
end


Program provided as an argument, eg f("2o"), input taken from stdin.

Try it online!