Convertendo "0xUsernames"


25

0xUsernames

Há tantas pessoas usando um serviço de mensagens que estão ficando sem espaço para armazenar todos os nomes de usuário! Para corrigir isso, eles começarão a armazenar nomes de usuário como hexadecimal, sempre que possível.

Se um nome de usuário consistir apenas em caracteres 0123456789ABCDEF(sem distinção entre maiúsculas e minúsculas), ele poderá ser convertido em um hexadecimal e armazenado como um número inteiro. Por exemplo, o nome de usuário ba5eba11pode ser interpretado como 0xBA5EBA11um número inteiro hexadecimal.

Mas que tal 05AB1E? Isso tem um zero à esquerda, que seria perdido. Portanto, sempre que convertermos um nome de usuário, adicione um 1antes de a antes de lê-lo como um número inteiro.


O desafio

Sua tarefa é escrever um programa ou função que, dado um nome de usuário não vazio como uma string, 'hexa-comprima' o nome de usuário:

  • Se puder ser interpretado como um número inteiro hexadecimal, acrescente 1, interprete como hexadecimal e imprima o resultado como base 10.
  • Caso contrário, basta retornar a string não modificada.

Isso é , então a solução mais curta (em bytes) vence! Funções de conversão de base incorporadas são permitidas.


Casos de teste

Você pode supor que quaisquer números inteiros resultantes estejam dentro do intervalo inteiro padrão do seu idioma.

Como nos nomes de usuário na maioria dos sistemas de mensagens, as seqüências de entrada conterão apenas alfanuméricos e sublinhados.

Lembre-se de que você sempre precisa adicionar um líder 1antes da conversão!

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

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

Para referência, aqui está uma implementação do Python 3 que eu usei para os casos de teste (não destruídos):

import re

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

Ah, não vi isso. Além disso, e se alguns dos casos de teste maiores resultarem em números fora dos limites do maior tipo inteiro do nosso idioma?
Maçaneta

2
@ Doorknob boa captura. Eu direi que um número inteiro resultante nunca será mais do que o tipo inteiro padrão do seu idioma. (por favor, não abuse isso e usar uma linguagem com inteiros de 1 bit)
FlipTack

Tudo bem assumir que a entrada é apenas maiúscula?
Adám

@ Adám muito, mas seu programa deve ser maiúsculas e minúsculas (ver casos de teste)
FlipTack

Como Unary, exceto que ele está codificando nomes de usuário em vez de BF
MilkyWay90

Respostas:


27

05AB1E , 4 bytes

D1ìH

Explicação

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

Se a entrada tiver caracteres hexadecimais inválidos, Hnão enviará nada, portanto o último valor na pilha será a entrada duplicada; é por isso que o programa imprime sua entrada em caso de entrada inválida.

Experimente online!


9
A ironia é bem forte aqui. 05AB1Eé um nome de usuário válido.
precisa saber é o seguinte

1
É isso mesmo, porém o nome foi escolhido como um número hexadecimal. Por isso, é :) válida
Osable

Gostaria de saber por que você estava enganando. Tentando pensar em uma maneira de usar $ em vez embora ....
Magia Octopus Urna

16

JavaScript (ES6), 15 bytes

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

Como funciona

'0x1'+sconverte a entrada em uma string hexadecimal literal com um prefixo 1, por exemplo 0x105ab1e. Em seguida, -0lança o resultado em um número. O JavaScript vê isso 0xno começo e tenta implicitamente converter de hexadecimal; se scontiver caracteres não-hexadecimais, isso retornará NaN. Como isso é falso (e a saída 0nunca pode ser fornecida por causa do anexo 1), podemos usar ||spara retornars se a conversão hexadecimal falhar.

Snippet de teste

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
Solução muito boa!
Grax32

Conversão implícita é verdadeiramente belo ...: ')
Downgoat

10

Python 2 , 44 bytes

Recebe a entrada como uma string entre aspas. -2 bytes graças a Rod!

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

