转换“ 0xUsernames”


25

0x用户名

有太多人在使用消息传递服务,以至于他们用光了存储所有用户名的空间!为了解决这个问题,他们将在可能的情况下开始以十六进制存储用户名。

如果用户名仅包含字符0123456789ABCDEF(不区分大小写),则可以将其转换为十六进制并存储为整数。例如,用户名ba5eba11可以解释为0xBA5EBA11十六进制整数。

但是呢05AB1E?那是一个前导零,它将丢失。因此,无论何时转换用户名,都必须1在将其读取为整数之前确保在前面加上a 。


挑战

您的任务是编写一个给定非空用户名作为字符串的程序或函数,以“六压缩”用户名:

  • 如果可以将其解释为十六进制整数,则将1解释为十六进制,然后将结果打印为以10为基数。
  • 否则,只需返回未修改的字符串即可。

这是,因此最短的解决方案(以字节为单位)获胜!允许内置的基本转换功能。


测试用例

您可以假设任何所得的整数都在您语言的标准整数范围内。

与大多数邮件系统中的用户名一样,输入字符串将仅包含字母数字和下划线。

请记住,您始终需要1在转换前添加前导!

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

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

作为参考,这是我用于测试用例(无溶剂)的Python 3实现:

import re

def convert_name(name):
    if re.fullmatch('^[0-9A-Fa-f]+$', name):
        return int('1' + name.upper(), base = 16)
    else:
        return name

啊,没看到。另外,如果某些较大的测试用例导致数字超出了我们语言最大的整数类型的范围,该怎么办?
Doorknob

2
@Doorknob好抓。我会说,结果整数将永远不会超过您语言的标准整数类型。(请不要滥用它,并使用具有1位整数的语言)
FlipTack

可以假设输入仅是大写吗?
亚当

@Adám抱歉,但是您的程序应该不区分大小写(请参见测试用例)
FlipTack

像一元一样,除了它编码用户名而不是BF
MilkyWay90

Answers:


27

05AB1E,4个字节

D1ìH

说明

D    Duplicate input
 1ì  Prepend 1
   H Interpret as hexadecimal and implicitly display the value in base 10

如果输入具有无效的十六进制字符,H则不会压入任何内容,因此堆栈上的最后一个值将是重复的输入,这就是程序在输入无效的情况下打印其输入的原因。

在线尝试!


9
具有讽刺意味的是,在这里。05AB1E是有效的用户名。
devRicher

1
是的,但是名称被选择为十六进制数字。因此,它是有效的:)
奥萨卜莱

想知道你为什么要欺骗。试图想办法使用$来代替,虽然....
魔术八达通金塔

16

JavaScript(ES6),15个字节

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

怎么运行的

'0x1'+s将输入转换为带前缀的文字十六进制字符串1,例如0x105ab1e。然后-0将结果转换为数字。JavaScript首先看到,0x然后隐式尝试从十六进制转换;如果s包含任何非十六进制字符,则返回NaN。由于这是虚假的(并且0由于前置1,因此永远无法给出输出),因此如果十六进制转换失败,我们可以使用||sreturn s

测试片段

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


2
非常好的解决方案!
Grax32

隐式转换真的很漂亮……:')
Downgoat

10

Python 2,44字节

将输入作为带引号的字符串。-2个字节感谢Rod!

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

由于我们保证输入将仅包含字母数字和下划线,因此0x1除了拥有十六进制字符串外,没有其他方法可以创建有效的Python 。如果输入的是其他任何内容,则错误将被忽略,并按原样打印。

我似乎无法使regex匹配的时间短于try/except。实际上,正则表达式非常冗长:

import re
lambda n:re.match('^[0-9A-F]+$',n,2)and int('1'+n,16)or n

您也可以替换a=int('1'+a,16)exec'a=0x1'+a(可能需要测试)
Rod

你知道吗,如果我继续打高尔夫球,我们将有完全相同的答案吗?
Anthony Pham

在那种情况下对于有效的Python用户名无效,例如"+input()"
heinrich5991

失败的原因是“ abc”(注意末尾的空格)(int允许在开头和结尾使用空格)
Siphor

我不知道Python 2到底是什么,但是我认为您可以()input()
RudolfJelin

8

Perl 6字节

{:16(1~S/_/Z/)//$_}

测试一下

展开:

{   # 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

}

7

Perl,27个字节

-1个字节感谢@ardnew

26个字节的代码+ -p标志。

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

提供输入而无需最后的换行符。随着echo -n比如:

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

解释
这很简单:/[^0-9a-f]/i如果输入包含的字符不是十六进制数字内允许的字符,则为true。如果为false $_(包含输入),则将其设置为转换后的值(转换由内建完成hex)。
$_通过-pflag 隐式打印。


您可以避免三元操作来剃除一个字节$_=hex"1$_"if!/[^0-9a-f]/i
ardnew

@ardnew嗡嗡声,既然您这样说,那么三元状态就很糟糕...总之,谢谢!
达达


3

批次,33个字节

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

怎么运行的

字符串作为参数传入,前缀为1,然后将字符串隐式转换为十进制并打印。如果字符串不是有效的十六进制,则仅显示该字符串。

请注意,由于批处理数学使用带符号的32位整数,因此允许的最大用户名是FFFFFFF

cmd /c 接受下一条命令,在新终端中运行它,然后退出。

set /a 不存储到变量时执行数学运算并以十进制隐式显示结果。

0x1%1 告诉set在第一个参数前加上1(这很容易,因为所有批处理变量都是字符串),并指示应将字符串视为十六进制。

2>nul 使无效的十六进制数引起的任何错误静音

||是逻辑或,如果左侧命令执行不成功,则执行右侧命令。到目前为止,所有括号都由一个命令组成。

echo %1 仅显示第一个参数。


3

常见的Lisp,71

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

测验

定义功能

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

引用问题给出的预期输入清单:

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

解析并收集结果

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

检查预期输出是否与实际输出匹配:

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

2

C,108字节

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);}

