Convert CMYK values to RGB

9

1

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

Wasi

Posted 2017-06-30T17:33:33.523

Reputation: 1 682

1Can we take CMYK values as decimals from 0 to 1 or is it required to do 0 to 100? – HyperNeutrino – 2017-06-30T17:39:26.580

1Also, are we supposed to input multiple CMYK codes at once or just one and convert it? – HyperNeutrino – 2017-06-30T17:41:09.540

7Can we take the input as a list of numbers or does it have to be a delimited string? – Business Cat – 2017-06-30T17:41:26.987

Is the output required to have a # at the beginning? – Mr. Xcoder – 2017-06-30T17:58:50.837

@Mr.Xcoder Yes it is required. – Wasi – 2017-06-30T18:03:33.663

@BusinessCat String – Wasi – 2017-06-30T18:04:55.723

@HyperNeutrino It is okay if your code just works for one input and converts it. But, you can also submit code that handles multiple CMYK codes as well. However, try to reduce source code size as much as you can. – Wasi – 2017-06-30T18:10:07.913

@HyperNeutrino 0-100. – Wasi – 2017-06-30T18:12:12.200

7The input / output that you provided doesn't match the formula, also how should we handle the rounding? – Rod – 2017-06-30T18:33:13.720

Is uppercase required for #RRGGBB format? – LarsW – 2017-06-30T23:31:17.210

2@Rod It's a bit unclear yet how floating-point inaccuracies should be handled. – Erik the Outgolfer – 2017-07-01T07:33:36.770

Answers

5

PHP, 90 bytes

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

Try it online!

Jörg Hülsermann

Posted 2017-06-30T17:33:33.523

Reputation: 13 026

2

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!

totallyhuman

Posted 2017-06-30T17:33:33.523

Reputation: 15 378

Golfing the math. o0 Thanks! – totallyhuman – 2017-06-30T18:42:59.573

2

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 #.

Neil

Posted 2017-06-30T17:33:33.523

Reputation: 95 035

2

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

Jonathan Allan

Posted 2017-06-30T17:33:33.523

Reputation: 67 804

Another way to round would be _.Ċ instead of +.Ḟ...but the latter is maybe more widely used. – Erik the Outgolfer – 2017-07-01T07:47:22.957

2

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!

Justin Mariner

Posted 2017-06-30T17:33:33.523

Reputation: 4 746

2

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>

nderscore

Posted 2017-06-30T17:33:33.523

Reputation: 4 912

2

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.

Karl Napf

Posted 2017-06-30T17:33:33.523

Reputation: 4 131

1

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!

officialaimm

Posted 2017-06-30T17:33:33.523

Reputation: 2 739

1

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!

Alexis Andersen

Posted 2017-06-30T17:33:33.523

Reputation: 591

1

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

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

Try it online!

Xcali

Posted 2017-06-30T17:33:33.523

Reputation: 7 671

0

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.

Erik the Outgolfer

Posted 2017-06-30T17:33:33.523

Reputation: 38 134

You can save a byte: $ is just the same as – kalsowerus – 2017-07-07T12:45:45.430

@kalsowerus Well, not exactly, but it'd work in this case... – Erik the Outgolfer – 2017-07-07T12:47:15.090

Oh right.. I'm not sure which input is input when there would be multiple – kalsowerus – 2017-07-07T12:48:49.790

0

dc, 53 bytes

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

Try it online!

R. Kap

Posted 2017-06-30T17:33:33.523

Reputation: 4 730

0

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"))

Herman L

Posted 2017-06-30T17:33:33.523

Reputation: 3 611

0

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.

streetster

Posted 2017-06-30T17:33:33.523

Reputation: 3 635

0

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']

Sergii Martynenko Jr

Posted 2017-06-30T17:33:33.523

Reputation: 213

0

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

Zongor

Posted 2017-06-30T17:33:33.523

Reputation: 51