36
\$\begingroup\$

Related to: Make a ;# interpreter

In the above linked challenge the task was to create an interpreter for the esoteric language ;#.

The ;# language

The language has exactly two commands: ; and # (all other characters are ignored by the interpreter):

;: Increment the accumulator

#: Modulo the accumulator by 127, print the corresponding ASCII character and reset the accumulator to 0.

Challenge

Because I am lazy but still want to test some more testcases, I need a program or function which converts plain text to ;# code.

Input

The input is a string, taken either as argument or through stdin. It will only contain printable ASCII characters and newlines.

Output

The output is the generated ;# program by returning, or printing to stdout. As long as the program is valid, it may contain excess characters other than # and ; as all other characters are ignored.

Examples

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

Input: ABC
Output: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#

Input: ;#
Output: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#

Leaderboard

var QUESTION_ID=122139,OVERRIDE_USER=73772;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}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\$
  • 9
    \$\begingroup\$ Brilliant! Glad to see ;# is getting attention! \$\endgroup\$ – caird coinheringaahing May 23 '17 at 6:41
  • 1
    \$\begingroup\$ You can test your output here, as ;#+ is a superset of ;#. \$\endgroup\$ – Adám May 23 '17 at 7:02
  • 3
    \$\begingroup\$ Can the output contain additional character? ;# ignores all other characters, so the generated program would still work. \$\endgroup\$ – Dennis May 23 '17 at 7:23
  • 2
    \$\begingroup\$ @Benoît: The modulus is irrelevant when generating code, since it's always easier to generate code that uses the minimum number of ;. Secondly, 127 is correct, as stated in the linked question that contains the specification of the ;# language. \$\endgroup\$ – Joey May 24 '17 at 7:16
  • 2
    \$\begingroup\$ This isn't really transpiling. "Generate #; code" is a better title. I'm going to change it to that. \$\endgroup\$ – Mego May 24 '17 at 20:24

73 Answers 73

0
\$\begingroup\$

J, 23 Bytes

Nothing special.