该函数将字符串作为参数,并将结果打印到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

很好地使用隐式int:)
FlipTack

2

JavaScript:46 41字节

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

正则表达式可以缩短2个字节:/[^0-9a-f]/i
GilZ

我通过替换0-9为节省了1个\d字节,通过添加不区分大小写的标志(感谢@GilZ)节省了3个字节,并通过删除了另外2个字节(F=不需要)。谢谢你的建议。
路加福音

2

PHP,42字节

如果输入不是有效的十六进制字符串,则hex2bin()返回false。这比使用正则表达式查找非十六进制数字要短,但是我们需要@运算符,因为它在失败时不会保持沉默。

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

hex2bin对于长度不均匀的字符串失败。仍然比通过以下方式少两个字节preg_match<?=@hex2bin($s=$argv[1])|@hex2bin($s.a)?hexdec("1$s"):$s;57个字节。
泰特斯

2

bash,46 35 31字节

(echo $[0x1$1])2> >(:)||echo $1

另存为脚本,并将用户名作为参数传递。


1

Python 2- 635250,46字节

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

它使用Python的Python int()将任何具有适当基数的字符串转换为10。在这种情况下,字符串是附加到输入的数字1。如果输入无效(除了0123456789ABCDEF(不区分大小写)其他字符),则返回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

在这里尝试!

感谢@FlipTack节省了15个字节!


如果字符串不是以零开头怎么办?如果字符串以零开头,则只应在字符串左侧添加一个。
0WJYxW9FMN

@FlipTack哎呀,我傻了。
0WJYxW9FMN

1

Ruby,47个 44字节

p gets=~/^[a-f\d]+\s$/i?('1'+$&).to_i(16):$_

可以通过更改puts为删除3个字节p,但是我觉得输出将被认为是错误的,因为它的末尾有换行符。

编辑:更改putsp尾随换行符通常被接受,谢谢@Mego。


通常认为STDOUT上的尾随换行符是可以接受的。
Mego


1

Dyalog APL,37 个字节

不使用内置验证或十六进制转换。要求⎕IO←0在许多系统上是默认设置。

{∧/(u1(819⌶)⍵)∊d←⎕D,6↑⎕A:161,du⋄⍵}

取消高尔夫:

{
    d  D , 6  A
    u1 (819⌶) 
    ∧/ u  d: 16  1 , d  u
    
}

d ← ⎕D , 6 ↑ ⎕Ad得到d igits接着的前6个元素 lphabet

u ← 1 (819⌶) ⍵变大写(819≈“ Big”)参数

∧/ u ∊ d: 如果u的所有元素都是d的成员,则:在d中
16 ⊥ 1 , d ⍳ u  找到u的索引,以1开头,并以16为底进行求值

else:返回(未修改的)参数

在线TryAPL:

  1. 设置⎕IO为零,定义更换(禁止在TryAPL出于安全原因),并集⎕PPP RINT P recision)为10,大结果

  2. 尝试所有测试用例


1

REXX, 49 48字节

signal on syntax
pull a
a=x2d(1||a)
syntax:
say a

每当发生语法错误时,signal on syntax告诉告诉解释器跳到标签syntax。程序尝试a使用前导1到十六进制到十进制的转换版本进行重新分配,但是syntax如果失败,则跳转到标签。如果转换通过,它将简单地忽略标签并输出重新分配的变量。


2
你能解释一下你的代码,请
安东尼范

0

PowerShell,35个字节

param($v)(($h="0x1$v"|iex),$v)[!$h]

在线尝试!运行所有测试用例!

说明

  1. 取参数($v
  2. 创建一个双元件阵列,其中所述第一元件(0)是含有一个字符串的结果0x1$v管道入Invoke-Expressioniex),而同时分配此值$h。如果转换失败,$h将保留$null
  3. 数组的第二个元素是原始参数。
  4. 布尔-not值为的数组索引$h。取反之前,无论$h是什么,都将被隐式转换为[bool]$null在无效转换的情况下变为$false,在成功转换的情况下将变为正整数$true),然后[int]由数组索引器将其隐式转换为[]$true将为1$false将为0),因此如果转换成功,则选择数组的第一个元素(转换结果),如果转换不成功,则选择第二个元素。

0

Scala,40个字节

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

用法:

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

说明:

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
  }

0

C#,58个字节

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

不用测试用例:

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"));
        Console.Read();
    }
}

在线尝试


0

Dart,51个字节

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

在这里尝试

大部分开销都来自命名参数...哦!

如果您想:D,至少Dart可以让您动态输入

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.