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

Leaderboard

Here is a Stack Snippet to generate both a regular leaderboard and an overview of winners by language.

/* Configuration */

var QUESTION_ID = 121921; // Obtain this from the url
// It will be like https://XYZ.stackexchange.com/questions/QUESTION_ID/... on any question page
var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";
var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk";
var OVERRIDE_USER = 48934; // This should be the user ID of the challenge author.

/* App */

var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page;

function answersUrl(index) {
  return "https://api.stackexchange.com/2.2/questions/" +  QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER;
}

function commentUrl(index, answers) {
  return "https://api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER;
}

function getAnswers() {
  jQuery.ajax({
    url: answersUrl(answer_page++),
    method: "get",
    dataType: "jsonp",
    crossDomain: true,
    success: function (data) {
      answers.push.apply(answers, data.items);
      answers_hash = [];
      answer_ids = [];
      data.items.forEach(function(a) {
        a.comments = [];
        var id = +a.share_link.match(/\d+/);
        answer_ids.push(id);
        answers_hash[id] = a;
      });
      if (!data.has_more) more_answers = false;
      comment_page = 1;
      getComments();
    }
  });
}

function getComments() {
  jQuery.ajax({
    url: commentUrl(comment_page++, answer_ids),
    method: "get",
    dataType: "jsonp",
    crossDomain: true,
    success: function (data) {
      data.items.forEach(function(c) {
        if (c.owner.user_id === OVERRIDE_USER)
          answers_hash[c.post_id].comments.push(c);
      });
      if (data.has_more) getComments();
      else if (more_answers) getAnswers();
      else process();
    }
  });  
}

getAnswers();

var SCORE_REG = /<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/;

var OVERRIDE_REG = /^Override\s*header:\s*/i;

function getAuthorName(a) {
  return a.owner.display_name;
}

function process() {
  var valid = [];
  
  answers.forEach(function(a) {
    var body = a.body;
    a.comments.forEach(function(c) {
      if(OVERRIDE_REG.test(c.body))
        body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>';
    });
    
    var match = body.match(SCORE_REG);
    if (match)
      valid.push({
        user: getAuthorName(a),
        size: +match[2],
        language: match[1],
        link: a.share_link,
      });
    
  });
  
  valid.sort(function (a, b) {
    var aB = a.size,
        bB = b.size;
    return aB - bB
  });

  var languages = {};
  var place = 1;
  var lastSize = null;
  var lastPlace = 1;
  valid.forEach(function (a) {
    if (a.size != lastSize)
      lastPlace = place;
    lastSize = a.size;
    ++place;
    
    var answer = jQuery("#answer-template").html();
    answer = answer.replace("{{PLACE}}", lastPlace + ".")
                   .replace("{{NAME}}", a.user)
                   .replace("{{LANGUAGE}}", a.language)
                   .replace("{{SIZE}}", a.size)
                   .replace("{{LINK}}", a.link);
    answer = jQuery(answer);
    jQuery("#answers").append(answer);

    var lang = a.language;
    if (/<a/.test(lang)) lang = jQuery(lang).text();
    
    languages[lang] = languages[lang] || {lang: a.language, user: a.user, size: a.size, link: a.link};
  });

  var langs = [];
  for (var lang in languages)
    if (languages.hasOwnProperty(lang))
      langs.push(languages[lang]);

  langs.sort(function (a, b) {
    if (a.lang > b.lang) return 1;
    if (a.lang < b.lang) return -1;
    return 0;
  });

  for (var i = 0; i < langs.length; ++i)
  {
    var language = jQuery("#language-template").html();
    var lang = langs[i];
    language = language.replace("{{LANGUAGE}}", lang.lang)
                       .replace("{{NAME}}", lang.user)
                       .replace("{{SIZE}}", lang.size)
                       .replace("{{LINK}}", lang.link);
    language = jQuery(language);
    jQuery("#languages").append(language);
  }

}
body { text-align: left !important}

