# RGB to hexadecimal

Based off a Scratch project

The pen extension in Scratch has a set pen color to () block. The () is normally a color dropdown, but you can also use the join()() block. In the join()() block, normally a hex value is in the first input, but the second is just an empty string.

However, many new Scratchers that want to take advantage of this find it hard (after all we count in decimal). Your task today, is: given three positive integers r,g,b, calculate the hex value and return it as #rrggbb.

## Input:

r, g, b.

1. $$\0\le r\le255\$$
2. $$\0\le g\le255\$$
3. $$\0\le b\le255\$$
4. Input will always follow these rules
5. Input won't have leading zeros except for 0 itself

## Output

A string in the format #rrggbb. Hexadecimal letters can be all uppercase or all lowercase.

## Method

1. Convert r,g,b to hexadecimal
2. Concatenate r,g,b
3. Prepend a #
4. Return it

## Testcases:

r, g, b     -> Output

0, 127, 255   -> #007fff
1, 1, 1       -> #010101
245, 43, 2    -> #f52b02
72, 1, 134    -> #480186
0, 0, 0       -> #000000
255, 255, 255 -> #ffffff


This is , so shortest answer wins!

NOTE: There's an earlier question that qualifies this as a duplicate, but it's closed (because the scoring criterion was ambiguous)

• I'm surprised this hasn't been asked already :p Nov 3, 2022 at 11:11
• Related Nov 3, 2022 at 16:26
• Are we allowed to assume that the inputed numebrs don't have leading zeros (barring 0 itself)? Nov 4, 2022 at 3:22
• You are allowed to assume that. Nov 4, 2022 at 4:00

# Python 3, 22 bytes

("#"+"%02x"*3).__mod__


Try it online!

Takes inputs as a tuple. The idea is to avoid a lambda or def by having the answer be an object method.

Same length:

f"#{'%02x'*3}".__mod__

• I never realised %-formatting is just a modulo overload Nov 3, 2022 at 10:52
• What does module overload mean? Nov 3, 2022 at 12:38
• @DialFrost Operator overloading happens when an operator acts differently depending on its arguments. The % operator (which refers to <object>.__mod__) is mostly used to perform the modulo operation, but in the case of strings it is used for formatting. Nov 3, 2022 at 13:28

# [5,171,30]😉 - 05AB1E, 9 bytes

₁+h€¦J'#ì


Input as list [r,g,b]. Outputs in uppercase.

Explanation:

₁+         # Add 256 to each value in the (implicit) input-triplet
h        # Convert each from integer to a hexadecimal string
€¦      # Remove the leading "1" from each string
J     # Join them together
'#ì '# Prepend a leading "#"
# (after which the result is output implicitly)

• Alternative 9 byter. Don't know if this can be golfed down more Apr 17, 2023 at 13:07
• @emirps I'm afraid it's incorrect for inputs in the range [1,15]. The ε2∍} will extend single hexadecimal characters (e.g. 5 to 55 instead of the intended 05). So input [5,171,30] will result in #55AB1E instead of #05AB1E with your program. (PS: It could be golfed to 8 bytes by changing ε2∍} to 2δ∍ btw. :) In this case δ (double-vectorized builtin) works as a map on the given list with builtin ∍ and argument 2.) Apr 17, 2023 at 13:24

# C (GCC), 39 bytes

m(r,g,b){printf("#%06x",r<<16|g<<8|b);}


Attempt This Online!

I could to this all day in every language

# R, 20 bytes

\(...)rgb(...,m=255)


Attempt This Online!

Somehow, when I first posted this answer, I managed to overlook the linked related challenge, where it was clearly pointed out that R has a built-in for this specific task...

My original non-built-in solution:

# R, 38 bytes

cat("#",sprintf("%02x",scan()),sep="")


Attempt This Online!

# Ruby, 19 bytes

