18
\$\begingroup\$

Different systems have different ways to describe colors, even if all of them are speaking in R-G-B-A space. A front-end developer who is familiar with CSS may prefer #RRGGBBAA. But Android developers may prefer #AARRGGBB. When handling AAS file format, #AABBGGRR is needed. That's too confusing. Maybe we need a program which can convert between different color formats.

Input:

The input contains 3 parts:

  • The color to be transformed (e.g. #1459AC0F), a string starting with sharp sign # followed by 8 hex digits.
  • The format of the given color (e.g. #RRGGBBAA), a string starting with # followed by 8 letters which fall into 4 different groups and each group is one of RR/GG/BB/AA.
  • The format to convert to.

Output:

  • Output the color in converted format

Test Cases:

Color, OriginalFormat, TargetFormat -> Result
#12345678, #RRGGBBAA, #AARRGGBB -> #78123456
#1A2B3C4D, #RRGGBBAA, #AABBGGRR -> #4D3C2B1A
#DEADBEEF, #AARRGGBB, #GGBBAARR -> #BEEFDEAD

Input / output are case insensitive. You may input / output in any acceptable way.

Rules:

This is code golf, shortest (in byte) codes of each language win

\$\endgroup\$
4
  • \$\begingroup\$ AARRGGBB is objectively the best color format. If something expects 24 bit RRGGBB and you give it 32 bit AARRGGBB instead, it can just ignore the upper byte and still work. \$\endgroup\$
    – 12Me21
    Mar 22, 2018 at 13:08
  • 2
    \$\begingroup\$ The color DEADBEEF looks a little Salmon-y. \$\endgroup\$ Mar 22, 2018 at 14:22
  • 1
    \$\begingroup\$ I've been a front end web dev for years now and I'd never heard of #RRGGBBAA until today, wish more browsers supported it. \$\endgroup\$
    – DasBeasto
    Mar 22, 2018 at 14:41
  • \$\begingroup\$ @12Me21 And the next question is which endianness is better. \$\endgroup\$
    – tsh
    Sep 18, 2018 at 13:56

19 Answers 19

10
\$\begingroup\$

APL (Dyalog Unicode), 6 bytesSBCS

Full program. Prompts on STDIN for Original, then Target, then Color. Prints Result to STDOUT.

⍞[⍞⍋⍞]

Try it online!

   prompt for Original

⍞⍋ prompt for Target and find the indices into Original that would make Original into Target

⍞[] prompt for Color and use the above obtained indices to reorder Color

\$\endgroup\$
8
\$\begingroup\$

JavaScript (ES6), 53 52 bytes

Saved 1 byte thanks to @tsh

Takes input as 3 distinct parameters: (Color, From, To).

(C,F,T)=>T.replace(/\w/g,(x,i)=>C[F.search(x)-~i%2])

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ (C,F,T)=>T.replace(/\w/g,(x,i)=>C[F.search(x)-~i%2]) save one byte \$\endgroup\$
    – tsh
    Mar 22, 2018 at 9:19
  • \$\begingroup\$ @tsh Nice one. ^^ \$\endgroup\$
    – Arnauld
    Mar 22, 2018 at 9:31
5
\$\begingroup\$

Stax, 8 bytes

ç▼☺↔kàÅJ

Run and debug it

This program takes input in this format.

"{Color}" "{OriginalFormat}" "{TargetFormat}"

Here's the commented ungolfed unpacked version of the same program.

u       drop duplicated characters from target format
{       for each character remaining in target format, map using block...
  [     duplicate original format at second position in stack
  |I    get all indices of target character in original format
  xs@   retrieve characters from those indices from the color string
m       perform map
        output implicitly when complete

Run this one

\$\endgroup\$
4
\$\begingroup\$

Python 2, 59 bytes

lambda c,o,t:'#'+''.join(c[o.find(v):][:2]for v in t[1::2])

Try it online!

\$\endgroup\$
4
\$\begingroup\$

Retina 0.8.2, 33 bytes

(.)(?<=(..).{7}\1\1.*)\1
$2
.*#
#

Try it online! Link includes test cases. Explanation:

(.)(?<=(..).{7}\1\1.*)\1
$2

For each pair of identical characters, look back for another copy of that pair, and then the 9th and 8th characters before that, and replace the pair with those characters. This is only possible for the pairs of characters in the target format, and replaces them with the desired result.

.*#
#

Delete the colour and source format.

\$\endgroup\$
3
\$\begingroup\$

Haskell, 108 104 100 94 87 bytes

(s,(r@(x,y):z))!c|x==c=(s++[y],z)|(p,q)<-(s,z)!c=(p,r:q)
c%i=fst.(foldl(!)("",zip i c))

Try it online!


Old version

Thanks to Laikoni for shortening 6 bytes by finding a shorter way to use lookup!

f(Just x)=x
p('#':z)=p z
p(x:y:z)=[x,y]:p z
p e=[]
c!i=('#':).(f.(`lookup`zip(p i)(p c))=<<).p

Try it online!

Explanation:

  • the p function "parses" a string by ignoring the leading # and returning groups (lists) of 2 chars.
  • the (!) operator takes as input the color and the input format and returns a function that takes as a parameter the output format and returns the converted color. It turned out that the pointfree version was shorter, but I started with the more readable version:

f c i o='#':concat[x#zip(p<$>[i,c])|x<-p o]

Try it online!

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

Perl 5 -p, 33 32 27 bytes

Give input in the order: target, original, number

#!/usr/bin/perl -p
s%.%$2x/(..)+$&(.){10}/g%eg

Try it online!

For each character in the input find the same character an even number of places forward then from there go 10 more characters forward and take that character as replacement. If you can't do these steps replace by nothing.

    +--even-+----10---+   
    |       |         |
#AARRGGBB #RRGGBBAA #12345678
    |    >-will get removed-<
    v
    2
\$\endgroup\$
2
\$\begingroup\$

05AB1E, 10 bytes

2FI2ô™J}I‡

Try it online!


2F     }   # Loop twice...
  I        # First 2 inputs.
   2ô™     # Title case in pairs of 2.
      J    # Rejoin together.
        I  # Last input (The color).
         ‡ # Transliterate, put color in pattern from a into pattern from b.

This works because I change the input from:

AARRGGBB

To:

AaRrGgBb

So each value is mapped uniquely, then I can use transliterate.

The arguments are reversed.

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

Java 10, 179 105 102 bytes

(a,b,c)->{var r="#";for(int i=1,t;i<9;)r+=a.substring(t=b.indexOf(c.substring(i,i+=2)),t+2);return r;}

Whopping -77 bytes thanks to @OlivierGrégoire.

Explanation:

Try it online.

(a,b,c)->{            // Method with String as three parameters and return-type
  var r="#";          //  Result-String, starting at "#"
  for(int i=1,t;i<9;  //  Loop `i` from 1 to 9 (exclusive)
    r+=               //   Append the result with:
       a.substring(   //    A substring from the first input,
        t=b.indexOf(  //    where an index is determined in the second input
           c.substring(i,i+=2)),t+2);
                      //    based on a substring of the third input
    return r;}        //  Return the result-String
\$\endgroup\$
3
  • 1
    \$\begingroup\$ 105 bytes Builds the string from the target by finding the target element in the source format. \$\endgroup\$ Mar 22, 2018 at 9:35
  • \$\begingroup\$ @OlivierGrégoire I knew it would be possible without that pesky Map. Thanks a lot, -74 bytes right there! \$\endgroup\$ Mar 22, 2018 at 10:00
  • \$\begingroup\$ 102 bytes by switching to Java 10, which is now supported on TIO. \$\endgroup\$ Mar 22, 2018 at 12:26
2
\$\begingroup\$

J, 5 bytes

/:i./

The left argument is the color. The right argument is a character matrix where the first row is the target format and the second row is the original format. Try it online!

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

CJam, 14 bytes

{'#\1f>2f/~er}

Try it Online!

Input is an array in the reverse order.

{
 `#\      e# Push '#'+[input array] on to stack
  1f>     e# Remove the '#' symbol from each input string
  2f/     e# Split each input string into an array of substrings of length 2.
  ~       e# Dump the substring-arrays from the container array onto the stack
  er      e# Perform a string replace operation
}     
\$\endgroup\$
0
\$\begingroup\$

Python 2, 62 bytes

lambda c,s,e:[c[s.index(e[i]):][:2]for i in range(1,len(e),2)]
\$\endgroup\$
0
\$\begingroup\$

SmileBASIC, 144 bytes

DEF R C,I,O
C[0]="&H
A=R+G+B
RGBREAD VAL(C)OUT VAR(I[1]),VAR(I[3]),VAR(I[5]),VAR(I[7])?"#";RGB(VAR(O[1]),VAR(O[3]),VAR(O[5]),VAR(O[7]))END
\$\endgroup\$
0
\$\begingroup\$

Red, 154 120 114 bytes

func[c o t][g: func[q][parse q[skip collect 4 keep 2 skip]]
prin"#"foreach p g t[prin pick g c index? find g o p]]

Try it online!

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

Python 3, 102 bytes

lambda x,a,b:['#']+[[x[i:i+2]for i in range(1,len(x),2)][i]for i in[a[1::2].index(i)for i in b[1::2]]]

Try it online!

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

Jelly, 6 bytes

ẹЀQị⁵

Try it online!

Full program.

Argument 1: Original
Argument 2: Target
Argument 3: Color

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

C (clang), 89 bytes

char *a,b[10],*i,*o;f(x,y){*b=*a;for(x=1;x<8;b[x++]=a[y=index(i,o[x])-i],b[x++]=a[y+1]);}

Try it online!

Takes input value in a, in format in i and out format in o. Returns out value in b

Minor cheat: storing result in b instead of printing to save bytes. Question doesn't disallow it.

C (clang), 100 bytes

char *a,b[10],*i,*o;f(x,y){*b=*a;for(x=1;x<8;b[x]=a[y=index(i,o[x])-i],b[x+1]=a[y+1],x+=2);puts(b);}

Try it online!

C (gcc), 181 bytes

char *a,*i,*o;c[4],x,y,z;g(x){x=x==82?0:x==71?1:x==66?2:3;}f(){a++;for(;z<2;z++){i=(z?o:i)+1;for(y=0;y<7;z?printf("%s%2X","#"+!!y,c[g(i[y])]):sscanf(a+y,"%2X",&c[g(i[y])]),y+=2);}}

Try it online!

Creates a RGBA value in c[] array based on format i, then prints in o format

\$\endgroup\$
1
  • \$\begingroup\$ Suggest char*a,b[10],*i,*o;f(x) instead of char *a,b[10],*i,*o;f(x,y) and x+=2)bcopy(a+(long)index(i,o[x])-i,b+x,2); instead of b[x++]=a[y=index(i,o[x])-i],b[x++]=a[y+1]); \$\endgroup\$
    – ceilingcat
    Oct 4, 2018 at 18:58
0
\$\begingroup\$

Clojure 1.8, 156 bytes

(fn[c o t](reduce #(str %(val %2))""(sort-by key(reduce-kv #(let[s(clojure.string/index-of t(nth o %2))](assoc %(if(contains? % s)(inc s)s)%3)){}(vec c)))))

Ungolfed

  (fn [c o t]
    (reduce
     #(str % (val %2))
     ""
     (sort-by key
              (reduce-kv
               #(let [s (clojure.string/index-of t (nth o %2))]
                  (assoc %
                         (if (contains? % s) (inc s) s)
                         %3))
               {}
               (vec c)))))

Try it online does not have Clojure 1.8 support. Very strange!

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

Perl 6, 55 51 46 bytes

{[~] %(@^b Z=>@^a){@^c}}o*.map(*.comb(/\w?./))

Try it online!

Takes a (color, original, target) list as input. Splits each input string into components, creates a Hash mapping source keys to color values, looks up color values in target key order, then formats the result.

\$\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.