Ubah angka menjadi Heksadesimal


23

Tantangan

Ini yang sederhana.

Tulis fungsi atau program ketika diberi nomor dalam basis 10 sebagai input, itu akan mengembalikan atau mencetak nilai nomor itu dalam Heksadesimal .

Contohnya

15 -> F
1000 -> 3E8
256 -> 100

Aturan

  • Tidak ada fungsi heksadesimal bawaan
  • Huruf mungkin huruf kecil atau huruf besar
  • Anda hanya perlu khawatir tentang bilangan bulat non-negatif, tidak ada negatif atau desimal sial
  • Ini harus bekerja dengan angka besar sembarang hingga batas jenis bahasa default.
  • Baris baru tidak wajib
  • Seperti biasa, ini adalah , jadi kode terpendek yang diukur dalam byte menang!

Masalah pertama, semoga kalian nikmati!
Random Guy

5
Apakah angka nol di depan diperbolehkan dalam output, misalnya untuk angka 32bit 000003E8?
nimi

Ada batasan pada input?
Loovjo

1
@nimi Ya, itu diizinkan.
Random Guy

1
Fakta menyenangkan: C ++ memiliki hex builtin.
Matius Roh

Jawaban:


4

APL (Dyalog APL) , 17 byte

Harus dijalankan ⎕IO←0, yang merupakan standar pada banyak sistem APL.

(⎕D,⎕A)[16⊥⍣¯1⊢⎕]

Cobalah online!

(⎕D,⎕A)[... ]D igits digabung menjadi A lphabet, lalu diindeks oleh ...

16⊥⍣¯1  kebalikan dari 16-Base-to-Number, yaitu Number-to-Base-16

 diaplikasikan ke

 input numerik


Bukankah ini 17 karakter dan sekitar 23 byte?
Julie Pelletier

1
@JuliePelletier Tidak, Dyalog APL menggunakan codepage 256 karakternya sendiri.
Adám

Oh! Senang mendengarnya.
Julie Pelletier

14

Kode Mesin Turing, 412 byte

Seperti biasa, saya menggunakan sintaks tabel aturan yang didefinisikan di sini. Anda dapat mengujinya di situs itu atau, sebagai alternatif, menggunakan implementasi java ini.

0 * * l B
B * * l C
C * 0 r D
D * * r E
E * * r A
A _ * l 1
A * * r *
1 0 9 l 1
1 1 0 l 2
1 2 1 l 2
1 3 2 l 2
1 4 3 l 2
1 5 4 l 2
1 6 5 l 2
1 7 6 l 2
1 8 7 l 2
1 9 8 l 2
1 _ * r Y
Y * * * X
X * _ r X
X _ _ * halt
2 * * l 2
2 _ _ l 3
3 * 1 r 4
3 1 2 r 4
3 2 3 r 4
3 3 4 r 4
3 4 5 r 4
3 5 6 r 4
3 6 7 r 4
3 7 8 r 4
3 8 9 r 4
3 9 A r 4
3 A B r 4
3 B C r 4
3 C D r 4
3 D E r 4
3 E F r 4
3 F 0 l 3
4 * * r 4
4 _ _ r A

Menghitung mundur dari input pada basis 10 sambil menghitung dari 0 pada basis 16. Pada pengurangan nol, itu menghapus blok input dan berakhir.


Ini sangat keren, dibutuhkan 10*n + 33instruksi untuk menyelesaikan untuk sembarang arbitrer n. Saya tidak mengerti kodenya.
Guci Gurita Ajaib

@MagicOctopusUrn Ini menciptakan blok sel baru di sebelah kiri input, awalnya berisi 0. Kemudian, itu berulang kali mengurangi blok input di basis 10 sambil menambah blok output di basis 16, sampai mencoba untuk mengurangi sel kosong selama siklus pengurangan [yang memberi tahu bahwa blok input sekarang 0], pada titik mana ia membersihkan kaset (jadi hanya output yang tersisa di kaset) sebelum berhenti.
SuperJedi224

@ MagicOctopusUrn Juga persamaan Anda untuk runtime tidak benar (saya tidak tahu apa persamaan umum yang benar, hanya saja itu jelas bukan). Cobalah dengan input 2, misalnya.
SuperJedi224

