Перетворити число в шістнадцятковий


23

Виклик

Ось простий.

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

Приклади

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

Правила

  • Жодних вбудованих шістнадцяткових функцій немає
  • Букви можуть бути малими або великими
  • Вам потрібно буде турбуватися лише про негативні цілі числа, без негативів чи примхливих десяткових знаків
  • Він повинен працювати з будь-якою довільно великою кількістю до обмеження типового типу мови.
  • Новий рядок не є обов'язковим
  • Як завжди, це , тому найкоротший код, виміряний в байтах, виграє!

Перша проблема, сподіваюся, вам сподобається!
Випадковий хлопець

5
Чи дозволені провідні нулі у висновку, наприклад для 32-бітних чисел 000003E8?
німі

Будь-яке обмеження на вхід?
Loovjo

1
@nimi Так, це дозволено.
Випадковий хлопець

1
Веселий факт: у C ++ є вбудований шестигранник.
Метью Рох

Відповіді:


4

APL (Dyalog APL) , 17 байт

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

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

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

(⎕D,⎕A)[]D запалює з'єднаний з A lphabet, потім індексований…

16⊥⍣¯1  обернена 16-база до числа, тобто число-до-бази-16

 застосовується до

 числовий вхід


Це не 17 символів і близько 23 байт?
Джулі Пелтьє

1
@JuliePelletier Ні, Dyalog APL використовує власну кодову сторінку з 256 символами.
Адам

Ой! Добре знати.
Джулі Пелтьє,

14

Код машини Тьюрінга, 412 байт

Як завжди, я використовую визначений тут синтаксис таблиці правил . Ви можете протестувати його на цьому веб-сайті або, альтернативно, використовувати цю реалізацію Java.

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

Відраховується від входу в базі 10, підраховуючи від 0 в базі 16. Після зменшення нуля він стирає блок введення і закінчується.


Це дійсно круто, потрібно 10*n + 33заповнити інструкції для будь-якого довільного n. Я не розумію коду, хоча.
Magic Octopus Urn

@MagicOctopusUrn Він створює новий блок комірок зліва від входу, спочатку містить 0. Потім він повторно зменшує вхідний блок у базі 10, збільшуючи вихідний блок у базі 16, поки не намагається зменшити порожню комірку під час цикл зменшення [який говорить про те, що блок введення зараз 0], в цей момент він очищає стрічку (тому на стрічці залишається тільки вихід) перед зупинкою.
SuperJedi224

@MagicOctopusUrn Також ваше рівняння під час виконання невірно (я не знаю, що є правильним загальним рівнянням, але це явно не так). Спробуйте, наприклад, із введенням 2.
SuperJedi224

певно, ні. Схоже, близькі за високими значеннями. Я нічого не знаю про це і намагався побачити візерунки.
Чарівний Восьминіг Урна

9

Java, 92 89 байт

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

9

Javascript, 49 43 байт.

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

6 байт врятовані user81655 .

Перевірте це тут .

У цьому є два провідні нулі, що дозволено правилами.

Ось версія без перших нулів: (47 байт).

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

Перевірте це тут .

І те і інше використовує абсолютно такий самий підхід, як і моя відповідь Python .


Використовуйте двійкові І. i&15автоматично перетвориться на цілі числа, скидаючи десяткові знаки. Не потрібно~~
edc65

Я врятував 3 байти і один провідний нуль:h=i=>i&&h(i>>4)+"0123456789abcdef"[i&15]
Ніл

8

CJam, 22 21 байт

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

Дякуємо @ MartinBüttner за те, що виграли 1 байт!

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

Як це працює

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
Кількість байтів:ri{Gmd_9>7*sc+\}h;]W%
Мартін Ендер

6

Pyth, 33 26 21 20 байт

Це було весело.

sm@+jkUTGi_d2_c_.BQ4

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

Пояснили:

                .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.

Чи можете ви додати пояснення?
TanMath

Впевнений, кого з вас цікавить?
Лука

Найцікавіша відповідь! ;) це не має значення ... Хоча це гарна ідея розміщувати пояснення для всіх
TanMath

5

C (функція), 51

Рекурсивна функція приймає вхідне ціле число як параметр:

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

Тест-драйвер:

#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

Хаскелл, 59 58 43 41 39 байт

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

Приклад використання: sequence(s<$s)!!) $ 1000-> "00000000000003E8".

Це створює список усіх шістнадцяткових чисел до 16 шістнадцяткових цифр. На щастя, це відбувається в порядку, тому ми можемо просто вибрати той n.

Редагувати: @Mauris видавив 2 байти. Спасибі!


Список даних
Monad

