There's so many people using a messaging service that they're running out of space to store all the usernames! To fix this, they are going to start storing usernames as hexadecimal, where possible.

If a username consists of only the characters 0123456789ABCDEF (case insensitive), it can be converted to a hexadecimal and stored as an integer. For example, the username ba5eba11 can be interpreted as 0xBA5EBA11, a hexadecimal integer.

But what about 05AB1E? That's got a leading zero, which would be lost. So, whenever we convert a username, we make sure to prepend a 1 before reading it as an integer.

## The Challenge

• If it can be interpreted as a hexadecimal integer, prepend a 1, interpret as hexadecimal, and then print the result as base 10.
• Otherwise, just return the string unmodified.

This is , so the shortest solution (in bytes) wins! Built-in base conversion functions are permitted.

## Test Cases

You can assume that any resulting integers with be within your language's standard integer range.

As with usernames on most messaging systems, the input strings will only contain alphanumerics and underscores.

Remember, you always need to add a leading 1 before conversion!

"ba5eba11" -> 7421737489
"05AB1E"   -> 17148702
"dec0de"   -> 31375582
"Beef"     -> 114415
"da7aba5e" -> 7960443486
"500"      -> 5376

"DENNIS" -> "DENNIS"
"Garth"  -> "Garth"
"A_B_C"  -> "A_B_C"
"0x000"  -> "0x000"


For reference, here is a Python 3 implementation I used for the test cases (ungolfed):

import re

def convert_name(name):

# JavaScript (ES6), 15 bytes

s=>'0x1'+s-0||s


### How it works

'0x1'+s converts the input into a literal hexadecimal string with a prepended 1, e.g. 0x105ab1e. Then -0 casts the result to a number. JavaScript sees the 0x at the beginning and implicitly tries to convert from hexadecimal; if s contains any non-hexadecimal chars, this returns NaN. Since this is falsy (and output 0 can never be given because of the prepended 1), we can use ||s to return s if the hex conversion failed.

### Test snippet

f = s=>'0x1'+s-0||s

for(i of [
"ba5eba11", "05AB1E", "dec0de", "Beef", "da7aba5e", "500",
"DENNIS", "Garth", "A_B_C", "0x000"
]) console.log(i + ":", f(i));

• Very nice solution! – Grax32 Jan 3 '17 at 2:26
• Implicit casting is truly beautiful... :') – Downgoat Jan 5 '17 at 9:23

# Python 2, 44 bytes

Takes input as a quoted string. -2 bytes thanks to Rod!

a=input()
try:exec'a=0x1'+a
except:1
print a


As we're guaranteed that the input will only contain alphanumerics and underscores, there's no way to create valid Python after 0x1 other than having a hex string. If the input is anything else, the error is ignored, and printing as it originally was.

I couldn't seem to make a regex match any shorter than try/except. In fact, regex turned out to be terribly verbose:

import re
lambda n:re.match('^[0-9A-F]+$',n,2)and int('1'+n,16)or n  • you can also replace a=int('1'+a,16) with exec'a=0x1'+a (probably, need to test) – Rod Jan 2 '17 at 15:07 • You know, we are going to have to same exact answer if I continue golfing right? – Anthony Pham Jan 2 '17 at 15:15 • Doesn't work for usernames that would be valid Python in that context, e.g. "+input()". – heinrich5991 Jan 2 '17 at 19:10 • fails for "abc " (notice the whitespace at the end)(int allows whitespace at beginning and end) – Siphor Jan 2 '17 at 20:32 • I don't know exactly how it is for Python 2, but I think you can remove the brackets () at input() – RudolfJelin Jan 3 '17 at 20:20 # Perl 6, 19 bytes {:16(1~S/_/Z/)//$_}


Test it

## Expanded:

{   # bare block lambda with implicit parameter ｢$_｣ :16( # convert from base 16 1 ~ # Str concatenated S/_/Z/ # replace an underscore with an invalid base 16 character ) // # defined or$_       # the input unchanged

}


