Konwertowanie „0xUsernames”


25

0x Nazwy użytkowników

Tak wielu ludzi korzysta z usługi przesyłania wiadomości, że zabrakło miejsca na przechowywanie wszystkich nazw użytkowników! Aby to naprawić, zaczną przechowywać nazwy użytkowników w systemie szesnastkowym, o ile to możliwe.

Jeśli nazwa użytkownika składa się tylko z znaków 0123456789ABCDEF(bez rozróżniania wielkości liter), można ją przekonwertować na postać szesnastkową i zapisać jako liczbę całkowitą. Na przykład nazwa użytkownika ba5eba11może być interpretowana jako 0xBA5EBA11liczba szesnastkowa.

Ale co z tym 05AB1E? To ma wiodące zero, które zostałoby utracone. Tak więc, za każdym razem, gdy konwertujemy nazwę użytkownika, upewniamy się, że poprzedzamy ją znakiem 1przed odczytaniem jej jako liczby całkowitej.


Wyzwanie

Twoim zadaniem jest napisanie programu lub funkcji, która, biorąc pod uwagę niepustą nazwę użytkownika jako ciąg, „hexa-kompresuje” nazwę użytkownika:

  • Jeśli można go interpretować jako liczbę szesnastkową, należy poprzedzić 1, interpretować jako wartość szesnastkową, a następnie wydrukować wynik jako podstawę 10.
  • W przeciwnym razie po prostu zwróć ciąg niezmodyfikowany.

To jest , więc wygrywa najkrótsze rozwiązanie (w bajtach)! Wbudowane podstawowe funkcje konwersji są dozwolone.


Przypadki testowe

Możesz założyć, że wszelkie wynikowe liczby całkowite mieszczą się w standardowym zakresie liczb całkowitych twojego języka.

Podobnie jak w przypadku nazw użytkowników w większości systemów przesyłania komunikatów, łańcuchy wejściowe będą zawierać tylko znaki alfanumeryczne i znaki podkreślenia.

Pamiętaj, że zawsze musisz dodać wiodącą 1przed konwersją!

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

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

Dla porównania, oto implementacja Pythona 3, której użyłem dla przypadków testowych (nie golfowych):

import re

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

Ach, nie widziałem tego. A co, jeśli niektóre większe przypadki testowe spowodują, że liczby wykroczą poza granice największej liczby całkowitej naszego języka?
Klamka

2
@Doorknob good catch. Powiem, że wynikowa liczba całkowita nigdy nie będzie większa niż standardowy typ liczb całkowitych w twoim języku. (proszę nie nadużywaj tego i używaj języka z liczbami całkowitymi 1-bitowymi)
FlipTack

Czy można założyć, że dane wejściowe są pisane wielkimi literami?
Adám

@ Adám przepraszam, ale twój program powinien rozróżniać małe i wielkie litery (patrz przypadki testowe)
FlipTack

Jak Unary, ale koduje nazwy użytkowników zamiast BF
MilkyWay90

Odpowiedzi:


27

05AB1E , 4 bajty

D1ìH

Wyjaśnienie

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

Jeśli dane wejściowe zawierają nieprawidłowe znaki szesnastkowe, Hniczego nie wypchną, więc ostatnia wartość na stosie będzie zduplikowanym wejściem, dlatego program wypisuje dane wejściowe w przypadku nieprawidłowych danych wejściowych.

Wypróbuj online!


9
Ironia jest tutaj dość silna. 05AB1Ejest prawidłową nazwą użytkownika.
devRicher

1
Zgadza się, jednak nazwa została wybrana jako liczba szesnastkowa. Dlatego jest ważny :)
Osable

Zastanawiałem się, dlaczego oszukujesz. Próbuję wymyślić sposób, aby zamiast tego użyć $ ....
Magic Octopus Urn

16

JavaScript (ES6), 15 bajtów

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

Jak to działa

'0x1'+skonwertuje dane wejściowe na dosłowny ciąg szesnastkowy z poprzedzającym 1, np 0x105ab1e. Następnie -0rzutuje wynik na liczbę. JavaScript widzi 0xna początku i niejawnie próbuje przekonwertować z systemu szesnastkowego; jeśli szawiera dowolne nieszesnastkowe znaki, zwraca to NaN. Ponieważ jest to fałsz (i 0nigdy nie można podać danych wyjściowych z powodu wcześniejszego 1), możemy użyć funkcji ||sreturn, sjeśli konwersja szesnastkowa się nie powiedzie.

Testowy fragment kodu

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
Bardzo fajne rozwiązanie!
Grax32

Domniemany casting jest naprawdę piękny ...: ')
Downgoat

10

Python 2 , 44 bajty

Pobiera dane wejściowe jako ciąg cytowany. -2 bajty dzięki Rod!

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

