Преобразовать число в шестнадцатеричное

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 igits сцеплены для 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. При уменьшении нуля он стирает блок ввода и завершается.

SuperJedi224
источник
Это действительно круто, требуются 10*n + 33инструкции для выполнения любого произвольного n. Я не понимаю код, хотя.
Волшебная урна осьминога
@MagicOctopusUrn Создает новый блок ячеек слева от входа, изначально содержащий 0. Затем он многократно уменьшает входной блок в базе 10, увеличивая при этом выходной блок в базе 16, пока не попытается уменьшить пустую ячейку во время цикл декремента [который сообщает ему, что входной блок теперь равен 0], после чего он очищает ленту (поэтому на ленте остается только вывод) перед остановкой.
SuperJedi224
@MagicOctopusUrn Также ваше уравнение для времени выполнения неверно (хотя я не знаю, что такое правильное общее уравнение, просто это явно не так). Попробуйте это с вводом 2, например.
SuperJedi224
возможно нет. Казалось, близко для высоких значений, хотя. Я ничего не знаю об этом и пытался увидеть шаблоны.
Волшебная Урна Осьминога
9

Ява, 92 89 байт

String x(int v){String z="";for(;v>0;v/=16)z="0123456789ABCDEF".charAt(v%16)+z;return z;}
SuperJedi224
источник
9

Javascript, 49 43 байта.

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

6 байтов сохранено пользователем 81655 .

Проверьте это здесь .

Это имеет два ведущих нуля, что разрешено правилами.

Вот версия без начальных нулей: (47 байт).

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

Проверьте это здесь .

Оба они используют точно такой же подход, как и мой ответ на Python .

Loovjo
источник
Используйте двоичное И. 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

С (функция), 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 байта. Благодарность!

Ними
источник
Dat list
monad
@Daenyth: я переключился с Monad на Functor
nimi
Как насчетs="0123456789ABCDEF";(sequence(s<$s)!!)
Линн
@Mauris: круто!
Ними
4

DC, 37

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

Рекурсивно делит на 16, помещая остаток в стек, пока не останется ничего для деления. Затем напечатайте каждый элемент стека, используя divmod на 10, чтобы получить цифры AF. Вероятно, более подробно завтра ... (и, надеюсь, меньше байтов).

Цифровая травма
источник
4

Python, 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.
Loovjo
источник
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)
Виллем
4

C (gcc) , 45 44 байта

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

Попробуйте онлайн!

ceilingcat
источник
В упражнении есть фраза «• Не обязательный перевод строки», это означает, что число должно заканчиваться на «\ n»?
Рослуп
3

Баш (функция), 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 Хорошо - спасибо! По какой-то причине я обычно забываю попробовать рекурсию в bash, хотя я использую ее в других ответах. Использование ()вместо { ;}всей функции тела экономит еще больше :)
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[  ]

Наконец, он объединяет ~их, используя Rмета-оператор reverse ( ).

[R[~]] 

Если это приводит к значению False (пустой строке), вернуть 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
Брэд Гилберт b2gills
источник
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.

Mama Fun Roll
источник
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или попробуйте их онлайн .

Titus
источник
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

Ungolfed:

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" 
manatwork
источник
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 в виде строки, может считаться слишком большой частью «шестнадцатеричного встроенного».

quintopia
источник
1

Javascript ES6, 64 58 байт

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

Сохранено 6 байтов благодаря ן n useruɐɯɹɐ ן oɯ и user81655.

SuperJedi224
источник
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 31.12.15
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.

histocrat
источник
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, что не имеет никакого эффекта.

PidgeyUsedGust
источник
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 байт

Украдено у Inspired ответом manatwork, но с использованием интересной лазейки, чтобы сделать его короче.

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
idrougge
источник
0

C, 48 байтов

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

Это не совсем оригинально, я сбил 5 байтов от версии Digital Trauma.

Bijan
источник
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
RosLuP
источник