@Daenyth: Я перейшов від монади до функтора
Ними

Як щодоs="0123456789ABCDEF";(sequence(s<$s)!!)
Лінн

@Mauris: приголомшливо!
німі

4

постійний струм, 37

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

Рекурсивно поділяється на 16, проштовхуючи залишки до стеку, поки нічого не залишається для поділу. Потім надрукуйте кожен елемент стека, використовуючи divmod по 10 для досягнення цифр AF. Напевно, детальніше завтра ... (і, сподіваємось, менше байт).


4

Пітон, 59 58 байт

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

1 байт, збережений CarpetPython

Виконувати як: print h(15)

Перевірте це тут (Ideone.com).

Пояснення:

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
Хороша робота. Ви також можете зберегти інший байт за допомогою h=lambda i:(i>15 and h(i/16)or'')+"0123456789abcdef"[i%16].
Логічний лицар

Хороша робота справді, ви можете зберегти ще два таких:h=lambda i:(i>15 and h(i/16)or'')+chr(48+i%16+i%16/10*7)
Віллем


3

Bash (функція), 62

Завдяки @manatwork за пропозицію використовувати рекурсію.

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

Приємно. Але рекурсивний шлях все ще здається коротшим:h(){ x=({0..9} {A..F});echo `(($1>15))&&h $[$1/16]`${x[$1%16]}; }
маніпуляція

1
@manatwork Приємно - дякую! Я чомусь зазвичай забуваю спробувати рекурсію в баші, хоча я використовую її в інших відповідях. Використання ()замість { ;}навколо функції тіла економить ще більше :)
Digital Trauma

3

Perl 6 ,  53  48 байт

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

Це створює послідовність значень, які поділяються на цілі числа ( div), поки результат не буде 0виключений 0із послідовності

$_, * div 16 ...^ 0

Потім він перетинає ( X) цю послідовність, використовуючи оператор модуля ( %) з16

(  ) X[%] 16

Він використовує ці значення як індекси у сплющеному списку, що складається з двох діапазонів 0..9і'A'..'Z'

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

Нарешті, він об'єднує ( ~) їх за допомогою метаоператора reverse ( R)

[R[~]] 

Якщо це призведе до помилкового значення (порожній рядок), поверніться 0

 || 0

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

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

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

Для цього використовується випуск 5.1.0 мови / компілятора, що є раніше, ніж це завдання.

Приклад

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

Пояснення

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 символів / 62 байти

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

Try it here (Firefox only).

Гаразд, я з'ясував ще деякі речі, які гольфували його.

Пояснення

Це по суті те саме рішення, що і рішення ES6 @ SuperJedi224, але з чимось іншим.

Бачите ⩥ḊĀⒸª⩥⁽ṁṇ⸩⨝? Це дійсно фантазійний спосіб написання "0123456789ABCDEF". ⩥Ḋстворює діапазон від 0 до 10, Ⓒª⩥⁽ṁṇ⸩створює діапазон від 65 до 71 і перетворює його в рядок ASCII і Ā...⨝з'єднує два діапазони і з'єднує їх в одну рядок. Це, мабуть, найкрутіша частина мого рішення.

Бонусна неконкурентна версія, 24 символів / 45 байт

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

Я вирішив додати рядок алфавіту, як у Pyth.


2

sed, 341 байт

:
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*//

Це не очевидна мова для цього виклику, але він має перевагу в підтримці вхідних номерів до (залежно від вашої реалізації) між 4000 цифрами та обмеженням доступної (віртуальної) пам'яті вашої системи. Я перетворив RSA-1024 в шістнадцять приблизно за 0,6 секунди, тому він масштабується досить добре.

Він працює, використовуючи послідовне ділення на два, накопичуючи кожні 4 біти перенесення у шістнадцяткову цифру. Ми використовуємо небуквені символи для представлення нашого результату, щоб ми завжди накопичували перенесення між десятковим введенням і шістнадцятковим висновком і перетворювали на звичайні шістнадцяткові в самому кінці.


2

PHP, 65 66 64 + 1 62 59 байт

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

рекурсивна функція друку, друкує провідний нуль (вставити >16перед тим, &&щоб видалити його)


програми, 64 байти +1 для -R(запустіть як труба з -nR)

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

потрібен PHP 5.6 або новішої версії (5.5 не може індексувати рядкові літерали)

або

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

вимагає PHP 5.6 або 7.0 (7.1 розуміє негативні рядкові індекси)


Запустіть як трубу -nRабо спробуйте їх в Інтернеті .


1
Я пропускаю знак плюс echo+$sдля введення 0
Йорг Гюльсерманн

