Convertire un numero in esadecimale


23

Sfida

Eccone uno semplice.

Scrivi una funzione o un programma quando viene inserito un numero in base 10 come input, restituirà o stamperà il valore di quel numero in esadecimale .

Esempi

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

Regole

  • Nessuna funzione esadecimale integrata
  • Le lettere possono essere minuscole o maiuscole
  • Avrai solo bisogno di preoccuparti per numeri interi non negativi, senza negativi o fastidiosi decimali
  • Dovrebbe funzionare con qualsiasi numero arbitrariamente grande fino al limite del tipo predefinito della lingua.
  • Newline non obbligatorio
  • Come al solito, si tratta di , quindi vince il codice più breve misurato in byte!

Primo problema, spero che vi divertiate!
Ragazzo casuale

5
Sono consentiti zeri iniziali nell'output, ad esempio per numeri a 32 bit 000003E8?
nimi

Qualche limite sull'input?
Loovjo,

1
@nimi Sì, è permesso.
Ragazzo casuale

1
Curiosità: C ++ ha un hex incorporato.
Matthew Roh,

Risposte:


4

APL (Dyalog APL) , 17 byte

Deve essere eseguito con ⎕IO←0, che è predefinito su molti sistemi APL.

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

Provalo online!

(⎕D,⎕A)[... ]D igits concatenazioni A lphabet, poi indicizzati da ...

16⊥⍣¯1  l'inverso di 16-Base-a-Numero, cioè da Numero-a-Base-16

 applicata ai

 input numerico


Non sono 17 caratteri e circa 23 byte?
Julie Pelletier,

1
@JuliePelletier No, Dyalog APL utilizza la sua tabella codici 256 caratteri.
Adám,

Oh! Buono a sapersi.
Julie Pelletier,

14

Codice di Turing Machine, 412 byte

Come al solito, sto usando la sintassi della tabella delle regole definita qui. Puoi provarlo su quel sito o, in alternativa, usando questa implementazione 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

Conta alla rovescia dall'ingresso in base 10 mentre conta da 0 in base 16. Al decremento di zero, cancella il blocco di input e termina.


Questo è davvero bello, ci vogliono 10*n + 33istruzioni per completare qualsiasi arbitrario n. Non capisco il codice però.
Magic Octopus Urn,

@MagicOctopusUrn Crea un nuovo blocco di celle a sinistra dell'ingresso, inizialmente contenente uno 0. Quindi, decrementa ripetutamente il blocco di input nella base 10 mentre incrementa il blocco di output nella base 16, fino a quando tenta di decrementare una cella vuota durante il ciclo di decremento [che indica che il blocco di input è ora 0], a quel punto pulisce il nastro (quindi solo l'output rimane sul nastro) prima di arrestarsi.
SuperJedi224,

@MagicOctopusUrn Anche la tua equazione per il runtime è errata (non so quale sia l'equazione generale corretta, solo che chiaramente non è così). Provalo con un input di 2, ad esempio.
SuperJedi224,

probabilmente no. Sembrava vicino per valori elevati però. Non ne so nulla e stavo tentando di vedere schemi.
Magic Octopus Urn

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 salvati dall'utente81655 .

Provalo qui .

Questo ha due zeri iniziali, che è consentito dalle regole.

Ecco una versione senza zeri iniziali: (47 byte).

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

Provalo qui .

Entrambi utilizzano esattamente lo stesso approccio della mia risposta Python .


Usa AND binario. i&15si convertirà automaticamente in numero intero, eliminando i decimali. Non c'è bisogno di~~
edc65, il

Ho salvato 3 byte e uno zero iniziale:h=i=>i&&h(i>>4)+"0123456789abcdef"[i&15]
Neil

8

CJam, 22 21 byte

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

Grazie a @ MartinBüttner per il golf off 1 byte!

Provalo online!

Come funziona

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
Stesso numero di byte:ri{Gmd_9>7*sc+\}h;]W%
Martin Ender il

6

Pyth, 33 26 21 20 byte

Questo è stato divertente.

sm@+jkUTGi_d2_c_.BQ4

Provalo online.

Ha spiegato:

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

Puoi aggiungere una spiegazione?
TanMath,

Certo, a quale sei interessato?
Luca

La risposta più interessante! ;) non importa ... Anche se è una buona idea pubblicare spiegazioni per tutti loro
TanMath

5

C (funzione), 51

La funzione ricorsiva accetta l'input intero come parametro:

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

Test 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)!!)

Esempio di utilizzo: sequence(s<$s)!!) $ 1000-> "00000000000003E8".

Questo crea un elenco di tutti i numeri esadecimali fino a 16 cifre esadecimali. Fortunatamente questo accade nell'ordine, quindi possiamo semplicemente scegliere nquello.

