Convertir un número a hexadecimal


23

Reto

Aquí hay uno simple.

Escriba una función o programa cuando se le dé un número en la base 10 como entrada, devolverá o imprimirá el valor de ese número en hexadecimal .

Ejemplos

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

Reglas

  • Sin funciones hexadecimales incorporadas
  • Las letras pueden ser minúsculas o mayúsculas
  • Solo tendrá que preocuparse por enteros no negativos, negativos o decimales molestos
  • Debería funcionar con cualquier número arbitrariamente grande hasta el límite del tipo predeterminado de idioma.
  • Nueva línea no obligatoria
  • Como de costumbre, este es el , por lo que gana el código más corto medido en bytes.

Primer problema, ¡espero que lo disfruten!
Random Guy

55
¿Se permiten ceros iniciales en la salida, por ejemplo, para números de 32 bits 000003E8?
nimi

¿Algún límite en la entrada?
Loovjo

1
@nimi Sí, eso está permitido.
Random Guy

1
Dato curioso: C ++ tiene un hexadecimal incorporado.
Matthew Roh

Respuestas:


4

APL (Dyalog APL) , 17 bytes

Debe ejecutarse con ⎕IO←0, lo cual es predeterminado en muchos sistemas APL.

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

Pruébalo en línea!

(⎕D,⎕A)[... ]D igits concatenados a un lphabet, a continuación, indexados por ...

16⊥⍣¯1  el inverso de 16-Base-to-Number, es decir, Number-to-Base-16

 aplicado a

 entrada numérica


¿No son 17 caracteres y alrededor de 23 bytes?
Julie Pelletier

1
@JuliePelletier No, Dyalog APL usa su propia página de códigos de 256 caracteres.
Adám

Oh! Bueno saber.
Julie Pelletier

14

Código de máquina de Turing, 412 bytes

Como de costumbre, estoy usando la sintaxis de la tabla de reglas definida aquí. Puede probarlo en ese sitio o, alternativamente, usar esta implementación de 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

Cuenta hacia atrás desde la entrada en la base 10 mientras cuenta desde 0 en la base 16. Al disminuir el cero, borra el bloque de entrada y termina.


Esto es realmente genial, se necesitan 10*n + 33instrucciones para completar cualquier arbitrario n. Aunque no entiendo el código.
Urna mágica del pulpo

@MagicOctopusUrn Crea un nuevo bloque de celdas a la izquierda de la entrada, que inicialmente contiene un 0. Luego, disminuye repetidamente el bloque de entrada en la base 10 mientras incrementa el bloque de salida en la base 16, hasta que intenta disminuir una celda vacía durante el ciclo de disminución [que le dice que el bloque de entrada ahora es 0], momento en el que limpia la cinta (por lo que solo queda la salida en la cinta) antes de detenerse.
SuperJedi224

@MagicOctopusUrn También su ecuación para el tiempo de ejecución es incorrecta (no sé cuál es la ecuación general correcta, solo que claramente no lo es). Pruébelo con una entrada de 2, por ejemplo.
SuperJedi224

Probablemente no. Sin embargo, parecía cercano a valores altos. No sé nada al respecto e intentaba ver patrones.
Urna de pulpo mágico el

9

Java, 92 89 bytes

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

9

Javascript, 49 43 bytes.

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

6 bytes guardados por el usuario 81655 .

Pruébalo aquí .

Esto tiene dos ceros a la izquierda, lo cual está permitido por las reglas.

Aquí hay una versión sin ceros a la izquierda: (47 bytes).

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

Pruébalo aquí .

Ambos utilizan exactamente el mismo enfoque que mi respuesta de Python .


Use binario AND. i&15se convertirá automáticamente a entero, dejando decimales. No hay necesidad de~~
edc65

Ahorré 3 bytes y un cero a la izquierda:h=i=>i&&h(i>>4)+"0123456789abcdef"[i&15]
Neil

8

CJam, 22 21 bytes

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

¡Gracias a @ MartinBüttner por jugar golf en 1 byte!

Pruébalo en línea!

Cómo funciona

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.

55
Mismo conteo de bytes:ri{Gmd_9>7*sc+\}h;]W%
Martin Ender

6

Pyth, 33 26 21 20 bytes

Esto fue divertido.

sm@+jkUTGi_d2_c_.BQ4

Pruébalo en línea.

Explicado:

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

¿Puedes agregar una explicación?
TanMath

Claro, ¿en cuál estás interesado?
Lucas

¡La respuesta más interesante! ;) no importa ... Aunque es una buena idea publicar explicaciones para todos ellos
TanMath

5

C (función), 51

La función recursiva toma el entero de entrada como parámetro:

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

Conductor de prueba:

#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 bytes

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

Ejemplo de uso: sequence(s<$s)!!) $ 1000-> "00000000000003E8".

Esto crea una lista de todos los números hexadecimales de hasta 16 dígitos hexadecimales. Afortunadamente, esto sucede en orden, por lo que simplemente podemos elegir el nth.

