# Daily Challenge #236 - RGB to Hex Conversion

This rgb function is incomplete. Complete it so that passing in RGB decimal values will result in a hexadecimal representation being returned. Valid decimal values for RGB are 0 - 255. Any values that fall out of that range must be rounded to the closest valid value.

The following are examples of expected output values:

rgb(255, 255, 255) # returns FFFFFF
rgb(255, 255, 300) # returns FFFFFF
rgb(0,0,0) # returns 000000
rgb(148, 0, 211) # returns 9400D3

Tests:
rgb(-20,275,125)
rgb(255,255,255)

This challenge comes from jhoffner on CodeWars. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions! Vidit Sarkar

Here is a short Python solution,

``````def rgb(r, g, b):
return ('{:02x}'*3).format(*map(lambda x : max(0, min(255, x)), (r, g, b))).upper()
``````

Output,

``````print(rgb(255, 255, 300)) # output -> FFFFFF
print(rgb(0,0,0)) # output -> 000000
print(rgb(148, 0, 211)) # output -> 9400D3
print(rgb(-20,275,125)) # output -> 00FF7D
print(rgb(255, 255, 255)) # output -> FFFFFF
`````` Andrew (he/him) • Edited

Scala, providing the shortest and most elegant solution so far 😎

``````def rgb(r: Int, g: Int, b: Int) = {
def h(x: Int) = f"\${x max 0 min 255}%02X"
h(r) + h(g) + h(b)
}
``````

Tests

``````scala> rgb(255, 255, 255)
res24: String = FFFFFF

scala> rgb(255, 255, 300)
res25: String = FFFFFF

scala> rgb(0, 0, 0)
res26: String = 000000

scala> rgb(148, 0, 211)
res27: String = 9400D3

scala> rgb(-20, 275, 125)
res28: String = 00FF7D

scala> rgb(255, 255, 255)
res29: String = FFFFFF
`````` Peter • Edited

In rust:

``````// Convert number to hex string.
pub fn to_hex (value: i32) -> String {
let value = if value > 255 { 255 } else if value < 0 { 0 } else { value };
format!("{:02X}", value)
}

// Join all hex strings together from rgb input.
pub fn rgb (r: i32, g: i32, b: i32) -> String {
format!("{}{}{}", to_hex(r), to_hex(g), to_hex(b))
}

#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_should_be_black() {
assert_eq!(rgb(255, 255, 255), "FFFFFF".to_string());
}
#[test]
fn it_should_be_black_too() {
assert_eq!(rgb(255, 255, 300), "FFFFFF".to_string());
}
#[test]
fn it_should_be_white() {
assert_eq!(rgb(0, 0, 0), "000000".to_string());
}
#[test]
fn it_should_be_other() {
assert_eq!(rgb(148, 0, 211), "9400D3".to_string());
}
}
`````` Andrew (he/him)

A similar solution in R

``````rgb <- function(r, g, b) {
h <- function(x) toupper(format(as.hexmode(min(255, max(0, x))), width=2))
paste0(h(r), h(g), h(b))
}
``````

Tests

``````> rgb(255, 255, 255)
 "FFFFFF"
> rgb(255, 255, 300)
 "FFFFFF"
> rgb(0, 0, 0)
 "000000"
> rgb(148, 0, 211)
 "9400D3"
> rgb(-20, 275, 125)
 "00FF7D"
> rgb(255, 255, 255)
 "FFFFFF"
`````` Ken Bellows

JavaScript:

``````function rgb(r, g, b) {
return [r,g,b].map(n =>
Math.max(0, Math.min(255, n))
.toString(16)
.toUpperCase()
).join('')
}
`````` ``````import Numeric (showIntAtBase)
import Data.Char (intToDigit)

clamp :: (Ord a) => a -> a -> a -> a
clamp mi ma x = minimum [maximum [x, mi], ma]

padStart :: Int -> a -> [a] -> [a]
padStart l x = until ((>=l) . length) (x:)

rgb2num :: (Int, Int, Int) -> Int
rgb2num (r, g, b) = clampColor r * 65536 + clampColor g * 256 + clampColor b
where clampColor = clamp 0 255

rgb2hex :: (Int, Int, Int) -> String
rgb2hex n = padStart 6 '0' \$ showIntAtBase 16 intToDigit (rgb2num n) ""
`````` Python

``````r = int(input("R: "))
g = int(input("G: "))
b = int(input("B: "))

def rgb(var):
if var < 0:
var = 0
if var > 255:
var = 255

return hex(var).split('x')[-1].zfill(2)

