Create a function or program that takes a number as input, and outputs a string where ASCII-code points for the lower and upper case alphabet are substituted by their character equivalents.

  • The upper case alphabet use the code points: 65-90
  • The lower case alphabet use the code points: 97-122

If any adjacent digits in the input equals the code point of a letter, then that letter shall replace the digits in the output string.


  • The input will be a positive integer with between 1 and 99 digits
  • You can assume only valid input is given
  • You start substituting at the beginning of the integer (976 -> a6, not 9L)
  • The input can be on any suitable format (string representation is OK)
  • The output can be on any suitable format
  • Standard rules apply







Shortest code in bytes win!


The Stack Snippet at the bottom of this post generates the catalog from the answers a) as a list of shortest solution per language and b) as an overall leaderboard.

To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:

## Language Name, N bytes

where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:

## Ruby, <s>104</s> <s>101</s> 96 bytes

var QUESTION_ID=71735,OVERRIDE_USER=31516;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>

  • 2
    \$\begingroup\$ "The input will be a positive integer with between 1 and 99 digits" In just about any programming language I know, it'll be a string with between 1 and 99 digits, as even a 64-bit int only holds up to 19 decimal digits... \$\endgroup\$ Feb 11 '16 at 17:41
  • 3
    \$\begingroup\$ @T.J.Crowder I assume he meant integer in the mathematical sense, not the data type. \$\endgroup\$
    – Dennis
    Feb 11 '16 at 17:59
  • 1
    \$\begingroup\$ @T.J.Crowder valid point :-) Although, if I'm not mistaken, 1e99 is technically still an integer. long int isn't enough, you need super long int. \$\endgroup\$ Feb 11 '16 at 18:04
  • 2
    \$\begingroup\$ @StewieGriffin: Hah! :-) I'm sure there's a language somewhere with such a thing. \$\endgroup\$ Feb 11 '16 at 18:05

10 Answers 10


Perl, 39 38 bytes

(1 byte added for the -p flag.)

s/                           /          replace...
  @{[                      ]}           this string, treated as a regex:
     join"|",65..90,97..122             65|66|67|68|...|121|122
                                   /ge  ...with this string, eval()'d:
                                 $&     the entirety of the last match
                              chr       convert to char from ASCII code

Right Tool for the Job™.

The explanation is outdated after one small optimization (thanks dev-null!) that makes it a single byte shorter (but a bit less elegant): the $" variable represents what to join on when interpolating an arrray into a string, so setting $"="|" removes the need for join.


llama@llama:~$ perl -pe '$"="|";s/@{[65..90,97..122]}/chr$&/ge' 
  • \$\begingroup\$ I guess you can save a single byte by setting $"="|" instead of join? \$\endgroup\$ Feb 11 '16 at 23:09
  • \$\begingroup\$ eg. $"="|";s/@{[65..90,97..122]}/chr$&/ge \$\endgroup\$ Feb 11 '16 at 23:17
  • \$\begingroup\$ @dev-null That does work, thanks! \$\endgroup\$
    – Doorknob
    Feb 12 '16 at 14:24

Javascript, 80 bytes


See regex in action here: https://regex101.com/r/iX8bJ2/1


document.body.innerHTML = '<pre>' +
    "f('1234567')\n" + f('1234567') + '\n\n' +
    "f('3456789')\n" + f('3456789') + '\n\n' +
    "f('9865432')\n" + f('9865432') + '\n\n' +
    "f('6566676869707172737475767778798081828384858687888990')\n" + f('6566676869707172737475767778798081828384858687888990') + '\n\n' +
    "f('6711110010100071111108102')\n" + f('6711110010100071111108102') +

Just for curiosity, one thing I learned here:

I can't change x=>String.fromCharCode(x) to String.fromCharCode because ...


CJam, 22 bytes


Try it online!


Simply replacing all occurrences of digit groups with the corresponding letters (in whatever order we may choose) will fail to comply with the left-to-right rule.

Instead, we can generate all prefixes of the input string, and attempt to make all possible substitutions while we're generating them. Since no code point is contained in another code point, the order of these attempts is not important.

For example:


6     -> 6
67    -> C
 C4   -> C4
 C46  -> C46
 C467 -> C4B


How it works

q                       Read all input from STDIN.
 {                  }*  Fold; push the first character, and for each subsequent
                        character, push it and do the following:
  +                       Append the character to the string on the stack.
   '[,_el^                Push the string of all ASCII letters.
                          See: http://codegolf.stackexchange.com/a/54348
          {       }/      For each ASCII letter:
           _                Push a copy of the letter.
            i               Convert to integer, i.e., compute its code point.
             s              Cast to string.
              @\            Rotate and swap.
                /           Split the modified input characters at occurrences (at
                            most one) of the string repr. of the code point.
                 *          Join, separating by the corresponding letter.

PHP, 110 102 101 68 67 bytes

Pretty hard challenge. This is the best I could come up with. This is a completely new version.