Ponieważ gwarantujemy, że dane wejściowe będą zawierały tylko znaki alfanumeryczne i znaki podkreślenia, nie ma sposobu na utworzenie poprawnego języka Python 0x1poza ciągiem szesnastkowym. Jeśli dane wejściowe to cokolwiek innego, błąd jest ignorowany i drukowanie jest takie, jak było.

Nie mogłem sprawić, by dopasowanie wyrażenia regularnego było krótsze niż try/except. W rzeczywistości wyrażenie regularne okazało się bardzo gadatliwe:

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

można również wymienić a=int('1'+a,16)z exec'a=0x1'+a(prawdopodobnie trzeba przetestować)
Rod

Wiesz, będziemy mieli tę samą dokładną odpowiedź, jeśli będę kontynuować grę w golfa, prawda?
Anthony Pham

Nie działa dla nazw użytkowników, które byłyby poprawne w tym kontekście dla Pythona, np "+input()".
heinrich5991

kończy się niepowodzeniem dla „abc” (zwróć uwagę na białe znaki na końcu) (int pozwala na białe znaki na początku i na końcu)
Siphor

Nie wiem dokładnie, jak to jest w Pythonie 2, ale myślę, że można usunąć wsporniki ()nainput()
RudolfJelin

8

Perl 6 , 19 bajtów

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

Sprawdź to

Rozszerzony:

{   # 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 bajtów

-1 bajt dzięki @ardnew .

26 bajtów kodu + -pflaga.

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

Podaj dane wejściowe bez końcowej nowej linii. Z echo -nna przykład:

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

Objaśnienie
Jest to dość proste: /[^0-9a-f]/ijest prawdziwe, jeśli dane wejściowe zawierają znak inny niż dozwolony w liczbach szesnastkowych. Jeśli jest fałszem $_(który zawiera dane wejściowe), jest on ustawiany na przekonwertowaną wartość (konwersja jest wykonywana przez wbudowane hex).
I $_jest domyślnie drukowane dzięki -pflagom.


możesz ogolić bajt, unikając potrójnej operacji$_=hex"1$_"if!/[^0-9a-f]/i
nowy

@ardnew Hum, teraz, kiedy to mówisz, ta trójka była całkiem okropna ... W każdym razie dzięki!
Dada


3

Partia, 33 bajty

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

Jak to działa

Łańcuch jest przekazywany jako argument, 1 jest do niego poprzedzany, a łańcuch jest domyślnie konwertowany na dziesiętny i drukowany. Jeśli ciąg nie jest prawidłowy w systemie szesnastkowym, jest po prostu wyświetlany.

Należy zauważyć, że ponieważ matematyka wsadowa używa 32-bitowych liczb całkowitych ze znakiem, największa dozwolona nazwa użytkownika to FFFFFFF.

cmd /c przyjmuje następne polecenie, uruchamia je w nowym terminalu i kończy działanie.

set /a wykonuje matematykę i domyślnie wyświetla wynik w postaci dziesiętnej, gdy nie jest przechowywany w zmiennej.

0x1%1 mówi setowi, aby wstawił 1 do pierwszego argumentu (jest to łatwe, ponieważ wszystkie zmienne wsadowe są łańcuchami) i wskazuje, że ciąg powinien być traktowany jako szesnastkowy.

2>nul wycisza wszelkie błędy wynikające z nieprawidłowej liczby szesnastkowej

||jest logiczną operacją OR i wykonuje polecenie po prawej stronie, jeśli polecenie po lewej stronie nie powiedzie się. Nawiasy tworzą wszystko do tego momentu jedno polecenie.

echo %1 po prostu wyświetla pierwszy argument.


3

Common Lisp, 71

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

Testy

Zdefiniuj funkcję

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

Podaj listę oczekiwanych danych wejściowych, zgodnie z pytaniem:

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

Analizuj i zbieraj wyniki

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

Sprawdź, czy oczekiwane wyniki są zgodne z rzeczywistymi:

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

2

C, 108 bajtów

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

Jest to funkcja, która bierze ciąg jako argument i wypisuje wynik do 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

Miłe użycie niejawnego int:)
FlipTack

2

JavaScript: 46 41 bajtów

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

Wyrażenie regularne może być o 2 bajty krótsze:/[^0-9a-f]/i
GilZ

I zapisane 1 bajt, zastępując 0-9przez \d, 3 bajty dodając flagę wielkości liter (dzięki @GilZ) i 2 przez usunięcie więcej bajtów F=, co nie jest potrzebne. Dzieki za sugestie.
Łukasza

2

PHP, 42 bajty

hex2bin () zwraca false, jeśli dane wejściowe nie są prawidłowym łańcuchem szesnastkowym. Jest to krótsze niż użycie wyrażenia regularnego do szukania cyfr innych niż szesnastkowe, ale potrzebujemy operatora @, ponieważ nie jest cichy, gdy zawiedzie.

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

hex2binzawodzi w przypadku ciągów o nierównej długości. Nadal dwa bajty krótsze niż z preg_match: <?=@hex2bin($s=$argv[1])|@hex2bin($s.a)?hexdec("1$s"):$s;dla 57 bajtów.
Tytus

