การแปลง“ 0xUsernames”


25

0xUsernames

มีคนจำนวนมากที่ใช้บริการส่งข้อความที่พวกเขาไม่มีพื้นที่ในการจัดเก็บชื่อผู้ใช้ทั้งหมด! ในการแก้ไขปัญหานี้พวกเขาจะเริ่มจัดเก็บชื่อผู้ใช้เป็นเลขฐานสิบหกหากเป็นไปได้

หากชื่อผู้ใช้ประกอบด้วยอักขระ0123456789ABCDEF( ตัวพิมพ์เล็กและตัวพิมพ์ใหญ่) มันสามารถแปลงเป็นเลขฐานสิบหกและเก็บเป็นจำนวนเต็ม ตัวอย่างเช่นชื่อผู้ใช้ba5eba11สามารถตีความได้ว่า0xBA5EBA11เป็นจำนวนเต็มฐานสิบหก

แต่เกี่ยวกับ05AB1Eอะไร นั่นคือศูนย์นำที่จะหายไป ดังนั้นเมื่อใดก็ตามที่เราแปลงชื่อผู้ใช้เราต้องแน่ใจว่าได้เติม a 1ก่อนที่จะอ่านมันเป็นจำนวนเต็ม


ความท้าทาย

งานของคุณคือการเขียนโปรแกรมหรือฟังก์ชั่นที่ให้ชื่อผู้ใช้ที่ไม่ว่างเปล่าเป็นสตริงชื่อผู้ใช้ 'hexa-compresses':

  • หากสามารถตีความได้ว่าเป็นเลขจำนวนเต็มฐานสิบหกให้เพิ่ม 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

อาไม่เห็นอย่างนั้น นอกจากนี้จะเกิดอะไรขึ้นถ้ากรณีทดสอบขนาดใหญ่บางอันส่งผลให้เกิดตัวเลขนอกขอบเขตประเภทจำนวนเต็มที่ใหญ่ที่สุดของภาษาของเรา
Doorknob

2
@ doorknob จับที่ดี ฉันจะบอกว่าจำนวนเต็มที่เกิดขึ้นจะไม่เกินประเภทจำนวนเต็มมาตรฐานของภาษาของคุณ (โปรดอย่าใช้สิ่งนี้ในทางที่ผิดและใช้ภาษาที่มีจำนวนเต็ม 1 บิต)
FlipTack

จะถือว่าการป้อนข้อมูลเป็นตัวพิมพ์ใหญ่เท่านั้นหรือไม่
Adám

@ Adámขออภัยโปรแกรมของคุณควรจะไม่ตรงตามตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ (ดูกรณีทดสอบ)
FlipTack

Like 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
ถูกต้องอย่างไรก็ตามชื่อนี้ถูกเลือกให้เป็นเลขฐานสิบหก ดังนั้นจึงใช้ได้ :)
Osable

สงสัยว่าทำไมคุณถึงกำลังตกหล่นอยู่ พยายามคิดหาวิธีใช้ $ แทน แต่ ....
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

การคัดเลือกโดยนัยมีความสวยงามอย่างแท้จริง ... : ')
Downgoat

10

Python 2 , 44 ไบต์

รับอินพุตเป็นสตริงที่อยู่ในเครื่องหมายคำพูด -2 ไบต์ต้องขอบคุณ Rod!

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

เนื่องจากเรารับประกันว่าการป้อนข้อมูลจะประกอบด้วยตัวอักษรและขีดล่างเท่านั้นจึงไม่มีวิธีในการสร้าง Python ที่ถูกต้องหลังจากที่0x1อื่นนอกจากมีสตริงเลขฐานสิบหก หากอินพุตเป็นอย่างอื่นข้อผิดพลาดจะถูกละเว้นและพิมพ์ตามเดิม

ฉันไม่สามารถทำให้ regex จับคู่สั้นกว่าtry/exceptนี้ได้ ในความเป็นจริง regex กลายเป็น verbose verribose:

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

คุณรู้ไหมว่าเราจะต้องตอบเหมือนกันทุกประการถ้าฉันเล่นกอล์ฟต่อไปใช่ไหม?
Anthony Pham

"+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เป็นความจริงถ้าใส่ประกอบด้วยอักขระอื่นนอกเหนือจากที่ได้รับอนุญาตภายในเลขฐานสิบหก ถ้ามันเป็นเท็จ$_(ซึ่งมีการป้อนข้อมูล) มันจะถูกตั้งค่าเป็นค่าที่แปลง (การแปลงจะทำโดย builtin hex)
และ$_พิมพ์โดยปริยายต้องขอบคุณ-pธง


