Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Given an input string containing only letters and numbers, write a program or function that prints the possible printable ASCII characters (Hex 20-7E) that correspond with the string's value in bases 8, 10, and 16 (where possible). The characters must be written in increasing order in terms of the bases with which they correspond (base 8 first, etc). The output can be in array format (like [& . F]) or separated by spaces or newlines (a trailing newline is optional) like the samples.

If there is not a possible printable ASCII character that can be formed, the program must not have any output.

Samples

31
==> 1

47
==> ' / G

69
==> E i

7A
==> z

100
==> @ d

156
==> n

189
==> <empty>

potaTO
==> <empty>

5G
==> <empty>

19
==> <empty>

This is , so the answer with the fewest bytes wins. Standard rules apply.

share|improve this question

11 Answers 11

JavaScript (SpiderMonkey 30+), 74 bytes

s=>[for(b of'o0x')if((c=+(0+b+s))>31&c<127)String.fromCharCode(c)].join` `
share|improve this answer
    
You and your ES7 are killing mah ES6 o_o – Cᴏɴᴏʀ O'Bʀɪᴇɴ Feb 16 at 22:38
2  
@CᴏɴᴏʀO'Bʀɪᴇɴ When you're using both map and filter, array comprehensions are really useful. – Neil Feb 16 at 22:43
    
@Neil Any reason to use '0'+b+... when b will always be a string? 0+b+... – andlrc Feb 17 at 0:27
    
@dev-null Bah, I fixed it in codegolf.stackexchange.com/a/73323/17602 but forgot to do it here too. – Neil Feb 17 at 0:36

MATL, 23 24 28 bytes

1 byte off thanks to @David

8H6hhYs"G@ZA32:126m?6Mc

Try it online!

8H6hhYs         % array [8,10,16]
"               % for each base
  G             %   push input. Do nothing the first time
  @             %   push base (8, 10 or 16)
  ZA            %   convert from base to decimal. Takes implicit input the first time
  32:126m       %   is result in acceptable range?
  ?             %   if so
    6M          %     push result of base conversion again
    c           %     convert to char
                %   implicitly end if
                % implicitly end for each
                % implicitly display stack contents
share|improve this answer
    
I'm not sure if the D is necessary, is it? Nice work on creating the vector, I did almost the same as you but couldn't shorten the vector from [8,10,16]. – David Feb 16 at 23:30
    
@David Thanks! I thought D was necessary in this case to empty the stack. But you're right, it's not! Thanks! – Luis Mendo Feb 16 at 23:33
1  
@David I need to include ' ':'~' as a predefined literal for next release! – Luis Mendo Feb 16 at 23:35
1  
32:126m is a good idea!! – David Feb 16 at 23:40

Python 3, 84 82 bytes

def a(s):
 for n in 8,10,16:
  try:b=int(s,n);31<b<127and print(chr(b))
  except:0
share|improve this answer

Pyth, 23 21 20 18 bytes