+ знак вирізає вихід на першій букві ... так .. ?:0
Тит

1

Джулія, 55 байт

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

Це основна рекурсивна реалізація функції. Він приймає ціле число і повертає рядок.

Якщо вхід менше 15, підлогу поділіть на 16 і повторіть повтор, інакше візьміть порожній рядок. Поставте це на передній панелі відповідно обраного шістнадцяткового символу.


1

Pyre , 98 байт

Робити це мовою без арифметичних операторів, ймовірно, було помилкою.

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

Використовуйте так:

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

Безголівки:

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

Рубі, 48 символів

(Копія Loovjo «s відповідь на Python .)

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

Проба зразка:

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

Серйозно, 35 байт

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

Шестнадцятковий дамп:

2c603b34a640252934a6405c60ce58ee204460403b37a6442b40393c372a2b632b606e

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

Пояснення:

,                                    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.

Зауважте, що ;7ªD+@9<7*+cеквівалент 4ª▀E, який би економив 8 байтів, але я подумав, що, можливо, функція, яка висуває базові b цифри як рядок, може вважатися занадто великою "важкодоступною вбудованою".


1

Javascript ES6, 64 58 байт

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

Збережено 6 байт завдяки ן nɟuɐɯɹɐ ן oɯ та користувачеві81655.


1
Використовуйте eval:v=>eval('for(z="";v;v=v/16|0)z="0123456789ABCDEF"[v%16]+z')
Mama Fun Roll

1
О так, спробуйте використати atob та btoa для цієї довгої струни.
Mama Fun Roll

@ ן nɟuɐɯɹɐ ן oɯ Спробував v=>{for(z="";v>0;v=v/16|0)z=btoa``Ó]·ã»óÐ1``[v%16]+z;return z}(Подвійні тильди - це поодинокі тильди) ==> 64 символів, 71 байт. Не варто.
usandfriends

1
v=v/16|0це просто складний спосіб написання v>>=4.
user81655

1

Befunge-93, 58

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

Перший раз, коли робите справжню проблему з гольфу в Бефунге, я думаю, що для цього короткий осередок, який коротший, оскільки всі ці місця в середині другої лінії здаються марними.

Ви можете переступити через це тут . Часткове пояснення:

&: Візьміть вклад.

:88+%: Візьміть решту модуля 16.

"0"+: Додайте його до значення ASCII 0.

:"9"`: Якщо результат більший за значення ASCII 9 ...

7*+: Додайте 7, щоб перетворити його на лист.

\: Збережіть отриманий символ у стеку.

8/2/: Розділіть на 16 округлення вниз.

:!#|_: Вийдіть з циклу, якщо результат дорівнює 0.

#: Інакше поверніться до кроку модуля.

>:#,_@ (обгортання): Після завершення виведіть стек у порядку LIFO.


1

> <> , 46 + 3 = 49 байт

Це було б коротше, якби> <> мав ціле ділення, яке ми зараз мусимо наслідувати відніманням модуля 1. Все-таки я думаю, що для цього використовуються досить акуратні обгортки навколо хитрощів!

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

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

Пояснення

Перша петля

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

Перший цикл виконує класичне перетворення в шістнадцятковий алгоритм. Він робить модуль 16 ( :f1+%) і перевіряє, чи є результат <10 ( :a(?). Якщо це не так, нам потрібно додати 7 ( 7+), щоб перейти від десяткових знаків до великого алфавіту таблиці ASCII. В іншому випадку ми можемо продовжити, додавши значення ASCII для 0 ( "0"+) і перемістивши символ для виведення в нижню частину стека, оскільки нам доведеться виводити їх у зворотному порядку. Потім верхнє значення замінюється його результатом цілочисельного поділу на 16. Це емулюється обчисленням a / b - (a / b)% 1 (f1+,:1%- ). Коли цикл закінчений, стек містить шістнадцяткові символи у зворотному порядку виведення та 0.

Друга петля

!?:r<ro;

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


0

SpecBAS - 110 байт

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$

Для цього використовується алгоритм, який я знайшов у WikiHow (2-й метод).

Рядки в SpecBAS базуються на 1, отже, +1виберіть правильний елемент.



0

Рубін, 40 байт

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

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

0

REXX, 80 78 байт

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

0

C, 48 байт

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

Це не зовсім оригінально, я поголив 5 байт від версії Digital Trauma, яку мислимо.


0

APL (NARS), символи 34, байти 68

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

тест:

  g←{⍵≤0:,'0'⋄(∇⌊⍵÷16),(1+16∣⍵)⊃⎕D,⎕A}
  g 0
0
  g 100
064
  g 1000
03E8
  g 1
01
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.