Conversion de «0xUsernames»


25

0xUsernames

Il y a tellement de gens qui utilisent un service de messagerie qu'ils manquent d'espace pour stocker tous les noms d'utilisateur! Pour résoudre ce problème, ils vont commencer à stocker les noms d'utilisateur sous forme hexadécimale, si possible.

Si un nom d'utilisateur se compose uniquement des caractères 0123456789ABCDEF(insensible à la casse), il peut être converti en hexadécimal et stocké sous forme d'entier. Par exemple, le nom d'utilisateur ba5eba11peut être interprété comme 0xBA5EBA11un entier hexadécimal.

Mais qu'en est-il 05AB1E? Cela a un zéro de tête, qui serait perdu. Ainsi, chaque fois que nous convertissons un nom d'utilisateur, nous nous assurons de faire précéder un 1avant de le lire comme un entier.


Le défi

Votre tâche consiste à écrire un programme ou une fonction qui, étant donné un nom d'utilisateur non vide sous forme de chaîne, «hexa-compresse» le nom d'utilisateur:

  • S'il peut être interprété comme un entier hexadécimal, ajoutez un 1, interprétez-le comme hexadécimal, puis imprimez le résultat en base 10.
  • Sinon, renvoyez simplement la chaîne non modifiée.

Il s'agit de , donc la solution la plus courte (en octets) l'emporte! Les fonctions de conversion de base intégrées sont autorisées.


Cas de test

Vous pouvez supposer que tous les entiers résultants se trouvent dans la plage d'entiers standard de votre langue.

Comme pour les noms d'utilisateur sur la plupart des systèmes de messagerie, les chaînes d'entrée ne contiendront que des caractères alphanumériques et des traits de soulignement.

N'oubliez pas, vous devez toujours ajouter un interligne 1avant la 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"

Pour référence, voici une implémentation de Python 3 que j'ai utilisée pour les cas de test (non golfée):

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, je n'ai pas vu ça. De plus, que se passe-t-il si certains des cas de test les plus importants aboutissent à des nombres en dehors des limites du plus grand type entier de notre langue?
Poignée de porte

2
@ Doorknob bonne capture. Je dirai qu'un entier résultant ne sera jamais plus que le type entier standard de votre langue. (veuillez ne pas abuser de cela et utiliser un langage avec des entiers 1 bit)
FlipTack

Est-il acceptable de supposer que l'entrée est en majuscules uniquement?
Adám

@ Adám désolé, mais votre programme doit être insensible à la casse (voir les cas de test)
FlipTack

Comme Unary, sauf qu'il encode les noms d'utilisateur au lieu de BF
MilkyWay90

Réponses:


27

05AB1E , 4 octets

D1ìH

Explication

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

Si l'entrée contient des caractères hexadécimaux invalides, Helle ne poussera rien, donc la dernière valeur de la pile sera l'entrée dupliquée, c'est pourquoi le programme imprime son entrée en cas d'entrée invalide.

Essayez-le en ligne!


9
L'ironie est assez forte ici. 05AB1Eest un nom d'utilisateur valide.
devRicher

1
C'est vrai, mais le nom a été choisi comme un nombre hexadécimal. Par conséquent, il est valide :)
Osable

Vous vous demandiez pourquoi vous trompiez. Essayer de penser à un moyen d'utiliser $ à la place cependant ....
Urne Magic Octopus le

16

JavaScript (ES6), 15 octets

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

Comment ça marche

'0x1'+sconvertit l'entrée en une chaîne hexadécimale littérale avec un préfixe 1, par exemple 0x105ab1e. -0Convertit ensuite le résultat en un nombre. JavaScript voit le 0xau début et essaie implicitement de convertir de l'hexadécimal; si scontient des caractères non hexadécimaux, cela renvoie NaN. Puisque c'est faux (et que la sortie 0ne peut jamais être donnée à cause du préfixé 1), nous pouvons utiliser ||spour retourner ssi la conversion hexadécimale a échoué.

Extrait de test

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
Très belle solution!
Grax32

Le casting implicite est vraiment beau ...: ')
Downgoat

10

Python 2 , 44 octets

Prend l'entrée comme une chaîne entre guillemets. -2 octets grâce à Rod!

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

