Conversione di "0xUsernames"


25

0xUsernames

Ci sono così tante persone che usano un servizio di messaggistica che stanno esaurendo lo spazio per memorizzare tutti i nomi utente! Per risolvere questo problema, inizieranno a memorizzare i nomi utente come esadecimali, ove possibile.

Se un nome utente è composto solo da caratteri 0123456789ABCDEF (senza distinzione tra maiuscole e minuscole), può essere convertito in esadecimale e archiviato come numero intero. Ad esempio, il nome utente ba5eba11può essere interpretato come 0xBA5EBA11un numero intero esadecimale.

Ma che dire 05AB1E? Ha uno zero iniziale, che andrebbe perso. Quindi, ogni volta che convertiamo un nome utente, ci assicuriamo di anteporre a1 prima di leggerlo come intero.


La sfida

Il tuo compito è scrivere un programma o una funzione che, dato un nome utente non vuoto come stringa, "hexa-comprime" il nome utente:

  • Se può essere interpretato come un numero intero esadecimale, anteporre un 1, interpretarlo come esadecimale e quindi stampare il risultato come base 10.
  • Altrimenti, restituisci la stringa non modificata.

Questo è , quindi vince la soluzione più breve (in byte)! Le funzioni di conversione di base integrate sono consentite.


Casi test

Puoi presumere che qualsiasi numero intero risultante rientri nell'intervallo intero standard della tua lingua.

Come per i nomi utente sulla maggior parte dei sistemi di messaggistica, le stringhe di input conterranno solo caratteri alfanumerici e di sottolineatura.

Ricorda, devi sempre aggiungere un lead 1prima della conversione!

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

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

Per riferimento, ecco un'implementazione di Python 3 che ho usato per i casi di test (non risolto):

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, non l'ho visto. Inoltre, cosa succede se alcuni dei più grandi casi di test generano numeri al di fuori dei limiti del più grande tipo intero della nostra lingua?
Maniglia della porta

2
@Doorknob buona cattura. Dirò che un numero intero risultante non sarà mai più del tipo intero standard della tua lingua. (per favore non abusare di questo e usare una lingua con numeri interi a 1 bit)
FlipTack

Va bene supporre che l'input sia solo in maiuscolo?
Adám,

@ Adám dispiace, ma il tuo programma non dovrebbe fare distinzione tra maiuscole e minuscole (vedi casi di test)
FlipTack

Come Unary, tranne per il fatto che sta codificando nomi utente anziché BF
MilkyWay90 il

Risposte:


27

05AB1E , 4 byte

D1ìH

Spiegazione

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

Se l'input ha caratteri esadecimali non validi, H non invierà nulla, quindi l'ultimo valore nello stack sarà l'input duplicato, ecco perché il programma stampa il suo input in caso di input non valido.

Provalo online!


9
L'ironia è piuttosto forte qui. 05AB1Eè un nome utente valido.
devRicher

1
Esatto, tuttavia il nome è stato scelto come numero esadecimale. Quindi è valido :)
Osable il

Mi chiedevo perché stavi ingannando. Sto cercando di pensare a un modo per usare $ invece ...
Magic Octopus Urn

16

JavaScript (ES6), 15 byte

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

Come funziona