->*v{?#+"%02x"*3%v}


Try it online!

• Some other answers take input as an array, this would allow getting rid of the asterisk. Nov 3, 2022 at 10:47

# JavaScript (ES6), 49 bytes

Not the right tool for the job.

Expects [r,g,b].

a=>'#'+a.map(x=>(x>>4&&'')+x.toString(16)).join


Try it online!

# JavaScript (ES6), 53 bytes

Expects r,g,b.

(r,g,b)=>'#'+(r+256<<16|g<<8|b).toString(16).slice(1)


Try it online!

# Vyxals, 7 bytes

H2↳›\#p


Try it Online!

The benefits of string padding. And flags. Helps not be beaten by half a byte :p

## Explained

H2↳›\#p
H         # Convert each item in the input to hexadecimal
2↳›      # append 0s until each string is of length 2
\#p   # and prepend a "#"
# the s flag joins the top of the stack into a single string


# Excel, 31 29 bytes

-7 bytes thanks to Dominic van Essen

-2 bytes thanks to Taylor Alex Raine

="#"&CONCAT(DEC2HEX(0&A1#,2))


Where A1 contains the following: ={0,127,255}.

• "Hexadecimal letters can be all uppercase or all lowercase" = should save 7 bytes... Nov 3, 2022 at 17:42
• ="#"&z(A1)&z(B1)&z(C1) and z is a named lambda function =LAMBDA(a,DEC2HEX(a,2)) ....I don't think this really counts as golfing, but it is 20+23+1= 44 characters . (The +1 is for the letter z in the function name)
Nov 3, 2022 at 18:35
• You can drop 2 bytes if you expect array input (A1# ) Nov 26, 2022 at 20:33

# Jelly, 9 bytes

”#2Øhṗị@‘


A full program that accepts a list of integers from $$\[0,255]\$$ and prints the resulting hexadecimal string.

Try it online!

...a fair bit shorter than the naive approach of a monadic Link like +⁹b⁴Ḋ€‘ịØh”#; which comes in at 13 bytes - TIO.

### How?

”#2Øhṗị@‘ - Main Link: list of integers, Colours
”#        - '#' character
... the chaining of nilad nilad nilad (”#2Øh)
forces this to be printed to STDOUT with no trailing character(s)
2       - two
Øh     - hexadecimal characters -> "0123456789abcdef"
ṗ    - Cartesian power -> ["00","01",...,"ff"]
‘ - increment (Colours) (vectorises)
@  - with swapped arguments:
ị   -   index into
- implicit, smashing print


# Nibbles, 7.5 bytes (15 nibbles)

"#"+.$&"0"2hex  "#"+.$&"0"2hex
.           # map over
$# each number in the input hex # converting it to hexadecimal$         # and justifying it
2     # to two characters wide
"0"      # using "0" as filler,
+            # then, flatten this list
"#"             # and prepend a "#" character.


# Python 3, 20 bytes

lambda x:"#"+x.hex()


Try it online!

Takes input as a bytearray.

Test bed borrowed from @xnor.

# CP-1610 machine code, 34 DECLEs1 = 42.5 bytes2

1. A CP-1610 opcode is encoded with a 10-bit value (0x000 to 0x3FF), known as a 'DECLE'.
2. This routine is 34 DECLEs long, i.e. 340 bits. As per the exception described in this meta answer, the score is 42.5 bytes.

A routine expecting a pointer to three bytes in R3 and writing the result at R4 (in white, assuming ColorStack mode).

### Test code

    |           |        ROMW    10            ; 10-bit ROM
|           |        ORG     $4800 ; map the program at$4800
|           |
4800|001        |        SDBD                  ; set up an ISR for minimal
4801|2B8 030 048|        MVII    #isr,   R0    ; STIC initialization
4804|240 100    |        MVO     R0,     $100 4806|040 | SWAP R0 4807|240 101 | MVO R0,$101
|           |
4809|002        |        EIS                   ; enable interrupts
|           |
480A|001        |        SDBD                  ; R4 = BACKTAB pointer
480B|2BC 000 002|        MVII    #$200, R4 480E|001 | SDBD ; R3 = pointer to test cases 480F|2BB 01E 048| MVII #test, R3 | | 4812|004 148 040|loop CALL rgb ; invoke our routine | | 4815|2FC 00D | ADDI #13, R4 ; advance to the beginning | | ; of the next line 4817|001 | SDBD 4818|37B 030 048| CMPI #done, R3 ; done? 481B|225 00A | BLT loop | | 481D|017 | DECR R7 ; loop forever | | 481E|000 07F 0FF|test DECLE 0, 127, 255 ; #007fff 4821|001 001 001| DECLE 1, 1, 1 ; #010101 4824|0F5 02B 002| DECLE 245, 43, 2 ; #f52b02 4827|048 001 086| DECLE 72, 1, 134 ; #480186 482A|000 000 000| DECLE 0, 0, 0 ; #000000 482D|0FF 0FF 0FF| DECLE 255, 255, 255 ; #ffffff | |done | | ;; ------------------------------------------- ;; | | ;; ISR ;; | | ;; ------------------------------------------- ;; | |isr PROC 4830|240 020 | MVO R0,$0020 ; enable display
4832|280 021    |        MVI     $0021, R0 ; colorstack mode | | 4834|1C0 | CLRR R0 4835|240 030 | MVO R0,$0030 ; no horizontal delay
4837|240 031    |        MVO     R0,     $0031 ; no vertical delay 4839|240 032 | MVO R0,$0032 ; no border extension
483B|240 028    |        MVO     R0,     $0028 ; black background 483D|240 02C | MVO R0,$002C ; black border
|           |
483F|0AF        |        JR      R5            ; return from ISR
|           |        ENDP


### Routine ($4840-$4861)

    |           |        ;; ------------------------------------------- ;;
|           |        ;;  our routine                                ;;
|           |        ;; ------------------------------------------- ;;
|           |rgb     PROC
4840|275        |        PSHR    R5            ; push the return address
|           |
4841|2B8 01F    |        MVII    #$1F, R0 ; draw the '#' 4843|260 | MVO@ R0, R4 | | 4844|2BA 003 | MVII #3, R2 ; repeat 3 times | | 4846|298 |@@loop MVI@ R3, R0 ; R0 = byte to display 4847|00B | INCR R3 ; advance R3 4848|004 148 054| CALL @@hexa ; draw the upper nibble 484B|04C | SLL R0, 2 ; shift the lower nibble 484C|04C | SLL R0, 2 484D|004 148 054| CALL @@hexa ; draw it 4850|012 | DECR R2 ; loop? 4851|22C 00C | BNEQ @@loop | | 4853|2B7 | PULR R7 ; return | | 4854|081 |@@hexa MOVR R0, R1 ; copy R0 into R1 4855|3B9 0F0 | ANDI #$F0,   R1    ; isolate the upper nibble
4857|2F9 10F    |        ADDI    #$10F, R1 ; add the offset for '0' | | ; and set the lower nibble | | ; so that we write in white 4859|379 19F | CMPI #$19F,  R1    ; if greater than '9' ...
485B|206 002    |        BLE     @@print
|           |

Try it online!

Uses the commandline flag -l043 to prepopulate $\ with '#' and for each input line, appends the result of unpacking the number to H2 (0-padded hex representation). # Retina 0.8.2, 49 bytes .+$*
%^(.{16})*(.)*
$#1¶$#2
Tdl..
.\B|¶

^
#


Try it online! Takes input on separate lines but link is to test suite that splits on commas for convenience. Explanation:

.+
• Alternatively, 24 bytes in Zsh: printf \#;printf %02x $@ Nov 26, 2022 at 23:26 # Java 8, 41 40 bytes (r,g,b)->"".format("#%06x",r<<16|g<<8|b)  -1 byte thanks to @Arnauld by porting @mousetail's C answer. Output in lowercase. Could be in uppercase by replacing the x with X. Try it online. Explanation: (r,g,b)-> // Method with three integer parameters and String return-type "".format("#%06x", // Return a String with a format as: # // A leading hash "#" % x // And an integer converted to a hexadecimal value 6 // of size 6 0 // with potential leading 0s if it's smaller than 6 // Where the integer is: r<<16 // Input r bitwise right-shifted by 16 | // Bitwise-ORed with g<<18 // Input g bitwise right-shifted by 8 | // Bitwise-ORed with b) // Input b as is  • Using mousetail's method would be 1 byte shorter. Nov 3, 2022 at 15:23 • @Arnauld Thanks for the heads up. Nov 3, 2022 at 21:13 # Raku, 26 25 bytes {printf '#'~'%02x'x 3,@_}  Try it online! -1 byte thanks to @IsmaelMiguel • You can save 1 byte by using printf - docs.raku.org/routine/printf - you have to remove the "put" from the test cases, but the output will be in the same line, which doesn't matter. Nov 4, 2022 at 12:14 • Ok, thanks @IsmaelMiguel – andm Nov 4, 2022 at 13:58 # K (ngn/k), 12 bytes "#",hex@c$


Try it online!

Takes input as a list of 3 integers.

c$ Cast to string (bytes). hex@ Format bytes as hexadecimal values. "#", Prepend a #. # Julia 1.0, 36 bytes ~x="#"*(string.(x,base=16,pad=2)...)  Try it online! -1 byte thanks to @amelies: Replace prod with *. A single operator can behave as both a monad and dyad in Julia! • splat (...) instead of using prod to save 1 byte Nov 4, 2022 at 12:42 • My best attempt with splatting the multiplication is still 37 bytes (~x=*("#",string.(x,base=16,pad=2)...)), and string has methods that support either splatting or named arguments, but not both. Nov 4, 2022 at 14:31 • I meant ~x="#"*(string.(x,base=16,pad=2)...), which seems to use both unadic and dyadic form for * at the same time Nov 4, 2022 at 14:52 # C#, 31 bytes (r,g,b)=>$"#{r:X2}{g:X2}{b:X2}"


# ><> (Fish), 102 bytes

Since this challenge is super easy I wanted to try some esolangs.

Takes input as raw byte values.

"#"o03i:&82*,01.
:9)?v68*+o.
v+"W"<;
o14&82*%01.
\.05i:&82*,01.
06&82*%01.
07i:&82*,01.
52&82*%01.


## Explanation:

This is a function that prints a single hexadecimal number:

 :9)?v68*+o.
v+"W"<
o
\.


Basically, check if the number is more than 9, if so add "W" ("W"+9 = 'a'), and print it. Otherwise add 6*8='0'. In both cases we use . to "return" from the function.

The function wraps around the left margin since this is "dead space". Since you can't jump to the leftmost

The rest of the code is either of these 2 statements repeated:

07i:&82*,01.


First 2 values are the return pointer, it's where the function will return. Then we take input and copy 1 value to the register. We divide by 16 (2*8), then push the start address of the print function, and call it with .

The other variant is very similar:

14&82*%01.


Again 14 is the return value. We take the value form the register, but this time modulo it by 16. Again we call the function at 01.

Notice the last function returns to 52, which is the location of the stray ; (right of the < inside the function) that exits the program.

# ><>, 119 bytes

"#"oi:&82*,:9)"'"*+"0"+o&82*%:9)"'"*+"0"+oi:&82*,:9)"'"*+"0"+o&82*%:9)"'"*+"0"+oi:&82*,:9)"'"*+"0"+o&82*%:9)"'"*+"0"+o;


