Octal, Decimal, or Hexadecimal?

11

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.

Arcturus

Posted 2016-02-16T22:23:45.067

Reputation: 6 537

Answers

6

JavaScript (SpiderMonkey 30+), 74 bytes

s=>[for(b of'o0x')if((c=+(0+b+s))>31&c<127)String.fromCharCode(c)].join` `

Neil

Posted 2016-02-16T22:23:45.067

Reputation: 95 035

You and your ES7 are killing mah ES6 o_o – Conor O'Brien – 2016-02-16T22:38:02.753

2@CᴏɴᴏʀO'Bʀɪᴇɴ When you're using both map and filter, array comprehensions are really useful. – Neil – 2016-02-16T22:43:28.483

@Neil Any reason to use '0'+b+... when b will always be a string? 0+b+... – andlrc – 2016-02-17T00:27:04.933

@dev-null Bah, I fixed it in http://codegolf.stackexchange.com/a/73323/17602 but forgot to do it here too.

– Neil – 2016-02-17T00:36:44.477

4

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

Luis Mendo

Posted 2016-02-16T22:23:45.067

Reputation: 87 464

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 – 2016-02-16T23:30:22.187

@David Thanks! I thought D was necessary in this case to empty the stack. But you're right, it's not! Thanks! – Luis Mendo – 2016-02-16T23:33:25.083

1@David I need to include ' ':'~' as a predefined literal for next release! – Luis Mendo – 2016-02-16T23:35:50.223

132:126m is a good idea!! – David – 2016-02-16T23:40:27.280

4

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

Cameron Aavik

Posted 2016-02-16T22:23:45.067

Reputation: 723

3

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.

lirtosiast

Posted 2016-02-16T22:23:45.067

Reputation: 20 331

2

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.

Conor O'Brien

Posted 2016-02-16T22:23:45.067

Reputation: 36 228

1

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.

Digital Trauma

Posted 2016-02-16T22:23:45.067

Reputation: 64 644

1

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.

Digital Trauma

Posted 2016-02-16T22:23:45.067

Reputation: 64 644

Your loop "increment" statement is awesome! It could be shortened though. – anatolyg – 2016-02-17T16:53:06.843

j*=j,j/=6 is more plainly written as j=j*j/6 – anatolyg – 2016-02-17T19:56:50.503

@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 – 2016-02-17T20:32:56.923

j<20, the comma operator discards the whole effect of this. – luser droog – 2016-03-08T10:58:13.517

@luserdroog Yes - thanks! – Digital Trauma – 2016-03-09T17:38:19.580

1

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

Qwertiy

Posted 2016-02-16T22:23:45.067

Reputation: 2 697

1

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

Katenkyo

Posted 2016-02-16T22:23:45.067

Reputation: 2 857

0

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>

Conor O'Brien

Posted 2016-02-16T22:23:45.067

Reputation: 36 228

Hmm, how old a JavaScript do you need that numbers beginning with 0 parse as octal? – Neil – 2016-02-16T22:40:27.860

@Neil Firefox seems to work okay with it. – Conor O'Brien – 2016-02-16T22:40:46.877

Doesn't seem to work with 47. – Neil – 2016-02-16T22:41:55.980

@Neil Works again by reverting back to eval... – Conor O'Brien – 2016-02-16T22:44:26.447

Ah, Number() requires 0o but eval is happy with just 0. Sorry for the confusion. – Neil – 2016-02-17T00:39:39.953

@Neil It's good! – Conor O'Brien – 2016-02-17T00:46:54.867

oh right, forgot about that :P – Mama Fun Roll – 2016-02-18T14:13:12.243

0

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

mnel

Posted 2016-02-16T22:23:45.067

Reputation: 826