'0x1'+sconverte l'input in una stringa esadecimale letterale con un anteposto 1, ad es 0x105ab1e. Quindi -0lancia il risultato su un numero. JavaScript vede 0xall'inizio e tenta implicitamente di convertire da esadecimale; se scontiene caratteri non esadecimali, questo restituisce NaN. Poiché questo è falso (e l'output 0non può mai essere dato a causa della anteposta 1), possiamo usare ||sper restituire sse la conversione esadecimale fallisce.

Snippet di prova

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
Ottima soluzione!
Grax32,

Il casting implicito è veramente bello ...: ')
Downgoat il

10

Python 2 , 44 byte

Accetta l'input come stringa tra virgolette. -2 byte grazie a Rod!

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

Poiché garantiamo che l'input conterrà solo caratteri alfanumerici e di sottolineatura, non è possibile creare dopo Python valido 0x1 se non avere una stringa esadecimale. Se l'input è qualcos'altro, l'errore viene ignorato e viene stampato com'era in origine.

Non riesco a far corrispondere una regex a una durata inferiore try/except. In effetti, regex si è rivelato terribilmente prolisso:

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

puoi anche sostituirlo a=int('1'+a,16)con exec'a=0x1'+a(probabilmente, devi testare)
Rod

Sai, avremo la stessa risposta esatta se continuo a giocare a golf, giusto?
Anthony Pham,

Non funziona con nomi utente che sarebbero validi Python in quel contesto, ad es "+input()".
heinrich5991,

non riesce per "abc" (notare lo spazio bianco alla fine) (int consente lo spazio bianco all'inizio e alla fine)
Siphor

Non so esattamente come sia per Python 2, ma penso che puoi rimuovere le parentesi ()ainput()
RudolfJelin

8

Perl 6 , 19 byte

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

Provalo

Allargato:

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

-1 byte grazie a @ardnew .

26 byte di codice + -pflag.

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

Fornire l'input senza newline finale. Con echo -nper esempio:

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

Spiegazione
Questo è piuttosto semplice: /[^0-9a-f]/iè vero se l'input contiene un carattere diverso da quelli consentiti all'interno di numeri esadecimali. Se è falso, $_(che contiene l'input) è impostato sul valore convertito (la conversione viene eseguita dall'integrato hex).
Ed $_è implicitamente stampato grazie alla -pbandiera.


puoi radere un byte evitando l'operazione ternaria$_=hex"1$_"if!/[^0-9a-f]/i
ardnew

@ardnew Hum, ora che lo dici, quel ternario era abbastanza orribile ... Comunque, grazie!
Dada,


3

Lotto, 33 byte

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

Come funziona

Una stringa viene passata come argomento, 1 viene anteposta ad essa e la stringa viene convertita implicitamente in decimale e stampata. Se la stringa non è esadecimale valida, viene semplicemente visualizzata.

Va notato che poiché la matematica batch utilizza numeri interi a 32 bit con segno, il nome utente più grande consentito è FFFFFFF.

cmd /c accetta il comando successivo, lo esegue in un nuovo terminale ed esce.

set /a esegue la matematica e visualizza implicitamente il risultato in decimali quando non è memorizzato in una variabile.

0x1%1 indica a set di anteporre un 1 al primo argomento (questo è facile poiché tutte le variabili batch sono stringhe) e indica che la stringa deve essere trattata come esadecimale.

2>nul mette a tacere tutti gli errori risultanti da un numero esadecimale non valido

||è un OR logico ed esegue il comando a destra se il comando a sinistra non ha esito positivo. Le parentesi fanno di tutto un comando fino a questo punto.

echo %1 visualizza semplicemente il primo argomento.


3

Lisp comune, 71

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

test

Definire la funzione

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

Cita un elenco di input previsti, come indicato dalla domanda:

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

Analizzalo e raccogli i risultati

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

Verificare che gli output previsti corrispondano a quelli effettivi:

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

2

C, 108 byte

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

Questa è una funzione che accetta la stringa come argomento e stampa il risultato su 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

Bello l'uso di implicito int:)
FlipTack

2

JavaScript: 46 41 byte

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

Il regex può essere più corto di 2 byte:/[^0-9a-f]/i
GilZ

Ho salvato 1 byte sostituendo 0-9con \d, 3 byte aggiungendo il flag senza distinzione tra maiuscole e minuscole (grazie a @GilZ) e altri 2 byte rimuovendo F=, il che non è necessario. Grazie per il suggerimento
Luca

2

PHP, 42 byte

hex2bin () restituisce false se l'input non è una stringa esadecimale valida. È più breve dell'uso di regex per cercare cifre non esadecimali, ma abbiamo bisogno dell'operatore @ perché non tace quando fallisce.

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

hex2binnon riesce per stringhe con lunghezze irregolari. Ancora due byte più brevi di quelli con preg_matchperò: <?=@hex2bin($s=$argv[1])|@hex2bin($s.a)?hexdec("1$s"):$s;per 57 byte.
Tito

2

bash, 46 35 31 byte

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

Salva come script e passa il nome utente come argomento.


1

Python 2 - 63, 52, 50, 46 byte

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

Questo utilizza Python int()che converte qualsiasi stringa con la sua base appropriata in base 10. In questo caso, la stringa è il numero 1 collegato all'input. Se l'input non è valido (ha caratteri diversi da 0123456789ABCDEF(maiuscole e minuscole), restituisce 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

Provalo qui!

Grazie a @FlipTack per aver salvato 15 byte!


Cosa succede se la stringa non inizia con uno zero? Dovresti aggiungere uno a sinistra della stringa solo se inizia con uno zero.
0WJYxL9FMN

@FlipTack Whoops, sciocco me.
0WJYxL9FMN

1

Ruby, 47 44 byte

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

ho potuto rimuovere 3 byte cambiando putsper p, ma mi sento come l'uscita sarebbe considerato sbagliato in quanto ha una nuova riga alla fine.

Modifica: modificato putsin pquanto le nuove righe finali sono generalmente accettate, grazie @Mego.


Le nuove righe finali su STDOUT sono generalmente considerate accettabili.
Mego


1

Dyalog APL , 37 byte

Non utilizza alcuna convalida integrata o conversione hex-dec. Richiede il ⎕IO←0valore predefinito su molti sistemi.

{∧/(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 ottiene D igits seguita dai primi 6 elementi di A dell'alfabeto

u ← 1 (819⌶) ⍵u ottiene l'argomento maiuscolo (819 ≈ "Grande")

∧/ u ∊ d: se tutti gli elementi di u sono membri di d , allora:
16 ⊥ 1 , d ⍳ u trova gli indici di u in d , anteponi un 1 e valuta come base 16

else: restituisce l'argomento (non modificato)

TryAPL online:

  1. Impostare ⎕IOa zero, definire un sostituto per (proibito su TryAPL per motivi di sicurezza) e le impostazioni ⎕PP( P tampa P recision) a 10 per i grandi risultati

  2. Prova tutti i casi di test


1

REXX, 49 48 byte

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

Il signal on syntaxdice all'interprete di saltare all'etichetta syntaxogni volta che si verifica un errore di sintassi. Il programma tenta di riassegnare acon una versione convertita esadecimale con un 1 iniziale, ma salta syntaxall'etichetta se fallisce. Se la conversione viene eseguita, ignora semplicemente l'etichetta e genera la variabile riassegnata.


2
Potresti spiegare il tuo codice per favore
Anthony Pham,

0

PowerShell , 35 byte

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

Provalo online! oppure Esegui tutti i casi di test!

Spiegazione

  1. Prendi parametro ($v )
  2. Crea un array a due elementi in cui il primo elemento ( 0) è il risultato di una stringa contenente il 0x1$vpiping in Invoke-Expression( iex), mentre allo stesso tempo assegna questo valore a $h. Se la conversione fallisce, $hrimarrà $null.
  3. Il secondo elemento dell'array è il parametro originale.
  4. Indice nell'array con il -notvalore booleano di $h. Qualunque cosa $hverrà convertita in modo implicito in [bool]( $nullnel caso di una conversione non valida, diventerà $falseun numero intero positivo in caso di conversione riuscita $true) prima di essere negata, che viene quindi implicitamente convertita [int]dall'indicizzatore di array []( $truesarà 1, $falsesarà 0), ottenendo così il primo elemento dell'array (il risultato della conversione) scelto se la conversione ha avuto esito positivo e il secondo elemento scelto se la conversione non ha avuto esito positivo.

0

Scala, 40 byte

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

Spiegazione:

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 byte

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

Non rigato con casi di test:

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

Prova online


0

Dardo, 51 byte

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

Provalo qui

Gran parte dell'overhead proviene da parametri nominati ... Oh bene!

Almeno Dart ti consente di essere digitato in modo dinamico, se vuoi: D

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.