Try it online!

Alternate solution that uses just 1 line.

# x86-32 machine code, 28 27 bytes

"\x6a\x23\x58\x99\xaa\xb1\x1c\xac\xd3\xc0\x3c\x0a\x1c\x69\x2f\xaa"
"\xd3\xe8\x30\xce\x75\xf4\x42\x7b\xee\x88\x27"


#### Requirements:

• SS:ESP-4 -> 4 bytes of writable memory
• DS:ESI -> 3 bytes of readable memory containing r, g, b
• ES:EDI -> 8 bytes of writable memory to receive NUL-terminated ASCII string ("#XXXXXX\0")
• Direction Flag clear

#### In assembly language:

6a 23           push 23h  ; "#"
58              pop eax
99              cdq
aa              stosb
b1 1c           mov cl, 1Ch
__byteloop:
ac              lodsb
d3 c0           rol eax, cl
__nibbleloop:
3c 0a           cmp al, 0Ah  ; someone's old trick for converting a nibble to hex
1c 69           sbb al, 69h
2f              das
aa              stosb
d3 e8           shr eax, cl
30 ce           xor dh, cl
75 f4           jnz __nibbleloop
42              inc edx
7b ee           jnp __byteloop
88 27           mov [edi], ah


# Scratch, 235 Bytes

