9
\$\begingroup\$

Given Color codes in CMYK, convert it to RGB value.

Input:
string of 4 integers(ranging from 0-100) separated by space

86 86 0 43
28 14 0 6
0 41 73 4

Output:

#141592
#ABCDEF
#F49043 

Shortest code wins!

HINT: For converting CMYK to RGB you may use formula such as:

Red   = 255 x (1 - Cyan/100)    x (1 - Black/100)   
Green = 255 x (1 - Magenta/100) x (1 - Black/100)   
Blue  = 255 x (1 - Yellow/100)  x (1 - Black/100)   

and use these three variables to get the value in #RRGGBB format

\$\endgroup\$
11
  • 1
    \$\begingroup\$ Can we take CMYK values as decimals from 0 to 1 or is it required to do 0 to 100? \$\endgroup\$
    – hyperneutrino
    Commented Jun 30, 2017 at 17:39
  • 1
    \$\begingroup\$ Also, are we supposed to input multiple CMYK codes at once or just one and convert it? \$\endgroup\$
    – hyperneutrino
    Commented Jun 30, 2017 at 17:41
  • 7
    \$\begingroup\$ Can we take the input as a list of numbers or does it have to be a delimited string? \$\endgroup\$ Commented Jun 30, 2017 at 17:41
  • 7
    \$\begingroup\$ The input / output that you provided doesn't match the formula, also how should we handle the rounding? \$\endgroup\$
    – Rod
    Commented Jun 30, 2017 at 18:33
  • 2
    \$\begingroup\$ @Rod It's a bit unclear yet how floating-point inaccuracies should be handled. \$\endgroup\$ Commented Jul 1, 2017 at 7:33

16 Answers 16

5
\$\begingroup\$

PHP, 90 bytes

<?="#";for($c=explode(" ",$argn);$i<3;)printf("%02X",255*(1-$c[+$i++]/100)*(1-$c[3]/100));

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Python 3, 100 98 bytes

-2 bytes thanks to Rod.

lambda s:'#'+''.join('%02X'%int(.0255*(100-int(i))*(100-int(s.split()[3])))for i in s.split()[:3])

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Golfing the math. o0 Thanks! \$\endgroup\$ Commented Jun 30, 2017 at 18:42
2
\$\begingroup\$

Jelly, 24 bytes

ḲV÷ȷ2ạ1×Ṫ$×255ḞṃØHṙ1¤ṭ”#

A full program which prints the result.

Try it online!

Note: rounding rather than flooring may be used by inserting the two bytes of code +. between 255 and .

How?

ḲV÷ȷ2ạ1×Ṫ$×255ḞṃØHṙ1¤ṭ”# - Main link: list of character, s
Ḳ                        - split at spaces (makes a list of lists of characters)
 V                       - evaluate as Jelly code (makes a list of the decimal numbers)
   ȷ2                    - literal 100
  ÷                      - divide (vectorises to yield [C/100, M/100, Y/100, K/100])
     ạ1                  - absolute difference with 1 -> [1-(C/100),...]
         $               - last two links as a monad:
        Ṫ                -   tail (this is 1-(K/100))
       ×                 -   multiply (vectorises across the other three)
          ×255           - multiply by 255 (vectorises)
              Ḟ          - floor to the nearest integer
                    ¤    - nilad followed by link(s) as a nilad:
                ØH       -   hex-digit yield = "0123456789ABCDEF"
                  ṙ1     -   rotate left by 1 -> "123456789ABCDEF0"
               ṃ         - base decompress (use those as the digits for base length (16))
                      ”# - literal character '#'
                     ṭ   - tack
                         - implicit print
\$\endgroup\$
1
  • \$\begingroup\$ Another way to round would be _.Ċ instead of +.Ḟ...but the latter is maybe more widely used. \$\endgroup\$ Commented Jul 1, 2017 at 7:47
2
\$\begingroup\$

Retina, 103 bytes

\d+
$*1;100$*
(1*);\1

1(?=.* (1*))|1
$1
1
51$*
(1{32000})*(1{2000})*1*.
;$#1;$#2
T`d`L`1\d
;B\B|;

^
#

Try it online! Note: This code is very slow, so please don't hammer Dennis's server. Explanation:

\d+
$*1;100$*
(1*);\1

Convert each number to unary and subtract from 100.

1(?=.* (1*))|1
$1

Multiply all the numbers by the last number, which is deleted.

1
51$*

Multiply by 51, so that once we divide by 2000, we get 100 * 100 * 51 / 2000 = 255 as desired.

(1{32000})*(1{2000})*1*.
;$#1;$#2

Divide by 32000 and floor divide the remainder by 2000, thus generating a pair of base 16 values, although sadly themselves still written in base 10.

T`d`L`1\d
;B\B|;

Convert from base 10 to base 16.

^
#

Insert the leading #.

\$\endgroup\$
2
\$\begingroup\$

Java 8, 166 bytes

s->{int i=0,c[]=java.util.Arrays.stream(s.split(" ")).mapToInt(Byte::new).toArray();for(s="#";i<3;)s+=s.format("%02X",(int)(.0255*(100-c[i++])*(100-c[3])));return s;}

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Javascript (ES6), 106 bytes

f=
(s,z=s.split` `,k=z.pop())=>'#'+z.map(x=>('0'+(.0255*(100-x)*(100-k)+.5|0).toString(16)).slice(-2)).join``
<input id=i value="28 14 0 6"/><button onclick="o.innerHTML=f(i.value)"/>Go</button>
<pre id=o></pre>

