5
\$\begingroup\$

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.
\$\endgroup\$
13
  • \$\begingroup\$ How does O work? \$\endgroup\$ Commented Sep 10, 2019 at 10:57
  • \$\begingroup\$ @tsh Yes. I'll update that. \$\endgroup\$ Commented Sep 10, 2019 at 10:59
  • \$\begingroup\$ @EriktheOutgolfer It reads the integer in the same format that o outputs it \$\endgroup\$ Commented Sep 10, 2019 at 11:01
  • \$\begingroup\$ @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? \$\endgroup\$ Commented Sep 10, 2019 at 11:02
  • \$\begingroup\$ What is acceptable format for an integer input the interpreter must handle? Will +03 be valid input for integer? \$\endgroup\$
    – tsh
    Commented Sep 10, 2019 at 11:21

3 Answers 3

1
\$\begingroup\$

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[0]),I=I.slice(1);O+=`\n`;O+=B([A]);A-=C".split`;`[B(s)[0]*73%378%22]),A=C=K=0,O='',B=Buffer)&&O

Try it online!

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

\$\endgroup\$
1
  • \$\begingroup\$ 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. \$\endgroup\$
    – Arnauld
    Commented Sep 11, 2019 at 7:22
0
\$\begingroup\$

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
\$\endgroup\$
0
\$\begingroup\$

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!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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