Comme nous sommes garantis que l'entrée ne contiendra que des caractères alphanumériques et des traits de soulignement, il n'y a aucun moyen de créer un Python valide après 0x1avoir une chaîne hexadécimale. Si l'entrée est autre chose, l'erreur est ignorée et s'imprime telle qu'elle était à l'origine.

Je n'arrivais pas à faire une correspondance regex plus courte que try/except. En fait, l'expression régulière s'est avérée terriblement verbeuse:

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

vous pouvez également remplacer a=int('1'+a,16)par exec'a=0x1'+a(probablement, besoin de tester)
Rod

Vous savez, nous aurons la même réponse exacte si je continue de jouer au golf, n'est-ce pas?
Anthony Pham

Ne fonctionne pas pour les noms d'utilisateurs qui seraient valides Python dans ce contexte, par exemple "+input()".
heinrich5991

échoue pour "abc" (remarquez les espaces à la fin) (int autorise les espaces au début et à la fin)
Siphor

Je ne sais pas exactement comment c'est pour Python 2, mais je pense que vous pouvez supprimer les crochets ()àinput()
RudolfJelin

8

Perl 6 , 19 octets

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

Essaye-le

Étendu:

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

-1 octet grâce à @ardnew .

26 octets de code + -p indicateur.

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

Fournissez l'entrée sans nouvelle ligne finale. Avececho -n par exemple:

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

Explication
C'est assez simple: /[^0-9a-f]/ic'est vrai si l'entrée contient un caractère autre que ceux autorisés à l'intérieur des nombres hexadécimaux. S'il est faux, $_(qui contient l'entrée), il est défini sur la valeur convertie (la conversion est effectuée par la fonction intégrée hex).
Et $_est implicitement imprimé grâce au -pdrapeau.


vous pouvez vous raser un octet en évitant l'opération ternaire$_=hex"1$_"if!/[^0-9a-f]/i
ardnew

@ardnew Hum, maintenant que vous le dites, ce ternaire était plutôt horrible ... Quoi qu'il en soit, merci!
Dada


3

Lot, 33 octets

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

Comment ça marche

Une chaîne est passée en argument, 1 y est ajoutée et la chaîne est implicitement convertie en décimal et imprimée. Si la chaîne n'est pas hexadécimale valide, elle est simplement affichée.

Il convient de noter que, puisque les calculs par lots utilisent des entiers 32 bits signés, le plus grand nom d'utilisateur autorisé est FFFFFFF.

cmd /c prend la commande suivante, l'exécute dans un nouveau terminal et quitte.

set /a effectue des calculs et affiche implicitement le résultat en décimal lorsqu'il n'est pas stocké dans une variable.

