0
\$\begingroup\$

This question already has an answer here:

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\$

marked as duplicate by caird coinheringaahing, DJMcMayhem code-golf Aug 30 '17 at 19:18

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • \$\begingroup\$ Is a transpiler allowed? \$\endgroup\$ – Okx Aug 30 '17 at 12:31
  • \$\begingroup\$ @Okx no, that'd be a separate challenge \$\endgroup\$ – caird coinheringaahing Aug 30 '17 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 Aug 30 '17 at 12:38
  • \$\begingroup\$ Ummm, I love rule #2. \$\endgroup\$ – Mr. Xcoder Aug 30 '17 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 Aug 30 '17 at 15:01
3
\$\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\$
  • \$\begingroup\$ You're not handling rule 3 - breaks on unexpected characters in the program. \$\endgroup\$ – m-chrzan Aug 30 '17 at 14:40
  • \$\begingroup\$ @m-chrzan Oops, I forgot threeish chars, one sec \$\endgroup\$ – Conor O'Brien Aug 30 '17 at 14:41
  • \$\begingroup\$ @m-chrzan Thanks again, fixed \$\endgroup\$ – Conor O'Brien Aug 30 '17 at 14:48
  • \$\begingroup\$ Using string interpolation saves 3 bytes ("#{{...}[e]};"). \$\endgroup\$ – m-chrzan Aug 30 '17 at 14:55
0
\$\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\$
  • \$\begingroup\$ Wouldn't switching to Python 2 save bytes? \$\endgroup\$ – caird coinheringaahing Aug 30 '17 at 13:52
  • \$\begingroup\$ @cairdcoinheringaahing print(end=...) would be pretty expensive in python2 \$\endgroup\$ – ovs Aug 30 '17 at 13:53
  • \$\begingroup\$ 253 bytes \$\endgroup\$ – Mr. Xcoder Aug 30 '17 at 14:02
  • \$\begingroup\$ 252 (-1 byte) by using lexicographical comparison (sorry for golfing byte-to-byte). \$\endgroup\$ – Mr. Xcoder Aug 30 '17 at 14:30
  • \$\begingroup\$ @Mr.Xcoder this would not work as we need to ignore every character which is not in ";#*:)" \$\endgroup\$ – ovs Aug 30 '17 at 14:57

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