Editar: @Mauris exprimió 2 bytes. ¡Gracias!


Dat list
monad

@Daenyth: He cambiado de Monad a Functor
nimi

¿Qué tals="0123456789ABCDEF";(sequence(s<$s)!!)
Lynn

@Mauris: ¡genial!
nimi

4

dc, 37

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

Divide recursivamente por 16, empujando el resto a la pila hasta que no quede nada para dividir. Luego imprima cada elemento de la pila, usando divmod por 10 para lograr los dígitos AF. Probablemente más detalles mañana ... (y con suerte menos bytes).


4

Python, 59 58 bytes

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

1 byte guardado por CarpetPython

Correr como: print h(15)

Probarlo aquí (Ideone.com).

Explicación:

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
Buen trabajo. También puede guardar otro byte con h=lambda i:(i>15 and h(i/16)or'')+"0123456789abcdef"[i%16].
Logic Knight el

Buen trabajo de hecho, puedes salvar otros dos como este:h=lambda i:(i>15 and h(i/16)or'')+chr(48+i%16+i%16/10*7)
Willem

4

C (gcc) , 45 44 bytes

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

Pruébalo en línea!


En el ejercicio aparece la frase "• Nueva línea no obligatoria", ¿esto significa que el número debe terminar con '\ n'?
RosLuP

3

Bash (función), 62

Gracias a @manatwork por sugerir el uso de la recursividad.

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

Agradable. Pero la forma recursiva todavía parece ser más corto:h(){ x=({0..9} {A..F});echo `(($1>15))&&h $[$1/16]`${x[$1%16]}; }
manatwork

1
@manatwork Nice - ¡gracias! Por alguna razón, generalmente me olvido de intentar la recursividad en bash, aunque lo estoy usando en otras respuestas. Usar en ()lugar de { ;}alrededor del cuerpo de la función ahorra aún más :)
Digital Trauma

3

Perl 6 ,  53  48 bytes

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

Esto crea una secuencia de valores que son enteros divididos ( div), hasta que el resultado 0excluya el 0de la secuencia

$_, * div 16 ...^ 0

Luego cruza ( X) esa secuencia usando el operador de módulo ( %) con16

(  ) X[%] 16

Utiliza esos valores como índices en una lista aplanada que consta de dos rangos 0..9y'A'..'Z'

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

Finalmente los concatena ( ~) usando el Rmeta operador reverse ( )

[R[~]] 

Si eso da como resultado un valor falso (cadena vacía), devuelva 0

 || 0

Uso:

# (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 bytes

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

Esto usa versión 5.1.0 del lenguaje / compilador, que es anterior a este desafío.

Ejemplo

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

Explicación

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 caracteres / 62 bytes

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

Try it here (Firefox only).

Bien, descubrí algunas cosas más que lo jugaron golf.

Explicación

Es esencialmente la misma solución que la solución ES6 de @ SuperJedi224, pero con algo diferente.

⩥ḊĀⒸª⩥⁽ṁṇ⸩⨝¿ Ves ? Esa es una forma muy elegante de escribir "0123456789ABCDEF". ⩥Ḋcrea un rango de 0 a 10, Ⓒª⩥⁽ṁṇ⸩crea un rango de 65 a 71 y lo convierte en una cadena de ASCII, y Ā...⨝concatena los dos rangos y los une en una sola cadena. Esta fue probablemente la parte más genial de mi solución.

Versión no competitiva adicional, 24 caracteres / 45 bytes

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

Decidí agregar una cadena de alfabeto, como en Pyth.


2

sed, 341 bytes

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

No es el lenguaje obvio para este desafío, pero tiene la ventaja de admitir números de entrada hasta (dependiendo de su implementación) entre 4000 dígitos y el límite de memoria disponible (virtual) de su sistema. Convertí RSA-1024 a hexadecimal en aproximadamente 0.6 segundos, por lo que se escala razonablemente bien.

Funciona usando la división sucesiva por dos, acumulando cada 4 bits de acarreo en un dígito hexadecimal. Utilizamos caracteres que no son letras para representar nuestra salida, de modo que siempre acumulamos acarreo entre la entrada decimal y la salida hexadecimal, y la convertimos a hexadecimal convencional al final.


2

PHP, 65 66 64 + 1 62 59 bytes

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

función de impresión recursiva, imprime un cero inicial (inserte >16antes &&para eliminarlo)


programas, 64 bytes +1 para -R(ejecutar como canalización con -nR)

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

requiere PHP 5.6 o posterior (5.5 no puede indexar literales de cadena)

o

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

requiere PHP 5.6 o 7.0 (7.1 entiende los índices de cadena negativos)


Ejecutar como tubería -nRo probarlos en línea .


1
Me falta un signo más echo+$spara la entrada 0
Jörg Hülsermann

+signo corta la salida en la primera letra ... así que ...?:0
Titus

