Перетворення "0xНазви користувачів"


25

0xНазви користувачів

Є стільки людей, які використовують послугу обміну повідомленнями, що у них не вистачає місця для зберігання всіх імен користувачів! Щоб виправити це, вони почнуть зберігати імена користувачів як шістнадцяткові, де це можливо.

Якщо ім'я користувача складається лише з символів 0123456789ABCDEF(нечутливих до регістру), воно може бути перетворене в шістнадцятковий і збережене як ціле число. Наприклад, ім'я користувача ba5eba11можна інтерпретувати як 0xBA5EBA11шістнадцяткове число.

А як же 05AB1E? Ось отриманий провідний нуль, який був би втрачений. Отже, кожного разу, коли ми перетворюємо ім'я користувача, ми обов'язково додаємо a 1перед тим, як прочитати його як ціле число.


Змагання

Ваше завдання - написати програму або функцію, яка, надаючи непусте ім'я користувача як рядок, "hexa-стискає" ім'я користувача:

  • Якщо це можна інтерпретувати як шістнадцяткове ціле число, додайте 1, інтерпретуйте як шістнадцятковий, а потім виведіть результат як базу 10.
  • В іншому випадку просто поверніть рядок немодифікованою.

Це , тому найкоротше рішення (у байтах) виграє! Дозволені вбудовані базові функції перетворення.


Випробування

Ви можете припустити, що будь-які результуючі цілі числа знаходяться в стандартному цілому діапазоні вашої мови.

Як і для імен користувачів у більшості систем обміну повідомленнями, рядки введення містять лише буквено-цифрові та підкреслення.

Пам’ятайте, вам завжди потрібно додати ведучу 1перед конвертацією!

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

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

Для довідки, ось реалізація Python 3, яку я використовував для тестових випадків (необроблений):

import re

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

Ах, не бачив цього. Крім того, що робити, якщо деякі більші тестові випадки призводять до цифр за межами найбільшого цілого типу нашої мови?
Дверна ручка

2
@Doorknob хороший улов. Я скажу, що отримане ціле число ніколи не буде більше, ніж стандартний цілий тип вашої мови. (будь ласка, не зловживайте цим і використовуйте мову з 1-бітними цілими числами)
FlipTack

Чи гаразд припускати, що вхід є лише великими літерами?
Адам

@ Adám вибачте, але ваша програма повинна бути нечутливою до справ (див. Тестові випадки)
FlipTack

Як і Unary, крім того, що вона кодує імена користувачів замість BF
MilkyWay90

Відповіді:


27

05AB1E , 4 байти

D1ìH

Пояснення

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

Якщо вхід містить недійсні шістнадцяткові символи, Hнічого не натискатиме, тому останнє значення в стеці буде дублюватим введенням, тому програма надрукує його в разі недійсного введення.

Спробуйте в Інтернеті!


9
Іронія тут досить сильна. 05AB1E- дійсне ім’я користувача.
devRicher

1
Це правильно, проте ім'я було обрано як шістнадцяткове число. Отже, це дійсно :)
Доступний

Цікаво, чому ти дублюєш. Намагаючись придумати спосіб використання $ натомість ....
Magic Octopus Urn

16

JavaScript (ES6), 15 байт

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

Як це працює

'0x1'+sперетворює вхід у буквальний шістнадцятковий рядок із попередньо створеною формою 1, наприклад 0x105ab1e. Потім -0закидає результат на число. JavaScript бачить 0xпочаток і неявно намагається перетворити з шістнадцяткової; якщо sмістить якісь не шістнадцяткові символи, це повертається NaN. Оскільки це хибність (і вихід 0ніколи не може бути наданий із-за попередньо передбаченого 1), ми можемо використовувати ||sдля повернення, sякщо шестнадцяткова конверсія не вдалася.

Фрагмент тесту

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
Дуже приємне рішення!
Grax32

Неявний кастинг по-справжньому прекрасний ...: ')
Пуховик

10

Python 2 , 44 байти

Вводиться в якості рядка, що цитується. -2 байти завдяки Роду!

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