## Perl, 27 bytes

-1 byte thanks to @ardnew.

26 bytes of code + -p flag.

$_=hex"1$_"if!/[^0-9a-f]/i


Supply the input without final newline. With echo -n for instance:

echo -n 05AB1E | perl -pe '$_=hex"1$_"if!/[^0-9a-f]/i'


Explanation
This is pretty straight forward: /[^0-9a-f]/i is true if the input contains a character other than those allowed inside hexadecimal numbers. If it's false, $_ (which contains the input) it is set to the converted value (the conversion is done by the builtin hex). And $_ is implicitly printed thanks to -p flag.

• you can shave a byte by avoiding the ternary operation $_=hex"1$_"if!/[^0-9a-f]/i – ardnew Jan 3 '17 at 17:21
• @ardnew Hum, now that you say it, that ternary was pretty awful... Anyway, thanks! – Dada Jan 3 '17 at 18:35

# Pyth - 9 bytes

.xi+1z16z


Same idea as fliptack's answer. Try hexadecimal-decimal conversion else output the input.

Try it here!

# Batch, 33 bytes

@(cmd/cset/a0x1%1 2>nul)||echo %1


## How it works

A string is passed in as an argument, 1 is prepended to it, and the string is implicitly converted to decimal and printed. If the string is not valid hexadecimal, it is simply displayed.

It should be noted that since batch math uses signed 32-bit integers, the biggest allowed username is FFFFFFF.

cmd /c takes the next command, runs it in a new terminal, and exits.

set /a performs math and implicitly displays the result in decimal when not stored to a variable.

0x1%1 tells set to prepend a 1 to the first argument (this is easy since all batch variables are strings) and indicates that the string should be treated as hexadecimal.

2>nul silences any errors resulting from an invalid hexadecimal number

|| is a logical OR and performs the command on the right if the command on the left is not successful. The parentheses make everything up to this point one command.

echo %1 simply displays the first argument.

## Common Lisp, 71

(lambda(n)(or(ignore-errors(parse-integer(format()"1~A"n):radix 16))n))


## Tests

Define function

CL-USER> (lambda(n)(or(ignore-errors(parse-integer(format()"1~A"n):radix 16))n))
#<FUNCTION (LAMBDA (N)) {10041D213B}>


Quote a list of expected inputs, as given by the question:

CL-USER> '("ba5eba11" -> 7421737489
"05AB1E"   -> 17148702
"dec0de"   -> 31375582
"Beef"     -> 114415
"da7aba5e" -> 7960443486
"500"      -> 5376

"DENNIS" -> "DENNIS"
"Garth"  -> "Garth"
"A_B_C"  -> "A_B_C"
"0x000"  -> "0x000")
("ba5eba11" -> 7421737489 "05AB1E" -> 17148702 "dec0de" -> 31375582 "Beef" ->
114415 "da7aba5e" -> 7960443486 "500" -> 5376 "DENNIS" -> "DENNIS" "Garth" ->
"Garth" "A_B_C" -> "A_B_C" "0x000" -> "0x000")


Parse it and collect results

CL-USER> (loop for (in _ out) on * by #'cdddr
collect (list in out (funcall ** in)))
(("ba5eba11" 7421737489 7421737489) ("05AB1E" 17148702 17148702)
("dec0de" 31375582 31375582) ("Beef" 114415 114415)
("da7aba5e" 7960443486 7960443486) ("500" 5376 5376)
("DENNIS" "DENNIS" "DENNIS") ("Garth" "Garth" "Garth")
("A_B_C" "A_B_C" "A_B_C") ("0x000" "0x000" "0x000"))


Check that the expected outputs match the actual ones:

CL-USER> (every (lambda (x) (equalp (second x) (third x))) *)
T


## C, 108 bytes