#answer-list {
  padding: 10px;
  width: 290px;
  float: left;
}

#language-list {
  padding: 10px;
  width: 290px;
  float: left;
}

table thead {
  font-weight: bold;
}

table td {
  padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b">
<div id="answer-list">
  <h2>Leaderboard</h2>
  <table class="answer-list">
    <thead>
      <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr>
    </thead>
    <tbody id="answers">

    </tbody>
  </table>
</div>
<div id="language-list">
  <h2>Winners by Language</h2>
  <table class="language-list">
    <thead>
      <tr><td>Language</td><td>User</td><td>Score</td></tr>
    </thead>
    <tbody id="languages">

    </tbody>
  </table>
</div>
<table style="display: none">
  <tbody id="answer-template">
    <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
  </tbody>
</table>
<table style="display: none">
  <tbody id="language-template">
    <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
  </tbody>
</table>

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

109 Answers 109

0
\$\begingroup\$

MaybeLater, 99 bytes

s=read()wheni is*{if((S=s[i])!=u){if(S==";")a++if(S=="#"){writechra%127a=0}when0secondpass i++}}i=0

Ungolfed & Commented

input_string=read()                                 // Read the input from STDIN
when index is *{                                    // When index updates...
    if((this_char=input_string[index])!=undefined){ // If it's not undefined (So we've iterated onto another entry)...
        if(this_char==";")                          // If this character is a ;
            accumulator++                           // Increment the accumulator (Which defaults to 0)
        if(this_char=="#"){                         // If it's # however
            write(chr(accumulator%127))             // Write the character value of the accumlator % 127, and reset the accumulator.
            accumulator=0
        }
        when 0 second pass                          // When 0 seconds pass, to prevent stack overflow, increment the index. Which loops.
            index++
    }
}
                                                    // Start off the index.
index = 0

Try it online!

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

Pyth, 18 bytes

My misunderstanding works anyways... hmm?

Jcw"#"VtlJpC/@JN";

Explanation:

Jcw"#"        Split the input by "#" and store it in J
VtlJ          For the length of J - 1...
 p            Print without newline...
  C/@JN";       Character from charcode (length of ';'s at the Nth position in J)

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Doesn't work. You need this. (Does Pyth have a constant tho?) \$\endgroup\$ – a'_' yesterday
0
\$\begingroup\$

Clojure, 69 bytes

#(reduce(fn[a c](case c\;(inc a)\#(do(print(char(mod a 127)))0)a))0%)

A simple reduction over the code. Alters the accumulator accordingly for each character that's read.

(defn interpret [code]
  (reduce (fn [acc chr]
            (case chr
              \; (inc acc)
              \# (do (print (char (mod acc 127))) ; Print the char,
                     0) ; then reset the accumulator
              acc)) ; An ignored character; don't do anything
          0 ; The initial accumulator
          code))
\$\endgroup\$
0
\$\begingroup\$

Kotlin, 105 bytes

Submission

fun d(l:String):String=l.split("#").map{(it.length%127).toChar()}.joinToString("").removeSuffix("\u0000")

TryItOnline

Link

Explanation

  • It splits the string into ; chunks
  • Then it changes them into characters
  • It joins them into a string
  • Then it removes the null byte from the end
\$\endgroup\$
0
\$\begingroup\$

Ahead, 26 bytes

r  o%721$<
~>j@i:'#=n';=+~

Try it online!

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

Noether, 42 bytes

I~sL(si/~c{";"=}{!a}c{"#"=}{a127MBP0~a}!i)

Try it online!

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

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), 86 bytes

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

Try it online!

\$\endgroup\$
  • \$\begingroup\$ This is not applying the modulo by 127. \$\endgroup\$ – Deadcode yesterday
  • \$\begingroup\$ Fixed -- thanks! \$\endgroup\$ – ggorlen 20 hours ago

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.