@rd\m.xCizd0[8T16

Output as an array. There's a literal \x80 between the backslash and the C, which I've replaced with a .

@rd\•m.xCizd0[8T16    Implicit: z=input
     m     d [8T16    Map the following lambda d over [8, 10, 16]:
      .x                try:
         izd              convert z from that base
        C                                          and convert to char
            0           except: return the number 0
@                     Filter that on presence in
 rd\•                   strings from space to \x80 (the printable ASCII characters).

Try it here.

share|improve this answer

Jolf, 26 bytes

Try it here! Test suite

 fΜ‘Ci8iΗi’dpAHdh sH"[ -~]

Explanation

 fΜ‘Ci8iΗi’dpAHdh sH"[ -~]
   ‘      ’                array containing
    Ci8                     input as base 8
       i                    input as base 10
        Ηi                  input as base 16
  Μ        d               mapped
            pAH             with from char code
_f             d           filtered
                _sH"[ -~]   with strings matching that.
share|improve this answer

Bash + GNU utilities + ascii, 36

Not sure if the use of the ascii utility is allowed. Input is taken as a commandline parameter.

ascii $1|tac|grep -Po '(?<=s as `).'

ascii may be installed on Ubuntu with sudo apt-get install ascii.

share|improve this answer

Javascript ES6, 89 chars

s=>'0o,,0x'.split`,`.map(x=>(x+=s)>31&x<128&&String.fromCharCode(x)).filter(x=>x).join` `

Test:

f=s=>'0o,,0x'.split`,`.map(x=>(x+=s)>31&x<128&&String.fromCharCode(x)).filter(x=>x).join` `
"31,47,69,7A,100,156,189,potaTo,5G,19".split`,`.map(f) == "1,' / G,E i,z,@ d,n,,,,"
share|improve this answer

Lua, 147 Bytes

I don't think I can golf it down a lot more, I've tested a lot of ways to do it, and here come the shortest. Even using an old compiler which contains the deprecated function table.foreach(table,function) doesn't shave off some bytes.

This program takes a string as argument, and print the concatenation of a table values separated by spaces.

t={}for _,i in pairs({8,10,16})do x=tonumber(arg[1],i)x=x and x or 0 t[#t+1]=127>x and 19<x and string.char(x)or nil end print(table.concat(t," "))

Ungolfed and explanations

t={}                        -- Initalise the array containing the chars to print
for _,i in pairs({8,10,16}) -- Iterate over the array {8,10,16}
do
  x=tonumber(arg[1],i)      -- convert the input in base i to a number in base 10
  x=x and x or 0            -- if the input wasn't a number, x is nil
                            -- use a ternary operator to set x in this case
  t[#t+1]=127>x and 19<x    -- if x is the bytecode of a printable character
    and string.char(x)or nil-- insert this character into t
end
print(table.concat(t," "))  -- concatenate the values in t with " " as separator
                            -- and print it

If you're wandering why there's a variable set but not used in a golfed code (the variable _ in the for loop), here's why:

You have 2 ways to iterate over an array in Lua, either in a for style:

for i=1,#table do --[[code here, use table[i] ]] end

or in a foreach style:

for key,value do pairs(table) do --[[code here]] end

I was needing the values contained in the table {8,10,16} as they are the different bases I have to iterate over. But functions with multiple return won't allow you to chose which one you actually want to be returned, they follow an order. To have the variable value set, I need to catch the value of key too: that's what we call a dummy _.

share|improve this answer

C (function), 76

  • 2 bytes saved thanks to @anatolyg.
  • 5 bytes saved thanks to @luserdroog.
j,c;f(char*s){for(j=8;c=strtol(s,0,j);j=j*j/6)isprint(c)?printf("%c ",c):0;}

Ideone.

share|improve this answer
    
Your loop "increment" statement is awesome! It could be shortened though. – anatolyg Feb 17 at 16:53
    
j*=j,j/=6 is more plainly written as j=j*j/6 – anatolyg Feb 17 at 19:56
    
@anatolyg of course -thanks! I was trying to be clever with combining operators - something like j*=j/6 but that didn't work due to loss of precision during integer division – Digital Trauma Feb 17 at 20:32
    
j<20, the comma operator discards the whole effect of this. – luser droog Mar 8 at 10:58
    
@luserdroog Yes - thanks! – Digital Trauma Mar 9 at 17:38

JavaScript ES6, 89 88 bytes

Saved 1 byte thanks to Neil!

n=>[..."0x+"].map(t=>String.fromCharCode(eval(`0${t+n}`))).filter(k=>~k.search(/[ -~]/))

Returns an array. If that's not okay, this works for an extra 8 bytes, displaying the possible matches.

n=>[..."0x+"].map(t=>String.fromCharCode(eval(`0${t+n}`))).filter(k=>~k.search(/[ -~]/)).join` `

F=n=>[..."0x+"].map(t=>String.fromCharCode(eval(`0${t+n}`))).filter(k=>~k.search(/[ -~]/)).join` `
//`
U=x=>o.innerHTML=F(+i.value);
i.onchange=i.onkeydown=i.onkeyup=i.onkeypress=U;U();
*{font-family:Consolas,monospace;}
<input id=i type="number" value=31><div id=o></div>

share|improve this answer
    
Hmm, how old a JavaScript do you need that numbers beginning with 0 parse as octal? – Neil Feb 16 at 22:40
    
@Neil Firefox seems to work okay with it. – Cᴏɴᴏʀ O'Bʀɪᴇɴ Feb 16 at 22:40
    
Doesn't seem to work with 47. – Neil Feb 16 at 22:41
    
@Neil Works again by reverting back to eval... – Cᴏɴᴏʀ O'Bʀɪᴇɴ Feb 16 at 22:44
    
Ah, Number() requires 0o but eval is happy with just 0. Sorry for the confusion. – Neil Feb 17 at 0:39

R, 84 bytes

function(x){s=sapply;y=s(c(8,10,16),strtoi,x=x);cat(s(y[y%in%c(32:126)],intToUtf8))}

uses strtoi to convert to each of the bases and then convert to character if in the appropriate range. Could save 4 more bytes by removing cat if we allowed the default printing of characters (wrapped in "")

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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