Link to the editor for the script

Source:

when gf clicked
set[I v]to(0
set[X v]to[#
repeat(3
change[I v]by(1
set[X v]to(join(x)(join(letter(((item(I)of[C v])-((item(I)of[C v])mod(16)))+(1))of[0123456789ABCDEF])(letter(((item(I)of[C v])mod(16))+(1))of[0123456789ABCDEF
end
say(X


It was exhausting to put this into plain text, so I'm not golfing this down YET.

• You can calculate the byte count by using ScratchBlocks syntax scratchblocks.github.io May 31, 2023 at 10:19
• @noodleman thanks May 31, 2023 at 10:20
• You can take input from a Custom Block (the purple ones), you may assume that any variables are initialized at 0 (so you may remove [set I...], and you may output via the X variable as long as it's checked in the interface so you can see it. Idk where the links are but these are all allowed for Scratch posts, you can save bytes with them. May 31, 2023 at 10:29
• I would love to accept this, but I'm afraid it's too long. May 31, 2023 at 12:49
• @noodleman I think Custom blocks are now pink colored May 31, 2023 at 15:16

# Bitcoin Cash Script (BitAuth IDE), 601 bytes, 93 bytes as raw bytecode

// Input
<127>
<0>
<255>
// Program
OP_DUP
<16> OP_MOD
OP_SWAP
<16> OP_DIV
OP_DUP <9> OP_GREATERTHAN
OP_IF
OP_ENDIF
OP_SWAP
OP_DUP <9> OP_GREATERTHAN
OP_IF
OP_ENDIF
OP_CAT
OP_ROT
OP_DUP
<16> OP_MOD
OP_SWAP
<16> OP_DIV
OP_DUP <9> OP_GREATERTHAN
OP_IF
OP_ENDIF
OP_SWAP
OP_DUP <9> OP_GREATERTHAN
OP_IF
OP_ENDIF
OP_CAT
OP_ROT
OP_DUP
<16> OP_MOD
OP_SWAP
<16> OP_DIV
OP_DUP <9> OP_GREATERTHAN
OP_IF
OP_ENDIF
OP_SWAP
OP_DUP <9> OP_GREATERTHAN
OP_IF
OP_ENDIF
OP_CAT
OP_ROT
OP_CAT OP_CAT
<'#'> OP_SWAP OP_CAT
// Output string left on stack

// We can also execute it all using raw bytecode
OP_DROP // Clean up
// Input
<127>
<0>
<255>
/// Program
0x7660977c60967659a0635793680130937c7659a0635793680130937e7b7660977c60967659a0635793680130937c7659a0635793680130937e7b7660977c60967659a0635793680130937c7659a0635793680130937e7b7e7e01237c7e


Try it online!

# Factor, 25 bytes

[ "#%02x%02x%02x"printf ]


Try it online!

# Clojure, 30 bytes

#(format"#%02x%02x%02x"% %2%3)


Try it online!

# Gaia, 28 bytes

h¦⟨)₵HE¤\⟩¦¦$¦⟨0¤+3⊂ḥ⟩¦$'#¤+


Try it online!

28 bytes may seem like a lot of bytes until you discover that there is no "convert a number to hexadecimal as a string" built-in in Gaia. Why was "convert to base 16 as a list of digits" the thing that got added and not to string?

Using a similar algorithm to the 05AB1E and MathGolf answers would probably be longer.

Gaia does not have list input in the input box, so this is a function submission.

## Explained

h¦⟨)₵HE¤\⟩¦¦$¦⟨0¤+3⊂ḥ⟩¦$'#¤+
h¦                          # Convert each number to base 16 (list of digits)
⟨      ⟩¦¦                 # To each digit in each number:
)                        #  Increment it to account for 1-indexing
₵HE                     #  and index it into the string "0123456789ABCDEF"
¤\                   #  Remove some extra junk from the stack
$¦ # Convert each list to a single string ⟨ ⟩¦ # To each hex string: 0¤+ # Prepend 0 3⊂ # repeat the first character of the string enough times to make it at least length 3 ḥ # remove the leading 0$'#¤+  # join into a single string and prepend the # character


# Sequences, $$\22 \log_{256}(96) \approx 18.1\$$ bytes

"#"H3x{\016iB2jH}g""JF


### Explanation

"#"H3x{\016iB2jH}g""JF
"#"H                    // Push "#" to the list
3x{         }       // Repeat 3 times:
i            //   Get a numeric input
16 B           //   Convert to hexadecimal
\0    2j         //   Fill with 0s on the left up to 2 characters
H        //   Append to the list
g      // Get the list
""J   // And join by ""
F  // Output the joined string