Modifica: @Mauris ha eliminato 2 byte. Grazie!


Elenco dati monad doe
Daenyth,

@Daenyth: Ho passato da Monade a Functor
Nome del modello

Che ne dicis="0123456789ABCDEF";(sequence(s<$s)!!)
Lynn

@Mauris: fantastico!
nimi

4

dc, 37

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

Divmodifica ricorsivamente di 16, spingendo il resto in pila fino a quando non rimane nulla da dividere. Quindi stampa ogni elemento della pila, usando divmod per 10 per ottenere cifre AF. Probabilmente più dettagli domani ... (e speriamo meno byte).


4

Python, 59 58 byte

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

1 byte salvato da CarpetPython

Correre come: print h(15)

Provatelo qui (Ideone.com).

Spiegazione:

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
Bel lavoro. Puoi anche salvare un altro byte con h=lambda i:(i>15 and h(i/16)or'')+"0123456789abcdef"[i%16].
Logic Knight

Bel lavoro davvero, puoi salvarne altri due in questo modo:h=lambda i:(i>15 and h(i/16)or'')+chr(48+i%16+i%16/10*7)
Willem,


3

Bash (funzione), 62

Grazie a @manatwork per aver suggerito di utilizzare la ricorsione.

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

Bello. Ma il modo ricorsivo sembra ancora essere più breve:h(){ x=({0..9} {A..F});echo `(($1>15))&&h $[$1/16]`${x[$1%16]}; }
manatwork

1
@manatwork Nice - grazie! Per qualche ragione di solito mi dimentico di provare la ricorsione in bash, anche se la sto usando in altre risposte. L'uso al ()posto del { ;}corpo della funzione consente di risparmiare ancora di più :)
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}

Questo crea una sequenza di valori che sono interi divisi ( div), fino a quando il risultato non 0esclude 0dalla sequenza

$_, * div 16 ...^ 0

Quindi attraversa ( X) quella sequenza usando l'operatore modulo ( %) con16

(  ) X[%] 16

Utilizza questi valori come indici in un elenco appiattito composto da due intervalli 0..9e'A'..'Z'

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

Infine li concatena ( ~) usando il Rmeta operatore reverse ( )

[R[~]] 

Se ciò risulta in un valore False (stringa vuota), restituisce 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 byte

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

Questo utilizza la versione 5.1.0 del linguaggio / compilatore, che è precedente a questa sfida.

Esempio

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

Spiegazione

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 caratteri / 62 byte

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

Try it here (Firefox only).

Okay, ho capito qualche altra roba che l'ha rovesciata.

Spiegazione

È essenzialmente la stessa soluzione della soluzione ES6 di @ SuperJedi224 - ma con qualcosa di diverso.

Vedi ⩥ḊĀⒸª⩥⁽ṁṇ⸩⨝? È un modo davvero fantastico di scrivere "0123456789ABCDEF". ⩥Ḋcrea un intervallo da 0 a 10, Ⓒª⩥⁽ṁṇ⸩crea un intervallo da 65 a 71 e lo converte in una stringa di ASCII, Ā...⨝concatena i due intervalli e li unisce in una stringa. Questa è stata probabilmente la parte più bella della mia soluzione.

Versione bonus non competitiva, 24 caratteri / 45 byte

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

Ho deciso di aggiungere una stringa alfabetica, come in 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*//