\$\endgroup\$
2
\$\begingroup\$

C++ (gcc), 169 166 bytes

#import<iostream>
#import<iomanip>
#define F(x)int(.0255*(100-x)*(100-k))
int main(){
int c,m,y,k;
std::cin>>c>>m>>y>>k;
std::cout<<"#"<<std::hex<<F(c)<<F(m)<<F(y);
}

Try it online!

Using the optimized formula. Added +.5 to convert CMYK=0 0 0 0 correct to RGB=0xffffff which is not necessary.

\$\endgroup\$
1
\$\begingroup\$

Python 3, 114 110 108 106 104 bytes

  • @xnor saved 4 bytes: deleted unnecessary code
  • @rod saved 2 bytes: shorter formula
  • saved 2+2 bytes: range[3] as [0,1,2], unwanted [] removed
n=input().split()
print('#'+''.join(hex(int(.0255*(100-int(n[i]))*(100-int(n[3]))))[2:]for i in[0,1,2]))

Try it online!

\$\endgroup\$
0
1
\$\begingroup\$

Ruby, 92+1 for -p flag= 93 bytes

gsub(/(.+) (.+) (.+) (.+)/){'#%X%X%X'%[$1,$2,$3].map{|n|255*(1-n.to_i/1e2)*(1-$4.to_i/1e2)}}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Javascript, 104 bytes

s=>"#"+[0,1,2].map(n=>("0"+((255-2.55*s[n])*(1-s[3]/100)|0).toString(16)).slice(-2),s=s.split` `).join``

Example code snippet:

f=

s=>"#"+[0,1,2].map(n=>("0"+((255-2.55*s[n])*(1-s[3]/100)|0).toString(16)).slice(-2),s=s.split` `).join``

console.log(f("86 86 0 43"))
console.log(f("28 14 0 6"))
console.log(f("0 41 73 4"))

\$\endgroup\$
1
\$\begingroup\$

Perl 5, 58 52 + 1 (-a) = 59 53 bytes

printf"#%2X%2X%2X",map{.0255*(100-$_)*(100-$F[3])}@F

Try it online!

\$\endgroup\$
0
\$\begingroup\$

dc, 53 bytes

16o?35Pskrsprlpr[Fk100/1r-255*1lk100/-*0k1/nz0<b]dsbx

Try it online!

\$\endgroup\$
0
\$\begingroup\$

q/kdb+, 55 bytes

Solution:

"#",raze{(last($)0x0 vs)each"h"$.0255*x[3]*x 0 1 2}100-

Examples:

q)"#",raze{(last($)0x0 vs)each"h"$.0255*x[3]*x 0 1 2}100-86 86 0 43
"#141491"
q)"#",raze{(last($)0x0 vs)each"h"$.0255*x[3]*x 0 1 2}100-28 14 0 6
"#adcef0"
q)"#",raze{(last($)0x0 vs)each"h"$.0255*x[3]*x 0 1 2}100-0 41 73 4
"#f59042"

Explanation:

Fairly straightforward, stole the 0.0255 trick from other solutions (thanks!). Evaluation is performed right to left.

"#",raze {(last string 0x0 vs) each "h"$ .0255 * a[3] * a 0 1 2}100- / ungolfed
         {                                                     }     / lambda function
                                                                100- / subtract from 100 (vector)
                                                        a 0 1 2      / index into a at 0, 1 and 2 (CMY)
                                                 a[3]                / index into at at 3 (K)
                                                      *              / multiply together
                                         .0255 *                     / multiply by 0.255
                                    "h"$                             / cast to shorts
          (                  ) each                                  / perform stuff in brackets on each list item
                       0x0 vs                                        / converts to hex, 1 -> 0x0001
                string                                               / cast to string, 0x0001 -> ["00", "01"]
           last                                                      / take the last one, "01"
    raze                                                             / join strings together
"#",                                                                 / prepend the hash

Notes:

Rounds numbers by default, would cost 3 bytes (_) to floor instead before casting to short.

\$\endgroup\$
0
\$\begingroup\$

05AB1E, 18 bytes

$#т/-¤s¨*255*hJ'#ì

Try it online!

-1 thanks to kalsowerus.

Has floating-point inaccuracies, so results might be off-by-one, but the formula in the question is used.

\$\endgroup\$
3
  • \$\begingroup\$ You can save a byte: $ is just the same as \$\endgroup\$
    – kalsowerus
    Commented Jul 7, 2017 at 12:45
  • \$\begingroup\$ @kalsowerus Well, not exactly, but it'd work in this case... \$\endgroup\$ Commented Jul 7, 2017 at 12:47
  • \$\begingroup\$ Oh right.. I'm not sure which input is input when there would be multiple \$\endgroup\$
    – kalsowerus
    Commented Jul 7, 2017 at 12:48
0
\$\begingroup\$

Haskell, 165 bytes

q=(1-).(/100)
x!y=h$ceiling$q x*(q y)*255
f c m y k=concat["#",c!k,m!k,y!k]
h x|x<16=[s!!x]|0<1=(h((x-m)`quot`16))++[s!!m] where m=x`mod`16
s=['0'..'9']++['a'..'f']
\$\endgroup\$
0
\$\begingroup\$

Fortran, 156 bytes

PROGRAM C
REAL,DIMENSION(4,3)::d
READ(*,*)((d(i,j),i=1,4),j=1,3)
WRITE(*,'((A,3(Z2)))')(35,(INT(.0255*(100-d(i,j))*(100-d(4,j))),i=1,3),j=1,3)
END PROGRAM C
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.