i;f(char*s){char*S=malloc(strlen(s)+2);*S=49;strcpy(S+1,s);sscanf(S,"%x%c",&i,&i)<2?printf("%d",i):puts(s);}


This is a function that takes the string as an argument and prints the result to STDOUT.

i;                           // declare i as an int
f(char*s){
char*S=malloc(strlen(s)+2);  // allocate space for a new string with 1 more char
*S=49;                       // set the first char to '1' (ASCII 49)
strcpy(S+1,s);               // copy the original string to the remainder
sscanf(S,"%x%c",&i,&i)       // scan a hex integer followed by any char
<2?                          // if less than 2 items were scanned (i.e. the hex
// integer made up the entire string),
printf("%d",i)               // output the hex integer
:puts(s);}                   // otherwise, output the original string

• Nice use of implicit int :) – FlipTack Jan 2 '17 at 15:14
• 100 bytes – ceilingcat May 25 '20 at 4:47

# JavaScript: 46 41 bytes

s=>/[^\dA-F]/i.test(s)?s:parseInt(1+s,16)

• The regex can be 2 bytes shorter: /[^0-9a-f]/i – GilZ Jan 2 '17 at 16:03
• I saved 1 byte by replacing 0-9 by \d, 3 bytes by adding the case-insensitive flag (thanks @GilZ) and 2 more bytes by removing F=, which isn't needed. Thanks for the suggestion. – Luke Jan 2 '17 at 16:10

# PHP, 42 bytes

hex2bin() returns false if the input is not a valid hex string. This is shorter than using regex to look for non hex digits, but we need the @ operator because it's not silent when it fails.

<?=@hex2bin($s=$argv[1])?hexdec("1$s"):$s;

• hex2bin fails for strings with uneven lengths. Still two bytes shorter than with preg_match though: <?=@hex2bin($s=$argv[1])|@hex2bin($s.a)?hexdec("1$s"):$s; for 57 bytes. – Titus Jan 4 '17 at 16:52 # bash, 4635 31 bytes (echo$[0x1$1])2> >(:)||echo$1


Save as a script, and pass the username as an argument.

# Python 2 - 63, 52, 50, 46 Bytes

n=input()
try:n=int("1"+n,16)
except:1
print n


This uses Python's int() which converts any string with its appropriate base into base 10. In this case, the string is the number 1 attached to the input. If the input is invalid (has characters other than 0123456789ABCDEF (case-insensitive), it returns ValueError:

n = input()                   # Get input (with quotes)
try:                          # Trying conversion to base 10
n = int("1"+n,16)
except:                       # If invalid string for base 36,
1                         # do nothing to n
print n                       # Print result


Try it here!

Thanks to @FlipTack for saving 15 bytes!

• What if the string doesn't start with a zero? You should only be adding a one to the left of the string if it starts with a zero. – 0WJYxW9FMN Jan 2 '17 at 14:41
• @FlipTack Whoops, silly me. – 0WJYxW9FMN Jan 2 '17 at 14:42

# Ruby, 47 44 bytes