mungkin tidak. Tampaknya dekat untuk nilai tinggi. Saya tidak tahu apa-apa tentang hal itu dan berusaha melihat pola.
Magic Gurita Guci

9

Java, 92 89 byte

String x(int v){String z="";for(;v>0;v/=16)z="0123456789ABCDEF".charAt(v%16)+z;return z;}

9

Javascript, 49 43 byte.

h=i=>(i?h(i>>4):0)+"0123456789abcdef"[i%16]

6 byte disimpan oleh user81655 .

Uji di sini .

Ini memiliki dua nol terkemuka, yang diizinkan oleh aturan.

Berikut ini adalah versi tanpa nol nol: (47 byte).

h=i=>(i>15?h(i>>4):"")+"0123456789abcdef"[i%16]

Uji di sini .

Keduanya menggunakan pendekatan yang persis sama dengan jawaban Python saya .


Gunakan biner AND. i&15akan secara otomatis dikonversi ke integer, menjatuhkan desimal. Tidak perlu~~
edc65

Saya menyimpan 3 byte dan satu nol di depan:h=i=>i&&h(i>>4)+"0123456789abcdef"[i&15]
Neil

8

CJam, 22 21 byte

ri{Gmd_A<70s=+\}h;]W%

Terima kasih kepada @ MartinBüttner untuk bermain golf 1 byte!

Cobalah online!

Bagaimana itu bekerja

ri                      e# Read an integer from STDIN.
  {             }h      e# Do:
   Gmd                  e#   Push qotient and residue of the division by 16.
      _A<               e#   Check if the residue is less than 10.
         70s            e#   Push "70".
            =           e#   Select the character that corresponds to the Boolean.
             +          e#   Add the character to the digit.
                        e#   This way, 10 -> 'A', etc.
               \        e#   Swap the quotient on top of the stack.
                        e# While the quotient is non-zero, repeat the loop.
                  ;     e# Pop the last quotient.
                   ]W%  e# Reverse the stack.

5
Jumlah byte yang sama:ri{Gmd_9>7*sc+\}h;]W%
Martin Ender

6

Pyth, 33 26 21 20 byte

Ini menyenangkan.

sm@+jkUTGi_d2_c_.BQ4

Cobalah online.

Dijelaskan:

                .BQ      Convert input to a binary string, e.g. 26 -> '11010'
             _c_   4     Reverse, chop into chunks of 4, and reverse again. We reverse 
                         because chop gives a shorter last element, and we want a shorter
                         first element: ['1', '0101']
                         Reversing three times is still shorter than using .[d4 to pad the
                         binary string to a multiple of 4 with spaces.
 m                       Map across this list:
         i_d2                Take the value of the reversed string in binary,
  @                          and use it as an index into the string:
   +jkUTG                    '0123456789abcdefghijklmnopqrstuvwxyz'
                             (The alphabet appended to the range 0 to 10)
s                        Concatenate to create the final string.

Bisakah Anda menambahkan penjelasan?
TanMath

Tentu, yang mana yang kamu minati?
Luke

Jawaban yang paling menarik! ;) tidak masalah ... Meskipun itu adalah ide yang bagus untuk mengirim penjelasan untuk semuanya
TanMath

5

C (fungsi), 51

Fungsi rekursif mengambil integer input sebagai parameter:

f(n){n>>4?f(n>>4):0;n&=15;n+=n>9?55:48;putchar(n);}

Tes driver:

#include <stdio.h>

f(n){if(n>>4)f(n>>4);n&=15;n+=n<10?48:55;putchar(n);}

int main (int argc, char **argv) {

    f(15);puts("");
    f(1000);puts("");
    f(256);puts("");
    f(0);puts("");

    return 0;
}

5

Haskell, 59 58 43 41 39 byte

s="0123456789ABCDEF"
(sequence(s<$s)!!)

Contoh penggunaan: sequence(s<$s)!!) $ 1000-> "00000000000003E8".

Ini membuat daftar semua angka heksadesimal hingga 16 digit hex-digit. Untungnya ini terjadi secara berurutan, jadi kita bisa memilih yang terbaik n.

Sunting: @Mauris diperas 2 byte. Terima kasih!


Dat list monad doe
Daenyth

