11
\$\begingroup\$

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.

\$\endgroup\$

11 Answers 11

6
\$\begingroup\$

JavaScript (SpiderMonkey 30+), 74 bytes

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

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
\$\endgroup\$
  • \$\begingroup\$ 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]. \$\endgroup\$ – David Feb 16 '16 at 23:30
  • \$\begingroup\$ @David Thanks! I thought D was necessary in this case to empty the stack. But you're right, it's not! Thanks! \$\endgroup\$ – Luis Mendo Feb 16 '16 at 23:33
  • 1
    \$\begingroup\$ @David I need to include ' ':'~' as a predefined literal for next release! \$\endgroup\$ – Luis Mendo Feb 16 '16 at 23:35
  • 1
    \$\begingroup\$ 32:126m is a good idea!! \$\endgroup\$ – David Feb 16 '16 at 23:40
4
\$\begingroup\$

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

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.

\$\endgroup\$
2
\$\begingroup\$

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.
\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

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,,,,"
\$\endgroup\$
1
\$\begingroup\$

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 _.

\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ Your loop "increment" statement is awesome! It could be shortened though. \$\endgroup\$ – anatolyg Feb 17 '16 at 16:53
  • \$\begingroup\$ j*=j,j/=6 is more plainly written as j=j*j/6 \$\endgroup\$ – anatolyg Feb 17 '16 at 19:56
  • \$\begingroup\$ @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 \$\endgroup\$ – Digital Trauma Feb 17 '16 at 20:32
  • \$\begingroup\$ j<20, the comma operator discards the whole effect of this. \$\endgroup\$ – luser droog Mar 8 '16 at 10:58
  • \$\begingroup\$ @luserdroog Yes - thanks! \$\endgroup\$ – Digital Trauma Mar 9 '16 at 17:38
0
\$\begingroup\$

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>

\$\endgroup\$
  • \$\begingroup\$ Hmm, how old a JavaScript do you need that numbers beginning with 0 parse as octal? \$\endgroup\$ – Neil Feb 16 '16 at 22:40
  • \$\begingroup\$ @Neil Firefox seems to work okay with it. \$\endgroup\$ – Conor O'Brien Feb 16 '16 at 22:40
  • \$\begingroup\$ Doesn't seem to work with 47. \$\endgroup\$ – Neil Feb 16 '16 at 22:41
  • \$\begingroup\$ @Neil Works again by reverting back to eval... \$\endgroup\$ – Conor O'Brien Feb 16 '16 at 22:44
  • \$\begingroup\$ Ah, Number() requires 0o but eval is happy with just 0. Sorry for the confusion. \$\endgroup\$ – Neil Feb 17 '16 at 0:39
0
\$\begingroup\$

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 "")

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