74
\$\begingroup\$

I recently created a new language called ;# (pronounced "Semicolon Hash") which only has two commands:

; add one to the accumulator

# modulo the accumulator by 127, convert to ASCII character and output without a newline. After this, reset the accumulator to 0. Yes, 127 is correct.

Any other character is ignored. It has no effect on the accumulator and should do nothing.

Your task is to create an interpreter for this powerful language!

It should be either a full program or a function that will take a ;# program as input and produce the correct output.

Examples

Output: Hello, World!
Program: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#

Output: ;#
Program: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#

Output: 2 d����{���
Program: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;hafh;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;f;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;###ffh#h#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ffea;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#au###h;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;h;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;o

Output: Fizz Buzz output
Program: link below

Output: !
Program: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#

Fizz Buzz up to 100

\$\endgroup\$
11
  • 1
    \$\begingroup\$ Is it acceptable if an interpreter doesn't terminate its execution at the end of the input but instead keeps looping indefinitely without producing extra output? \$\endgroup\$
    – Leo
    May 22, 2017 at 9:26
  • 6
    \$\begingroup\$ The second example makes me wonder about a program to encode a program to produce an output... recursive compilation! \$\endgroup\$
    – frarugi87
    May 22, 2017 at 9:29
  • 1
    \$\begingroup\$ @iamnotmaynard Semicolon Hash \$\endgroup\$ May 23, 2017 at 15:09
  • 5
    \$\begingroup\$ Maybe Wink Hash would be easier to say \$\endgroup\$ May 23, 2017 at 17:42
  • 1
    \$\begingroup\$ The Pastebin link appears to be dead. \$\endgroup\$
    – EasyasPi
    May 22, 2021 at 4:29

139 Answers 139

4
\$\begingroup\$

Red, 70 bytes

a: #""parse ask""[any[";"(a: a + 1)|"#"(prin a % 127 a: #"")| skip]]()

Try it locally in interpreter.

\$\endgroup\$
4
\$\begingroup\$

Golfscript, 39 29 25 24 bytes

'#'/);{';'/,(127%}%'':n+

Try it online!

Explanation:

'#'/);                   # Splits the input with '#' and discards the last part. 
                  %      # For each splited string, executes the preceding block: 
      {';'/,(127%}       # Splits the string with ';' and counts how many splits were made(which is equal to the number of ';'s). Then, mods that number with 127. 
                   '':n+ # Turns every calculated numbers into characters. 

Note: The final :n isn't needed if a trailing newline is allowed. Also, there was a bug in the 29-bytes version that it couldn't handle the input without '#'. Luckily, I could fix that bug and golf my code at the same time.

\$\endgroup\$
4
\$\begingroup\$

Rockstar, 208 168 152 148 bytes

listen to S
cut S
O's ""
N's 0
while S
roll S in C
let N be+C's ";"
if C's "#"
let M be N/127
turn down M
cast N-M*127 in N
let O be+N
N's 0


say O

Try it here (Code will need to be pasted in)

listen to S           :Read input string into variable S
cut S                 :Split into an array
O's ""                :Initialise O as an empty string
N's 0                 :Initialise N as 0
while S               :While S is not empty
roll S in C           :  Pop the first element of S into variable C
let N be+C's ";"      :  Increment N by C===";", implicitly casting from Boolean to integer
if C's "#"            :  If C==="#" then
let M be N/127        :    Initialise M as N/127
turn down M           :    Floor M
cast N-M*127 in N     :    Get the character at codepoint N-M*127 and assign it to N
let O be+N            :    Append N to O
N's 0                 :    Reset N to 0
                      :  End if
                      :End while loop
say O                 :Output O

If we need to be able to handle newlines in the input then we'll need this 169 byte version as each line in Rockstar is a separate input.

listen to S
O's ""
N's 0
while S
cut S
while S
roll S in C
let N be+C's ";"
if C's "#"
let M be N/127
turn down M
cast N-M*127 in N
let O be+N
N's 0


listen to S

say O
\$\endgroup\$
3
\$\begingroup\$

Alice, 22 bytes

I!?';-n+?h$'@u%?'#-n$O

Try it online!

Explanation

We keep on the stack only a single counter of how many ; we have encountered. When the stack is empty (e.g. at the start of the program) this is implicitly a 0.

I!?';-n+?h$'@u%?'#-n$O
I                      Push codepoint of next char from input
 !?                    store it on the tape and reload it right away
   ';-n+               add 1 to the counter if this char is a semicolon,
                       0 otherwise
        ?h$'           If the input char was -1 (EOF) execute the next command,
                       otherwise push its codepoint
            @          Terminate the program (or push 64)
             u         Set all bits up to the most significant as equal to 1
                       this turns 64 (1000000b) into 127 (1111111b)
              %        Compute modulo
               ?       reload the input char from the tape
                '#-n$O if it is a hash, pop the counter and print
                       the corresponding character
                       wrap back to the start of the line

A shorter, but non-terminating version of this program can be found here.

\$\endgroup\$
7
  • \$\begingroup\$ Confirmed it here \$\endgroup\$ May 22, 2017 at 15:00
  • \$\begingroup\$ Sorry for the bad formatting, I've posted this from my phone, I'll fix it as soon as I get my hands on a pc \$\endgroup\$
    – Leo
    May 22, 2017 at 15:01
  • \$\begingroup\$ Programs have to terminate unless specified otherwise in the challenge. \$\endgroup\$ May 23, 2017 at 9:08
  • \$\begingroup\$ You can save a byte by using a literal 0x7F instead of ~h though. \$\endgroup\$ May 23, 2017 at 9:11
  • \$\begingroup\$ @MartinEnder made it terminating. I couldn't manage to insert a 0x7F in the code, but I think this alternative modification is more interesting anyway :) \$\endgroup\$
    – Leo
    May 23, 2017 at 9:38
3
\$\begingroup\$

JS (ES6), 97 92 bytes

c=>(a=0,y="",c.split``.map(x=>x=="#"?(a%=127,y+=String.fromCharCode(a),a=0):x==";"?a++:0),y)

Tried to take a different approach than Shaggy's answer. Oh well.

\$\endgroup\$
0
3
\$\begingroup\$

Bash + coreutils, 46 39 bytes

tr -dc \;#|sed 'y/;/1/;s/#/.ZC7%P/g'|dc

Try it online!

Explanation

(Thanks Cows Quack for -7 bytes!)

The tr portion removes all extraneous characters (I could put this in the sed for exactly the same bytecount, but then it doesn't handle the linefeed character correctly, since sed leaves them in and dc only gets up to the first linefeed with ?)

sed takes the rest and builds a dc program:

Strings of ; become strings of 1 (a long literal)

# becomes .ZC7%P (if this follows a string of 1, the . is a decimal point for a no-op. But if it's at the beginning of the program, or following another #, it's a literal 0. Then it takes the length of the number, mods it, and Prints the corresponding ASCII.)

\$\endgroup\$
3
  • \$\begingroup\$ You don't need to escape the ; inside '...' and can simply change dc -ez? to dc. Besides that, instead of ;'s adding 1 to the stack, you can group them together and get their length using Z to reach this tio.run/##S0oszvj/…. \$\endgroup\$
    – user41805
    Sep 8, 2018 at 9:10
  • \$\begingroup\$ @Cowsquack That's good, thank you! (and the dc -ez? was a consequence of needing an extra zero to start the program) But your program adds additional output to stderr in either the cases of consecutive # or input that doesn't end with # (in both cases, I mean after extraneous characters are removed). I don't know if there's a consensus, but I feel like the extra output invalidates the solution. I adapted your idea, though, and wound up at just one byte more than your suggestion without dc throwing errors! \$\endgroup\$ Sep 9, 2018 at 6:09
  • \$\begingroup\$ According to this stderr can be ignored unless the challenge explicitly states as such, so that is very handy for dc. Also note that this current solution fails with consecutive #s because Z of 0 is 1, so it outputs 0x01 instead of 0x00 (I fell into that same trap as well, but my browser displays unprintables as their hexcodes so I caught that). \$\endgroup\$
    – user41805
    Sep 10, 2018 at 9:00
3
\$\begingroup\$

C, 65 64 60 bytes

(-2 thanks to ceilingcat)

c;f(char*s){for(c=0;*s;s++)c+=*s-35?*s==59:-putchar(c%127);}
\$\endgroup\$
3
  • \$\begingroup\$ You'll need to initialize c to zero to make the function reusable. \$\endgroup\$ May 21, 2017 at 23:40
  • \$\begingroup\$ @ConorO'Brien Fixed. Unfortunately I didn't manage to come up with anything shorter than simply adding in the c=0, and I wouldn't want to cheat by copying from Dennis's answer. \$\endgroup\$
    – hvd
    May 22, 2017 at 19:41
  • \$\begingroup\$ @ceilingcat Thanks again, I was able to take off three more bytes after that. This does use a trick in Dennis's answer (checked after editing), but this time, so much time had passed that I had forgotten all about it and came up with it on my own. \$\endgroup\$
    – hvd
    Sep 17, 2018 at 10:59
3
\$\begingroup\$

asm2bf, 74 bytes

Try it online!

Golfed code:

@l
in r1
ceqr1,.;
cadr2,1
ceqr1,.#
cjz%d
modr2,127
outr2
clrr2
@d
jnzr1,%l

Commented code:

; Wrap everything in a loop.
@l
; Read a character from stdin.
    in  r1
; if r1 = ';', set the condition flag.
    ceq r1,.;
; if condition flag is set, add 1 to r2
; r2 is used as an accumulator.
    cad r2,1
; if r1 = '#', set the condition flag.
    ceq r1,.#
; if condition flag is not set, jump to d
    cjz %d
; display acc%127 and clear it.
    mod r2,127
    out r2
    clr r2
@d
; loop if didn't hit an EOF
    jnz r1, %l
\$\endgroup\$
3
\$\begingroup\$

Add++, 31 bytes

D,g,@,59C€=Bs127%
L^,"#"$t€gbUp

Try it online!

How it works

D,g,@,		; Define a helper function g that takes one argument, S
	59C	; Push a ';' character
	€=	; Over each character in S, is it ';'?
	Bs	; Sum
	127%	; Mod 127

L^,		; Define the main lambda with one argument, P
		; The ^ flag tells the output to convert numbers to code points and concatenate
	"#"	; Push a '#' character
	$t	; Split P on '#' characters
	€g	; Run g over each section
	bU	; Splat to the stack
	p	; Remove the last one
\$\endgroup\$
3
\$\begingroup\$

Vim, 58 68 bytes

@cairdcoinheringaahing and @kops pointed out a few issues, +10 bytes to fix them.

:%j
:s/[^;#]//g
:s/#/x/g
A <Esc>^qqcfx<C-r>=nr2char(len("<C-r>"<BS>")%127)
<Esc>l@qq@qD

Try it online!

Explanation:

:%j                                                # Delete all newlines
:s/[^;#]//g                                        # Delete all unnecessary characters
:s/#/x/g                                           # Replace all '#' with 'x'
A <Esc>^                                           # Append ' ' to the line
        qq                                         # Define macro q:
          cfx                                      #   Cut from here through next 'x'
             <C-r>=nr2char(len("<C-r>"<BS>")%127)  #   Convert (length_of_the_cut_string % 127) to a character
<Esc>l                                             #   Exit insert mode and move to next ';'
      @q                                           #   Call macro q
        q@q                                        # End the macro and run it
           D                                       # Delete any remaining characters
\$\endgroup\$
3
  • \$\begingroup\$ This assumes the input ends with a #: Try it online! should output Hello, World, as the final ! isn't printed \$\endgroup\$ Apr 29, 2021 at 16:33
  • \$\begingroup\$ This will also do Bad Things if there are newlines or spaces in the input program. \$\endgroup\$
    – kops
    Apr 29, 2021 at 16:53
  • \$\begingroup\$ @cairdcoinheringaahing Fixed. Can't have Bad Things happening, now can we? \$\endgroup\$ Apr 29, 2021 at 17:09
3
\$\begingroup\$

APL (Dyalog Unicode), 26 bytes

Anonymous tacit prefix function.

⎕UCS 127|1⊥¨';'='#'(⌽=⊂⊢)⌽

Try it online!

 reverse the argument

'#'() apply the following tacit function with hash as left argument:

 the right argument (the ;# code)

 partitioned by…

= the equality (where there are hashes)

 reverse that

';'= equality to semicolon

1⊥¨ sum each (lit. evaluate each as unary)

127| division remainder when divided by 127

⎕UCS Convert to corresponding Unicode character

\$\endgroup\$
3
\$\begingroup\$

Subleq, 29 18 binary words

-11 from various changes explained below

-1 35 -1
1 35 12
0 28 9
35 35 0
28 -1 15
28 28 9

Changes

Old       New 
-1 25 3  | -1 35 -1 'combined first two line to read character and exit if null;
24 25 -1 |          'changed address to 35 so it could be used for the comparison to "#"
26 25 15 | 1 35 12  'changed addresses of data and comparison
27 28 12 | 0 28 9   'increment 28: using 0: instead of another address containing -1
25 25 0  | 35 35 0  'changed address from 25 to 35
28 -1 18 | 28 -1 15 'no changes except for address in the 3rd argument (which isn't used)
28 28 21 | 28 28 9  'changed to goto line that sets 35: = 0 to eliminate duplicate next line
25 25 0  |          'deleted
0 0 35 -1 0 |       'eliminated initialization data because the two non-zero items are
                    'elsewhere and 0 values (28: and 35:) do not need to be initialized

Original

-1 25 3     
24 25 -1    
26 25 15    
27 28 12    
25 25 0     
28 -1 18    
28 28 21    
25 25 0     
0 0 35 -1 0 

Explanation

-1 25 3     ' move next char in input to 25:
24 25 -1    ' 25: = 25: - 24:(0) if 25: <= 0 exit (if input empty exit)
26 25 15    ' 25: = 25: - 26:(35) if 25: <= 0 goto 15: (if input = "#" goto 15)
27 28 12    ' increment 28: by 1
25 25 0     ' 25: = 0 goto 0
28 -1 18    ' output 28:
28 28 21    ' 28: = 0
25 25 0     ' 25: = 0 goto  0
0 0 35 -1 0 ' values for 24: - 28:

Subleq emulator

\$\endgroup\$
3
\$\begingroup\$

C, 96 bytes

This is my first golf attempt!

i;a;main(z,s)char**s;{while(s[1][i])switch(s[1][i++]){case 35:putchar(a%127);a=-1;case 59:++a;}}
\$\endgroup\$
2
2
\$\begingroup\$

Befunge-98, 38 bytes

v+1$>';-!#;_
>~:;|-#';#:_@
^   >$' %,

Try it online!

Note that the input is terminated with a null byte and there is an unprintable (ASCII 127) on the third line after '

\$\endgroup\$
2
\$\begingroup\$

Perl 6, 49 bytes

{S:g/(<-[#]>*)(\#)?/{chr($0.comb(';')%127)x?$1}/}
\$\endgroup\$
2
\$\begingroup\$

C (gcc), 66 bytes

a;f(char*c){for(a=0;*c;a+=*c==59,a=*c++==35&&putchar(a%127)?0:a);}

Try it online!

\$\endgroup\$
2
\$\begingroup\$

QBIC, 48 66 57 bytes

[_l;||D=_sA,a,1|┘b=b-(D=@;`)~D=@#`|b=b%127?chr$(b)';`┘b=0

Explanation:

[    |           FOR
 _l;|              the length of the cmd line arg A$
 D=_sA,a,1|      Take the next character out of the string as D$
┘                Syntactic linebreak
b=b-(D=@;`)      If D$ == ";", this yields -1. Subtracting this from ACC reverses the sign
~D=@#`|          And if D$ == "#"
b=b%127          Do the Modulo-print thingy
?chr$(b)';`
┘b=0             And reset the acc
\$\endgroup\$
0
2
\$\begingroup\$

Go, 104 102 bytes

Yeeeeaaaaaaaaaah, Go.

import."fmt"
func f(c string){i:=0;for _,r:=range c{if';'==r{i++};if'#'==r{Print(string(i%127));i=0}}}

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Pyth, 16 bytes

smC%/d\;127Pcw\#

Try it!

explanation

smC%/d\;127Pcw\#
            cw\#    ## split the input on '#'
           P        ## remove the last element (everything after the last #)
 m                  ## map over this list of strings (variable: d)
    /d\;            ## count the semicolons
   %    127         ## modulo 127
  C                 ## the character with that number
s                   ## concat the list of characters

imperative version I did for fun: J0FHwIqH\;=+J1)IqH\#pC%J127=J0

\$\endgroup\$
0
2
\$\begingroup\$

C#, 110 108 103 101 98 bytes

-2 bytes by removing braces, where unnecessary

-5 bytes by removing else, from else if

-2 bytes, thanks to TheLethalCoder

-3 bytes, thanks to Andrew Piliser

a=>{var b=0;var d="";foreach(var c in a){if(c==59)b++;if(c==35){d+=(char)(b%127);b=0;}}return d;};

Anonymous function, returns the output.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Compare c to an int to save 2 bytes. \$\endgroup\$ May 22, 2017 at 8:17
  • 1
    \$\begingroup\$ I don't think you need the +"", it works without it for me. \$\endgroup\$
    – Andrew
    May 22, 2017 at 17:54
2
\$\begingroup\$

Chip, 179 bytes

 HGFEDCB
,\\///\/A
`--v~.
   |z^.
 ,\#xZ<
a^xx/'`.
 ,\#xZ~<
b^xx/' |
 ,\#xZ~<
c^xx/' |
 ,\#xZ~<
d^xx/' |
 ,\#xZ~<
e^xx/' |
 ,\#xZ~<
f^xx/' |
 ,\#xZ~'
g^x-/'HGFEDCB
S÷^---\\/\\\/A

(UTF8, so ÷ is \xc3\xb7)

Try it online!

The upper block with A-H and the slashes is detecting the semicolon character, and the similar lower block is detecting the hash. If other bogus characters needn't be handled, the whole thing would be somewhere around 133 bytes.

The middle block does the following:

Z's are the registers, one for each of the seven bits.

The half-adders # allow for incrementing by 1 in case of a semicolon. If not a semicolon, increment by 0.

If we get a hash, send the current register values to a-g, which outputs the desired character, and then reset the values to zero with the switches \.

If the registers are 0b1111110 (126), as determined by the right two columns, the next increment results in zero due to the switches /.

\$\endgroup\$
2
\$\begingroup\$

R, 66 bytes

intToUtf8(nchar(gsub("[^;]","",el(strsplit(scan(,""),"#"))))%%127)

Test:

> intToUtf8(nchar(gsub("[^;]","",el(strsplit(scan(,""),"#"))))%%127)
1: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;... <truncated>
2: 
Read 1 item
[1] "Hello, World!"
\$\endgroup\$
2
  • \$\begingroup\$ Unfortunately this approach seems to fail for trailing semicolons without a hash after them, which shouldn't be printed. \$\endgroup\$ Sep 27, 2020 at 17:14
  • \$\begingroup\$ Yes, you are right. \$\endgroup\$
    – djhurio
    Sep 28, 2020 at 16:53
2
\$\begingroup\$

Common Lisp, 89 bytes

(do((a 0))(())(case(read-char)(#\;(incf a))(#\#(princ(code-char(mod a 127)))(setf a 0))))

Try it online!.

This is an actual interpreter.

\$\endgroup\$
2
\$\begingroup\$

Cubix, 53 bytes

#..Wc.@n.!0i?\?;u...'u;.'\.U;.\w;;U.;).;'%o;c;.!;.U;

Contains one non-printable character, DEL, which is ASCII 127. If the accumulator is 0 and an ignored character is read in, an additional 0 is added to the stack so this runs the risk of stack overflow.

Try it online! and Watch it online

Cubified:

      # . .
      W c .
      @ n .
! 0 i ? \ ? ; u . . . '
u ; . ' \ . U ; . \ w ;
; U . ; ) . ; '   % o ;
      c ; .
      ! ; .
      U ; .
\$\endgroup\$
2
\$\begingroup\$

JavaScript (ES6), 91 85 bytes

ETH beat me to the punch with a variation on the Japt solution I was working on (that'll learn me to check the answers first!) so here's the JS solution I was using as the basis for it:

s=>s.split`#`.slice(0,-1).map(x=>String.fromCharCode(--x.split`;`.length%127)).join``

Try it

f=
s=>s.split`#`.slice(0,-1).map(x=>String.fromCharCode(--x.split`;`.length%127)).join``
oninput=_=>o.innerText=f(i.value)
o.innerText=f(i.value=";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#")
<input id=i><pre id=o>

\$\endgroup\$
6
  • \$\begingroup\$ You could use ~-x.split`;`.length%127 to get rid of the ||0 and the extra parens \$\endgroup\$ May 22, 2017 at 14:32
  • \$\begingroup\$ Good thinking, @ETHproductions; thanks. I was so focused on golfing down the Japt version, I forgot to golf this version before posting it. \$\endgroup\$
    – Shaggy
    May 22, 2017 at 14:38
  • \$\begingroup\$ You've done --x.split rather than ~-x.split. Is this intentional or a mistake? \$\endgroup\$ May 22, 2017 at 15:04
  • \$\begingroup\$ It was a misreading of what ETH posted without my glasses on, @RandomUser, but the result is the same, as you can see in the Snippet. \$\endgroup\$
    – Shaggy
    May 22, 2017 at 15:07
  • \$\begingroup\$ Actually I can't see in the Snippet (on mobile) \$\endgroup\$ May 22, 2017 at 15:13
2
\$\begingroup\$

SNOBOL4 (CSNOBOL4), 182 167 bytes

	S =INPUT
R	S NOTANY(';#') =	:S(R)
K	K =
T	S LEN(1) . C REM . S	:F(O)
	K =IDENT(C,';') K + 1	:S(T)
	&ALPHABET LEN(REMDR(K,127)) LEN(1) . A
	Y =Y A	:(K)
O	OUTPUT =Y
END

Try it online!

Due to size limitations in this implementation of SNOBOL, it can only read in lines of 1024 characters at a time, discarding the rest. So it only manages to print Hello, Worl. Ah well.

	S =INPUT				;*read input
R	S NOTANY(';#') =Y	:S(R)		;*recursively remove non ;# characters
K	K =0					;*counter
T	EQ(SIZE(S)) :S(O)			;*if string is empty, goto output
	S LEN(1) . C REM . S			;*set C to the first char, the REMainder to S
	K =IDENT(C,';') K + 1	:S(T)		;*if C is identical to ';', increment C and goto T
	&ALPHABET LEN(REMDR(K,127)) LEN(1) . A	;*get the K % 127th character, set it to A
	Y =Y A	:(K)				;*append A to Y
O	OUTPUT =Y				;*output Y
END
\$\endgroup\$
2
\$\begingroup\$

Haskell, 66 bytes

f s|(a,_:b)<-span(/='#')s=toEnum(mod(sum[1|';'<-a])127):f b|1<3=[]

Try it online!

  • f takes a string s as input and looks for the first # with (a,_:b)<-span(/='#')s, which splits s in the part a before the first # and b everything after.
  • sum[1|';'<-a] counts the number of ; in a which is converted into the corresponding character by toEnum after taking it modulo 127.
  • f b recursively processes the rest of the string.
  • The pattern match (a,_:b)<-span(/='#')s fails if no # exists anymore, in which case in the second pattern guard 1<3=[] the empty list is returned.
\$\endgroup\$
2
\$\begingroup\$

PowerShell, 67 65

-join$(switch("$input"|% t*y){';'{$a++}'#'{[char]($a%127);$a=0}})

Fairly straightforward with not many surprising twists.

  • 2018-09-06: Shorter way of converting the string to a character array.
\$\endgroup\$
2
  • \$\begingroup\$ Nice expression with switch. \$\endgroup\$
    – mazzy
    Sep 6, 2018 at 12:43
  • \$\begingroup\$ Maybe a bit late :) Down to 54 bytes by escaping ; and # instead of quoting them and using splatting to pass the command through: TIO \$\endgroup\$
    – Julian
    Nov 11, 2022 at 0:52
2
\$\begingroup\$

Shakespeare Programming Language, 447 439 404 bytes

,.Ajax,.Ford,.Act I:.Scene I:.[Exeunt][Enter Ajax and Ford]Ajax:Open mind.Ford:Am I as big as the sum ofa pig twice twice the sum ofa pig a big big big big cat?If soyou be the sum ofyou a cat.Be you worse the sum ofa pig twice the cube ofa big big cat?If notyou zero.Am I as big as the sum ofa cat twice the sum ofa cat a big big big big cat?If soSpeak thy.If soYou zero.Am I nicer zero?If soLet usAct I.

Try it online!

-35 bytes thanks to Joe King!

\$\endgroup\$
2
  • \$\begingroup\$ 404 bytes with proper termination \$\endgroup\$
    – Jo King
    Sep 10, 2018 at 0:51
  • \$\begingroup\$ Y'know, I should've thought about wrapping the accumulator manually. \$\endgroup\$ Sep 10, 2018 at 1:37
2
\$\begingroup\$

F# (.NET Core), 71 bytes

Seq.fold(fun a->function|';'->a+1|'#'->printf"%c"(a%127|>char);0|_->a)0

Try it online!

\$\endgroup\$
2

Your Answer

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

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