61
\$\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: 2d{ (unprintable characters here; should have 4 `\000` bytes between the `d` and the `{` and 3 after the `{`)
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\$
  • 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 '17 at 9:26
  • 5
    \$\begingroup\$ The second example makes me wonder about a program to encode a program to produce an output... recursive compilation! \$\endgroup\$ – frarugi87 May 22 '17 at 9:29
  • \$\begingroup\$ @Leo yes that's fine \$\endgroup\$ – caird coinheringaahing May 22 '17 at 14:46
  • 1
    \$\begingroup\$ @iamnotmaynard Semicolon Hash \$\endgroup\$ – caird coinheringaahing May 23 '17 at 15:09
  • 2
    \$\begingroup\$ Maybe Wink Hash would be easier to say \$\endgroup\$ – James Waldby - jwpat7 May 23 '17 at 17:42

105 Answers 105

0
\$\begingroup\$

Clojure, 65 bytes

(fn[c](map #(char(mod((frequencies %)\;)127))(re-seq #"[^#]+"c)))

Splits the code by '#', counts the number of ';', and turns the number (mod 127) into its ascii value

Try it online!

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

Swift, 117 bytes

func f(i:String){var a=0;for c in i{if c==";" {a+=1}else{print(Character(UnicodeScalar(a%127)!),terminator:"");a=0}}}

Expanded out:

func f(i: String) {
    var a = 0
    for c in i {
        if c==";" {
            a += 1
        } else {
            print(Character(UnicodeScalar(a%127)!),terminator:"")
            a=0
        }
    }
}

Run it online

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

Pascal (FPC), 134 133 122 bytes

var c:char;a:word;begin repeat read(c);if c='#'then begin write(chr(a mod 127));a:=0 end;if c=';'then Inc(a)until eof end.

Try it online!

Assumes non-empty input.

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

Haskell, 73 bytes

f[]a=""
f(c:s)a|c==';'=f s(a+1)|c=='#'=toEnum(a`mod`127):f s 0|0<1=f s a
\$\endgroup\$
  • 1
    \$\begingroup\$ It looks like you require f to be called with an additional argument, however the question only allows taking a string as argument. Therefore you need to add something like g x=f x 0, or by swapping the arguments just the anonymous function f 0: Try it online! \$\endgroup\$ – Laikoni Aug 11 '18 at 11:09
  • 1
    \$\begingroup\$ However you can save some bytes by replacing True with 0<1, moving f a[]="" to the last line and writing it as f a e=e and by replacing f by an infix operator. \$\endgroup\$ – Laikoni Aug 11 '18 at 11:13
0
\$\begingroup\$

Ruby -naF#, 34 bytes (30+4)

$F.map{|x|putc x.count ?;%127}

Try it online!

An alternative to manatwork's answer, with shorter code, but the same overall byte count with switches. Too bad, Ruby doesn't automatically assume -na when separator -F is specified.

\$\endgroup\$
  • \$\begingroup\$ meta discussion on flags -- you don't count them as part of your byte count, but this ends up being a different language than "Ruby"; it's "Ruby with naF flags" \$\endgroup\$ – Giuseppe Aug 14 '18 at 13:34
  • \$\begingroup\$ Yes, I'm aware of that meta, but this is an older challenge, and after all, the main point here is comparing different approaches in Ruby, rather than answering in a "new" language :) \$\endgroup\$ – Kirill L. Aug 14 '18 at 13:47
0
\$\begingroup\$

brainfuck, 201 bytes

+[>>,[>+>+<<-]>>>----[>+<----]>----[-<<->>]+<<[>>-<<[-]]>>[-<<<[-]<<+[->>+>+<<<]>>>>>--[<+>--]<[-<->]<[[-]<[->>+<<]>][-]<[-]>>[-<<<<+>>>>]>]<<<[>--[>--<+++++++]>-[<+>-]<[-<->]<[[-]-]+[[-]<<.[-]>>]]<<<]

Try it online! As a note, this will take 60 seconds to finish because the program will never halt, so it will stop after the Tio 60 second timeout.

How it works

This works differently than the given algorithm. Instead of using mod it just wraps to 0 after counting 127 semicolons.

+[                              'while true
    >>,                         'read input
    [>+>+<<-]                   
    >>>----[>+<----]>----       
    [-<<->>]+<<[>>-<<[-]]>>     'if(input == ';')
    [                       
        -<<<[-]<<+              'increment counter 
        [->>+>+<<<]
        >>>>>--[<+>--]<
        [-<->]  
        <[                      'if(counter == 127) counter = 0
            [-]<[->>+<<]>
        ]
        [-]<[-]                 
        >>[-<<<<+>>>>]>
    ]
    <<<[                        'if(input != 59)
        >--[>--<+++++++]>-      
        [<+>-]          
        <[-<->]     
        <[                      'if(input == '#')
            [-]-                
        ]
        +[                      
            [-]                 
            <<.[-]>>            'print counter as ascii and clear tape
        ]
    ]
    <<<         
]
\$\endgroup\$
0
\$\begingroup\$

Forth (gforth), 77 bytes

: f 0 tuck do over i + c@ '# - ?dup if 24 = - else 127 mod emit 0 then loop ;

Try it online!

Code Explanation

: f            \ start a new word definition
  0 tuck       \ put 0 on the top of the stack and stick a copy behind the second stack item
  do           \ begin a counted loop from 0 to string length - 1
    over i +   \ get the address of the next character
    c@ '# -    \ get the next character's ascii value and subtract ascii # (35)
    ?dup       \ if result is not 0, duplicate
    if         \ if result is true (not 0)
      24 = -   \ check if result = 24, and subtract -1 from accumulator if it is (0 otherwise)
    else       \ else (if result was equal to 35)
      127 mod  \ get accumulator mod 127
      emit 0   \ output accumulator and replace with 0
    then       \ end if
  loop         \ end loop
;              \ end word definition
\$\endgroup\$
0
\$\begingroup\$

Powershell, 67 bytes

See also Joey's answer

-join($args-split'#|[^#]*$'|%{[char]((($_-split';').Count-1)%127)})

Test script:

$f = {

    -join($args-split'#|[^#]*$'|%{[char]((($_-split';').Count-1)%127)})

}

$c00 = [char]0x0000
$c23 = [char]0x0017

@(
    ,($c00,'#')
    ,('',';;;;;;')
    ,("2$($c23)d$c00$c00$c00$c00{$c00$c00$($c00)",';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;hafh;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;f;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;###ffh#h#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ffea;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#au###h;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;h;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;o')
    ,('Hello, World!', ';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#')
    ,(';#', ';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#')
    ,('!', ';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#')
) | %{
    $e,$s = $_
    $r = &$f $s
    "$($e-eq$r): $r"
}

Output:

True:
True:
True: 2d    {
True: Hello, World!
True: ;#
True: !

Explanation:

-join(                                   #
    $args-split'#|[^#]*$'|%{             # extract strings tailed by # symbol from arguments
        [char](                          #
            (($_-split';').Count-1)%127  # count ; symbol in each extracted string, get remain by 127
        )                                # convert int to char
    }                                    #
)                                        # join all chars
\$\endgroup\$
0
\$\begingroup\$

VBA (Excel) 103 Bytes

Function a(b)
  For Each c In Split(b,"#")
    a=a &Chr((Len(c)-Len(Replace(c,";","")))Mod 127)
  Next
End Function

Un-golfed With Comments:

Function fromSemiHash(myString)    'SemiHash is how I think it should be pronounced :D
    'For each string in myString split by hashes
    For Each littleString In Split(myString,"#")
        'Append the char from((the length of everything minus length of everything but ;'s) mod 127)
        toSemiHash = toSemiHash & Chr((Len(littleString) - Len( Replace( littleString , ";" ,""))) Mod 127)
    Next littleString
End Function
\$\endgroup\$
0
\$\begingroup\$

PHP, 84 bytes

First attempt 144 133 bytes

I was able to remove 11 by using all ternary conditions, this required adding some ( ) to cement in the operation order. PHP has a weird thing with that.

function f($s,$i,$c,$r){echo''==($a=$s[$i])?$r:('#'==$a?f($s,++$i,0,$r.=chr($c%127)):(';'==$a?f($s,++$i,++$c,$r):f($s,++$i,$c,$r)));}

Test it like this:

error_reporting(0);

$strings =[';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#',
    ';;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#',
    ';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;hafh;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;f;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;###ffh#h#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ffea;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#au###h;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;h;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;o',
    ';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#'
];

foreach($strings as $s){
    f($s,0,0,''); echo "\n";
}

function f($s,$i,$c,$r){echo''==($a=$s[$i])?$r:('#'==$a?f($s,++$i,0,$r.=chr($c%127)):(';'==$a?f($s,++$i,++$c,$r):f($s,++$i,$c,$r)));}

Output

Hello, World!
;#
2d����{���
!

Sandbox

Notes/Explanation

This is a recursive function. Most of the space savings comes from using ternary conditionals,short variable names and grouping some of the setters into the aforementioned conditions. It takes 4 input arguments and sets 1 local variable:

Arguments/Variables

$s - the ;# string to parse.

$i - the iterator, to keep track of the current position in the string, starts at 0.

$c - the register keeps the count of ; prior to #, starts at 0.

$r - the results, the output of the parser, starts as an empty string.

Expanded version:

function f($s,$i,$c,$r){
    if( '' == ( $a = $s[$i] ) ){
         echo $r;
    }else{
        if( '#' == $a ){
            f( $s, ++$i, 0, $r.=chr( $c % 127 ));
        }else{
            if( ';' == $a ){
                f( $s, ++$i, ++$c, $r);
            }else{
                f( $s, ++$i, $c, $r);
            }
        }
    }
}

Update attempt 2, 77 84 Bytes (PHP < 7)

Had to add aomw to fix a bug with it having an empty element in the array at the end.

 function f($s){foreach(split('#',$s)as$a)echo!$a?'':chr(substr_count($a,';')%127);}

You can change split to explode to make it compatible with PHP7, but add 2 bytes. Test it the same as above, produces the same output.

Sandbox2

Expanded version:

function f($s){
     $array = split('#',$s)
     foreach($array as $a){
        if(!$a){
           echo '';
        }else{
           $count = substr_count($a,';');
           echo chr($count%127);
        }
     }
}

It's shorter, simpler, and should be faster. The key to this one was substr_count which I already know about but didn't think of right away, as I was a bit rushed for time on the first attempt. After thinking about it some, I came up with this and almost cut it in half. Not bad!

Basically it splits it on the # and then counts the occurrences of ; in each array item and outputs the character that generates.

Cheers!

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

Kotlin, 77 bytes

{Regex(";*#").findAll(it).fold(""){a,v->a+((v.value.length-1)%127).toChar()}}

Try it online!

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

Whitespace, 119 bytes

[S S S N
_Push_0][N
S S N
_Create_Label_LOOP][S N
S _Duplicate_top][S N
S _Duplicate_top][T N
T   S _Read_STDIN_as_character][T   T   T   _Retrieve][S N
S _Duplicate_input][S S S T S S S T T   N
_Push_35][T S S T   _Subtract][N
T   S S N
_If_0_Jump_to_Label_PRINT_CHAR][S S S T T   T   S T T   N
_Push_59][T S S T   _Subtract][N
T   S T N
_If_0_Jump_to_Label_INCREASE][N
S N
N
_Jump_to_Label_LOOP][N
S S S N
_Create_Label_PRINT_CHAR][S N
N
_Discard_top][S S S T   T   T   T   T   T   T   N
_Push_127][T    S T T   _Modulo][T  N
S S _Print_as_character][S S S N
_Push_0][N
S N
N
_Jump_to_Label_LOOP][N
S S T   N
_Create_Label_INCREASE][S S S T N
_Push_1][T  S S S _Add][N
S N
N
_Jump_to_Label_LOOP]

Letters S (space), T (tab), and N (new-line) added as highlighting only.
[..._some_action] added as explanation only.

Try it online (with raw spaces, tabs and new-lines only).

Pseudo-code:

Integer i = 0
Label LOOP:
  Character c = STDIN as character
  If(c == '#'):
    Jump to Label PRINT_CHAR
  If(c == ';'):
    Jump to Label INCREASE
  Jump to Label LOOP

Label PRINT_CHAR:
  i = i modulo-127
  Print i as character to STDOUT
  i = 0
  Jump to Label LOOP

Label INCREASE:
  i = i + 1
  Jump to Label LOOP
\$\endgroup\$
0
\$\begingroup\$

Stax, 12 bytes

î╟°♪ƒ▌○«*G<╠

Run and debug it

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

JavaScript (Node.js), 82 bytes

s=>[...s].map(e=>e==";"?++i:e=="#"?z+=String.fromCharCode(i,i=0)[0]:0,i=0,z="")&&z

Try it online!

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

Gaia, 17 bytes

@'#/⟨';Kl127%cp⟩¦

Try it online!

@			| read input as string
 '#/			| Split on '#'
                 ¦	| for each element:
     ⟨';K		| Keep only ';'
         l		| take the length
          127%		| modulo 127
              c		| convert to character
               p⟩	| and print
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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