1

Julia, 55 bytes

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

Esta es la implementación básica de la función recursiva. Acepta un entero y devuelve una cadena.

Si la entrada es menor que 15, el piso se divide por 16 y se repite; de ​​lo contrario, tome la cadena vacía. Agregue esto al frente del carácter hexadecimal seleccionado apropiadamente.


1

Pira , 98 bytes

Hacer esto en un lenguaje sin operadores aritméticos fue probablemente un error.

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

Usar así:

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

Sin golf:

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

(Copia de la respuesta de Python de Loovjo ).

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

Ejecución de muestra:

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

En serio, 35 bytes

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

Hex Dump:

2c603b34a640252934a6405c60ce58ee204460403b37a6442b40393c372a2b632b606e

Pruébalo en línea

Explicación:

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

Tenga en cuenta que ;7ªD+@9<7*+ces equivalente a 4ª▀E, lo que ahorraría 8 bytes, pero pensé que tal vez una función que empuja los dígitos de la base b como una cadena podría considerarse demasiado como un "incorporado hexadecimal".


1

Javascript ES6, 64 58 bytes

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

Guardado 6 bytes gracias a ן nɟuɐɯɹɐ ן oɯ y user81655.


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

1
Oh sí, intenta usar atob y btoa para esa larga cadena.
Mama Fun Roll

@ ן nɟuɐɯɹɐ ן oɯ Probado v=>{for(z="";v>0;v=v/16|0)z=btoa``Ó]·ã»óÐ1``[v%16]+z;return z}(las tildes dobles son tildes simples) ==> 64 caracteres, 71 bytes. No vale la pena.
usandfriends

1
v=v/16|0es solo una forma compleja de escribir v>>=4.
user81655

1

Befunge-93, 58

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

La primera vez que realizo un verdadero desafío de golf en Befunge, apuesto a que hay una sola línea para esto que es más corta ya que todos esos espacios en el medio de la segunda línea parecen ser un desperdicio.

Puedes recorrerlo aquí . Explicación parcial:

&: Tomar entrada.

:88+%: Tome el resto del módulo 16.

"0"+: Añádelo al valor ASCII de 0.

:"9"`: Si el resultado es mayor que el valor ASCII de 9 ...

7*+: Agregue 7 para convertirlo en una letra.

\: Guarda el personaje resultante en la pila.

8/2/: Divide entre 16 redondeando hacia abajo.

:!#|_: Salga del bucle si el resultado es 0.

#: De lo contrario, vuelva al paso de módulo.

>:#,_@ (ajuste): una vez terminado, envíe la pila en orden LIFO.


1

> <> , 46 + 3 = 49 bytes

Esto habría sido más corto si> <> tuviera una división entera, que ahora tenemos que emular restando el módulo 1. Aún así, ¡creo que esto usa algunos trucos envolventes!

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

Pruébalo en línea!

Explicación

Primer bucle

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

El primer bucle realiza la conversión clásica al algoritmo hexadecimal. Hace el módulo 16 ( :f1+%) y comprueba si el resultado es <10 ( :a(?). Si no es así, debemos agregar 7 ( 7+) para pasar de los decimales al alfabeto mayúscula en la tabla ASCII. De lo contrario, podemos proceder agregando el valor ASCII para 0 ( "0"+) y desplazando el carácter que se generará al final de la pila porque tendremos que generarlos en orden inverso. El valor superior se reemplaza por su resultado de la división de enteros por 16. Esto se emula calculando a / b - (a / b)% 1 ( f1+,:1%-). Cuando finaliza el ciclo, la pila contiene los caracteres hexadecimales en orden de salida invertido y un 0.

Segundo bucle

!?:r<ro;

El segundo bucle invierte la lista y comprueba si el elemento superior es 0. Si es así, sabemos que se imprimieron todos los que no son cero y debemos finalizar. De lo contrario, mostramos el carácter y volvemos a invertir la lista para prepararnos para la próxima iteración. Al :ingresar al segundo bucle, se duplicará el 0 que no tiene ningún efecto.


0

SpecBAS - 110 bytes

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$

Esto usa un algoritmo que encontré en WikiHow (segundo método).

Las cadenas en SpecBAS están basadas en 1, por lo tanto, +1para seleccionar el elemento correcto.



0

Rubí, 40 bytes.

Robado de Inspirado por la respuesta de manatwork, pero usando una escapatoria interesante para hacerlo más corto.

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

0

REXX, 80 78 bytes

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

0

C, 48 bytes

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

Esto no es completamente original, eliminé 5 bytes de la versión que trajo Digital Trauma.


0

APL (NARS), caracteres 34, bytes 68

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

prueba:

  g←{⍵≤0:,'0'⋄(∇⌊⍵÷16),(1+16∣⍵)⊃⎕D,⎕A}
  g 0
0
  g 100
064
  g 1000
03E8
  g 1
01
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.