Convertir "0xNombres de usuario"

25

0xNombres de usuario

¡Hay tantas personas que usan un servicio de mensajería que se están quedando sin espacio para almacenar todos los nombres de usuario! Para solucionar esto, comenzarán a almacenar nombres de usuario como hexadecimales, siempre que sea posible.

Si un nombre de usuario consta solo de los caracteres 0123456789ABCDEF(sin distinción entre mayúsculas y minúsculas), se puede convertir a hexadecimal y almacenar como un entero. Por ejemplo, el nombre de usuario ba5eba11se puede interpretar como 0xBA5EBA11un entero hexadecimal.

¿Pero que pasa 05AB1E? Eso tiene un cero a la izquierda, que se perdería. Entonces, cada vez que convertimos un nombre de usuario, nos aseguramos de anteponer un 1antes de leerlo como un entero.


El reto

Su tarea es escribir un programa o función que, dado un nombre de usuario no vacío como una cadena, 'comprima hexa' el nombre de usuario:

  • Si se puede interpretar como un entero hexadecimal, anteponga un 1, interprete como hexadecimal y luego imprima el resultado como base 10.
  • De lo contrario, solo devuelva la cadena sin modificar.

Este es el , por lo que gana la solución más corta (en bytes). Se permiten funciones de conversión de base incorporadas.


Casos de prueba

Puede suponer que los enteros resultantes estarán dentro del rango de enteros estándar de su idioma.

Al igual que con los nombres de usuario en la mayoría de los sistemas de mensajería, las cadenas de entrada solo contendrán caracteres alfanuméricos y guiones bajos.

Recuerde, ¡siempre necesita agregar un líder 1antes de la conversión!

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

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

Como referencia, aquí hay una implementación de Python 3 que utilicé para los casos de prueba (sin golf):

import re

def convert_name(name):
    if re.fullmatch('^[0-9A-Fa-f]+$', name):
        return int('1' + name.upper(), base = 16)
    else:
        return name
FlipTack
fuente
Ah, no vi eso. Además, ¿qué pasa si algunos de los casos de prueba más grandes resultan en números fuera de los límites del tipo entero más grande de nuestro idioma?
Pomo de la puerta
2
@Doorknob buena captura. Diré que un entero resultante nunca será más que el tipo de entero estándar de su idioma. (por favor no abuses de esto y usa un lenguaje con enteros de 1 bit)
FlipTack
¿Está bien asumir que la entrada es solo mayúscula?
Adám
@ Adám lo siento, pero su programa no debe ser sensible a mayúsculas y minúsculas (ver casos de prueba)
FlipTack
Como Unary excepto que está codificando nombres de usuario en lugar de BF
MilkyWay90

Respuestas:

27

05AB1E , 4 bytes

D1ìH

Explicación

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

Si la entrada tiene caracteres hexadecimales no válidos, Hno empujará nada, por lo que el último valor en la pila será la entrada duplicada, es por eso que el programa imprime su entrada en caso de entrada no válida.

Pruébalo en línea!

Osable
fuente
99
La ironía es bastante fuerte aquí. 05AB1Ees un nombre de usuario válido
devRicher
1
Así es, sin embargo, el nombre fue elegido como un número hexadecimal. Por lo tanto, es válido :)
Osable
Me preguntaba por qué te estabas engañando. Tratando de pensar en una forma de usar $ en su lugar ...
Urna de pulpo mágico el
16

JavaScript (ES6), 15 bytes

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

Cómo funciona

'0x1'+sconvierte la entrada en una cadena hexadecimal literal con un antecedente 1, por ejemplo 0x105ab1e. Luego -0arroja el resultado a un número. JavaScript lo ve 0xal principio e intenta implícitamente convertirlo de hexadecimal; si scontiene caracteres no hexadecimales, esto devuelve NaN. Como esto es falso (y la salida 0nunca se puede dar debido al antecedente 1), podemos usar ||spara regresar ssi la conversión hexadecimal falló.

Fragmento de prueba

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

ETHproducciones
fuente
2
Muy buena solución!
Grax32
El casting implícito es realmente hermoso ...: ')
Downgoat
10

Python 2 , 44 bytes

Toma la entrada como una cadena entre comillas. -2 bytes gracias a Rod!

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

Como se garantiza que la entrada solo contendrá caracteres alfanuméricos y guiones bajos, no hay forma de crear Python válido después 0x1de tener una cadena hexadecimal. Si la entrada es otra cosa, el error se ignora y se imprime como estaba originalmente.

