Konvertieren von "0xUsernames"

25

0xUsernames

Es gibt so viele Leute, die einen Nachrichtendienst nutzen, dass ihnen der Speicherplatz ausgeht, um alle Benutzernamen zu speichern! Um dies zu beheben, werden die Benutzernamen nach Möglichkeit hexadezimal gespeichert.

Wenn ein Benutzername nur aus Zeichen besteht 0123456789ABCDEF(ohne Berücksichtigung der Groß- und Kleinschreibung), kann er in ein Hexadezimalzeichen konvertiert und als Ganzzahl gespeichert werden. Beispielsweise kann der Benutzername ba5eba11als 0xBA5EBA11hexadezimale Ganzzahl interpretiert werden .

Aber was ist mit 05AB1E? Das hat eine führende Null, die verloren gehen würde. Wenn wir also einen Benutzernamen konvertieren, müssen wir a voranstellen, 1bevor wir ihn als Ganzzahl lesen.


Die Herausforderung

Ihre Aufgabe ist es, ein Programm oder eine Funktion zu schreiben, die bei einem nicht leeren Benutzernamen als Zeichenfolge den Benutzernamen hexadezimal komprimiert:

  • Wenn es als hexadezimale Ganzzahl interpretiert werden kann, stellen Sie eine 1 voran, interpretieren Sie es als hexadezimal und geben Sie das Ergebnis als Basis 10 aus.
  • Andernfalls geben Sie einfach die Zeichenfolge unverändert zurück.

Das ist , also gewinnt die kürzeste Lösung (in Bytes)! Eingebaute Basisumwandlungsfunktionen sind zulässig.


Testfälle

Sie können davon ausgehen, dass sich alle resultierenden Ganzzahlen innerhalb des Standard-Ganzzahlbereichs Ihrer Sprache befinden.

Wie bei Benutzernamen auf den meisten Nachrichtensystemen enthalten die Eingabezeichenfolgen nur alphanumerische Zeichen und Unterstriche.

Denken Sie daran, dass Sie 1vor der Konvertierung immer einen Lead hinzufügen müssen !

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

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

Als Referenz ist hier eine Python 3-Implementierung, die ich für die Testfälle verwendet habe (ungolfed):

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
quelle
Ah, das habe ich nicht gesehen. Was ist auch, wenn einige der größeren Testfälle zu Zahlen führen, die außerhalb der Grenzen des größten Integer-Typs unserer Sprache liegen?
Türklinke
2
@ Doorknob guten Fang. Ich werde sagen, dass eine resultierende Ganzzahl niemals mehr als der Standard-Ganzzahltyp Ihrer Sprache sein wird. (Bitte missbrauchen Sie dies nicht und verwenden Sie eine Sprache mit 1-Bit-Ganzzahlen)
FlipTack
Ist es in Ordnung anzunehmen, dass die Eingabe nur in Großbuchstaben erfolgt?
Adám
@ Adám sorry, aber dein Programm sollte Groß- und Kleinschreibung nicht
berücksichtigen
Wie Unary, außer dass es Benutzernamen anstelle von BF codiert
MilkyWay90

Antworten:

27

05AB1E , 4 Bytes

D1ìH

Erläuterung

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

Wenn die Eingabe ungültige hexadezimale Zeichen enthält, Hwird nichts übertragen, sodass der letzte Wert auf dem Stapel die duplizierte Eingabe ist. Aus diesem Grund druckt das Programm die Eingabe bei ungültiger Eingabe.

Probieren Sie es online!

Osable
quelle
9
Die Ironie ist hier ziemlich stark. 05AB1Eist ein gültiger Benutzername.
devRicher
1
Das ist richtig, aber der Name wurde gewählt als Hexadezimalzahl. Daher ist es gültig :)
Osable
Ich habe mich gefragt, warum du dich getäuscht hast. Der Versuch, über eine Möglichkeit nachzudenken, stattdessen $ zu verwenden ...
Magic Octopus Urn
16

JavaScript (ES6), 15 Byte

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

Wie es funktioniert

