27
\$\begingroup\$

Given an input of a color in #rrggbb hex format, output its RGB complement in the same format.

The RGB complement R2G2B2 of any color R1G1B1 is defined as the color with R2 value 255 - R1, B2 value 255 - B1, and G2 value 255 - G1.

Hex digits may be either in uppercase (#FFAA20) or lowercase (#ffaa20). The case of the input and output need not be consistent (so you may take input in lowercase but output in uppercase, and vice versa).

Since this is , the shortest code in bytes wins.

Test cases (note that since giving your program/function its own output should result in the original input (it is involutory), the test cases should work in both directions):

In/Out   Out/In
----------------
#ffffff  #000000
#abcdef  #543210
#badcab  #452354
#133742  #ecc8bd
#a1b2c3  #5e4d3c
#7f7f80  #80807f
\$\endgroup\$
  • 2
    \$\begingroup\$ I'm sorry, but sRGB doesn't work that way. You should convert to linear space first, which hex-codes aren't in. \$\endgroup\$ – John Dvorak Jan 1 '16 at 7:38
  • 2
    \$\begingroup\$ @JanDvorak Oh well. The state of the challenge will reflect my ignorance, then, since I can't really change it now. :P \$\endgroup\$ – Doorknob Jan 1 '16 at 14:42
  • \$\begingroup\$ Averaging two values in sRGB could be a decent separate challenge, though. sRGB = RGB^0.45 over most of the range, but linear near the bottom of the range. \$\endgroup\$ – John Dvorak Jan 1 '16 at 14:46

29 Answers 29

17
\$\begingroup\$

Pyth, 9 8 bytes

Thanks to @isaacg for -1 byte!

sXz.HM16

Subtracting a certain color's value from 255 is equivalent to subtracting each of its hexadecimal digits from 15. Say a number is 16a+b. Then the value of the number created by subtracting its digits from 15 is 16(15-a) + (15-b) = 255 - (16a+b).

sXz.HM16     implicit: z=input()
      16      
   .HM        map hex representation over range
   .HM16     '0123456789abcdef'
  z           the input string
 X            Translate characters in x1 present in x2 to reversed x2
              that is, '0' becomes f, '1' becomes 'e', and so on.
              The initial '#' is unchanged.
s             That produced a list, so join into a string by reducing +

Try it here. Test suite.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Nice answer! I borrowed your idea of using '0123456789abcdef' to convert to hex (instead of dec2hex function) \$\endgroup\$ – Luis Mendo Jan 1 '16 at 1:08
  • \$\begingroup\$ I think your link is incorrect. (Copy-paste FTW.) \$\endgroup\$ – PurkkaKoodari Jan 1 '16 at 1:10
  • \$\begingroup\$ @Pietu1998 Whoops; I'll fix it. \$\endgroup\$ – lirtosiast Jan 1 '16 at 1:42
  • \$\begingroup\$ The U is unnecessary - it's implicitly filled in by M. \$\endgroup\$ – isaacg Jan 1 '16 at 11:39
6
\$\begingroup\$

Retina, 13 10 bytes

T`w`G-A9-0

There are three parts to the code, separated by backticks (`): T specifies transliterate mode, which replaces each character in the second part with its corresponding character in the third part.

w is the same as traditional regex's \w, or _0-9A-Za-z, which is expanded to _0123456789ABCDEFGH....

The second part is expanded to GFEDCBA9876543210, thanks to Retina's nifty ability to expand in reverse order. Put these on top of each other, and we get:

_0123456789ABCDEFGH...
GFEDCBA987654321000...
 ^^^^^^^^^^^^^^^^

Note that the last character, 0, is repeated to fit the length of the longer string, but we only care about the hexadecimal characters, shown by carets.

Thanks to Martin Büttner for suggesting this approach.

Try the test suite online.

| improve this answer | |
\$\endgroup\$
4
\$\begingroup\$

Marbelous, 41 bytes

00@0
\\]]\/
-W/\@0
-W
~~
<A+700
+O//]]
+O

Online Interpreter here. Input should be in uppercase.

Explanation

The 00 and ]] at the bottom will fetch the first character (the #) and it will fall to the bottom and be outputted before anything else.

The first 3 lines are a loop to fetch all the remaining characters.

First we need to convert the hex digit characters to 0-15, by doing x -= 48, x -= x > 9 ? 7 : 0 (since 'A' - '9' is 8).

To find the complement, we simply need to convert every digit x to 15-x. This is equivalent to (for 8-bit values) (~x)+16 = ~(x-16).

Finally, we have to convert these numbers back into hex digits, by doing x += x > 9 ? 7 : 0, x += 48.

So now we have x -= 48, x -= x > 9 ? 7 : 0, x = ~(x - 16), x += x > 9 ? 7 : 0, x += 48.

Note that if we remove the expression with the first ternary operator, then input digits A-F will result in a negative x after negation.

Thus we can change the previous expression to: x -= 48, x -= 16, x = ~x, x += (x > 9 || x < 0) ? 7 : 0, x += 48, which is equal to x -= 64, x = ~x, x += (x > 9 || x < 0) ? 7 : 0, x += 48.

The above code is just an implementation of the last expression. -W is x -= 32 and +O is x += 24. Since Marbelous uses unsigned 8-bit arithmetic, the condition <A covers both the case of x > 9 and x < 0.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Did you create Marbelous? \$\endgroup\$ – Rɪᴋᴇʀ Jan 1 '16 at 1:16
  • \$\begingroup\$ @RikerW Marbelous was created/fleshed out by several PPCG users including myself: See here. \$\endgroup\$ – es1024 Jan 1 '16 at 1:19
  • \$\begingroup\$ Okay. Thanks for letting me know. \$\endgroup\$ – Rɪᴋᴇʀ Jan 1 '16 at 1:21
4
\$\begingroup\$

JavaScript ES6, 61 bytes 66 68 48 53 64

Saves quite a few bytes thanks to @Cᴏɴᴏʀ O'Bʀɪᴇɴ, @NinjaBearMonkey, and @nderscore

s=>"#"+(1e5+(8**8+~('0x'+s.slice(1))).toString(16)).slice(-6)

Takes advantage of auto-type-casting. Fixing the zeros killed the byte count

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Use eval(`0x${s.slice(1)}`) instead of parseInt \$\endgroup\$ – Conor O'Brien Jan 1 '16 at 0:07
  • \$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ That's the same length? \$\endgroup\$ – PurkkaKoodari Jan 1 '16 at 0:08
  • \$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ thanks, I used - instead of eval which saved even more bytes \$\endgroup\$ – Downgoat Jan 1 '16 at 0:09
  • \$\begingroup\$ Oh, forgot about auto type casting :D \$\endgroup\$ – Conor O'Brien Jan 1 '16 at 0:09
  • \$\begingroup\$ Try it with the input #FFFFFF. Returns #0. \$\endgroup\$ – Conor O'Brien Jan 1 '16 at 0:19
4
\$\begingroup\$

JavaScript ES6, 63 58 52 49 bytes

c=>c.replace(/\w/g,x=>(15-`0x${x}`).toString(16))

Thanks to nderscore for saving 11 bytes!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ -5 bytes: c=>"#"+[...c].map(x=>"fedcba9876543210"[+('0x'+x)]).join`` \$\endgroup\$ – nderscore Jan 1 '16 at 8:06
  • \$\begingroup\$ @nder exactly, thought about it already :) Thanks. Was going to use it, but with "eval". \$\endgroup\$ – nicael Jan 1 '16 at 8:09
  • 1
    \$\begingroup\$ ah, I've got one more -6: c=>c.replace(/\w/g,x=>"fedcba9876543210"[+('0x'+x)]) \$\endgroup\$ – nderscore Jan 1 '16 at 8:13
3
\$\begingroup\$

Jolf, 17 bytes

pq#-w^88C Li1~560
pq                pad
         _Li1     the input, w/out the first char
        C    ~5   parsed as a base-16 integer (~5 = 16)
    w^88          8 ^ 8 - 1 (the magic number)
   -              subtract the parsed input from said number
  #               convert result to hexadecimal
               60 pad the result with 6 0's

Try it here!, Test suite (Use full run, which now works.)

| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

Julia, 74 49 bytes

h->"#"join([hex(15-parse(Int,i,16))for i=h[2:7]])

Pretty long at the moment but it's a start. This is a lambda function that accepts a string and returns a string. The output will be in lowercase but the input can be in either.

As Thomas noted, subtracting each 2-digit color component from 255 is equivalent to subtracting each individual digit in the hexadecimal input from 15. Looping over the input string, excluding the leading #, we convert 15 - the parsed digit to hexadecimal. We join all of these then tack on a # and call it good.

| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

Japt, 35 32 22 20 16 15 bytes

¡Y?(F-XnG)sG :X

Explanation:

¡                 //Take input and map (shortcut to "Um@"). Input should in the form of "#123456"
 Y?               //if Y is not 0, then return (F-XnG)sG, otherwise last step...
    F-XnG           //Subtract X, converted from hexadecimal (G is 16) to decimal, from 15
          sG        //convert decimal to hexadecimal
             :X   //...otherwise return X unchanged (happens only with #, the first char)
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Nice one! I saw this last night and said to myself, "Tomorrow I'll help to golf it down." But by now you've golfed it further than I thought possible. :) \$\endgroup\$ – ETHproductions Jan 1 '16 at 19:54
2
\$\begingroup\$

Perl, 30 bytes

includes +1 for -p

s/\w/sprintf"%x",15&~hex$&/eg

usage: echo #000000 | perl -p file.pl
or echo #000000 | perl -pe 's/\w/sprintf"%x",15&~hex$&/eg'.

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

MATL, 21 bytes

35,5Y216,j6L)!16ZA-)h

This uses release 6.0.0 of the language/compiler, which is earlier than the challenge.

Input digits should be uppercase.

Example

This has been executed on Octave:

>> matl
 > 35,5Y216,j6L)!16ZA-)h
 >
> #FFAA20
#0055DF

Edit (June 12, 2016)

The code can now be tried online. Commas need to be replaced by spaces, and 6L by 4L, to conform to changes in the language.

Explanation

35,             % number literal: ASCII code of '#'
5Y2             % '0123456789ABCDEF'
16,             % number literal
j               % input string
6L)             % remove first element
!               % transpose
16ZA            % convert from hex to dec
-               % subtract from 16
)               % index into '0123456789ABCDEF' to convert back to hex
h               % prepend 35, which gets automatically converted into '#'
| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

x86-16 machine code, IBM PC DOS, 60 41 32 bytes

Binary:

00000000: be82 00ac cd29 b106 ac3c 397e 022c 272c  .....)...<9~.,',
00000010: 30f6 d03c f976 0204 2704 40cd 29e2 e9c3  0..<.v..'.@.)...

Unassembled listing:

BE 0082     MOV  SI, 82H            ; command line input set to string 
AC          LODSB                   ; load first '#' char 
CD 29       INT  29H                ; write it to console 
B1 06       MOV  CL, 6              ; loop 6 chars 
        INLOOP: 
AC          LODSB                   ; load next ASCII hex char into AL 
3C 39       CMP  AL, '9'            ; is char an alpha (a-f)? 
7E 02       JLE  NOHEX_IN           ; if not, is numeric 
2C 27       SUB  AL, 'f'-'9'-6      ; otherwise ASCII adjust a-f 
        NOHEX_IN: 
2C 30       SUB  AL, '0'            ; ASCII to decimal convert 
F6 D0       NOT  AL                 ; complement the color (magic happens here) 
3C F9       CMP  AL, 0F9H           ; is char <= 9? 
76 02       JBE  NOHEX_OUT          ; if not, is numeric 
04 27       ADD  AL, 'f'-'9'-6      ; otherwise ASCII adjust a-f 
        NOHEX_OUT: 
04 40       ADD  AL, '0'+10H        ; decimal convert to ASCII 
CD 29       INT  29H                ; write char to console 
E2 E9       LOOP INLOOP             ; keep looping 
C3          RET                     ; return to DOS

So nearly all of this code is brute-force conversion from an ASCII hex string into a numeric value and then back again. No CPU instructions on x86-16 to help with that I'm afraid!

I/O:

Standalone PC DOS executable. Input via command line, output to STDOUT.

enter image description here

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Pyth, 20 19 bytes

1 byte thanks to xnor.

%"#%06x"-t^8 8itz16

Try it online. Test suite.

Explanation

  • z is the input
  • tz removes the #
  • itz16 parses as a hexadecimal number
  • t^8 8 calculates 88 - 1
  • -t^8 8itz16 calculates 88 - 1 - input
  • %"#%06x"-t^2 24itz16 formats it into a zero-padded 6-character hex string and adds the #
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ How about 8^8 for 2^24? \$\endgroup\$ – xnor Jan 1 '16 at 0:14
1
\$\begingroup\$

Java, 95 90 bytes

String f(String v){return v.format("#%06x",0xFFFFFF^Integer.parseInt(v.substring(1),16));}

Bitwise XOR.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Haskell, 85 bytes

My first submission, it will probably be the longest (85 bytes) but hey, you got to start somewhere. In Haskell:

import Numeric;f=('#':).concatMap((flip showHex)"".(15-).fst.head.readHex.(:[])).tail

It's using the same subtract from 15 trick I saw other people use.

I also tried using printf along with the other trick (subtract 8^8 - 1) and it works in ghci but for some reason it doesn't compile:

g=printf "#%06x" .(8^8-1-).fst.head.readHex.tail

If someone could make this work that would be great!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Welcome to Programming Puzzles and Code Golf. These are very good answers (better than I could do in Haskell!). However, there is a common answer format for code-golf challenges which lets the Leaderboard snippet put your answer in the leaderboard. I'll edit it in for you; you can accept or deny the edit. \$\endgroup\$ – wizzwizz4 Jan 3 '16 at 11:44
  • \$\begingroup\$ To reply to other users' comments, type @username. \$\endgroup\$ – wizzwizz4 Jan 3 '16 at 11:49
  • \$\begingroup\$ @wizzwizz4 Many thanks for your assistance. \$\endgroup\$ – lpapez Jan 3 '16 at 11:58
  • \$\begingroup\$ Any time! Do you want to have a go at some of my challenges? Analyse your chair and Map string to Hilbert Curve are my favourites, although the Hilbert curve one is really hard. \$\endgroup\$ – wizzwizz4 Jan 3 '16 at 12:05
  • \$\begingroup\$ @wizzwizz4 Certainly, I'll see what I can do. \$\endgroup\$ – lpapez Jan 3 '16 at 12:10
1
\$\begingroup\$

Mathematica, 69 60 bytes

"#"<>IntegerString[8^8-#~StringDrop~1~FromDigits~16-1,16,6]&

Once again, it's the string processing that kills me here.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

C, 94 bytes

t(char*b){for(int i;i=*b;++b)*b=i>96&i<103?150-i:i>64&i<71|i>47&i<54?118-i:i>53&i<58?111-i:i;}

Function takes in a char array, returns inverse value. Produces uppercase letters for response. The code flips each ASCII hex character to its inverse if it's valid, ignores it otherwise.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ You can save some space by globally declaring i before the function: i; \$\endgroup\$ – Liam Jun 12 '16 at 16:49
1
\$\begingroup\$

𝔼𝕊𝕄𝕚𝕟 2, 18 chars / 34 bytes

ïē/\w⌿,↪(ḏ-`ᶍ⦃$}”ⓧ

Try it here (Firefox only).

Using a version created after the challenge.

Explanation

ïē/\w⌿,↪(ḏ-`ᶍ⦃$}”ⓧ // implicit: ï=input, ḏ=15
ïē/\w⌿,             // replace all alphanumeric chars in ï with:
       ↪(ḏ-`ᶍ⦃$}”ⓧ // (15 - char's decimal form) converted to hex
                    // implicit output

Non-competitive solution, 15 chars / 29 bytes

ïē/\w⌿,↪(ḏ-`ᶍ⦃$}”ⓧ

Uses transliteration.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Can you add a competitive version as well, so we can see how the language stacks up? \$\endgroup\$ – lirtosiast Jan 5 '16 at 22:36
  • \$\begingroup\$ Sure. See new edit. \$\endgroup\$ – Mama Fun Roll Jan 5 '16 at 23:24
  • \$\begingroup\$ Nice use of the APL symbol . \$\endgroup\$ – lirtosiast Jan 6 '16 at 0:01
  • \$\begingroup\$ Hehe, that symbol was the one that made the most sense for /g. \$\endgroup\$ – Mama Fun Roll Jan 6 '16 at 0:39
1
\$\begingroup\$

Python, 96

x=input()
print("#")
for i in range(3):
    print(hex(255-int(x[(1+2*i)]+x[(2+2*i)],16))[2:4])

First code golf, please give opinions :)

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ You are allowed to require the input be in "quotes" btw, so input() works. You don't need the newline and indent on the for loop, and range works just fine. There are also a couple spaces you can remove. \$\endgroup\$ – Rɪᴋᴇʀ Jun 13 '16 at 0:33
  • \$\begingroup\$ int("ff", 16) can be replaced with just 255. \$\endgroup\$ – Doorknob Jun 13 '16 at 1:54
  • \$\begingroup\$ Do you need the parentheses inside the brackets after each x? \$\endgroup\$ – Blue Jun 13 '16 at 2:08
1
\$\begingroup\$

Befunge-98, 37 bytes

~,v>v
~f<^ s
>,^ >-:9w>'0+
^+W'    ]^

This takes input in lowercase, outputs the answer in lowercase, then enters an infinite loop.

Try it online!

40 byte version that terminates

Explanation

~,v

This gets the first character of the input (which is always #), outputs it unchanged, and enters the loop.


~f<  s

At the start of the loop, f pushes 15 onto the stack, ~ gets the next character of the input, and s puts that character one space to its left in the source code (without executing it).

   >v
   ^I

(I'm using I to represent the character from the input that is now in the source code.) This section loops back around to execute that character. Every character in the range 0-9 or a-f pushes the corresponding hex value on the stack.

 
 
    >-:9w

The hex value is subtracted from 15 (the previous top of the stack) to get its complement. :9w creates a copy of the complement, and compares the copy with 9, with the IP going down, up or right depending on whether it is greater, less than, or equal.

 
 
         >
        ]^

If the complement is greater than 9, the IP goes down and hits the ] ("turn right") from above, turning to move left. If the copy was less than 9, the IP goes up and hits the ] from below, turning to move right. In that case, it gets redirected back to the third line. If the copy was exactly 9, the IP goes right and hits the > immediately.

 
 
          '0+
 

If the complement is less than or equal to 9 (i.e. a digit), it is added to ASCII 48 (0) to produce the correct digit.

 
 
 
^+W'

If the complement is greater than 9, it is added to ASCII 87 (W) to produce the correct character (in the range a-f).


  <
>,^

In all cases, the character corresponding to the complement is printed and the IP moves back to the start of the loop.

The loop repeats, outputting the complement of every hex digit in the input.

After we print the answer, the input has been completely used up. Once EOF is reached, ~ reflects the IP. This means that ~f< is now an infinite loop that pushes 15 on the stack forever. This doesn't produce any effects (except for possibly crashing), so we don't care about it.

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

CJam, 16 bytes

qA,'G,65>+s_W%er

This is fairly long because CJam handles base changes differently, so it was shorter to just do transliteration. See my Retina answer for more on transliteration.

Try it online.

Explanation

q      e# Get the input
A,     e# Push [0 1 ... 8 9]
'G,65> e# Push "ABCDEF"
+s     e# Combine and convert to string
_W%    e# Make a copy and reverse it
er     e# Replace each character in the first string with
       e# the corresponding character in the second
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Python 3, 44 bytes

Originally I used 256^3, then 16^6. Then I saw Pietu1998's 8^8 and now this solution uses that instead.

"#{:06x}".format(8**8-1-int(input()[1:],16))
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Bash + tr, 35 bytes

tr 0-9A-Fa-f fedcba9876543210543210

Output is always lowercase.

Unfortunately "tr" does not take ranges in reverse order so I had to spell them out.

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

C, 147 bytes

void p(char s[]){char c[3];int i=1;printf("#");while(i<6){strncpy(c,s+i++,2);i++;int x=255-strtol(c,NULL,16);x<10?printf("0%x",x):printf("%x",x);}}

Used strtol to convert from hex string to int then subtracted the number from 255 to get the compliment like the original post said. I am, however, wondering if there is a way to pass a range of characters from s to strtol so I don't have to waste a bunch of bytes copying to a new string?

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I don't think compilers usually enforce function returns and default to int, so you an probably omit the void return type? \$\endgroup\$ – Liam Jun 12 '16 at 16:52
0
\$\begingroup\$

R, 62 bytes

f=function(a)sprintf('#%06x',(8^8-1)-strtoi(substr(a,2,7),16))
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

sed, 48 bytes

y/0123456789ABCDEFabcdef/fedcba9876543210543210/

Or 36 bytes if you only need to support one case.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ You don't need to support both lowercase and uppercase. \$\endgroup\$ – Martin Ender Jan 2 '16 at 0:29
  • \$\begingroup\$ @MartinBüttner the question seems to require support for both cases in the input, but not in the output. Like my bash+tr solution, this solution supports both on input but only writes lower-case output. \$\endgroup\$ – Glenn Randers-Pehrson Jan 2 '16 at 13:30
  • \$\begingroup\$ You've got an extra 0 in your code, between the 9 and A (byte count is correct though, must be a copying error). \$\endgroup\$ – hobbs Jan 2 '16 at 19:00
  • \$\begingroup\$ The question says you can choose which case your input and output are. \$\endgroup\$ – lirtosiast Jan 5 '16 at 4:22
0
\$\begingroup\$

PowerShell, 48 bytes

param($a)"#{0:x6}"-f(16MB-1-("0x"+$a.Trim('#')))

Necessarily takes input via param($a) as a string, delimited with ' or ", since C:\Tools\Scripts\Golfing> .\complementary-colors #a1b2c3 on the PowerShell command line will treat #a1b2c3 as a comment and summarily ignore it.

Left-to-right, the "#{0:x6}"-f(...) formats our output calculations back into hexadecimal with a guaranteed 6 characters (to account for input #ffffff). Inside the parens, we subtract our input number from 0xffffff. We do this by leveraging the fact that PowerShell parses hexadecimal numbers in format 0xNNN, so we construct a proper-format hex number from our input number $a. (Note that concatenation plus .Trim() is shorter than .Replace() here by one byte.) We also leverage the MB unary operator via 16MB-1 to construct 16777215 instead of 0xffffff.

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

TeaScript, 24 bytes

"#"+S(8**8-1-xS1)t16))x6

Bugs in the interpreter aren't letting me get this shorter :(

Try it online

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Downvote explanation? It works for all the test cases \$\endgroup\$ – Downgoat Jan 1 '16 at 17:51
0
\$\begingroup\$

C (gcc), 53 bytes

p(char*s){printf("#%06x",0xffffff-strtol(s+1,0,16));}

Try it online!

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

PHP, 37 bytes

printf('#%06x',8**8-1-hexdec($argn));

Try it online!

Or if you prefer to be more bit-wise (and byte-foolish) about it:

PHP, 38 bytes

printf('#%06x',~hexdec($argn)&8**8-1);

Try it online!

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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