1
\$\begingroup\$

A few month back, I made a language called ;# (Semicolon Hash) and it started a little bit of a craze (it even got its own tag, as you can see). But, as with everything, the craze died down, and questions related to it stopped being posted.

However, a few people were annoyed at the lack of capability of ;# and this lead to someone creating a Turing complete version. Eventually, I decided to create ;# 2.0 with an extended set of commands:

; - Increment the accumulator
# - Modulo the accumulator by 127, output as ASCII character and reset the accumulator to 0
: - Open a while loop
) - Close a while loop. You can assume that all loops will be closed.
* - Take a byte of input, and add it to the accumulator. Input is recycled, so if the end of the input is reached, it wraps around to the start.

FYI: ;#*:) still isn't Turing complete

For example, a cat program would be

*:#*)

*     - Take a byte of input
 :  ) - While the input character is not a null byte...
  #   -   Print as character
   *  -   Take a byte of input

For this, the input must be terminated with a null byte, otherwise the program will repeat the input until the heat death of the universe.

and to add two numbers (input and output as char codes):

**#

*   - Take input (e.g. \x02); A=2
 *  - Take input (e.g. \x03); A=5
  # - Output A as character (\x05)

Your task is to interpret ;#*:). Your program/function will be given 2 inputs, the program and the program's input, and you have to interpret the given program.

A few rules:

1) Your program may not halt termination due to an error unless 2) happens. Output to STDERR is allowed, just so long as it doesn't affect the program's execution.

2) If the second input is empty (a ;#*:) program with no input) and * occurs in the code, you don't have to handle the error and can cause any kind of behaviour you want; summon Cthulhu, make Dennis lose his rep, anything you want.

3) All characters that aren't ;#*:) are ignored and have no effect on anything.

Nested loops can happen, and all loops will be closed, so ;:*:#*);) is valid code

This is a code golf, so shortest code wins.

Some tests to check your program against:

program, input (as ASCII characters; \xxx is a byte literal) => output

*#*:#*), "1" => 11111111...
**#, "12" => c
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#, "abc" => Hello, World!
*#, "" => undefined
Hello, World!, "" => (nothing)
*:#*):;#*)*#, "Hello,\x00World!" => Hello,W
*:#*), "Testing\x00" => Testing
*:#*), "Testing" => TestingTestingTestingTesting...
;:*:#*);*), "123\x00" => 223d3d3d...

And, to help you even more, this is an ungolfed reference implementation in Python. In this version, I have decided to make the * on empty input be ignored.

Good luck!

\$\endgroup\$
10
  • \$\begingroup\$ Is a transpiler allowed? \$\endgroup\$
    – Okx
    Commented Aug 30, 2017 at 12:31
  • \$\begingroup\$ @Okx no, that'd be a separate challenge \$\endgroup\$ Commented Aug 30, 2017 at 12:32
  • \$\begingroup\$ Can you clarify Nested loops can happen when paired with You can assume that all loops will be closed? \$\endgroup\$
    – Stephen
    Commented Aug 30, 2017 at 12:38
  • \$\begingroup\$ Ummm, I love rule #2. \$\endgroup\$
    – Mr. Xcoder
    Commented Aug 30, 2017 at 12:40
  • 1
    \$\begingroup\$ In R, the NUL character is no longer allowed in strings as of 3.1.3 so this challenge is impossible in newer versions of the language (and it truncated strings before, so this is probably impossible in older ones as well) \$\endgroup\$
    – Giuseppe
    Commented Aug 30, 2017 at 15:01

2 Answers 2

4
\$\begingroup\$

Ruby, 147 144 bytes

Saved 3 bytes thanks to m-chrzan!

z=STDIN.read
eval ARGV[i=a=0].gsub(/./){|e|"#{{?;=>"a+=1",?#=>"putc(a%127);a=0",?:=>"while a>0",?)=>"end",?*=>"a+=z[i%=z.size].ord;i+=1"}[e]};"}

Try it online!

Program is taken from first command line argument.

\$\endgroup\$
4
  • \$\begingroup\$ You're not handling rule 3 - breaks on unexpected characters in the program. \$\endgroup\$
    – m-chrzan
    Commented Aug 30, 2017 at 14:40
  • \$\begingroup\$ @m-chrzan Oops, I forgot threeish chars, one sec \$\endgroup\$ Commented Aug 30, 2017 at 14:41
  • \$\begingroup\$ @m-chrzan Thanks again, fixed \$\endgroup\$ Commented Aug 30, 2017 at 14:48
  • \$\begingroup\$ Using string interpolation saves 3 bytes ("#{{...}[e]};"). \$\endgroup\$
    – m-chrzan
    Commented Aug 30, 2017 at 14:55
1
\$\begingroup\$

Python 3, 261 253 bytes

-8 bytes thanks to @Mr.Xcoder

p,i=eval(input());a=k=c=z=0;j=[];m={}
for y in p:
 if':'==y:j+=[z]
 if')'==y:b=j.pop();m[b]=z;m[z]=b
 z+=1
while p[c:]:
 y=p[c];a+=';'==y
 if'*'==y:a+=ord(i[k%len(i)]);k+=1
 if'#'==y:print(end=chr(a%127));a=0
 if y in':)':c=[c,m[c]][(a>0)>(')'<y)]
 c+=1

Try it online!

Python 3, 253 bytes

Same length using exec

p,i=eval(input());a=k=c=z=0;j=[];m={}
for y in p:
 if':'==y:j+=[z]
 if')'==y:b=j.pop();m[b]=z;m[z]=b
 z+=1
while p[c:]:y=p[c];exec('a+=1 print(end=chr(a%127));a=0 a+=ord(i[k%len(i)]);k+=1 c=[c,m[c]][a<1] c=[c,m[c]][a>0] 1'.split()[';#*:)'.find(y)]);c+=1

Try it online!

\$\endgroup\$
6
  • \$\begingroup\$ Wouldn't switching to Python 2 save bytes? \$\endgroup\$ Commented Aug 30, 2017 at 13:52
  • \$\begingroup\$ @cairdcoinheringaahing print(end=...) would be pretty expensive in python2 \$\endgroup\$
    – ovs
    Commented Aug 30, 2017 at 13:53
  • \$\begingroup\$ 253 bytes \$\endgroup\$
    – Mr. Xcoder
    Commented Aug 30, 2017 at 14:02
  • \$\begingroup\$ 252 (-1 byte) by using lexicographical comparison (sorry for golfing byte-to-byte). \$\endgroup\$
    – Mr. Xcoder
    Commented Aug 30, 2017 at 14:30
  • \$\begingroup\$ @Mr.Xcoder this would not work as we need to ignore every character which is not in ";#*:)" \$\endgroup\$
    – ovs
    Commented Aug 30, 2017 at 14:57

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