Parece que no puedo hacer una coincidencia de expresiones regulares más corta que try/except. De hecho, regex resultó ser terriblemente detallado:

import re
lambda n:re.match('^[0-9A-F]+$',n,2)and int('1'+n,16)or n
FlipTack
fuente
También puede reemplazar a=int('1'+a,16)con exec'a=0x1'+a(probablemente, necesita probar)
Rod
Sabes, tendremos la misma respuesta exacta si sigo jugando al golf, ¿verdad?
Anthony Pham
No funciona para nombres de usuario que serían Python válidos en ese contexto, por ejemplo "+input()".
heinrich5991
falla para "abc" (observe el espacio en blanco al final) (int permite espacios en blanco al principio y al final)
Siphor
No sé exactamente cómo es para Python 2, pero creo que puedes quitar los corchetes ()eninput()
RudolfJelin
8

Perl 6 , 19 bytes

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

Pruébalo

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

}
Brad Gilbert b2gills
fuente
7

Perl, 27 bytes

-1 byte gracias a @ardnew .

26 bytes de código + -pbandera.

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

Proporcione la entrada sin nueva línea final. Con echo -npor ejemplo:

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

Explicación
Esto es bastante sencillo: /[^0-9a-f]/ies cierto si la entrada contiene un carácter distinto de los permitidos dentro de los números hexadecimales. Si es falso, $_(que contiene la entrada) se establece en el valor convertido (la conversión se realiza por el incorporado hex).
Y $_se imprime implícitamente gracias a la -pbandera.

Dada
fuente
puedes afeitarte un byte evitando la operación ternaria$_=hex"1$_"if!/[^0-9a-f]/i
ardnew
@ardnew Hum, ahora que lo dices, ese ternario fue bastante horrible ... De todos modos, ¡gracias!
Dada
3

Lote, 33 bytes.

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

Cómo funciona

Se pasa una cadena como argumento, se antepone 1, y la cadena se convierte implícitamente a decimal y se imprime. Si la cadena no es hexadecimal válida, simplemente se muestra.

Cabe señalar que, como las matemáticas por lotes utilizan enteros de 32 bits con signo, el nombre de usuario más grande permitido es FFFFFFF.

cmd /c toma el siguiente comando, lo ejecuta en una nueva terminal y sale.

set /a realiza cálculos matemáticos y muestra implícitamente el resultado en decimal cuando no se almacena en una variable.

0x1%1 le dice a set que anteponga un 1 al primer argumento (esto es fácil ya que todas las variables por lotes son cadenas) e indica que la cadena debe tratarse como hexadecimal.

2>nul silencia cualquier error resultante de un número hexadecimal no válido

||es un OR lógico y ejecuta el comando de la derecha si el comando de la izquierda no tiene éxito. Los paréntesis hacen que todo hasta este punto sea un comando.

echo %1 simplemente muestra el primer argumento.

Algo oscuro
fuente
3

Lisp común, 71

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

Pruebas

Definir función

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

Cite una lista de entradas esperadas, como se indica en la pregunta:

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

Analízalo y recoge 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"))

Compruebe que las salidas esperadas coinciden con las reales:

CL-USER> (every (lambda (x) (equalp (second x) (third x))) *)
T
volcado de memoria
fuente
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);}

Esta es una función que toma la cadena como argumento e imprime el resultado en 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
Pomo de la puerta
fuente
Buen uso de implícito int:)
FlipTack
2

JavaScript: 46 41 bytes

s=>/[^\dA-F]/i.test(s)?s:parseInt(1+s,16)
Luke
fuente
La expresión regular puede ser 2 bytes más corta:/[^0-9a-f]/i
GilZ
Ahorré 1 byte reemplazándolo 0-9por \d3 bytes agregando la marca que no distingue entre mayúsculas y minúsculas (gracias @GilZ) y 2 bytes más eliminando F=, lo que no es necesario. Gracias por la sugerencia.
Lucas
2

PHP, 42 bytes

hex2bin () devuelve falso si la entrada no es una cadena hexadecimal válida. Esto es más corto que usar expresiones regulares para buscar dígitos no hexadecimales, pero necesitamos el operador @ porque no es silencioso cuando falla.

<?=@hex2bin($s=$argv[1])?hexdec("1$s"):$s;
Alex Howansky
fuente
hex2binfalla para cadenas con longitudes desiguales. Aún dos bytes más cortos que con preg_matchaunque: <?=@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

Guardar como secuencia de comandos y pasar el nombre de usuario como argumento.