Оскільки ми гарантуємо, що вхід буде містити лише буквено-цифрові знаки та підкреслення, немає іншого способу створити дійсний Python, 0x1окрім як шістнадцятковий рядок. Якщо введення щось інше, помилка ігнорується та друкується так, як це було спочатку.

Я, здається, не міг зробити регулярний збіг коротшим, ніж try/except. Насправді, регулярний вираз виявився жахливо багатослівним:

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

ви також можете замінити a=int('1'+a,16)на exec'a=0x1'+a(можливо, потрібно тестувати)
Rod

Ви знаєте, нам доведеться відповідати точно, якщо я продовжую гольф правильно?
Ентоні Фам

Не працює для імен користувачів, які були б дійсними Python у цьому контексті, наприклад "+input()".
heinrich5991

не вдається "abc" (зауважте пробіл у кінці) (int дозволяє пробіл на початку та в кінці)
Siphor

Я точно не знаю, як це для Python 2, але я думаю, ви можете зняти дужки ()наinput()
RudolfJelin


7

Perl, 27 байт

-1 байт завдяки @ardnew .

26 байт коду + -pпрапор.

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

Поставити вхід без остаточного нового рядка. З echo -n, наприклад:

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

Пояснення
Це досить прямо вперед: /[^0-9a-f]/iвірно, якщо вхід містить символи, відмінні від дозволених всередині шістнадцяткових чисел. Якщо це false, $_(що містить вхід), воно встановлюється на перетворене значення (перетворення здійснюється вбудованим hex).
І $_друкується неявно завдяки-p прапору.


ви можете голити байт, уникаючи потрійної операції$_=hex"1$_"if!/[^0-9a-f]/i
ardnew

@ardnew Hum, тепер, коли ти це кажеш, цей потрійник був дуже жахливим ... У будь-якому випадку, дякую!
Дада


3

Пакет, 33 байти

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

Як це працює

Рядок передається як аргумент, 1 попередньо до нього, а рядок неявно перетворюється в десятковий і друкується. Якщо рядок не є шістнадцятковим, вона просто відображається.

Слід зазначити, що оскільки пакетна математика використовує підписані 32-бітні цілі числа, найбільшим дозволеним ім'ям користувача є FFFFFFF.

cmd /c приймає наступну команду, запускає її в новий термінал і виходить.

set /a виконує математику і неявно відображає результат у десятковій формі, коли не зберігається до змінної.

0x1%1 каже встановити, щоб додати аргумент 1 до першого аргументу (це легко, оскільки всі змінні пакетів є рядками) і вказує, що рядок слід розглядати як шістнадцятковий.

2>nul замовчує будь-які помилки внаслідок недійсного шістнадцяткового числа

||є логічним АБО і виконує команду праворуч, якщо команда зліва не є успішною. В дужках складено все до цього моменту однією командою.

echo %1 просто відображає перший аргумент.


3

Загальний Лісп, 71

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

Тести

Визначте функцію

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

Процитуйте перелік очікуваних входів, що задаються питанням:

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

Розбирайте її та збирайте результати

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

Перевірте, чи очікувані результати відповідають фактичним:

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

2

C, 108 байт

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

Це функція, яка приймає рядок як аргумент і друкує результат в 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

Приємне використання неявного int:)
FlipTack

2

JavaScript: 46 41 байт

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

Зворотний вираз може бути на 2 байти коротшим:/[^0-9a-f]/i
GilZ

Я врятував 1 байт, замінивши 0-9на \d3 байти, додавши прапор, нечутливий до регістру (спасибі @GilZ) та ще 2 байти, видаливши F=, що не потрібно. Дякую за пропозицію.
Лука

2

PHP, 42 байти

hex2bin () повертає значення false, якщо введення не є дійсною шістнадцятковою рядком. Це коротше, ніж використання регулярного вираження для пошуку не шістнадцяткових цифр, але нам потрібен оператор @, оскільки він не мовчить, коли він не працює.

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

hex2binне підходить для струн з нерівною довжиною. Ще два байти коротше, ніж з preg_matchхоч: <?=@hex2bin($s=$argv[1])|@hex2bin($s.a)?hexdec("1$s"):$s;на 57 байт.
Тит