'0x1'+skonvertiert die Eingabe in eine Literal-Hexadezimalzeichenfolge mit vorangestelltem 1, z 0x105ab1e. Dann -0wandelt das Ergebnis in einer Reihe. JavaScript sieht das 0xam Anfang und versucht implizit, von hexadezimal zu konvertieren. Wenn skeine hexadezimalen Zeichen enthalten sind, wird dies zurückgegeben NaN. Da dies falsch ist (und die Ausgabe 0aufgrund des vorangestellten Werts niemals möglich ist 1), können wir die ||sRückgabe verwenden, swenn die Hex-Konvertierung fehlgeschlagen ist.

Testschnipsel

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

ETHproductions
quelle
2
Sehr schöne Lösung!
Grax32,
Implizites Casting ist wirklich schön ...: ')
Downgoat
10

Python 2 , 44 Bytes

Nimmt Eingaben in Anführungszeichen. -2 Bytes dank Rod!

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

Da wir garantieren, dass die Eingabe nur alphanumerische Zeichen und Unterstriche enthält, gibt es keine 0x1andere Möglichkeit, gültiges Python zu erstellen, als eine hexadezimale Zeichenfolge. Wenn es sich bei der Eingabe um etwas anderes handelt, wird der Fehler ignoriert und so gedruckt, wie er ursprünglich war.

Ich konnte ein Regex-Match nicht kürzer machen als try/except. In der Tat stellte sich heraus, dass Regex furchtbar wortreich war:

import re
lambda n:re.match('^[0-9A-F]+$',n,2)and int('1'+n,16)or n
FlipTack
quelle
Sie können auch ersetzen a=int('1'+a,16)durch exec'a=0x1'+a(wahrscheinlich müssen testen)
Rod
Weißt du, wir werden die gleiche genaue Antwort haben, wenn ich weiter Golf spiele, oder?
Anthony Pham
Funktioniert nicht für Benutzernamen, die in diesem Kontext für Python gültig wären, z "+input()".
heinrich5991
fehlgeschlagen für "abc" (beachte das Leerzeichen am Ende) (int erlaubt Leerzeichen am Anfang und Ende)
Siphor
Ich weiß nicht genau, wie es für Python 2 ist, aber ich denke, Sie können die Klammern ()uminput()
RudolfJelin
8

Perl 6 , 19 Bytes

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

Probier es aus

Erweitert:

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

Perl, 27 Bytes

-1 Byte dank @ardnew .

26 Byte Code + -pFlag.

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

Geben Sie den Eingang ohne letzte Zeile ein. Mit echo -nzum Beispiel:

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

Erläuterung
Dies ist ziemlich einfach: Es /[^0-9a-f]/iist wahr, wenn die Eingabe ein anderes Zeichen enthält als das, das in hexadezimalen Zahlen zulässig ist. Wenn es falsch ist $_(was die Eingabe enthält), wird es auf den konvertierten Wert gesetzt (die Konvertierung wird vom eingebauten System durchgeführt hex).
Und $_wird dank -pFlagge implizit gedruckt .

Dada
quelle
Sie können ein Byte rasieren, indem Sie die ternäre Operation vermeiden$_=hex"1$_"if!/[^0-9a-f]/i
zwar am
@ardnew Hum, jetzt, wo du es sagst, war dieser Dreiklang ziemlich schrecklich ... Wie auch immer, danke!
Dada
3

Batch, 33 Bytes

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

Wie es funktioniert

Eine Zeichenfolge wird als Argument übergeben, ihr wird eine 1 vorangestellt, und die Zeichenfolge wird implizit in eine Dezimalzahl konvertiert und gedruckt. Wenn die Zeichenfolge nicht hexadezimal gültig ist, wird sie einfach angezeigt.

Da die Batch-Mathematik vorzeichenbehaftete 32-Bit-Ganzzahlen verwendet, ist der größte zulässige Benutzername FFFFFFF.

cmd /c Nimmt den nächsten Befehl entgegen, führt ihn in einem neuen Terminal aus und beendet ihn.