Mitchell Spector
fuente
1

Python 2 - 63, 52, 50, 46 bytes

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

Esto utiliza Python int()que convierte cualquier cadena con su base apropiada en la base 10. En este caso, la cadena es el número 1 adjunto a la entrada. Si la entrada no es válida (tiene caracteres distintos a 0123456789ABCDEF(no distingue entre mayúsculas y minúsculas), devuelve 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

Pruébalo aquí!

¡Gracias a @FlipTack por guardar 15 bytes!

Anthony Pham
fuente
¿Qué pasa si la cadena no comienza con un cero? Solo debe agregar un uno a la izquierda de la cadena si comienza con un cero.
0WJYxW9FMN
@FlipTack Whoops, tonto de mí.
0WJYxW9FMN
1

Ruby, 47 44 bytes

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

Yo podría eliminar 3 bytes cambiando putspara p, pero siento que la salida sería considerado equivocada ya que tiene una nueva línea al final.

Editar: Modificado putsporque las pnuevas líneas finales generalmente se aceptan, gracias @Mego.

Simon Landry
fuente
Las nuevas líneas finales en STDOUT generalmente se consideran aceptables.
Mego
1

Japt , 11 bytes

+`0x1{U}`ªU

Pruébalo en línea!

¡Muchas gracias a ETHproductions!

Oliver
fuente
1
Este es uno de los raros casos en los que puede deshacerse del espacio :-) (Además, el enlace TIO es al programa "Hello, World!")
ETHproductions
1

Dyalog APL , 37 bytes

No utiliza validación integrada o conversión hexadecimal. Requiere ⎕IO←0cuál es el predeterminado en muchos sistemas.

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

Sin golf:

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

d ← ⎕D , 6 ↑ ⎕Ad obtiene D igits seguidos de los primeros 6 elementos del alfabeto A

u ← 1 (819⌶) ⍵u obtiene argumento en mayúsculas (819 ≈ "Big")

∧/ u ∊ d: si todos los elementos de u son miembros de d , entonces:
16 ⊥ 1 , d ⍳ u encuentre los índices de u en d , anteponga un 1 y evalúe como base 16

else: devuelve el argumento (sin modificar)

TryAPL en línea:

  1. Ajuste ⎕IOa cero, definir un reemplazo para (prohibido en TryAPL por razones de seguridad), y un conjunto ⎕PP( P rint P recision) a 10 para los grandes resultados

  2. Prueba todos los casos de prueba

Adán
fuente
1

REXX 49 48 bytes

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

El signal on syntaxle dice al intérprete que salte a la etiqueta syntaxcada vez que se produce un error de sintaxis. El programa intenta reasignar acon una versión convertida de hexadecimal a decimal con un 1 inicial, pero salta a la syntaxetiqueta si eso falla. Si la conversión pasa, simplemente ignora la etiqueta y genera la variable reasignada.

idrougge
fuente
2
¿Podría explicar su código por favor
Anthony Pham
0

PowerShell , 35 bytes

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

Pruébalo en línea! o ejecutar todos los casos de prueba!

Explicación

  1. Tomar parámetro ( $v)
  2. Cree una matriz de dos elementos donde el primer elemento ( 0) sea el resultado de una cadena que contenga 0x1$ventubado en Invoke-Expression( iex), mientras asigna simultáneamente este valor a $h. Si la conversión falla, $hpermanecerá $null.
  3. El segundo elemento de la matriz es el parámetro original.
  4. Indice en la matriz con el -notvalor booleano de $h. Lo que $hsea ​​se convertirá implícitamente a [bool]( $nullen el caso de una conversión no válida, se convertirá en $falseun entero positivo en el caso de una conversión exitosa $true) antes de ser negado, que luego se convertirá implícitamente en [int]el indexador de matriz []( $trueserá 1, $falseserá 0), lo que resulta en el primer elemento de la matriz (el resultado de la conversión) elegido si la conversión fue exitosa, y el segundo elemento elegido si la conversión no fue exitosa.
briantista
fuente
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

Explicación:

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
  }
corvus_192
fuente
0

C #, 58 bytes

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

Sin golfos con casos de prueba:

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

Probar en línea

raznagul
fuente
0

Dart, 51 bytes

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

Pruébalo aquí

La mayor parte de la sobrecarga proviene de parámetros con nombre ... ¡Oh, bueno!

Al menos Dart te permite escribir de forma dinámica, si quieres: D

Dwayne Slater
fuente