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

115 Answers 115

1 2 3
4
0
\$\begingroup\$

Fourier, 32 bytes

$(I~Q{59}{&A}Q{35}{A%127a0~A}&i)

Try it on FourIDE!

Enter the program between quotation marks.

Explanation Pseudocode

While i != Input length
    Q = Pop character off start of string and get char ASCII code
    If Q = 59 Then
        Increment A
    End If
    If Q = 35 Then
        Convert A mod 127 to character and Print
        A = 0
    End If
    Increment i
End While
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Actually, 20 bytes

'#@s⌠';@c7╙D@%c⌡MdXΣ

Try it online!

Explanation:

'#@s⌠';@c7╙D@%c⌡MdXΣ
'#@s                  split on "#"
    ⌠';@c7╙D@%c⌡M     for each chunk:
     ';@c               count occurrences of ";"
         7╙D@%          mod by 127 (2**7-1)
              c         convert to ASCII char
                 dX   discard last item
                   Σ  concatenate
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Add $p=";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#"; to actually enjoy this tasty script. ($p is the input variable)

PowerShell, 98 bytes

[char[]]$p|%{if($_-eq';'){$o++}elseif($_-eq'#'){Write-Host -NoNewLine ([char]($o%127));[int]$o=0}}

Try it online!

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

JavaScript (ES6), 71 Bytes

p=>([...p].map(v=>v==";"?i++:b+=String.fromCharCode(i,i=0),i=0,b=""),b)

This can probably be golfed, but I think the concept passing extra arguments to functions is one of the reasons why JavaScript is one of the more interesting languages to golf in.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ This seems to insert spaces between each character of the output nor does it look like it ignores invalid characters. \$\endgroup\$ – Shaggy May 29 '17 at 12:05
0
\$\begingroup\$

java, 86 95 bytes

this is a lambda expression assignable to a Consumer<String>

s->{for(String t:s.split("#|[^#]*\\Z"))System.out.print((char)(t.split(";",-1).length-1%127));}

Explanation:

  • split the input using # as the delimiter and ignore everything after the last match
  • for each substring, count the number of ;'s and output the count as a char
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Ly, 44 bytes

0<i[[";"=[pp>1+<2$]p"#"=[pp>(127)%o0<2$]]i];

Try it online!

This submission does not work with the latest version of the Ly interpreter.
A version that does work, for 43 bytes:

ir[[";"=[pp>1+<2$]p"#"=[pp>(127)%o<2$]pp]];

Try it online!

| improve this answer | |
\$\endgroup\$
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!

| improve this answer | |
\$\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!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Doesn't work. You need this. (Does Pyth have a constant tho?) \$\endgroup\$ – user85052 Jan 23 at 10:56
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))
| improve this answer | |
\$\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
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Ahead, 26 bytes

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

Try it online!

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Noether, 42 bytes

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

Try it online!

| improve this answer | |
\$\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!

| improve this answer | |
\$\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

| improve this answer | |
\$\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.

| improve this answer | |
\$\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
| improve this answer | |
\$\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
        ]
    ]
    <<<         
]
| improve this answer | |
\$\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
| improve this answer | |
\$\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
| improve this answer | |
\$\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
| improve this answer | |
\$\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!

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Kotlin, 77 bytes

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

Try it online!

| improve this answer | |
\$\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
| improve this answer | |
\$\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!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ This is not applying the modulo by 127. \$\endgroup\$ – Deadcode Jan 23 at 9:26
  • \$\begingroup\$ Fixed -- thanks! \$\endgroup\$ – ggorlen Jan 23 at 15:01
0
\$\begingroup\$

Ral, 136 bytes

,:1-11:+:+:+:++:+:+:+?:11:+:+:+:+-:+:+1-+:0?10*+0=1+0?10*-0=111:+:+:+:++:++-:0?0-0?0*:1:+:+:+:+:+:+:+1-+:1+1111:+:++:+:++:+:++?1=.00=10?

Try it online!

Somewhat clarified

Code                         Stack after       Description
,:1-11:+:+:+:++:+:+:+?       n                 Input a character (n) and jump to the end if zero
:11:+:+:+:+-:+:+1-+:0?       n, n-59           Jump to the start if n>59
10*+0=                       n, n-59           Add 1 to the accumulator
1+0?                         n                 Jump to the start if n>58
10*-0=                       n                 Remove 1 from the accumulator
111:+:+:+:++:++-:0?          35-n              Jump to the start if n<35
0-0?                                           Jump to the start if n>35
0*                           acc               Load the accumulator from memory
:1:+:+:+:+:+:+:+1-+          acc, acc-127          Remove 127 from the accumulator
:1+1111:+:++:+:++:+:++?      acc, acc-127          Continue the loop (with acc=acc-127) if acc≥127
1=.                                            Print the accumulator
00=                                            Clear the accumulator
10?                                            Jump to the start
| improve this answer | |
\$\endgroup\$
1 2 3
4

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.