DEV Community

dev.to staff
dev.to staff

Posted on

Daily Challenge #158 - RGB To Hex Conversion

The rgb() method is incomplete. Complete the method so that passing in RGB decimal values will result in a hexadecimal representation being returned.

The valid decimal values for RGB are 0 - 255. Any (r,g,b) argument values that fall out of that range should 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


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!

Latest comments (17)

Collapse
 
qm3ster profile image
Mihail Malo • Edited

Nodejs (not web):

const rgb = (...args) => 
  Buffer.from(args).toString('hex') // .toUpperCase() // if you are wasteful xD

Not necessarily actually efficient, but definitely hilarious.

General JS:

const rgb = (...args) =>
  args.reduce((a, x, i) => a + x * 0x100 ** (2 /*or args.length*/ - i), 0)
  .toString(16).toUpperCase().padStart(6, '0')
Collapse
 
celyes profile image
Ilyes Chouia • Edited

My PHP Solution

// round the number to the closest value (255 or 0)
function roundToClosest($color)
{ 
    if($color > 255){
        return 255;
    }elseif($color < 0){
        return 0;
    }
    return $color; 
}

function rgb($r,$g,$b){

    $r = roundToClosest($r);
    $g = roundToClosest($g);
    $b = roundToClosest($b);

    return sprintf("%02X%02X%02X", $r, $g, $b);
}
Collapse
 
nickholmesde profile image
Nick Holmes

In C#, you don't even really need to implement a method for this, as its easily done with string interpolation;

    var rgb  = $"{red:X02}{green:X02}{blue:X02}";

(Useful for unique ad-hoc strings, but usually better factored out to a method anyway)

Collapse
 
herobank110 profile image
David Kanekanian

Python solution, supports 1 or 3 arguments like CSS.

rgb = lambda *_: "#"+eval("'%02X'"+(lambda a:a.pop(len(_)>1)+a.pop())(["%_","*3"]))

print(rgb(255)) # => #FFFFFF
print(rgb(126, 28, 29)) # => #7E1C1D
Collapse
 
maymeow profile image
May Meow

My solution in PHP

<?php

namespace MayMeow\PHPColor;

class Color
{
    /** int $red */
    public $red;

    /** int $green */
    public $green;

    /** int $blue */
    public $blue;

    public function __construct($red, $green, $blue)
    {
        $this->red = $red;
        $this->green = $green;
        $this->blue = $blue;
    }

    /**
     * Method convertToHex
     * Covert given color to string #RRGGBB
     */
    public static function convertToHex(Color $color)
    {
        $red = dechex($color->red);
        if (strlen($red) < 2) $red = '0' . $red; // check string length and add zero if needed

        $green = dechex($color->green);
        if (strlen($green) < 2) $green = '0' . $green;

        $blue = dechex($color->blue);
        if (strlen($blue) < 2) $blue = '0' . $blue;

        return '#' . $red . $green . $blue;
    }

    /**
     * Method convertToRGB
     * Convert given color string back to RGB color values
     */
    public static function convertToRGB($hex)
    {
        $hex = ltrim($hex, "#");

        $red = hexdec(substr($hex, 0, 2));
        $green = hexdec(substr($hex, 2, 2));
        $blue = hexdec(substr($hex, 4, 2));

        return new Color($red, $green, $blue);
    }
}
Collapse
 
dannemanne profile image
Daniel Viklund

Thanks for the tip! I've mostly used string formating for dealing with point numbers in decimals. Need to explore more use cases because the syntax is indeed preferable.

Collapse
 
vaibhavyadav1998 profile image
Vaibhav Yadav

In Go.

func rgb(r, g, b uint8) string {
    return fmt.Sprintf("#%x%x%x", r, g, b)
}
Collapse
 
adam_cyclones profile image
Adam Crockett 🌀

I'd do this with Uint8Array

Collapse
 
craigmc08 profile image
Craig McIlwrath

Haskell, using the word8 type to ensure the inputs are from 0-255.

import Data.Bits
import Data.Word 

hexMap :: (Integral a) => a -> Char
hexMap = ("0123456789ABCDEF"!!) . fromIntegral

toHex :: Word8 -> String
toHex word = let lo = word .&. 15
                 hi = word .&. 240
             in  hexMap lo : hexMap (hi `shift` (-4)) : [] 

rgb :: Word8 -> Word8 -> Word8 -> String
rgb r g b = toHex r ++ toHex g ++ toHex b
Collapse
 
aminnairi profile image
Amin

Elm

toHexadecimalLetter : Int -> String
toHexadecimalLetter integer =
    case integer of
        10 ->
            "A"

        11 ->
            "B"

        12 ->
            "C"

        13 ->
            "D"

        14 ->
            "E"

        15 ->
            "F"

        _ ->
            String.fromInt integer

toHexadecimal : Int -> String
toHexadecimal integer =
    let
        clampedInteger  = clamp 0 255 integer
        integerDivision = clampedInteger // 16
        decimalDivision = toFloat clampedInteger / 16.0
        rest            = floor ((decimalDivision - toFloat integerDivision) * 16)
    in
        toHexadecimalLetter integerDivision ++ toHexadecimalLetter rest 

rgb : Int -> Int -> Int -> String
rgb red green blue =
    [red, green, blue]
        |> List.map toHexadecimal
        |> String.join ""

Test.