Como garantimos que a entrada conterá apenas alfanuméricos e sublinhados, não há como criar Python válido depois 0x1de ter uma string hexadecimal. Se a entrada for qualquer outra coisa, o erro será ignorado e impresso como era originalmente.

Eu não conseguia fazer um regex corresponder mais curto que try/except. De fato, o regex mostrou-se terrivelmente detalhado:

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

Você também pode substituir a=int('1'+a,16)com exec'a=0x1'+a(provavelmente, necessidade de teste)
Rod

Você sabe, teremos a mesma resposta exata se eu continuar jogando golfe, certo?
Anthony Pham 2/17

Não funciona para nomes de usuário que seriam válidos em Python nesse contexto, por exemplo "+input()".
precisa saber é o seguinte

falhar por "abc" (note o espaço em branco no final) (int permite espaços em branco no início e fim)
Siphor

Eu não sei exatamente como ele é para Python 2, mas acho que você pode remover os suportes ()eminput()
RudolfJelin

8

Perl 6 , 19 bytes

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

Teste-o

Expandido:

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

-1 byte graças a @ardnew .

26 bytes de código -p sinalizador.

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

Forneça a entrada sem nova linha final. Comecho -n por exemplo:

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

Explicação
Isso é bastante direto: /[^0-9a-f]/ié verdadeiro se a entrada contiver um caractere diferente daqueles permitidos dentro de números hexadecimais. Se for falso, $_(que contém a entrada), é definido como o valor convertido (a conversão é feita pelo builtin hex).
E $_é implicitamente impresso graças à -pbandeira.


você pode raspar um byte, evitando a operação ternária$_=hex"1$_"if!/[^0-9a-f]/i
ardnew

@ardnew Hum, agora que você diz, esse ternário foi horrível ... De qualquer forma, obrigado!
Dada


3

Lote, 33 bytes

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

Como funciona

Uma sequência é passada como argumento, 1 é anexado a ela e a sequência é implicitamente convertida em decimal e impressa. Se a sequência não for hexadecimal válida, ela é simplesmente exibida.

Deve-se observar que, como a matemática do lote usa números inteiros assinados de 32 bits, o maior nome de usuário permitido é FFFFFFF.

cmd /c pega o próximo comando, executa-o em um novo terminal e sai.

set /a executa matemática e exibe implicitamente o resultado em decimal quando não armazenado em uma variável.

0x1%1 instrui o conjunto a acrescentar 1 ao primeiro argumento (isso é fácil, pois todas as variáveis ​​de lote são cadeias) e indica que a cadeia deve ser tratada como hexadecimal.

2>nul silencia quaisquer erros resultantes de um número hexadecimal inválido

||é um OR lógico e executa o comando à direita se o comando à esquerda não for bem-sucedido. Os parênteses compõem tudo até esse ponto, um comando.

echo %1 simplesmente exibe o primeiro argumento.


3

Lisp comum, 71

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

Testes

Definir função

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

Cite uma lista das entradas esperadas, conforme fornecido pela pergunta:

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

Analise e colete resultados

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

Verifique se as saídas esperadas correspondem às reais:

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

2

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

Essa é uma função que pega a string como argumento e imprime o resultado em 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

Uso legal da parte implícita int:)
FlipTack

2

JavaScript: 46 41 bytes

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

O regex pode ser 2 bytes mais curto:/[^0-9a-f]/i
GilZ 2/17/17

Salvei 1 byte substituindo 0-9por \d, 3 bytes adicionando o sinalizador que não diferencia maiúsculas de minúsculas (obrigado @GilZ) e mais 2 bytes removendo F=, o que não é necessário. Obrigado pela sugestão.
Lucas

2

PHP, 42 bytes

hex2bin () retorna false se a entrada não for uma sequência hexadecimal válida. Isso é mais curto do que usar regex para procurar dígitos não hexadecimais, mas precisamos do operador @ porque ele não fica silencioso quando falha.

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

hex2binfalha em strings com comprimentos irregulares. Ainda dois bytes mais curtos do que com preg_match: porém, <?=@hex2bin($s=$argv[1])|@hex2bin($s.a)?hexdec("1$s"):$s;para 57 bytes.
Titus