print('#',rgb(r), rgb(g), rgb(b), sep='')
`````` JP Antunes • Edited

Here's a quick one-liner JS solution... It would look better with a helper function to validate min/max though :-)

``````const rgb = (r, g, b) => Buffer.from([Math.max(0, Math.min(255, r)), Math.max(0, Math.min(255, g)), Math.max(0, Math.min(255, b))]).toString('hex').toUpperCase()
``````

edit:
Ok, so I came up with a nicer one-liner :-) but it requires using the funky Uint8ClampedArray, which normally shouldn't be used outside of canvas API... because it rounds values to nearest from 0 to 255... which is what we want! Without further ado:

``````const newRGB = (r, g, b) => Buffer.from(new Uint8ClampedArray([r, g, b])).toString('hex').toUpperCase()
`````` K.V.Harish • Edited

In javascript

``````const toHex = (c) => {
const toHex = (c) => {
const hex = Math.max(0, Math.min(255, c)).toString(16);
return hex.length == 1 ? `0\${hex}` : hex;
};

const rgb = (r, g, b) => {
return `#\${toHex(r)}\${toHex(g)}\${toHex(b)}`;
};

rgb(255, 255, 255) // #ffffff
rgb(255, 255, 300) // #ffffff
rgb(0,0,0) // #000000
rgb(148, 0, 211) // #9400d3
rgb(-20,275,125) // #00ff7d
rgb(255,255,255) // #ffffff
`````` peter279k

Here is the simple PHP solution:

``````function rgb(\$r,\$g,\$b) {
\$colorHexLists = [
0 => '0',
1 => '1',
2 => '2',
3 => '3',
4 => '4',
5 => '5',
6 => '6',
7 => '7',
8 => '8',
9 => '9',
10 => 'A',
11 => 'B',
12 => 'C',
13 => 'D',
14 => 'E',
15 => 'F',
];

if (\$r > 255) {
\$r = 255;
}
if (\$r < 0) {
\$r = 0;
}
if (\$g > 255) {
\$g = 255;
}
if (\$g < 0) {
\$g = 0;
}
if (\$b > 255) {
\$b = 255;
}
if (\$b < 0) {
\$b = 0;
}

\$rStringArray = [];
if (\$r <= 15) {
\$rStringArray[] = '0' . \$colorHexLists[(int)(\$r)];
} else {
while(count(\$rStringArray) !== 2) {
if (\$r < 16) {
\$rStringArray[] = \$colorHexLists[(int)(\$r)];
} else {
\$rStringArray[] = \$colorHexLists[(int)(\$r / 16)];
}
\$r = \$r % 16;
}
}

\$gStringArray = [];
if (\$g <= 15) {
\$gStringArray[] = '0' . \$colorHexLists[(int)(\$g)];
} else {
while(count(\$gStringArray) !== 2) {
if (\$g < 16) {
\$gStringArray[] = \$colorHexLists[(int)(\$g)];
} else {
\$gStringArray[] = \$colorHexLists[(int)(\$g / 16)];
}
\$g = \$g % 16;
}
}

\$bStringArray = [];
if (\$b <= 15) {
\$bStringArray[] = '0' . \$colorHexLists[(int)(\$b)];
} else {
while(count(\$bStringArray) !== 2) {
if (\$b < 16) {
\$bStringArray[] = \$colorHexLists[(int)(\$b)];
} else {
\$bStringArray[] = \$colorHexLists[(int)(\$b / 16)];
}
\$b = \$b % 16;
}
}

return implode(\$rStringArray) . implode(\$gStringArray) . implode(\$bStringArray);
}
`````` # BeanShell

``````int clip(int n) {
return Math.max(0, Math.min(n, 255));
}

String rgb(int r, int g, int b) {
r = clip(r);
g = clip(g);
b = clip(b);
return String.format("%02x%02x%02x", new Object[] { r, g, b}).toUpperCase();
}

show();
rgb(255, 255, 255); // returns FFFFFF
rgb(255, 255, 300); // returns FFFFFF
rgb(0,0,0); // returns 000000
rgb(148, 0, 211); // returns 9400D3
rgb(-20,275,125); // returns 00FF7D
``````

Run this code using AJShA Android app Valentin

Here's my solution, with C

``````int limit_value(int value) {
if(value <= 0) {
return 0;
}
if(value >= 255) {
return 255;
}
return value;
}

char *rgb(int r, int g, int b) {
r = limit_value(r);
g = limit_value(g);
b = limit_value(b);

char *result = calloc(7, sizeof(char));
sprintf(result, "%02X%02X%02X", r, g, b);
return result;
}
``````