Mengonversi “0xUsernames”

25

0x Nama pengguna

Ada begitu banyak orang yang menggunakan layanan olahpesan sehingga mereka kehabisan ruang untuk menyimpan semua nama pengguna! Untuk memperbaikinya, mereka akan mulai menyimpan nama pengguna sebagai heksadesimal, jika memungkinkan.

Jika nama pengguna hanya terdiri dari karakter 0123456789ABCDEF(tidak peka huruf besar-kecil), itu dapat dikonversi menjadi heksadesimal dan disimpan sebagai integer. Misalnya, nama pengguna ba5eba11dapat diartikan sebagai 0xBA5EBA11, integer heksadesimal.

Tapi bagaimana dengan itu 05AB1E? Itu mendapat nol di depan, yang akan hilang. Jadi, setiap kali kami mengonversi nama pengguna, kami pastikan untuk menambahkan 1sebelumnya sebelum membacanya sebagai bilangan bulat.


Tantangan

Tugas Anda adalah menulis sebuah program atau fungsi yang, diberi nama pengguna yang tidak kosong sebagai string, 'heksa-kompres' nama pengguna:

  • Jika itu dapat ditafsirkan sebagai bilangan bulat heksadesimal, tambahkan 1, diartikan sebagai heksadesimal, dan kemudian cetak hasilnya sebagai basis 10.
  • Jika tidak, kembalikan string yang tidak dimodifikasi.

Ini adalah , jadi solusi terpendek (dalam byte) menang! Fungsi konversi basis bawaan diizinkan.


Uji Kasus

Anda dapat mengasumsikan bahwa setiap bilangan bulat yang dihasilkan berada dalam rentang bilangan bulat standar bahasa Anda.

Seperti halnya nama pengguna pada sebagian besar sistem pengiriman pesan, string input hanya akan berisi alfanumerik dan garis bawah.

Ingat, Anda selalu perlu menambahkan arahan 1sebelum konversi!

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

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

Untuk referensi, berikut ini adalah implementasi Python 3 yang saya gunakan untuk kasus uji (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
sumber
Ah, tidak melihatnya. Juga, bagaimana jika beberapa kasus uji yang lebih besar menghasilkan angka di luar batas tipe integer terbesar bahasa kita?
Gagang Pintu
2
@ Donorknob tangkapan yang bagus. Saya akan mengatakan bahwa integer yang dihasilkan tidak akan pernah lebih dari tipe integer standar bahasa Anda. (tolong jangan penyalahgunaan ini dan gunakan bahasa dengan integer 1-bit)
FlipTack
Apakah boleh untuk menganggap input hanya huruf besar?
Adám
@ Adám maaf, tetapi program Anda harus peka terhadap huruf besar-kecil (lihat kotak uji)
FlipTack
Seperti Unary, kecuali itu penyandian nama pengguna dan bukan BF
MilkyWay90

Jawaban:

27

05AB1E , 4 byte

D1ìH

Penjelasan

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

Jika input memiliki karakter hex yang tidak valid, Htidak akan mendorong apa pun sehingga nilai terakhir pada stack akan menjadi input yang digandakan, itu sebabnya program mencetak inputnya jika input yang tidak valid.

Cobalah online!

Osable
sumber
9
Ironinya cukup kuat di sini. 05AB1Eadalah nama pengguna yang valid.
devRicher
1
Itu benar, namun nama itu dipilih sebagai angka heksadesimal. Oleh karena itu valid :)
Osable
Ingin tahu mengapa Anda menipu. Mencoba memikirkan cara untuk menggunakan $ sebagai gantinya ....
Magic Octopus Mm
16

JavaScript (ES6), 15 byte

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

Bagaimana itu bekerja

'0x1'+smengubah input menjadi string heksadesimal literal dengan prepended 1, mis 0x105ab1e. Lalu -0gips hasilnya ke nomor. JavaScript melihat 0xdi awal dan secara implisit mencoba untuk mengkonversi dari heksadesimal; jika sberisi karakter non-heksadesimal, ini akan mengembalikan NaN. Karena ini falsy (dan output 0tidak pernah dapat diberikan karena prepended 1), kita dapat menggunakan ||suntuk mengembalikan sjika konversi hex gagal.

Cuplikan tes

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

Produksi ETH
sumber
2
Solusi yang sangat bagus!
Grax32
Pengecoran implisit benar-benar indah ...: ')
Downgoat
10

Python 2 , 44 byte

Mengambil input sebagai string yang dikutip. -2 byte terima kasih kepada Rod!

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

Karena kami dijamin bahwa input hanya akan berisi alfanumerik dan garis bawah, tidak ada cara untuk membuat Python yang valid setelah 0x1selain memiliki string hex. Jika input lain, kesalahan diabaikan, dan dicetak seperti semula.

Saya sepertinya tidak bisa membuat pertandingan regex lebih pendek dari try/except. Faktanya, regex ternyata sangat bertele-tele:

import re
lambda n:re.match('^[0-9A-F]+$',n,2)and int('1'+n,16)or n
FlipTack
sumber
Anda juga dapat mengganti a=int('1'+a,16)dengan exec'a=0x1'+a(mungkin, perlu menguji)
Rod
Anda tahu, kita harus memiliki jawaban yang persis sama jika saya terus bermain golf, kan?
Anthony Pham
Tidak berfungsi untuk nama pengguna yang akan menjadi Python yang valid dalam konteks itu, misalnya "+input()".
heinrich5991
gagal untuk "abc" (perhatikan spasi putih di akhir) (int memungkinkan spasi putih di awal dan akhir)
Siphor
Saya tidak tahu persis bagaimana itu untuk Python 2, tapi saya pikir Anda dapat menghapus tanda kurung ()diinput()
RudolfJelin
8

Perl 6 , 19 byte

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

Menguji

Diperluas:

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

Perl, 27 byte

-1 byte terima kasih kepada @ardnew .

26 byte kode + -pbendera.

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

Masukkan input tanpa baris akhir final. Dengan echo -nmisalnya:

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

Penjelasan
Ini sangat mudah: /[^0-9a-f]/ibenar jika input berisi karakter selain yang diizinkan di dalam angka heksadesimal. Jika salah, $_(yang berisi input) diset ke nilai yang dikonversi (konversi dilakukan oleh builtin hex).
Dan $_dicetak secara tersirat berkat -pbendera.

Dada
sumber
Anda dapat mencukur byte dengan menghindari operasi ternary$_=hex"1$_"if!/[^0-9a-f]/i
ardnew
@ardnew Hum, sekarang Anda mengatakannya, ternary itu cukup mengerikan ... Bagaimanapun, terima kasih!
Dada
4

Pyth - 9 byte

.xi+1z16z

Gagasan yang sama dengan jawaban fliptack . Coba konversi heksadesimal-desimal yang lain menghasilkan input.

Coba di sini!

Gurupad Mamadapur
sumber
3

Batch, 33 byte

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

Bagaimana itu bekerja

Sebuah string diteruskan sebagai argumen, 1 didahului dengan itu, dan string secara implisit dikonversi menjadi desimal dan dicetak. Jika string tidak heksadesimal, itu hanya ditampilkan.

Perlu dicatat bahwa karena matematika bets menggunakan bilangan bulat 32-bit yang ditandatangani, nama pengguna terbesar yang diizinkan adalah FFFFFFF.

cmd /c mengambil perintah berikutnya, menjalankannya di terminal baru, dan keluar.

set /a melakukan matematika dan secara implisit menampilkan hasilnya dalam desimal ketika tidak disimpan ke variabel.

0x1%1 memberitahu set untuk menambahkan 1 ke argumen pertama (ini mudah karena semua variabel batch adalah string) dan menunjukkan bahwa string harus diperlakukan sebagai heksadesimal.

2>nul membungkam setiap kesalahan yang dihasilkan dari nomor heksadesimal yang tidak valid

||adalah OR logis dan melakukan perintah di sebelah kanan jika perintah di sebelah kiri tidak berhasil. Tanda kurung membuat semuanya hingga titik ini satu perintah.

echo %1 cukup tampilkan argumen pertama.

SomethingDark
sumber
3

Common Lisp, 71

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

Tes

Tentukan fungsi

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

Kutip daftar input yang diharapkan, seperti yang diberikan oleh pertanyaan:

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

Parsing dan kumpulkan hasilnya

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

Periksa apakah output yang diharapkan cocok dengan yang sebenarnya:

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

C, 108 byte

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

Ini adalah fungsi yang mengambil string sebagai argumen dan mencetak hasilnya ke 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
Gagang pintu
sumber
Bagus menggunakan int:) implisit
FlipTack
2

JavaScript: 46 41 byte

s=>/[^\dA-F]/i.test(s)?s:parseInt(1+s,16)
Luke
sumber
Regex bisa lebih pendek 2 byte:/[^0-9a-f]/i
GilZ
Saya menyimpan 1 byte dengan mengganti 0-9oleh \d, 3 byte dengan menambahkan flag case-insensitive (terima kasih @GilZ) dan 2 byte lebih banyak dengan menghapus F=, yang tidak diperlukan. Terima kasih untuk sarannya.
Luke
2

PHP, 42 byte

hex2bin () mengembalikan false jika input bukan string hex yang valid. Ini lebih pendek daripada menggunakan regex untuk mencari digit non hex, tetapi kita membutuhkan operator @ karena tidak diam ketika gagal.

<?=@hex2bin($s=$argv[1])?hexdec("1$s"):$s;
Alex Howansky
sumber
hex2bingagal untuk string dengan panjang yang tidak rata. Masih dua byte lebih pendek dari dengan preg_matchmeskipun: <?=@hex2bin($s=$argv[1])|@hex2bin($s.a)?hexdec("1$s"):$s;untuk 57 byte.
Titus
2