,([:,&'#'#&';')"0 u:inv

Explanation:

,([:,&'#'#&';')"0 u:inv
                  u:inv   | Convert string to code points
 (            )"0         | For each item:
  [:,&'#'#&';'            | Repeat ';' n times and append #
,                         | Ravel the resulting character array

Note that the result contains lots of whitespace, since arrays have to be rectangular.

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

Java 10, 63 bytes

c->{var s="";for(var d:c){for(;d-->0;)s+=";";s+="#";}return s;}

Try it online here.

Ungolfed version:

c -> { // lambda taking a char[] as argument and returning a String
    var s = ""; // the output String
    for(var d : c) { // iterate over all the input chars
        for(; d-- > 0 ;) // as many times as the ASCII value of the current char
            s += ";";    // append ";" to the program to compute the character
        s += "#"; // append "#" to output the character
    }
    return s; // return the finished program
}
\$\endgroup\$
0
\$\begingroup\$

Ahead, 13 bytes

~W$:ki@j";#"~

Try it online!

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

Noether, 21 bytes

I~sL(";"si/B*P"#"P!i)

Try it online!

Explanation:

I~s                   - Get input and store in the variable s
   L(               ) - Loop until the top of stack equals the length of s
     ";"              - Push the string ";"
        si/           - Return the character of string s at position i
           B          - Return the ASCII code of the character
            *P        - Multiply ";" by the ASCII code and print
              "#"P    - Push the string "#" and print
                  !i  - Increment i
\$\endgroup\$
0
\$\begingroup\$

Pascal (FPC), 94 bytes

var c:char;i:word;begin repeat read(c);for i:=1to ord(c)do write(';');write('#')until eof end.

Try it online!

Assumes non-empty input.

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

VBA (Excel) 82 Bytes

I really think this challenge should've been scored in the length of your program after it is converted into ;#. I would score 6769 characters (including newlines)

Function d(e)
  For i=1To Len(e)
    d=d &String(Asc(Mid(e,i,1)),";") &"#"
  Next
End Function

Note: the leading spaces aren't needed, just make it more read-able, not that I should be worried about that... just look at the output from this thing!!!

Un-golfed With Comments:

Function toSemiHash(translate)
    'For 1 to the length of the string
    For i = 1 To Len(translate)
        'Append a semicolon the char-code number of times along with a hash
        fromSemiHash = fromSemiHash & String(Asc(Mid(translate, i, 1)), ";") & "#"
    Next
End Function
\$\endgroup\$
0
\$\begingroup\$

PHP, 75 Bytes

This shorter then the parser I wrote for it.

Generator

function g($s){foreach(str_split($s)as$a)echo str_repeat(';',ord($a)).'#';}

You can test it like this:

$strings = [
    'Hello, World!',
    ';#',
    '!'
];

foreach($strings as $s){
    g($s); echo "\n\n";
}

function g($s){foreach(str_split($s)as$a){echo str_repeat(';',ord($a)).'#';}}

Parser (second attempt)

The one from my first attempt should work fine as well. This one is shorter, so well just use it to verify that the generator works correctly.

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

You can test both like this:

//turn of warning message or set in PHP.ini
error_reporting(0);
$s = "Hello, World!";

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

//output buffer the generator
ob_start();
    g($s);
$s=ob_get_clean();
f($s);

Output

 Hello, World!

Test both of them

A few things to note:

  • Because neither one return information, we can capture the output by using output buffering.
    • We could also put it a file, use $argv[1] for input, remove the function calls, add the shebang #!/bin/env php and run it from the terminal. Which would cut it down to around something like 65. Then we could just pipe that into the other script. So :-P
  • Because the parser is old, we have to use PHP < 7 for it. Don't worry our dev team is currently working hard on a patch to make it compatible with PHP7,(just change split to explode). They should have it done sometime in the spring after they quite code golfing and get back to work!

Lastly

My first attempt at a parser was recursive, so I thought it only fitting I make a generator that is also recursive. Unfortunately as with the first one, it's longer 89 bytes.

 function g($s,$i,$r){echo''==($a=$s[$i])?$r:g($s,++$i,$r.=str_repeat(';',ord($a)).'#');}

You can test it with the same code above:

error_reporting(0);
$s = "Hello, World!";

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

//recursive
function h($s,$i,$r){echo''==($a=$s[$i])?$r:h($s,++$i,$r.=str_repeat(';',ord($a)).'#');}

//output buffer the generator
ob_start();
   // g($s);
   h($s,0,'');
$s=ob_get_clean();
f($s);

Recursive Generator

Things that didn't make the cut

  //parser 98 bytes, strtok + do while
  function p($s){$f=strtok;$a=$f($s,'#');do{echo chr(substr_count($a,';')%127);}while($a=$f('#'));}
\$\endgroup\$
0
\$\begingroup\$

brainfuck, 48 bytes

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

Try it online!

How it works

+++++++[>+++++>++++++++<<-]>>+++>       'write ; and # onto the tape
,[                                      'read input as ascii values and loop
    [-<.>]                              'decrement input 1 and write ; then repeat until 0
    <<.>>                               'write #
,]                                      'read input as ascii values and loop
\$\endgroup\$
0
\$\begingroup\$

J, 23 bytes

[:,[:('#',~#&';')"+3&u:

Try it online!

[:,(35,~#&59)"+&.(3&u:)

Try it online!

Posting since the existing J answer is incorrect.

How it works

[:,[:('#',~#&';')"+3&u:
                   3&u:  Convert to ASCII value
     (          )"+      Apply to each number...
           #&';'           Convert to that many ';'s
      '#',~                and add '#' to the right
   [:                    Treat the above as monadic fork
  ,                      Ravel; flatten the multidimensional array
[:                       Treat the above as monadic fork

[:,(35,~#&59)"+&.(3&u:)
              f&.g       Apply g, f, then inverse of g...
                 (3&u:)    g: convert to ASCII value
   (        )"+            f: apply to each number...
        #&59                 convert to that many 59's (charcode of ';')
    35,~                     and add 35 to the right (charcode of '#')
[:,                      Ravel the result

Both use the "+ trick to avoid numeric literal problem.

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

Whitespace, 82 bytes

[N
S S N
_Create_Label_OUTER_LOOP][S S S N
_Push_0][S N
S _Duplicate_0][T   N
T   S _Read_STDIN_as_character][T   T   T   _Retrieve][N
S S S N
_Create_Label_INNER_LOOP][S N
S _Duplicate][N
T   S T N
_If_0_Jump_to_Label_HASTAG][S S S T N
_Push_1][T  S S T   _Subtract][S S S T  T   T   S T T   N
_Push_59_;][T   N
S S _Print_as_character][N
S N
S N
_Jump_to_Label_INNER_LOOP][N
S S T   N
_Create_Label_HASHTAG][S S S T  S S S T T   N
_Push_35_#][T   N
S S _Print_as_character][N
S N
N
_Jump_to_Label_OUTER_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).

Explanation in pseudo-code:

Start OUTER_LOOP:
  Integer c = read character from STDIN
  Start INNER_LOOP:
    If(c == 0):
      Jump to function HASHTAG
    c = c - 1
    Print ";" to STDOUT
    Go to next iteration of INNER_LOOP

function HASHTAG:
  Print "#" to STDOUT
  Go to next iteration of OUTER_LOOP

Note: All characters read from STDIN in Whitespace are automatically stored in the heap as their code-point values.

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

Brain-Flak, 94 bytes

{{({}[()])<>((((((()()()){})){}{}())()){}{})<>}{}<>(((((()()()){}())){}){}{})<>}<>{({}<>)<>}<>

Try it online!

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

Backhand, 27 bytes

}o" i# :" }]@_!}|{:" [; o".

Try it online!

I'm sure a shorter solution exists, given this has 6 no-ops. This prints a null byte to begin with

Explanation:

}o       Print a null byte
    i  :  }]  ! |{     Get a character of input and check if it is EOF
                   "  ; o"   If it is not, print a ;
               }| :  [       Decrement the counter and check again
                   Once the counter hits zero exit the loop
            @_    If the value was -1 (EOF) exit
           ]  !   Otherwise execute some garbage
 o" i#  "         Print a # and get the next character of input
\$\endgroup\$
-1
\$\begingroup\$

C, 51 bytes

c;main(){for(;c||~(c=getchar());puts("#;"+!!--c));}

Outputs lots of extra newlines, and an extra ; at the end, but neither of those affect the output of the ;# program, so it should be fine.

Using puts was suggested by ais523 in a comment: Make a ;# transpiler.

~(x) is a shorter way to write (x)!=-1.

"#;"+!!--c is a pointer arithmetic equivalent of --c?";":"#;".

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