2

bash, 46 35 31 bytes

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

Salve como um script e passe o nome de usuário como argumento.


1

Python 2 - 63., 52, 50., 46 bytes

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

Isso usa o Python int() que converte qualquer string com sua base apropriada em base 10. Nesse caso, a string é o número 1 anexado à entrada. Se a entrada for inválida (tiver caracteres diferentes de 0123456789ABCDEF(sem distinção entre maiúsculas e minúsculas), ela retornará 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

Experimente aqui!

Agradecemos ao @FlipTack por salvar 15 bytes!


E se a sequência não começar com um zero? Você só deve adicionar um à esquerda da sequência se começar com zero.
0JJxW9FMN

@FlipTack Opa, bobo eu.
0JMxW9FMN

1

Ruby, 47 44 bytes

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

Eu poderia remover 3 bytes mudando putsparap , mas sinto que a saída seria considerada incorreta, pois tem uma nova linha no final.

Editar: alterado putspara pcomo as novas linhas à direita geralmente são aceitas, obrigado @Mego.


Novas linhas à direita no STDOUT geralmente são consideradas aceitáveis.
Mego3


1

Dyalog APL , 37 bytes

Não usa validação interna ou conversão hex-dec. Requer ⎕IO←0qual é o padrão em muitos sistemas.

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

Ungolfed:

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

d ← ⎕D , 6 ↑ ⎕Ad recebe D igits seguidos pelos 6 primeiros elementos do alfabeto A

u ← 1 (819⌶) ⍵u recebe argumento em maiúsculas (819 ≈ "Grande")

∧/ u ∊ d: se todos os elementos de u são membros de d , então:
16 ⊥ 1 , d ⍳ u encontre os índices de u em d , adicione um 1 e avalie como base 16

else: retorna o argumento (não modificado)

TryAPL online:

  1. Definir ⎕IOa zero, definir um substituto para (proibido em TryAPL por razões de segurança), e um conjunto ⎕PP( P rint P recision) a 10, para os grandes resultados

  2. Experimente todos os casos de teste


1

REXX, 49. 48 bytes

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

O signal on syntaxdiz o intérprete para saltar para o rótulo syntaxsempre que ocorre um erro de sintaxe. O programa tenta reatribuir acom uma versão convertida hexadecimal em decimal com 1 inicial, mas pula para o syntaxrótulo se isso falhar. Se a conversão for aprovada, ela simplesmente ignora o rótulo e gera a variável reatribuída.


2
Você poderia explicar o seu código por favor
Anthony Pham

0

PowerShell , 35 bytes

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

Experimente online! ou Execute todos os casos de teste!

Explicação

  1. Pegue o parâmetro ( $v)
  2. Crie uma matriz de dois elementos em que o primeiro elemento ( 0) seja o resultado de uma string contendo 0x1$vcanalizado em Invoke-Expression( iex), enquanto atribui esse valor simultaneamente $h. Se a conversão falhar, $hpermanecerá $null.
  3. O segundo elemento da matriz é o parâmetro original.
  4. Índice na matriz com o -notvalor booleano de $h. O que quer que $hseja será implicitamente convertido em [bool]( $nullno caso de uma conversão inválida se tornará $false, um número inteiro positivo no caso de uma conversão bem-sucedida se tornará $true) antes de ser negado, o qual será convertido implicitamente [int]pelo indexador de matriz []( $trueserá 1, $falseserá 0), resultando no primeiro elemento da matriz (o resultado da conversão) escolhido se a conversão foi bem-sucedida e no segundo elemento escolhido se a conversão não tiver êxito.

0

Scala, 40 bytes

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

Uso:

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

Explicação:

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 bytes

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

Sem jogar com casos de teste:

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

Experimente on-line


0

Dardo, 51 bytes

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

Experimente aqui

A maior parte da sobrecarga vem de parâmetros nomeados ... Oh, bem!

Pelo menos o Dart permite que você seja digitado dinamicamente, se desejar: D

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.