คุณสามารถโกนไบต์ด้วยการหลีกเลี่ยงการดำเนินการแบบ$_=hex"1$_"if!/[^0-9a-f]/i
ไตรภาค

@ardnew Hum ตอนนี้ที่คุณพูดมันประกอบไปด้วยไตรภาคที่น่ากลัวมาก ... ยังไงก็ตามขอบคุณ!
Dada


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

จาวาสคริปต์: 46 41 ไบต์

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

Regex สามารถสั้นลงได้ 2 ไบต์:/[^0-9a-f]/i
GilZ

ฉันบันทึก 1 ไบต์โดยแทนที่0-9ด้วย\d, 3 ไบต์โดยการเพิ่มแฟล็ก case-insensitive (ขอบคุณ @GilZ) และอีก 2 ไบต์โดยการลบF=ซึ่งไม่จำเป็น ขอบคุณสำหรับคำแนะนำ
ลูกา

2

PHP, 42 ไบต์

hex2bin () ส่งคืนค่า false หากอินพุตไม่ใช่สตริงเลขฐานสิบหกที่ถูกต้อง นี่สั้นกว่าการใช้ regex เพื่อค้นหาเลขฐานสิบหกที่ไม่ใช่ แต่เราต้องการตัวดำเนินการ @ เนื่องจากมันไม่เงียบเมื่อล้มเหลว

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

hex2binล้มเหลวสำหรับสตริงที่มีความยาวไม่สม่ำเสมอ ยังคงสองไบต์สั้นกว่าด้วยpreg_match: <?=@hex2bin($s=$argv[1])|@hex2bin($s.a)?hexdec("1$s"):$s;สำหรับ 57 ไบต์
ติตัส


1

Python 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 อ๊ะฉันโง่
0WJYxW9FMN

1

Ruby, 47 44 ไบต์

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

ฉันสามารถลบ 3 ไบต์ด้วยการเปลี่ยนputsค่าpแต่ฉันรู้สึกว่าผลลัพธ์จะถือว่าผิดเนื่องจากมีบรรทัดใหม่ในตอนท้าย

แก้ไข: เปลี่ยนputsสำหรับpเป็นบรรทัดใหม่ต่อท้ายได้รับการยอมรับโดยทั่วไปขอบคุณ @Mego


การขึ้นบรรทัดใหม่ของ STDOUT จะถือว่ายอมรับได้
Mego

1

Japt , 11 ไบต์

+`0x1{U}`ªU

ลองออนไลน์!

ขอบคุณมากสำหรับ ETHproductions!


1
นี่เป็นหนึ่งในกรณีที่ไม่ค่อยเกิดขึ้นซึ่งคุณสามารถกำจัดพื้นที่ :-) (นอกจากนี้ลิงก์ TIO ยังเป็นโปรแกรม "Hello, World!")
ETHproductions

1

Dyalog APL ขนาด 37 ไบต์

ไม่ใช้การตรวจสอบภายในหรือการแปลงฐานสิบหก ต้องใช้⎕IO←0ซึ่งเป็นค่าเริ่มต้นในหลาย ๆ ระบบ

{∧/(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ได้รับD igits ตามด้วยองค์ประกอบ 6 ประการแรกของA lphabet

u ← 1 (819⌶) ⍵คุณได้รับอาร์กิวเมนต์ตัวพิมพ์ใหญ่ (819 ≈ "Big")

∧/ u ∊ d: ถ้าองค์ประกอบทั้งหมดของคุณเป็นสมาชิกของdดังนั้น:
16 ⊥ 1 , d ⍳ u หาดัชนีของคุณในd , เพิ่ม 1 และประเมินเป็นฐาน 16

อื่น ๆ : คืนค่าอาร์กิวเมนต์ (ไม่ได้แก้ไข)

TryAPL ออนไลน์:

  1. ตั้ง⎕IOศูนย์กำหนดทดแทนสำหรับ(ต้องห้ามใน TryAPL เหตุผลด้านความปลอดภัย) และชุด⎕PP( P rint 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
คุณช่วยอธิบายรหัสของคุณได้ไหม
Anthony Pham

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

สกาลา, 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;};

Ungolfed กับกรณีทดสอบ:

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

ลองออนไลน์


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.