set /a Führt eine Berechnung durch und zeigt das Ergebnis implizit als Dezimalzahl an, wenn es nicht in einer Variablen gespeichert ist.

0x1%1 Tellset stellt dem ersten Argument eine 1 voran (dies ist einfach, da alle Stapelvariablen Zeichenfolgen sind) und gibt an, dass die Zeichenfolge als hexadezimal behandelt werden soll.

2>nul entfernt alle Fehler, die aus einer ungültigen Hexadezimalzahl resultieren

||ist ein logisches ODER und führt den Befehl auf der rechten Seite aus, wenn der Befehl auf der linken Seite nicht erfolgreich ist. Die Klammern machen alles bis zu diesem Punkt zu einem Befehl.

echo %1 zeigt einfach das erste Argument an.

SomethingDark
quelle
3

Common Lisp, 71

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

Tests

Funktion definieren

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

Zitieren Sie eine Liste der erwarteten Eingaben, wie in der Frage angegeben:

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

Analysiere es und sammle Ergebnisse

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

Überprüfen Sie, ob die erwarteten Ausgaben mit den tatsächlichen übereinstimmen:

CL-USER> (every (lambda (x) (equalp (second x) (third x))) *)
T
Core-Dump
quelle
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);}

Dies ist eine Funktion, die die Zeichenfolge als Argument verwendet und das Ergebnis an STDOUT ausgibt.

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
Türknauf
quelle
Nizza implizite Verwendung int:)
FlipTack
2

JavaScript: 46 41 Bytes

s=>/[^\dA-F]/i.test(s)?s:parseInt(1+s,16)
Luke
quelle
Der /[^0-9a-f]/i
reguläre Ausdruck
Ich habe 1 Byte gespart, 0-9indem ich durch ersetzt habe \d, 3 Byte durch Hinzufügen des Flags ohne Berücksichtigung der Groß- / Kleinschreibung (danke @GilZ) und 2 weitere Byte durch Entfernen F=, was nicht benötigt wird. Danke für den Vorschlag.
Luke
2

PHP, 42 Bytes

hex2bin () gibt false zurück, wenn die Eingabe keine gültige Hex-Zeichenfolge ist. Dies ist kürzer als die Verwendung von Regex, um nach nicht hexadezimalen Ziffern zu suchen, aber wir benötigen den @ -Operator, da er nicht stumm ist, wenn er fehlschlägt.

<?=@hex2bin($s=$argv[1])?hexdec("1$s"):$s;
Alex Howansky
quelle
hex2binschlägt fehl für Saiten mit ungeraden Längen. Noch zwei Bytes kürzer als bei preg_matchobwohl: <?=@hex2bin($s=$argv[1])|@hex2bin($s.a)?hexdec("1$s"):$s;für 57 Bytes.
Titus
2

Bash, 46 35 31 Bytes

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

Speichern Sie als Skript und übergeben Sie den Benutzernamen als Argument.

Mitchell Spector
quelle
1

Python 2 - 63, 52, 5046 Bytes

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

Dies verwendet Python's int(), das jeden String mit der entsprechenden Basis in Basis 10 konvertiert. In diesem Fall ist der String die Nummer 1, die an die Eingabe angehängt ist. Wenn die Eingabe ungültig ist (andere Zeichen als 0123456789ABCDEF(ohne Berücksichtigung der Groß- / Kleinschreibung)), wird Folgendes zurückgegeben 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

Probieren Sie es hier aus!

Vielen Dank an @FlipTack für die Einsparung von 15 Bytes!

Anthony Pham
quelle
Was ist, wenn die Zeichenfolge nicht mit einer Null beginnt? Sie sollten nur dann eine Eins links von der Zeichenfolge hinzufügen, wenn diese mit einer Null beginnt.
0WJYxW9FMN
@ FlipTack Whoops, dumm mich.
0WJYxW9FMN
1

Ruby, 47 44 Bytes

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

Ich könnte 3 Bytes entfernen, indem ich putsfür pändere, aber ich glaube, dass die Ausgabe als falsch betrachtet würde, da sie am Ende eine neue Zeile hat.