Run like this:

php -r 'for($i=64;123>$i+=$i-90?1:7;)$t[$i]=chr($i)?><?=strtr($argv[1],$t);' 6711110010100071111108102;echo
> Code000Golf
  • Saved 8 bytes by using ctype_alpha instead of preg_match, thx to manatwork
  • Saved 1 byte by prepending 0 to the string instead of checking non-empty string: when the last character of the input is a 0, the substring I'm taking would be "0", which is falsy, whereas "00" is truthy, so it won't skip printing the last 0.
  • Saved a massive 33 bytes by using strtr after building an array with conversion pairs
  • Saved a byte by using short print tag
  • 1
    \$\begingroup\$ Yo will have to change the regular expression to #[A-Z]#i as the current one will happily allow “92” to be transformed in “\”. Or try ctype_alpha() instead of preg_match(). So far seems to work. \$\endgroup\$
    – manatwork
    Feb 11 '16 at 14:22
  • \$\begingroup\$ "0", which is falsy, whereas "00" is truthy Good going, PHP. \$\endgroup\$
    – cat
    Mar 30 '16 at 22:20

Python 3, 211 189 188 bytes

def f(c,i=0,n=""):
 while i<len(c):a=1;x=int(c[i:i+2]);a=2 if 64<x<91 or 96<x<100 else a;x=int(c[i:i+3]) if a<2 else x;a=3 if 99<x<123 else a;x=chr(x) if a>1 else c[i];n+=x;i+=a
 return n
  • Saved 23 bytes by replacing \n with ; thanks to Dennis


enter image description here

  • 1
    \$\begingroup\$ If you use ; instead of line breaks, you can put the entire while loop on a single line. Also, the first line can become def f(c,i=0,n=""):. \$\endgroup\$
    – Dennis
    Feb 11 '16 at 18:03
  • 1
    \$\begingroup\$ a=1;a=2 if 64<x<91 or 96<x<100 else a -> a=1+(64<x<91or 96<x<100) etc \$\endgroup\$
    – seequ
    Feb 11 '16 at 20:26

Jolf, 18 16 bytes

Try it here! I knew that upperLower function would be useful someday! Replace ó with ΢, or just use the interpreter link. This is encoded in ISO 8859-7.

      pw           upper and lower
        pu         of the uppercase alphabet
     G    E        split by nothing (E = "")
    Μ      dóH     map each char to its numeric counterpart
  La               regex alternate array (e.g. La[1,2,3] => "1|2|3")
ρi            ΅A   replace input with the character code of the match (΅ is string lambda)

Pyth, 20 18 bytes


Same algorithm as @Dennis. It's a lot easier to code in Pyth on my phone than in Jelly.

                implicit: z=input
.U              Reduce the following lambda b, Z over z
                b is the string being built; z is the next char
   u                Reduce the following lambda G,H over +bZ
                    G is the string, H is the next letter to match
     :                  Replace
       G                in G
       ` C H            the char code of H
       H                with H
     s rB            where H takes on values:
          G              the lowercase alphabet (that's the global value of G)
          1              concatenated to its uppercased self.

Thanks @isaacg

Try it here.

  • \$\begingroup\$ You just can't stay off this site on your phone, can you...? \$\endgroup\$ Feb 11 '16 at 22:41
  • 1
    \$\begingroup\$ Especially when I have the luxury of coding in all printable ASCII :D \$\endgroup\$
    – lirtosiast
    Feb 11 '16 at 22:42
  • 1
    \$\begingroup\$ That is true, probably nice to take a break from all that jelly... You know, a balanced diet ;) \$\endgroup\$ Feb 11 '16 at 22:43

05AB1E, 12 11 bytes


Try it online or verify all test cases or see a step-by-step reduction with just the first 9 bytes.


Å»         # Cumulative left reduce the (implicit) input-string by:
  «        #  Append the current character to the string
   žn      #  Push the builtin "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
     Ç     #  Convert it to a list of integer codepoints
      D    #  Duplicate this list
       ç   #  Convert each integer to its character again
           #  (so it's a list of the characters, instead of a string)
        :  #  Replace all integers with these characters (at the same indices)
           #  (would only replace 0 or 1 time)
}          # After the cumulative reduce-by is done:
 θ         # Pop the list, and only leave the last string
           # (after which it is output implicitly as result)

Io, 228 bytes

As for these warnings... let's just ignore them.

s :=method(H,r(H slice(0,1),H slice(1)))
r :=method(H,T,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"foreach(i,H=H asMutable replaceSeq(i asString,i asCharacter))if(T=="",return H)r(list(H,T slice(0,1))join,T slice(1)))

Try it online!


PowerShell, 51 bytes


Try it online!


  • replace by RegExp 65|66|67|68|...|121|122
  • replace to result of {[char]+"$_"}:

        $_   object with matched string 
       "$_"  matched string 
      +"$_"  convert the string to int

    [char]+"$_" convert the int to char


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.