0x1%1 indique à set de ajouter un 1 au premier argument (c'est facile car toutes les variables batch sont des chaînes) et indique que la chaîne doit être traitée comme hexadécimale.

2>nul supprime toutes les erreurs résultant d'un nombre hexadécimal non valide

||est un OU logique et exécute la commande à droite si la commande à gauche échoue. Les parenthèses font tout jusqu'à ce point une commande.

echo %1 affiche simplement le premier argument.


3

Lisp commun, 71

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

Les tests

Définir la fonction

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

Citez une liste des entrées attendues, comme indiqué par la 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")

Analyser et collecter les résultats

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

Vérifiez que les sorties attendues correspondent aux sorties réelles:

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

2

C, 108 octets

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

Il s'agit d'une fonction qui prend la chaîne en argument et imprime le résultat dans 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

2

JavaScript: 46 41 octets

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

L'expression régulière peut être plus courte de 2 octets:/[^0-9a-f]/i
GilZ

J'ai économisé 1 octet en remplaçant 0-9 par \d, 3 octets en ajoutant l'indicateur insensible à la casse (merci @GilZ) et 2 octets supplémentaires en supprimant F=, ce qui n'est pas nécessaire. Merci pour la suggestion.
Luke

2

PHP, 42 octets

hex2bin () renvoie false si l'entrée n'est pas une chaîne hexadécimale valide. C'est plus court que d'utiliser l'expression régulière pour rechercher des chiffres non hexadécimaux, mais nous avons besoin de l'opérateur @ car il n'est pas silencieux lorsqu'il échoue.

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

hex2binéchoue pour les cordes de longueurs inégales. Encore deux octets de moins qu'avec preg_match: <?=@hex2bin($s=$argv[1])|@hex2bin($s.a)?hexdec("1$s"):$s;pour 57 octets.
Titus

2

frapper, 46 35 31 octets

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

Enregistrez en tant que script et passez le nom d'utilisateur en argument.


1

Python 2 - 63, 52, 50, 46 octets

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

Cela utilise Python int()qui convertit n'importe quelle chaîne avec sa base appropriée en base 10. Dans ce cas, la chaîne est le numéro 1 attaché à l'entrée. Si l'entrée n'est pas valide (a des caractères autres que 0123456789ABCDEF(insensible à la casse), elle renvoie 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

Essayez-le ici!

Merci à @FlipTack pour avoir économisé 15 octets!


Et si la chaîne ne commence pas par un zéro? Vous ne devez ajouter un un à gauche de la chaîne que s'il commence par un zéro.
0WJYxW9FMN

@FlipTack Oups, idiot moi.
0WJYxW9FMN

1

Rubis, 47 44 octets

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

Je pourrais supprimer 3 octets en changeant putspour p, mais j'ai l'impression que la sortie serait considérée comme incorrecte car elle a une nouvelle ligne à la fin.

Edit: Changement putspour pque sont généralement sauts de lignes acceptées, merci @Mego.


Les sauts de ligne sur STDOUT sont généralement considérés comme acceptables.
Mego


1

Dyalog APL , 37 octets

N'utilise aucune validation intégrée ou conversion hex-dec. Requiert ⎕IO←0ce qui est par défaut sur de nombreux systèmes.

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

Non golfé:

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

d ← ⎕D , 6 ↑ ⎕Ad obtient D igits suivi des 6 premiers éléments de l' alphabet A

u ← 1 (819⌶) ⍵u se met en majuscule (819 argument "Big") argument

∧/ u ∊ d: si tous les éléments de u sont membres de d , alors:
16 ⊥ 1 , d ⍳ u trouver les indices de u dans d , ajouter un 1 au début et évaluer comme base 16

else: retourne l'argument (non modifié)

TryAPL en ligne:

  1. Mettre ⎕IOà zéro, définir un remplacement pour (interdit sur TryAPL pour des raisons de sécurité), et un ensemble ⎕PP( P Rint P recision) à 10 pour les grands résultats

  2. Essayez tous les cas de test


1

REXX, 49 48 octets

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

Le signal on syntaxdit à l'interpréteur de sauter à l'étiquette syntaxchaque fois qu'une erreur de syntaxe se produit. Le programme essaie de se réaffecter aavec une version convertie hexadécimale en décimale avec un 1 en tête, mais passe à l' syntaxétiquette en cas d'échec. Si la conversion réussit, elle ignore simplement l'étiquette et génère la variable réaffectée.


2
Pourriez-vous expliquer votre code s'il vous plaît
Anthony Pham

0

PowerShell , 35 octets

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

Essayez-le en ligne! ou Exécutez tous les cas de test!

Explication

  1. Prendre le paramètre ( $v)
  2. Créez un tableau à deux éléments où le premier élément ( 0) est le résultat d'une chaîne contenant 0x1$vpiped into Invoke-Expression( iex), tout en affectant simultanément cette valeur à $h. Si la conversion échoue, $hrestera $null.
  3. Le deuxième élément du tableau est le paramètre d'origine.
  4. Indexez dans le tableau avec la -notvaleur booléenne de $h. Tout ce qui $hest sera implicitement converti en [bool]( $nulldans le cas d'une conversion invalide deviendra $false, un entier positif dans le cas d'une conversion réussie deviendra $true) avant d'être annulé, qui est ensuite implicitement converti en [int]par l'indexeur de tableau []( $truesera 1, $falsesera 0), entraînant ainsi le premier élément du tableau (le résultat de la conversion) choisi si la conversion a réussi, et le deuxième élément choisi si la conversion a échoué.

0

Scala, 40 octets

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

Explication:

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 octets

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

Non golfé avec des cas de 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();
    }
}

Essayez en ligne


0

Fléchette, 51 octets

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

Essayez-le ici

La plupart des frais généraux proviennent de paramètres nommés ... Eh bien!

Au moins Dart vous permet de taper dynamiquement, si vous voulez: D

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.