p gets=~/^[a-f\d]+\s$/i?('1'+$&).to_i(16):$_  I could remove 3 bytes by changing puts for p, but I feel like the output would be considered wrong since it has a newline at the end. Edit: Changed puts for p as trailing newlines are typically accepted, thanks @Mego. • Trailing newlines on STDOUT are typically considered acceptable. – user45941 Jan 3 '17 at 5:12 ## Japt, 11 bytes +0x1{U}ªU  Try it Online! Big thanks to ETHproductions! • This is one of the rare cases where you can get rid of the space :-) (Also, the TIO link is to the "Hello, World!" program) – ETHproductions Jan 3 '17 at 20:32 # Dyalog APL, 37 bytes Uses no built-in validation or hex-dec conversion. Requires ⎕IO←0 which is default on many systems. {∧/(u←1(819⌶)⍵)∊d←⎕D,6↑⎕A:16⊥1,d⍳u⋄⍵}  Ungolfed: { d ← ⎕D , 6 ↑ ⎕A u←1 (819⌶) ⍵ ∧/ u ∊ d: 16 ⊥ 1 , d ⍳ u ⍵ }  d ← ⎕D , 6 ↑ ⎕Ad gets Digits followed by the first 6 elements of the Alphabet u ← 1 (819⌶) ⍵u gets uppercased (819 ≈ "Big") argument ∧/ u ∊ d: if all elements of u are members of d, then: 16 ⊥ 1 , d ⍳ u find the indices of u in d, prepend a 1, and evaluate as base 16 ⍵ else: return the (unmodified) argument TryAPL online: # REXX, 49 48 bytes signal on syntax pull a a=x2d(1||a) syntax: say a  The signal on syntax tells the interpreter to jump to the label syntax whenever a syntax error occurs. The program tries to reassign a with a hex-to-decimal converted version with a leading 1, but jumps to the syntax label if that fails. If the conversion does pass, it simply ignores the label and outputs the reassigned variable. • Could you explain your code please – Anthony Pham Jan 3 '17 at 16:31 # PowerShell, 35 bytes param($v)(($h="0x1$v"|iex),$v)[!$h]


### Explanation

1. Take parameter ($v) 2. Create a two-element array where the first element (0) is the result of a string containing 0x1$v piped into Invoke-Expression (iex), while simultaneously assigning this value to $h. If the conversion fails, $h will remain $null. 3. The second element of the array is the original parameter. 4. Index into the array with the boolean -not value of $h. Whatever $h is will be implicitly converted to [bool] ($null in the case of an invalid conversion will become $false, a positive integer in the case of successful conversion will become $true) before being negated, which is then implicitly converted to [int] by the array indexer [] ($true will be 1, $false will be 0), thus resulting in the first element of the array (the conversion result) chosen if the conversion was successful, and the second element chosen if the conversion was unsuccessful.

# Scala, 40 bytes

s=>try{BigInt("1"+s,16)}catch{case e=>s}


Usage:

val f:(String=>Any)=s=>try{BigInt("1"+s,16)}catch{case e=>s}
f("ba5eba11") //returns 7421737489


Explanation:

s=>                //define a anonymous function with a parameter called s
try {              //try...
BigInt("1"+s,16)   //to contruct a BigInt from "1" prepended to the number, parsing it as base 16
} catch {          //if the constructor throws an exception
case e =>          //in case of an execption which we'll call e
s                  //return s
}


# C#, 58 bytes

u=>{try{u=Convert.ToInt64("1"+u,16)+"";}catch{}return u;};


Ungolfed with test cases:

using System;
class Class
{
public static void Main()
{
Func<string, string> convert =
u=>
{
try
{
u = Convert.ToInt64("1" + u, 16) //Prepends "1" and tries to convert the string to and integer using base 16.
+ ""; //Appending an empty string converts the integer to a string. Shorter than calling .ToString()
}
catch { } //If the conversion fails catch the exception and discard it.
return u; //Return the result, or the unmodified input if the conversion failed.
};

Console.WriteLine(convert("ba5eba11"));
Console.WriteLine(convert("05AB1E"));
Console.WriteLine(convert("dec0de"));
Console.WriteLine(convert("Beef"));
Console.WriteLine(convert("da7aba5e"));
Console.WriteLine(convert("500"));
Console.WriteLine(convert("DENNIS"));
Console.WriteLine(convert("Garth"));
Console.WriteLine(convert("A_B_C"));
Console.WriteLine(convert("0x000"));
}
}


Try online

## Dart, 51 bytes

(s)=>int.parse('1\$s',radix:16,onError:(_)=>null)??s


Try it here

Most of the overhead comes from named parameters... Oh well!

At least Dart lets you be dynamically typed, if you want to :D