2

баш, 46 35 31 байт

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

Збережіть як сценарій та передайте ім'я користувача як аргумент.


1

Пітон 2 - 63, 52, 50, 46 байт

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

Для цього використовується Python, int()який перетворює будь-яку рядок із відповідною базою в базу 10. У цьому випадку рядок є числом 1, приєднаним до входу. Якщо введення даних недійсне (має символи, відмінні від 0123456789ABCDEF(регістр нечутливих до регістру), він повертає 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

Спробуйте тут!

Дякуємо @FlipTack за економію 15 байт!


Що робити, якщо рядок не починається з нуля? Ви повинні додавати один зліва від рядка, лише якщо він починається з нуля.
0WJYxW9FMN

@FlipTack Whoops, нерозумно мені.
0WJYxW9FMN

1

Рубін, 47 44 байт

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

Я міг би видалити 3 байти, змінивши putsна p, але я відчуваю, що висновок вважатиметься неправильним, оскільки в кінці є новий рядок.

Редагувати. Змінено putsна те p, що останні рядки зазвичай приймаються, спасибі @Mego.


Зазвичай нові рядки на STDOUT вважаються прийнятними.
Мего


1

Діялог АПЛ , 37 байт

Не використовує вбудованої перевірки чи шестигранної конверсії. Потрібно, ⎕IO←0що для багатьох систем за замовчуванням.

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

Безголівки:

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

d ← ⎕D , 6 ↑ ⎕Ad отримує D займання з подальшими першими 6 елементами A lphabet

u ← 1 (819⌶) ⍵u отримує верхній регістр (819 ≈ «великий») аргумент

∧/ u ∊ d: якщо всі елементи u є членами d , то:
16 ⊥ 1 , d ⍳ u знайдіть індекси u в d , додайте a 1 і оцініть як базу 16

інше: поверніть аргумент (немодифікований)

СпробуйтеAPL онлайн:

  1. Встановіть ⎕IOна нуль, визначає заміну (заборонену на TryAPL з міркувань безпеки), а також безліч ⎕PP( P ечаті P recision) 10 для великих результатів

  2. Спробуйте всі тестові випадки


1

REXX, 49 48 байт

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

signal on syntaxКаже перекладачеві , щоб перейти до мітки syntaxщоразу , коли виникає помилка синтаксису. Програма намагається перевлаштувати aперетворену шістнадцяткову в десяткову версію з провідною 1, але переходить до syntaxмітки, якщо це не вдалося . Якщо конверсія проходить, вона просто ігнорує мітку та виводить переділену змінну.


2
Чи можете ви пояснити свій код
Ентоні Фам

0

PowerShell , 35 байт

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

Спробуйте в Інтернеті! або Запустити всі тестові справи!

Пояснення

  1. Візьміть параметр ( $v)
  2. Створіть двоелементний масив, де перший елемент ( 0) є результатом рядка, що містить 0x1$vпіп у Invoke-Expression( iex), одночасно призначаючи це значення $h. Якщо конверсія не вдасться, $hзалишиться $null.
  3. Другий елемент масиву - вихідний параметр.
  4. Індексуйте у масив із булевим -notзначенням $h. Те, що $hє, буде імпліцитно перетворено [bool]( $nullу випадку недійсного перетворення стане $falseпозитивним цілим числом у разі успішної конверсії стане $true) перед тим, як його заперечують, яке потім неявно перетворюється [int]індексатором масиву []( $trueбуде 1, $falseбуде 0), в результаті чого перший елемент масиву (результат перетворення) обраний, якщо перетворення було успішним, а другий обраний елемент, якщо перетворення було невдалим.

0

Scala, 40 байт

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

Використання:

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

Пояснення:

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 байт

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

Недоліковані з тестовими кейсами:

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

Спробуйте в Інтернеті


0

Дарт, 51 байт

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

Спробуйте тут

Більшість накладних витрат походить від названих параметрів ... Ну добре!

Принаймні Dart дозволяє вам динамічно вводити текст, якщо ви хочете: D

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.