DEV Community

loading...

Daily Challenge #236 - RGB to Hex Conversion

thepracticaldev profile image dev.to staff ・1 min read

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!

Discussion

pic
Editor guide
Collapse
vidit1999 profile image
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
Collapse
awwsmm profile image
Andrew (he/him)

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
Collapse
kenbellows profile image
Ken Bellows

JavaScript:

function rgb(r, g, b) {
  return [r,g,b].map(n => 
    Math.max(0, Math.min(255, n))
      .toString(16)
      .padStart(2, '0')
      .toUpperCase()
  ).join('')
}
Collapse
awwsmm profile image
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)
[1] "FFFFFF"
> rgb(255, 255, 300)
[1] "FFFFFF"
> rgb(0, 0, 0)
[1] "000000"
> rgb(148, 0, 211)
[1] "9400D3"
> rgb(-20, 275, 125)
[1] "00FF7D"
> rgb(255, 255, 255)
[1] "FFFFFF"
Collapse
pavi2410 profile image
Pavitra Golchha

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

Collapse
valperignon profile image
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;
}
Collapse
craigmc08 profile image
Craig McIlwrath

Haskell solution:

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) ""
Collapse
citizen428 profile image
Michael Kohl

Just for fun in Postgres, with 2 helper functions, clamp8 for keeping the value to 8 bytes (0-255) and int_to_hex for converting an int into a hex number.

create function clamp8 (value integer)
    returns integer
    as 'select greatest(0, least(255, value));'
    language SQL
    immutable
        returns null on null input;

create function int_to_hex (n integer)
    returns text
    as $$ select lpad(to_hex(clamp8(n)), 2, '0'); $$
    language SQL
    immutable
        returns null on null input;

create function rgb (r integer, g integer, b integer)
    returns text
    as 'select upper(concat(int_to_hex(r), int_to_hex(g), int_to_hex(b)));'
    language SQL
    immutable
        returns null on null input;

See it in action:

select rgb(148, 0, 211);
┌────────┐
│  rgb   │
╞════════╡
│ 9400D3 │
└────────┘
(1 row)

The function definitions are a bit more verbose than they have to be, but they are immutable and return null on null inputs, so might as well add that.

Collapse
pmkroeker profile image
Peter

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

Rust Playground
GitHub Gist

Collapse
kvharish profile image
K.V.Harish

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
Collapse
peter279k profile image
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);
}
Collapse
jpantunes profile image
JP Antunes

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()
Collapse
maskedman99 profile image
Rohit Prasad

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='')
Collapse
pavi2410 profile image
Pavitra Golchha

You need to create a rgb function which takes three arguments. Also, this challenge didn't specify to put # at the start.