@Daenyth: Saya sudah beralih dari Monad ke Functor
nimi

Bagaimanas="0123456789ABCDEF";(sequence(s<$s)!!)
Lynn

@Mauris: luar biasa!
nimi

4

dc, 37

?[16~rd0<m]dsmxk[A~r17*+48+Pz0<p]dspx

Divodod secara rekursif sebesar 16, mendorong sisanya ke tumpukan hingga tidak ada lagi yang tersisa untuk dibagi. Kemudian cetak setiap elemen tumpukan, menggunakan divmod sebesar 10 untuk mencapai angka AF. Mungkin besok lebih detail ... (dan semoga lebih sedikit byte).


4

Python, 59 58 byte

h=lambda i:(i>15 and h(i/16)or'')+"0123456789abcdef"[i%16]

1 byte disimpan oleh CarpetPython

Jalankan sebagai: print h(15)

Uji di sini (Ideone.com).

Penjelasan:

h=lambda i:                                                 # Define h as a function that takes two arguments
           (i>15 and h(i/16)or'')                           # Evaluate h(i/16) if i > 15, else, give ''
                                 +"0123456789abcdef"[i%16]  # Append (i%16)'th hexadecimal number.

1
Kerja bagus. Anda juga dapat menyimpan byte lain dengan h=lambda i:(i>15 and h(i/16)or'')+"0123456789abcdef"[i%16].
Logic Knight

Kerja bagus memang, Anda dapat menyimpan dua lagi seperti ini:h=lambda i:(i>15 and h(i/16)or'')+chr(48+i%16+i%16/10*7)
Willem

4

C (gcc) , 45 44 byte

f(n){n&&f(n/16);n%=16;putchar(n+48+n/10*7);}

Cobalah online!


Dalam latihan ini terdapat frasa "• Baris baru tidak wajib" ini berarti bahwa angka tersebut harus diakhiri dengan '\ n'?
RosLuP

3

Bash (fungsi), 62

Terima kasih kepada @manatwork karena menyarankan menggunakan rekursi.

h()(x=({0..9} {A..F})
echo `(($1>15))&&h $[$1/16]`${x[$1%16]})

Bagus. Tetapi cara rekursif tampaknya masih lebih pendek:h(){ x=({0..9} {A..F});echo `(($1>15))&&h $[$1/16]`${x[$1%16]}; }
manatwork

1
@manatwork Nice - terima kasih! Untuk beberapa alasan saya biasanya lupa untuk mencoba rekursi dalam bash, walaupun saya menggunakannya dalam jawaban lain. Menggunakan ()alih-alih di { ;}sekitar fungsi tubuh menyimpan lebih banyak :)
Digital Trauma

3

Perl 6 ,  53  48 byte

{[R~] (0..9,'A'..'F').flat[($_,*div 16...^0)X%16]||0}
{[R~] (0..9,'A'..'F').flat[.polymod(16 xx*)]||0}

Ini menciptakan urutan nilai yang dibagi Integer ( div), hingga hasilnya 0tidak termasuk 0dari urutan

$_, * div 16 ...^ 0

Kemudian melintasi ( X) urutan yang menggunakan operator modulus ( %) dengan16

(  ) X[%] 16

Ini menggunakan nilai-nilai tersebut sebagai indeks ke daftar rata yang terdiri dari dua Ranges 0..9dan'A'..'Z'

( 0 .. 9, 'A' .. 'Z' ).flat[  ]

Akhirnya ia menggabungkan ( ~) mereka menggunakan Roperator meta terbalik ( )

[R[~]] 

Jika itu menghasilkan nilai False (string kosong), kembali 0

 || 0

Pemakaian:

# (optional) give it a lexical name for ease of use
my &code = {  }

say <15 1000 256 0>.map: &code;
# (F 3E8 100 0)

say code 10¹⁰⁰;
# 1249AD2594C37CEB0B2784C4CE0BF38ACE408E211A7CAAB24308A82E8F10000000000000000000000000

2

MATL , 27 byte

i`16H#\wt9>?7+]wt]xN$hP48+c

Ini menggunakan rilis 5.1.0 dari bahasa / kompiler, yang lebih awal dari tantangan ini.

Contoh

>> matl
 > i`16H#\wt9>?7+]wt]xN$hP48+c
 >
