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


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


Это действительно круто, требуются 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;}

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 .


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

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

Баш (функция), 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

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

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" 

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 useruɐɯɹɐ ן oɯ и user81655.


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.


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

Украдено у 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

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.