Non è il linguaggio ovvio per questa sfida, ma ha il vantaggio di supportare numeri di input fino a (a seconda dell'implementazione) tra 4000 cifre e il limite della memoria disponibile (virtuale) del sistema. Ho convertito RSA-1024 in esadecimale in circa 0,6 secondi, quindi si ridimensiona abbastanza bene.

Funziona usando la divisione successiva per due, accumulando ogni 4 bit di carry in una cifra esadecimale. Usiamo caratteri non letterali per rappresentare il nostro output, in modo da accumulare sempre carry tra l'input decimale e l'output esadecimale e convertirli in esadecimali convenzionali alla fine.


2

PHP, 65 66 64 + 1 62 59 byte

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

funzione di stampa ricorsiva, stampa uno zero iniziale (inserire >16prima &&per rimuoverlo)


programmi, 64 byte +1 per -R(esegui come pipe con -nR)

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

richiede PHP 5.6 o successivo (5.5 non può indicizzare valori letterali stringa)

o

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

richiede PHP 5.6 o 7.0 (7.1 comprende gli indici di stringa negativi)


Esegui come pipe -nRo provali online .


1
Mi manca un segno più echo+$sper l'ingresso 0
Jörg Hülsermann

+il segno taglia l'output alla prima lettera ... quindi ...?:0
Tito

1

Julia, 55 byte

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

Questa è l'implementazione della funzione ricorsiva di base. Accetta un numero intero e restituisce una stringa.

Se l'ingresso è inferiore a 15, il piano lo divide per 16 e ricorre, altrimenti prendi la stringa vuota. Attaccalo sulla parte anteriore del carattere esadecimale opportunamente selezionato.


1

Pira , 98 byte

Farlo in una lingua senza operatori aritmetici è stato probabilmente un errore.

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

Usa così:

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

Rubino, 48 caratteri

(Copia del Loovjo s' Python risposta .)

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

Esecuzione di esempio:

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

Scherzi a parte, 35 byte

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

Dump esadecimale:

2c603b34a640252934a6405c60ce58ee204460403b37a6442b40393c372a2b632b606e

Provalo online

Spiegazione:

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

Si noti che ;7ªD+@9<7*+cè equivalente a 4ª▀E, che risparmierebbe 8 byte, ma ho pensato che forse una funzione che spinge le cifre di base b come stringa potrebbe essere considerata troppo un "built-in esadecimale".


1

Javascript ES6, 64 58 byte

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

6 byte salvati grazie a ן nɟuɐɯɹɐ ן oɯ e user81655.


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

1
Oh sì, prova a usare atob e btoa per quella lunga stringa.
Mama Fun Roll

@ ן nɟuɐɯɹɐ ן oɯ Tried v=>{for(z="";v>0;v=v/16|0)z=btoa``Ó]·ã»óÐ1``[v%16]+z;return z}(Le doppie tilde sono singole tilde) ==> 64 caratteri, 71 byte. Non ne vale la pena.
usandfriends

1
v=v/16|0è solo un modo complesso di scrivere v>>=4.
user81655

1

Befunge-93, 58

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

La prima volta che faccio una vera sfida di golf in Befunge, scommetto che c'è un one-liner per questo che è più corto dal momento che tutti quegli spazi nel mezzo della seconda linea sembrano dispendiosi.

Puoi farlo qui . Spiegazione parziale:

&: Accetta input.

:88+%: Prendere il resto modulo 16.

"0"+: Aggiungilo al valore ASCII di 0.

:"9"`: Se il risultato è maggiore del valore ASCII di 9 ...

7*+: Aggiungi 7 per convertirlo in una lettera.

\: Salva il personaggio risultante in pila.

8/2/: Dividi per 16 arrotondando per difetto.

:!#|_: Esce dal ciclo se il risultato è 0.

#: Altrimenti tornare al passaggio del modulo.

>:#,_@ (avvolgente): una volta terminato, emettere lo stack in ordine LIFO.


1

> <> , 46 + 3 = 49 byte

Questo sarebbe stato più breve se> <> avesse avuto una divisione intera, che ora dobbiamo emulare sottraendo il modulo 1. Comunque, penso che questo usi dei trucchi piuttosto avvolgenti!

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

Provalo online!

Spiegazione

Primo ciclo

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

Il primo ciclo esegue la conversione classica in algoritmo esadecimale. Fa modulo 16 ( :f1+%) e controlla se il risultato è <10 ( :a(?). In caso contrario, è necessario aggiungere 7 ( 7+) per passare dai decimali all'alfabeto maiuscolo nella tabella ASCII. Altrimenti, possiamo procedere aggiungendo il valore ASCII per 0 ( "0"+) e spostando il carattere da emettere in fondo allo stack perché dovremo emetterli in ordine inverso. Il valore superiore viene quindi sostituito dal risultato della divisione intera per 16. Questo viene emulato calcolando a / b - (a / b)% 1 ( f1+,:1%-). Al termine del ciclo, lo stack contiene i caratteri esadecimali in ordine di output inverso e uno 0.

Secondo ciclo

!?:r<ro;

Il secondo ciclo inverte l'elenco e controlla se l'elemento superiore è 0. In caso affermativo, sappiamo che tutti i valori diversi da zero sono stati stampati e dovremmo terminare. Altrimenti, emettiamo il carattere e invertiamo di nuovo l'elenco per prepararci alla prossima iterazione. Il :entrando nel secondo ciclo duplicherà la 0 che non ha alcun effetto.


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$

Questo utilizza un algoritmo che ho trovato su WikiHow (secondo metodo).

Le stringhe in SpecBAS sono basate su 1, quindi il +1per selezionare l'elemento corretto.



0

Rubino, 40 byte

Rubato da Ispirato dalla risposta del manatwork, ma usando un'interessante scappatoia per renderlo più breve.

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);}

Questo non è del tutto originale, ho eliminato 5 byte dalla versione Digital Trauma installata.


0

APL (NARS), caratteri 34, byte 68

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

test:

  g←{⍵≤0:,'0'⋄(∇⌊⍵÷16),(1+16∣⍵)⊃⎕D,⎕A}
  g 0
0
  g 100
064
  g 1000
03E8
  g 1
01
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.