> 1000
3E8

Penjelasan

i              % input number
`              % do...
  16H#\        % remainder and quotient of division by 16
  w            % move remainder to top of stack
  t9>          % does it exceed 9?
  ?            % if so
    7+         % add 7 (for letter ASCII code)
  ]            % end if
  w            % move quotient back to the top
  t            % duplicate 
]              % ...while (duplicated) quotient is not zero
x              % delete last quotient (zero)
N$h            % create vector of all remainders 
P              % flip vector
48+c           % add 48 and convert to char (will be implicitly displayed)

2

𝔼𝕊𝕄𝕚𝕟, 31 karakter / 62 byte

↺a=⬯;ï;ï≫4@a=⩥ḊĀⒸª⩥⁽ṁṇ⸩⨝[ï%Ḑ]+a

Try it here (Firefox only).

Oke, saya menemukan beberapa hal lagi yang bisa menurunkannya.

Penjelasan

Ini pada dasarnya solusi yang sama dengan solusi ES6 @ SuperJedi224 - tetapi dengan sesuatu yang berbeda.

Lihat ⩥ḊĀⒸª⩥⁽ṁṇ⸩⨝? Itu cara menulis yang sangat mewah "0123456789ABCDEF". ⩥Ḋmembuat rentang dari 0 hingga 10,Ⓒª⩥⁽ṁṇ⸩ membuat kisaran 65 hingga 71 dan mengubahnya menjadi string ASCII, danĀ...⨝ menggabungkan dua rentang dan menggabungkannya menjadi satu string. Ini mungkin bagian paling keren dari solusi saya.

Versi bonus non-kompetitif, 24 karakter / 45 byte

↺;ï;ï≫4@ᵴ=(⩥Ḋ⨝+ᶐ)[ï%Ḑ]+ᵴ

Saya memutuskan untuk menambahkan string alfabet, seperti di Pyth.


2

sed, 341 byte

:
s/\b/_/2
s/[13579]/&;/g
y/123456789/011223344/
s/;0/5/g
s/;1/6/g
s/;2/7/g
s/;3/8/g
s/;4/9/g
s/;_;_;_;_/=/
s/;_;_;__/+/
s/;_;__;_/:/
s/;_;___/>/
s/;__;_;_/</
s/;__;__/?/
s/;___;_/(/
s/;____/*/
s/_;_;_;_/-/
s/_;_;__/^/
s/_;__;_/%/
s/_;___/$/
s/__;_;_/#/
s/__;__/@/
s/___;_/!/
s/____/)/
/[1-9_]/b
y/)!@#$%^-*(?<>:+=/0123456789ABCDEF/
s/^0*//

Ini bukan bahasa yang jelas untuk tantangan ini, tetapi memang memiliki keuntungan mendukung nomor input hingga (tergantung pada implementasi Anda) antara 4000 digit dan batas memori (virtual) sistem Anda yang tersedia. Saya mengonversi RSA-1024 menjadi hex dalam waktu sekitar 0,6 detik, jadi itu cukup baik.

Ia bekerja menggunakan pembagian berurutan oleh dua, mengumpulkan setiap 4 bit carry menjadi hex digit. Kami menggunakan karakter non-huruf untuk mewakili output kami, sehingga kami selalu mengumpulkan carry antara input desimal dan output hex, dan mengkonversi ke hexadecimal konvensional di akhir.


2

PHP, 65 66 64 + 1 62 59 byte

function h($n){$n&&h($n>>4);echo"0123456789abcdef"[$n&15];}

fungsi pencetakan rekursif, mencetak nol di depan (masukkan >16sebelum &&untuk menghapusnya)


program, 64 byte +1 untuk -R(dijalankan sebagai pipa dengan -nR)

for(;$n=&$argn;$n>>=4)$s="0123456789abcdef"[$n&15].$s;echo$s?:0;

membutuhkan PHP 5.6 atau lebih baru (5.5 tidak dapat mengindeks string literal)

atau

for(;$n=&$argn;$n>>=4)$s=(abcdef[$n%16-10]?:$n%16).$s;echo$s?:0;

membutuhkan PHP 5.6 atau 7.0 (7.1 memahami indeks string negatif)


Jalankan sebagai pipa dengan -nRatau coba online .


1
Saya kehilangan tanda plus echo+$suntuk input 0
Jörg Hülsermann

+tanda memotong output pada huruf pertama ... jadi ..?:0
Titus

1

Julia, 55 byte

h(n)=(n>15?h(n÷16):"")"0123456789ABCDEF"[(i=n%16+1):i]

Ini adalah implementasi fungsi rekursif dasar. Ia menerima integer dan mengembalikan sebuah string.

Jika input kurang dari 15, pisahkan dengan 16 dan ulang, jika tidak ambil string kosong. Tack ini ke bagian depan karakter heksadesimal yang dipilih dengan tepat.


1

Onggokan kayu api , 98 byte

Melakukan ini dalam bahasa tanpa operator aritmatika mungkin merupakan kesalahan.

let h=def (n)(if n.gt(15)h(n.div(16).int!)else "").concat("0123456789abcdef".list!.get(n.mod(16)))

Gunakan seperti ini:

do
  let h = ...
  print(h(15))
end

Tidak Disatukan:

let h = def (n) do
    if n.gt(15) 
        let x = h(n.div(16).int!)
    else 
        let x = ""
    x.concat("0123456789abcdef".list!.get(n.mod(16)))
end

1

Ruby, 48 karakter

(Copy dari Loovjo 's Python jawaban .)

h=->n{(n>15?h[n/16]:'')+[*?0..?9,*?a..?f][n%16]}

Contoh dijalankan:

2.1.5 :001 > h=->n{(n>15?h[n/16]:'')+[*?0..?9,*?a..?f][n%16]}
 => #<Proc:0x00000001404a38@(irb):1 (lambda)> 
2.1.5 :002 > h[15]
 => "f" 
2.1.5 :003 > h[1000]
 => "3e8" 
2.1.5 :004 > h[256]
 => "100" 

1

Serius, 35 byte

,`;4ª@%)4ª@\`╬Xε D`@;7ªD+@9<7*+c+`n

Hex Dump:

2c603b34a640252934a6405c60ce58ee204460403b37a6442b40393c372a2b632b606e

Cobalah secara Online

Penjelasan:

,                                    Get evaluated input
 `          `╬                       Repeat the quoted function until top of stack is 0
  ;4ª@%                              Make a copy of the number mod 16
       )                             Send it to bottom of stack
        4ª@\                         Integer divide the original copy by 16
              X                      Delete the leftover zero. At this point the stack is 
                                     the "digits" of the hex number from LSD to MSD
               ε                     Push empty string
                 D`              `n  Essentially fold the quoted function over the stack.
                   @;                Roll up the next lowest digit, make a copy
                     7ªD+            Add 48
                         @           Bring up the other copy
                          9<         1 if it's at least 10, else 0
                            7*       Multiply with 7. 
                              +      Add. This will shift 58->65 and so on.
                               c     Convert to character.
                                +    Prepend to current string.

Perhatikan bahwa ;7ªD+@9<7*+csetara dengan 4ª▀E, yang akan menghemat 8 byte, tapi saya pikir mungkin fungsi yang mendorong basis b digit sebagai string mungkin dianggap terlalu banyak "built-in heaxadecimal".


1

Javascript ES6, 64 58 byte

v=>eval('for(z="";v;v>>=4)z="0123456789ABCDEF"[v%16]+z')

Disimpan 6 byte berkat ן nɟuɐɯɹɐ ן oɯ dan user81655.


1
Gunakan eval:v=>eval('for(z="";v;v=v/16|0)z="0123456789ABCDEF"[v%16]+z')
Mama Fun Roll

1
Oh ya, coba gunakan atob dan btoa untuk string panjang itu.
Mama Fun Roll

@ ן nɟuɐɯɹɐ ן oɯ Mencoba v=>{for(z="";v>0;v=v/16|0)z=btoa``Ó]·ã»óÐ1``[v%16]+z;return z}( Tild ganda adalah tild tunggal) ==> 64 karakter, 71 byte. Tidak layak.
usandfriends

1
v=v/16|0hanyalah cara penulisan yang kompleks v>>=4.
user81655

1

Befunge-93, 58

&:88+%"0"+:"9"`7*+\8/2/:!#|_#
,_@                       >:#