bash, 46 35 31 byte

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

Simpan sebagai skrip, dan berikan nama pengguna sebagai argumen.

Mitchell Spector
sumber
1

Python 2 - 63, 52, 50, 46 Bytes

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

Ini menggunakan Python int()yang mengubah string apa pun dengan basis yang sesuai menjadi basis 10. Dalam hal ini, string adalah angka 1 yang melekat pada input. Jika input tidak valid (memiliki karakter selain 0123456789ABCDEF(tidak peka huruf besar-kecil), ia mengembalikan 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

Coba di sini!

Terima kasih kepada @FlipTack karena telah menghemat 15 byte!

Anthony Pham
sumber
Bagaimana jika string tidak dimulai dengan nol? Anda seharusnya hanya menambahkan satu di sebelah kiri string jika dimulai dengan nol.
0WJYxW9FMN
@FlipTack Whoops, konyol saya.
0WJYxW9FMN
1

Ruby, 47 44 byte

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

Aku bisa menghapus 3 byte dengan mengubah putsuntuk p, tapi aku merasa seperti output akan dianggap salah karena memiliki baris baru di akhir.

Sunting: Diubah putskarena ptrailing newlines biasanya diterima, terima kasih @Mego.

Simon Landry
sumber
Mengejar baris baru di STDOUT biasanya dianggap dapat diterima.
Mego
1

Japt , 11 byte

+`0x1{U}`ªU

Cobalah secara Online!

Terima kasih banyak untuk produk ETH!

Oliver
sumber
1
Ini adalah salah satu kasus langka di mana Anda dapat menyingkirkan ruang :-) (Juga, tautan TIO adalah ke program "Halo, Dunia!")
ETHproduksi
1

Dyalog APL , 37 byte

Tidak menggunakan validasi bawaan atau konversi hex-dec. Membutuhkan ⎕IO←0yang default pada banyak sistem.

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

Tidak Disatukan:

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

d ← ⎕D , 6 ↑ ⎕Ad mendapat D igits diikuti oleh 6 elemen pertama dari lfabet A

u ← 1 (819⌶) ⍵u mendapat argumen huruf besar (819 ≈ "Besar")

∧/ u ∊ d: jika semua elemen u adalah anggota d , maka:
16 ⊥ 1 , d ⍳ u cari indeks u dalam d , tambahkan 1, dan evaluasi sebagai basis 16

lain: kembalikan argumen (tidak dimodifikasi)

TryAPL online:

  1. Set ⎕IOke nol, menentukan pengganti (dilarang di TryAPL untuk alasan keamanan), dan set ⎕PP( P etak P recision) ke 10 untuk hasil besar

  2. Coba semua test case

Adám
sumber
1

REXX, 49 48 byte

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

The signal on syntaxmemberitahu juru bahasa untuk melompat ke label syntaxsetiap kali kesalahan sintaksis terjadi. Program mencoba untuk menetapkan ulang adengan versi konversi hex-to-desimal dengan angka 1 terkemuka, tetapi melompat ke syntaxlabel jika gagal. Jika konversi tidak lulus, itu hanya mengabaikan label dan menampilkan variabel yang ditugaskan kembali.

idrougge
sumber
2
Bisakah Anda jelaskan kode Anda
Anthony Pham
0

PowerShell , 35 byte

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

Cobalah online! atau Jalankan semua test case!

Penjelasan

  1. Ambil parameter ( $v)
  2. Buat array dua elemen di mana elemen pertama ( 0) adalah hasil dari string yang berisi 0x1$vpiped into Invoke-Expression( iex), sementara secara bersamaan menetapkan nilai ini ke $h. Jika konversi gagal, $hakan tetap ada $null.
  3. Elemen kedua dari array adalah parameter asli.
  4. Indeks ke dalam array dengan nilai boolean -notdari $h. Apa pun $hyang akan dikonversi secara implisit menjadi [bool]( $nulldalam kasus konversi yang tidak valid akan menjadi $false, bilangan bulat positif dalam kasus konversi yang berhasil menjadi $true) sebelum dinegasikan, yang kemudian secara implisit dikonversi ke [int]oleh pengindeks array []( $trueakan 1, $falseakan menjadi 0), sehingga menghasilkan elemen pertama dari array (hasil konversi) dipilih jika konversi berhasil, dan elemen kedua dipilih jika konversi tidak berhasil.
briantis
sumber
0

Scala, 40 byte

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

Pemakaian:

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

Penjelasan:

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

C #, 58 byte

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

Tidak disatukan dengan kasus uji:

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

Coba online

raznagul
sumber
0

Dart, 51 byte

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

Coba di sini

Sebagian besar overhead berasal dari parameter bernama ... Oh well!

Setidaknya Dart memungkinkan Anda diketik secara dinamis, jika Anda ingin: D

Dwayne Slater
sumber