Edit: Changed putsfür pschlepp newlines typischerweise akzeptiert werden, dank @Mego.

Simon Landry
quelle
Nachgestellte Zeilenumbrüche auf STDOUT werden normalerweise als akzeptabel angesehen.
Mego
1

Japt , 11 Bytes

+`0x1{U}`ªU

Probieren Sie es online!

Ein grosses Dankeschön an ETHproductions!

Oliver
quelle
1
Dies ist einer der seltenen Fälle, in denen Sie den Speicherplatz entfernen können :-) (Außerdem ist der TIO-Link auf das Programm "Hello, World!")
ETHproductions
1

Dyalog APL , 37 Bytes

Verwendet keine eingebaute Validierung oder Hex-Dec-Konvertierung. Benötigt, ⎕IO←0was auf vielen Systemen Standard ist.

{∧/(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 wird D durch die ersten 6 Elemente des gefolgt igits A lphabet

u ← 1 (819⌶) ⍵u wird groß geschrieben (819 ≈ "Big")

∧/ u ∊ d: Wenn alle Elemente von u Mitglieder von d sind , dann:
16 ⊥ 1 , d ⍳ u Finde die Indizes von u in d , stelle eine 1 voran und bewerte sie als Basis 16

sonst: gibt das (unveränderte) Argument zurück

TryAPL online:

  1. Setzen Sie ⎕IOden Wert auf Null, definieren Sie einen Ersatz für (aus Sicherheitsgründen in TryAPL nicht zulässig) und setzen Sie den Wert ⎕PP( P rint P recision) bis 10 für die großen Ergebnisse

  2. Probieren Sie alle Testfälle aus

Adam
quelle
1

REXX, 49 48 Bytes

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

Das signal on syntaxweist den Interpreter an, bei syntaxjedem Syntaxfehler zum Label zu springen . Das Programm versucht, aeine hexadezimal zu dezimal konvertierte Version mit einer führenden 1 neu zuzuweisen, springt jedoch zum syntaxLabel, wenn dies fehlschlägt. Wenn die Konvertierung erfolgreich ist, ignoriert sie einfach die Beschriftung und gibt die neu zugewiesene Variable aus.

idrougge
quelle
2
Könnten Sie bitte Ihren Code erklären
Anthony Pham
0

PowerShell , 35 Byte

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

Probieren Sie es online! oder Führen Sie alle Testfälle aus!

Erläuterung

  1. Parameter übernehmen ( $v)
  2. Erstellen Sie ein Array mit zwei Elementen, wobei das erste Element ( 0) das Ergebnis einer Zeichenfolge ist, die 0x1$vpiped into Invoke-Expression( iex) enthält, während Sie gleichzeitig diesen Wert zuweisen $h. Wenn die Konvertierung fehlschlägt, $hwird bleiben $null.
  3. Das zweite Element des Arrays ist der ursprüngliche Parameter.
  4. Index in das Array mit dem Booleschen -notWert von $h. Was $hauch immer implizit konvertiert wird [bool]( $nullim Falle einer ungültigen Konvertierung wird $falseeine positive Ganzzahl im Falle einer erfolgreichen Konvertierung $true), bevor es negiert wird, in das [int]der Array-Indexer implizit konvertiert []( $truewird 1, $falsewird) 0), was dazu führt, dass das erste Element des Arrays (das Konvertierungsergebnis) ausgewählt wird, wenn die Konvertierung erfolgreich war, und das zweite Element ausgewählt wird, wenn die Konvertierung nicht erfolgreich war.
Briantist
quelle
0

Scala, 40 Bytes

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

Verwendung:

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

Erläuterung:

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
quelle
0

C #, 58 Bytes

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

Ungolfed mit Testfällen:

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

Versuchen Sie es online

Rasnagul
quelle
0

Dart, 51 Bytes

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

Probieren Sie es hier aus

Der größte Teil des Overheads stammt von benannten Parametern ... Na ja!

Zumindest mit Dart können Sie dynamisch tippen, wenn Sie Folgendes möchten: D

Dwayne Slater
quelle