Pertama kali melakukan tantangan bermain golf nyata di Befunge, saya bertaruh ada satu garis untuk ini yang lebih pendek karena semua ruang di tengah garis kedua tampak boros.

Anda dapat melangkah melaluinya di sini . Penjelasan sebagian:

&: Ambil input.

:88+%: Ambil modulo 16 sisanya.

"0"+: Tambahkan ke nilai ASCII 0.

:"9"`: Jika hasilnya lebih besar dari nilai ASCII 9 ...

7*+: Tambahkan 7 untuk mengubahnya menjadi surat.

\: Simpan karakter yang dihasilkan di tumpukan.

8/2/: Membagi dengan 16 pembulatan ke bawah.

:!#|_: Keluar dari loop jika hasilnya 0.

#: Kalau tidak kembali ke langkah modulus.

>:#,_@ (membungkus): Setelah selesai, output tumpukan dalam urutan LIFO.


1

> <> , 46 + 3 = 49 byte

Ini akan menjadi lebih pendek jika> <> memiliki divisi integer, yang sekarang harus kita tiru dengan mengurangi modulo 1. Namun, saya pikir ini menggunakan beberapa trik yang cukup rapi!

>:?!v:f1+%:a(?v  v
\-%1:,+1f}+"0"<+7<
!?:r/ro;

Cobalah online!

Penjelasan

Loop pertama

>:?!v:f1+%:a(?v  v
\-%1:,+1f}+"0"<+7<

Loop pertama melakukan konversi klasik ke algoritma hex. Itu modulo 16 ( :f1+%) dan memeriksa apakah hasilnya <10 ( :a(?). Jika tidak, kita perlu menambahkan 7 ( 7+) untuk beralih dari desimal ke alfabet kapital dalam tabel ASCII. Selain itu, kita dapat melanjutkan dengan menambahkan nilai ASCII untuk 0 ( "0"+) dan menggeser karakter menjadi output ke bagian bawah tumpukan karena kita harus menampilkannya dalam urutan terbalik. Nilai teratas kemudian digantikan oleh hasil pembagian bilangannya dengan 16. Ini ditiru dengan menghitung a / b - (a / b)% 1 (f1+,:1%- ). Ketika loop selesai, stack berisi karakter heksadesimal dalam urutan output terbalik dan 0.

Lingkaran kedua

!?:r<ro;

Loop kedua membalik daftar dan memeriksa apakah elemen atas adalah 0. Jika ya, kita tahu semua bukan nol dicetak dan kita harus mengakhiri. Selain itu, kami menampilkan karakter dan membalik daftar lagi untuk mempersiapkan iterasi berikutnya. The :ketika memasuki loop kedua akan menduplikasi 0 yang tidak memiliki efek.


0

SpecBAS - 110 byte

1 h$="0123456789ABCDEF",r$=""
2 INPUT d
4 q=INT(d/16),r=d-(q*16),r$=h$(r+1)+r$,d=q
5 IF q>15 THEN 4
6  ?h$(q+1)+r$

Ini menggunakan algoritma yang saya temukan di WikiHow (metode kedua).

String di SpecBAS berbasis 1, maka +1untuk memilih elemen yang benar.



0

Ruby, 40 byte

Dicuri dari Terinspirasi oleh jawaban manatwork, tetapi menggunakan celah yang menarik untuk membuatnya lebih pendek.

h=->n{(n>15?h[n/16]:'')+(n%16).to_s(17)}

0

REXX, 80 78 byte

arg n
h=
do while n>0
  h=substr('0123456789ABCDEF',n//16+1,1)h
  n=n%16
  end
say h

0

C, 48 byte

h(x){x/16&&h(x/16);x%=16;putchar(x+=48+x/10*7);}

Ini tidak sepenuhnya asli, saya mencukur 5 byte dari versi Digital Trauma disiapkan.


0

APL (NARS), karakter 34, byte 68

{⍵≤0:,'0'⋄(∇⌊⍵÷16),(1+16∣⍵)⊃⎕D,⎕A}

uji:

  g←{⍵≤0:,'0'⋄(∇⌊⍵÷16),(1+16∣⍵)⊃⎕D,⎕A}
  g 0
0
  g 100
064
  g 1000
03E8
  g 1
01
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.