2

bash, 46 35 31 bajtów

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

Zapisz jako skrypt i przekaż nazwę użytkownika jako argument.


1

Python 2 - 63, 52, 50, 46 bajtów

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

To używa Pythona, int()który konwertuje dowolny ciąg z odpowiednią bazą na bazę 10. W tym przypadku ciąg jest liczbą 1 dołączoną do wejścia. Jeśli dane wejściowe są niepoprawne (ma znaki inne niż 0123456789ABCDEF(bez rozróżniania wielkości liter), zwraca 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

Wypróbuj tutaj!

Dzięki @FlipTack za oszczędność 15 bajtów!


Co jeśli ciąg nie zaczyna się od zera? Powinieneś dodawać jeden po lewej stronie ciągu, jeśli zaczyna się od zera.
0WJYxW9FMN

@FlipTack Ups, głupiutki ja.
0WJYxW9FMN

1

Ruby, 47 lat 44 bajtów

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

I może usunąć 3 bajty zmieniając putsza p, ale czuję się jak wyjście byłoby uznane za błędne, ponieważ ma nowego wiersza na końcu.

Edycja: Zmieniono putsna pjako końcowe znaki nowej linii są zwykle akceptowane, dzięki @Mego.


Końcowe znaki nowej linii w STDOUT są zwykle uważane za dopuszczalne.
Mego

1

Japt , 11 bajtów

+`0x1{U}`ªU

Wypróbuj online!

Ogromne podziękowania dla ETHproductions!


1
Jest to jeden z rzadkich przypadków, w których możesz pozbyć się miejsca :-) (Łącze TIO prowadzi do programu „Witaj, świecie!”)
ETHproductions

1

Dyalog APL , 37 bajtów

Nie używa wbudowanej walidacji ani konwersji hex-dec. Wymaga ⎕IO←0ustawienia domyślnego w wielu systemach.

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

Nie golfowany:

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

d ← ⎕D , 6 ↑ ⎕Ad otrzymuje D igits, a następnie pierwsze 6 elementów alfabetu A.

u ← 1 (819⌶) ⍵u dostaje duże litery (≈ 819 "Big") Argument

∧/ u ∊ d: jeżeli wszystkie elementy u są członkami d , a następnie:
16 ⊥ 1 , d ⍳ u znaleźć indeksy u w d i przedrostek 1, i ocenić jako podstawy 16

else: zwróć argument (niezmodyfikowany)

TryAPL online:

  1. Ustaw ⎕IOna zero, zdefiniuj zamiennik (zabroniony na TryAPL ze względów bezpieczeństwa) i ustaw ⎕PP( P rint P recision) na 10 dla dużych wyników

  2. Wypróbuj wszystkie przypadki testowe


1

REXX, 49 48 bajtów

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

signal on syntaxOpowiada tłumacza skok do etykiety syntax, gdy wystąpi błąd składni. Program próbuje ponownie przypisać awersję konwertowaną szesnastkowo na dziesiętną z wiodącym 1, ale syntaxjeśli to się nie powiedzie , przeskakuje do etykiety. Jeśli konwersja się powiedzie, po prostu ignoruje etykietę i wyświetla ponownie przypisaną zmienną.


2
Czy możesz wyjaśnić swój kod
Anthony Pham

0

PowerShell , 35 bajtów

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

Wypróbuj online! lub Uruchom wszystkie przypadki testowe!

Wyjaśnienie

  1. Weź parametr ( $v)
  2. Utwórz tablicę dwuelementową, w której pierwszy element ( 0) jest wynikiem ciągu zawierającego 0x1$vpotok do Invoke-Expression( iex), jednocześnie przypisując tę ​​wartość do $h. Jeśli konwersja się nie powiedzie, $hpozostanie $null.
  3. Drugim elementem tablicy jest oryginalny parametr.
  4. Indeks do tablicy o -notwartości logicznej $h. Cokolwiek $hzostanie niejawnie przekonwertowane na [bool]( $nullw przypadku niepoprawnej konwersji, stanie się $falsedodatnią liczbą całkowitą w przypadku pomyślnej konwersji $true), zanim zostanie zanegowane, a następnie zostanie domyślnie przekonwertowane [int]przez indeksator macierzy []( $truebędzie 1, $falsebędzie 0), co powoduje, że pierwszy element tablicy (wynik konwersji) zostanie wybrany, jeśli konwersja się powiedzie, a drugi element wybrany, jeśli konwersja się nie powiedzie.

0

Scala, 40 bajtów

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

Stosowanie:

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

Wyjaśnienie:

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 bajtów

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

Niegolfowany z przypadkami testowymi:

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

Wypróbuj online


0

Dart, 51 bajtów

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

Wypróbuj tutaj

Większość kosztów ogólnych pochodzi od nazwanych parametrów ... No cóż!

Przynajmniej Dart pozwala na dynamiczne pisanie, jeśli chcesz: D

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.