[Question]
  [
In CSS, colours can be specified by a "hex triplet" - a three byte (six digit) hexadecimal number where each byte represents the red, green, or blue components of the colour. For instance, `#FF0000` is completely red, and is equivalent to `rgb(255, 0, 0)`.
Colours can also be represented by the shorthand notation which uses three hexadecimal digits. The shorthand expands to the six digit form by duplicating each digit. For instance, `#ABC` becomes `#AABBCC`.
Since there are fewer digits in the hex shorthand, fewer colours can be represented.
## The challenge
Write a program or function that takes a six digit hexadecimal colour code and outputs the closest three-digit colour code.
Here's an example:
> 
> * Input hex code: #28a086
> * Red component
> 	+ 0x28 = 40 (decimal)
> 	+ 0x22 = 34
> 	+ 0x33 = 51
> 	+ 0x22 is closer, so the first digit of the shortened colour code is 2
> * Green component
> 	+ 0xa0 = 160
> 	+ 0x99 = 153
> 	+ 0xaa = 170
> 	+ 0x99 is closer, so the second digit is 9
> * Blue component
> 	+ 0x86 = 134
> 	+ 0x77 = 119
> 	+ 0x88 = 136
> 	+ 0x88 is closer, so the third digit is 8
> * The shortened colour code is #298 (which expands to #229988)
> 
> 
> 
Your program or function must accept as input a six digit hexadecimal colour code prepended with `#` and output a three digit colour code prepended with `#`.
## Examples
* #FF0000 → #F00
* #00FF00 → #0F0
* #D913C4 → #D1C
* #C0DD39 → #BD3
* #28A086 → #298
* #C0CF6F → #BC7
## Scoring
This is a code-golf challenge, so shortest answer in your language wins! Standard rules apply.
  
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), 13 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
ćs2ôH8+17÷hJ«
```
**[Try it online!](https://tio.run/##yy9OTMpM/f//SHux0eEtHhbahuaHt2d4HVr9/7@ys4Gzm5kbAA "05AB1E – Try It Online")**
### How?
```
ćs2ôH8+17÷hJ« | string, S   e.g. stack: "#B23F08"
ć             | decapitate              "B23F08", "#"
 s            | swap                    "#", "B23F08"
  2           | two                     "#", "B23F08", 2
   ô          | chuncks                 "#", ["B2", "3F", "08"]
    H         | from hexadecimal        "#", [178, 63, 8]
     8        | eight                   "#", [178, 63, 8], 8
      +       | add                     "#", [186, 71, 16]
       17     | seventeen               "#", [186, 71, 16], 17
         ÷    | integer divide          "#", [10, 4, 0]
          h   | to hexadecimal          "#", ["A", "4", "0"]
           J  | join                    "#", "A40"
            « | concatenate             "#A40"
              | print top of stack
```
[Answer]
# [Japt](https://github.com/ETHproductions/japt), 16 bytes
```
r"%w"²_n16_r17Ãg
```
[Try it](https://petershaggynoble.github.io/Japt-Interpreter/?v=1.4.6&code=ciIldyKyX24xNl9yMTfDZw&input=IiNmZjAwMDAi) or [run all test cases](https://petershaggynoble.github.io/Japt-Interpreter/?v=1.4.6&code=ciIldyKyX24xNl9yMTfDZw&input=WwoiI2ZmMDAwMCIKIiMwMGZmMDAiCiIjZDkxM2M0IgoiI2MwZGQzOSIKIiMyOGEwODYiCiIjYzBjZjZmIgpdLW1S)
```
r"%w"²_n16_r17Ãg     :Implicit input of string
r                    :Replace
 "%w"                :RegEx /\w/g
     ²               :Duplicate, giving /\w\w/g
      _              :Pass each match through a function
       n16           :  Convert to decimal
          _          :  Pass through the following function, and convert back to hex
           r17       :    Round to the nearest multiple of 17
              Ã      :  End function
               g     :  Get first character
```
[Answer]
# 8088 Assembly, IBM PC DOS, ~~59~~ 58 bytes
**Unassembled listing:**
```
BE 0082     MOV  SI, 82H    ; SI to begining of input string 
AC          LODSB           ; load first '#' char into AL 
B4 0E       MOV  AH, 0EH    ; BIOS display char function  
CD 10       INT  10H        ; call BIOS 
B3 11       MOV  BL, 17     ; set up for divide by 17 
B9 0304     MOV  CX, 0304H  ; hex byte loop counter (CH=3), shift counter (CL=4) 
        LOOP_BYTE: 
AD          LODSW           ; load next two ASCII hex chars into AX 
B7 02       MOV  BH, 2      ; hex chars loop counter
        LOOP_ALPHA:
2C 30       SUB  AL, '0'    ; convert from ASCII 
3C 0A       CMP  AL, 10     ; is digit > 10 (A-F)? 
7C 02       JL   NOT_ALPHA  ; if not, jump to next char
2C 07       SUB  AL, 7      ; ASCII adjust alpha char to binary 
        NOT_ALPHA: 
86 E0       XCHG AH, AL     ; swap first and second chars 
FE CF       DEC  BH         ; decrement loop counter
75 F2       JNZ  LOOP_ALPHA ; loop to next hex char
D2 E0       SHL  AL, CL     ; shift low nibble to high nibble 
02 C4       ADD  AL, AH     ; add first and second nibbles
32 E4       XOR  AH, AH     ; clear AH for add/division
05 0008     ADD  AX, 8      ; add 0.5 (8/16) to round (with overflow) 
F6 F3       DIV  BL         ; divide by 17 
3C 0A       CMP  AL, 10     ; is digit > 10? 
7C 02       JL   DISP_CHAR  ; if not, jump to display digit 
04 07       ADD  AL, 7      ; binary adjust alpha char to ASCII 
        DISP_CHAR: 
04 30       ADD  AL, '0'    ; convert to ASCII 
B4 0E       MOV  AH, 0EH    ; BIOS display char function  
CD 10       INT  10H        ; call BIOS 
FE CD       DEC  CH         ; decrement loop counter 
75 D4       JNZ  LOOP_BYTE  ; loop to next hex byte
C3          RET             ; return to DOS 
```
Standalone PC DOS executable. Input is via command line, output is to console.
Most of the code length is handling the conversion of required hex string I/O into bytes, since DOS/x86 machine code has no built-ins for that.
**I/O:**
[![enter image description here](https://i.stack.imgur.com/XWrel.png)](https://i.stack.imgur.com/XWrel.png)
Download and test [HEXCLR.COM](https://stage.stonedrop.com/ppcg/HEXCLR.COM), or `xxd` hexdump:
```
0000000: be82 00ac b40e cd10 b311 b904 03ad b702  ................
0000010: 2c30 3c0a 7c02 2c07 86e0 fecf 75f2 d2e0  ,0<.|.,.....u...
0000020: 02c4 32e4 0508 00f6 f33c 0a7c 0204 0704  ..2......<.|....
0000030: 30b4 0ecd 10fe cd75 d4c3                 0......u..
```
[Answer]
# JavaScript (ES6), 55 bytes
```
s=>s.replace(/\w./g,x=>(('0x'+x)/17+.5|0).toString(16))
```
[Try it online!](https://tio.run/##bcy9DoIwGIXh3asgYWgbtf0A5WeARNv0BlxdCBaCIZRQogzee8WhDuLZTvLkvZeP0lRjO0z7Xt@UrXNr8sLQUQ1dWSnMrk/Kmt2cFxgjmNF2JixItvT4AkInfZnGtm9wEBNiK90b3Sna6QbXGPlSwjJEiMeY5y9n8ysAPsYJkGshsiDiBydEwFeCgxBR5sRZRCsRpidIYyfCLP3T4DKW3wZP7Bs "JavaScript (Node.js) – Try It Online")
[Answer]
# [Retina 0.8.2](https://github.com/m-ender/retina/wiki/The-Language/a950ad7d925ec9316e3e2fb2cf5d49fd15d23e3d), 88 bytes
```
(\w)(.)
$1,$2;
[A-F]
1$&
T`L`d
\d+
$*
+`1,
,16$*
,
8$*
(1{17})*1*;
$#1;
T`d`L`1\d
B\B|;
```
[Try it online!](https://tio.run/##FYuxDsIgGIT3ew2IKRQNf2uQhqmFMDm6iQkmOLg4GBMH9dmR3nD5vuTueXvdH9dau/QW3U6Ak@KDw3nexguIb3DKx1yQSg8u0WdSUGQaKtjWHX3o8BOSpANn5Nq8tAOlgiUtX4daWYy6BUzrlcDCRKPfg3kdwjiBDXbW1qzuo4l/ "Retina 0.8.2 – Try It Online") Link includes test cases. Explanation:
```
(\w)(.)
$1,$2;
```
Pair up the hex digits.
```
[A-F]
1$&
T`L`d
```
Convert each digit separately to decimal.
```
\d+
$*
```
Convert each decimal digit to unary.
```
+`1,
,16$*
```
Finish the hexadecimal conversion of the pair of digits.
```
,
8$*
(1{17})*1*;
$#1;
```
Add 8 and divide by 17.
```
T`d`L`1\d
B\B|;
```
Convert back to hexadecimal.
[Answer]
# [PHP](https://php.net/), ~~75~~ 67 bytes
```
#<?php for($m=3;$m;)echo dechex((hexdec($argn)>>--$m*8&255)/17+.5);
```
[Try it online!](https://tio.run/##K8go@P9f2ca@IKNAIS2/SEMl19bYWiXXWjM1OSNfIQVIplZoaAAJIFNDJbEoPU/Tzk5XVyVXy0LNyNRUU9/QXFvPVNMaaIiRhaOBhZnCv/yCksz8vOL/um4A "PHP – Try It Online") or [verify all test cases](https://tio.run/##Pc/NDoIwDADg@56igUU3/xggAplAdAsvoR4IglwQIh5MjM@OG4g7NOuXtmnbqu33SVu1COFn0T07iOCEYG6mKVNvvgKwLDBVopExzROydEAZ2q7YTihtoVEwKd1wwqN0NTrBgQW7CZ0w0JgzUe7Kf6Xw0YUjVDaPIssrAr@tsg5w9rjdgcIbARR51YywAgOiGAyOkrg3h1NANRNcRy7HNadD6VXF4kWICupLhk4ax@s1rhfBzPE8atn@cuNR3o@zjfNdjfz0Xw).
[Answer]
# [Python 3](https://docs.python.org/3/), ~~72~~ ~~70~~ 68 bytes
```
lambda x:'#'+''.join(f"{(int(x[i:i+2],16)+8)//17:X}"for i in(1,3,5))
```
[Try it online!](https://tio.run/##Rc/RboMgFAbge5/ixF4AkbWom1USLzaJz7Ck64WzsrG0aipLXAzP7kBnxg0nHz/kp//Rn10bzzJ/m6/V7f1SwcjRDgUI7b861WLpT1i1Go8nxVUQnWmYkCAlh0N45K/Gl90dFNhcSGP6RMhcV0MzQA6TB/6uLJldPnej3akzxpwuxso/E1kYF4@LibBYrWBCxNliLyJeLUqfWZosFmXplitkItdccXRmPM/Vck0oNGPf1Lq52I6LDHulm9uACfcAqlp/V1fbVmJ3Riz1d/db@2v0EKDTdjvP1@jZwOSShv8/PG2TofDRaZjWqPHJ/As "Python 3 – Try It Online")
This is a port of [Grzegorz Oledzkis](https://codegolf.stackexchange.com/users/1104/grzegorz-oledzki) original [answer](https://codegolf.stackexchange.com/a/187469/86751), which I helped him golfing down.
Two features of Python 3 help us save bytes:
* Floating point division by default
* Format string literals
*-2 bytes thanx to [Jonathan Allan](https://codegolf.stackexchange.com/users/53748/jonathan-allan)*
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~20~~ 19 bytes
```
ḊØHiⱮs2ḅ⁴+8:17ịØHṭḢ
```
[Try it online!](https://tio.run/##ATYAyf9qZWxsef//4biKw5hIaeKxrnMy4biF4oG0Kzg6MTfhu4vDmEjhua3huKL///8iI0MwQ0Y2RiI "Jelly – Try It Online")
[Answer]
# [C# (Visual C# Interactive Compiler)](http://www.mono-project.com/docs/about-mono/releases/5.0.0/#csc), 81 bytes
```
x=>"".Aggregate("#",(a,b)=>a+$"{(Convert.ToInt32(x[b]+""+x[b+1],16)+8)/17:X}")
```
[Try it online!](https://tio.run/##Sy7WTS7O/O9WmpdsU1xSlJmXrgOh7NJs/1fY2ikxMrMq6TmmpxelpieWpGooKSvpaCTqJGna2iVqqyhVazjn55WlFpXoheR75pUYG2lURCfFaispaQNpbcNYHUMzTW0LTX1Dc6uIWiXN/9Zc4UWZJak@mXmpGmlAw9LSDIBASVMTXSLJyDjNwAKLhJFFooGFGUjiPwA "C# (Visual C# Interactive Compiler) – Try It Online")
[Answer]
# [Wolfram Language (Mathematica)](https://www.wolfram.com/wolframscript/), ~~63~~ 48 bytes
```
"#"<>Round[15List@@RGBColor@#]~IntegerString~16&
```
[Try it online!](https://tio.run/##y00syUjNTSzJTE78n6Zg@19JWcnGLii/NC8l2tDUJ7O4xMEhyN3JOT8nv8hBObbOM68kNT21KLikKDMvvc7QTO1/AJBV4qCVpqDvoFCtpOzmZgAESjoKSsoGBiAOmOliaWjsbAJmOhu4uBhbgplGFo4GFmZQUWc3Mzel2v8A "Wolfram Language (Mathematica) – Try It Online")
-15 bytes thanks to [attinat](https://codegolf.stackexchange.com/users/81203/attinat)! Replacing `StringJoin` with `<>` and compressing the syntax.
1. `RGBColor@#` converts the input string to a color of the form `RGBColor[r, g, b]` with three floating-point arguments in the range 0..1.
2. `Round[15 List @@ %]` multiplies the list of three arguments by 15 and rounds them to the nearest integer. We now have a list of three integer values corresponding to the three desired hexadecimal digits.
3. `%~IntegerString~16` converts this list of three integers to a list of three hexadecimal strings of one character each.
4. `"#"<>%` prepends a `#` character and joins all these characters together.
[Answer]
# [MathGolf](https://github.com/maxbergmark/mathgolf/blob/master/math_golf.txt), ~~19~~ 12 [bytes](https://github.com/maxbergmark/mathgolf/blob/master/code_page.py)
```
╞2/¢8+F/¢'#▌
```
Output as character-list. If this is not allowed, an additional trailing `y` has to be added to join the character-list to a string.
-7 bytes thanks to *@maxb*, since I looked past a builtin (`2ô_2<\1>]` to `2/`).
[Try it online.](https://tio.run/##y00syUjPz0n7///R1HlG@ocWWWi7AUl15UfTev7/V1d2czMAAnUudWUDAxAbxHKxNDR2NgGxnA1cXIwtQSwjC0cDCzOImLObmZs6AA)
**Explanation:**
```
╞              # Remove the first character from the (implicit) input-string
 2/            # Split the string into parts of size 2
   ¢           # Convert each part from hexadecimal to integer
    8+         # Add 8 to each integer
      F/       # Integer-divide each integer by 17
        ¢      # Then convert back from integer to hexadecimal
         '#▌  '# Prepend '#' in front of the list
               # (which is output implicitly as result)
```
[Answer]
## Ruby (2.5.3), 45, 44, 42 bytes
```
->a{a.gsub(/\w./){|b|"%X"%((8+b.hex)/17)}}
```
EDIT: saved one byte because we don't need a character group for the second character in the regex (inspired by Neil's answer)
EDIT 2: saved 2 bytes because the dash rocket lambda syntax doesn't need brackets around the argument
[Answer]
## Python 2 (109 101 97 85 83 74 bytes)
```
lambda x:'#'+''.join(hex(int(int(x[i:i+2],16)/17.+.5))[2:]for i in[1,3,5])
```
The "nearest distance" is handled by division by 17 and rounding.
Improvements:
-8 bytes by using the `int(...+.5)` trick instead of `int(round(...))`
-4 bytes by using list comprehension instead of `map()`
-1 byte by hardcoding `#` in the output (thanks @movatica)
-10 bytes by not using `re.findall("..",...)` in favor of explicit String splicing
-2 bytes by not using list comprehension, but an inline generator expression in `join` (thanks @movatica)
-1 byte by not splicing the `:7` ending for blue part
-9 bytes by better iteration over colors - i.e. iterating over indices, not actual characters (thanks @movatica)
[Answer]
# [Perl 5](https://www.perl.org/) `-p`, ~~35~~ 34 bytes
*@nwellnhof saved a byte*
```
s|\w.|sprintf'%X',.5+(hex$&)/17|ge
```
[Try it online!](https://tio.run/##Lcq7DoIwAIXhnadoUhVvlAJyi5O26ebu4EK0KEmlDW0CA7MP4CP6IFYInunky694I2KrfYDWvr@HhRCy1eBWNfxqgOHaAFkC3hVPJbi2ur@0qNeqqWpTuvOzu0XxZvng3Wyx8oO0v3NrIWN4GPi83gAO14EYjzQBZgPQPIjIbgIaEAcSTGmUT3CkkQPD7ICzZIIwz8aCsIT9C5J@pTKVrLX1TjHCAbaeEj8 "Perl 5 – Try It Online")
Reads from STDIN, replaces each pair of items that is not `#` with the appropriate single character using the division by 17 method for finding the nearest, then implicitly outputs (`-p`) the result. 
[Answer]
# Python 3, 67 bytes
```
f=lambda x:(f(x[:-2])if x[3:]else"#")+f'{(int(x[-2:],16)+8)//17:X}'
```
[Answer]
# [Red](http://www.red-lang.org), 103 bytes
```
func[c][r: to 1 c to #1 rejoin reverse collect[loop 3[keep to-hex/size r % 256 + 8 / 17 1 r: r / 256]]]
```
[Try it online!](https://tio.run/##TYzBDoIwEETvfMUkxJMxtKAI3AykH@C16aksESWUFDTGn6/LRdzL7JuZjKc2XKnVJuoqhO45Wm2N9hUWBwm7Sizh6e76keVFfiZYNwxkFz04NyHTD6KJi4cbvZO5/xA8dkhPOfYokECeeYkXPf/sGmPC5PtxQYdYKcEX/ViI1dm4KWVWHzeuRdNk5cZpcRFF/p/XKlfhCw "Red – Try It Online")
It turned out that the current Linux version of [Red](http://www.red-lang.org) doesn't have an implementation of the `hex-to-rgb` function, that's why I make the base conversion "manually" :)
# This works fine in the [Red](http://www.red-lang.org) GUI console on Windows:
# [Red](http://www.red-lang.org), 94 bytes
```
f: func[c][r: hex-to-rgb c to #1 rejoin collect[repeat n 3[keep to-hex/size r/:n + 8 / 17 1]]]
```
[Answer]
# [Perl 6](https://github.com/nxadm/rakudo-pkg), 35 bytes
```
{S:g[\w.]=fmt :16(~$/)/17+.5: '%X'}
```
[Try it online!](https://tio.run/##K0gtyjH7n1upoJamYPu/OtgqPTqmXC/WNi23RMHK0EyjTkVfU9/QXFvP1EpBXTVCvfZ/cWKlQpqGSrymQlp@kYINl7KbmwEQcCkbGIBYXMoulobGziZcys4GLi7GllzKRhaOBhZmIL6zm5kbl91/AA "Perl 6 – Try It Online")
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 22 bytes
```
#Ｆ⪪⮌…⮌Ｓ⁶¦²⍘÷⁺⁸⍘ι¹⁶¦¹⁷φ
```
[Try it online!](https://tio.run/##TYyxCsMgFEX3foUky3tgwWRIhWxJl2yh@QKxthFERY3Qr7dNW0qXM9zDuXIVQTphSpmDtgmqusL@cHOBwOKNTnBRWYWoYHxIo8bV@d8yWb@lJb2yOyBS0u1oEcnnaRBRfe1k01lnfVUwmy0Cp@RPakqad9qcdjDGELEvpW65YLwrx2ye "Charcoal – Try It Online") Link is to verbose version of code. Explanation:
```
#                       Literal `#`
      Ｓ                 Input string
     ⮌                  Reversed
    …  ⁶                Truncated to length 6
   ⮌                    Reversed
  ⪪      ²              Split into pairs of characters
 Ｆ                      Loop over each pair
               ι        Current pair
              ⍘ ¹⁶      Convert from base 16
            ⁺⁸          Add 8
           ÷       ¹⁷   Integer divide by 17
          ⍘          φ  Convert to large base
                        Implicitly print
```
[Answer]
# [R](https://www.r-project.org/), 57 bytes
```
cat("#",sprintf("%x",(col2rgb(scan(,""))+8)%/%17),sep="")
```
[Try it online!](https://tio.run/##K/r/PzmxRENJWUmnuKAoM68kTUNJtUJJRyM5P8eoKD1Jozg5MU9DR0lJU1PbQlNVX9XQXFOnOLXAFijyX9nZwMnQxO0/AA "R – Try It Online")
[Answer]
# [Pyth](https://github.com/isaacg1/pyth), 20 bytes
```
+\#sm.H/+8id16 17c3t
```
[Try it here.](http://pythtemp.herokuapp.com/?code=%2B%5C%23sm.H%2F%2B8id16+17c3t&input=%27%23c0dd39%27&debug=0)
NOTE: In case the link above raises an `ImportError`, go [here](http://pythtemp.herokuapp.com/?code=%2B%5C%23sm.H%2F%2B8id16+17c3t&input=%27%23c0dd39%27&debug=0) instead; there is currently a bug in the "official" page, and this is a temporary solution by [Maltysen](https://codegolf.stackexchange.com/users/31343/maltysen). This link may stop working after the official one is fixed.
[Answer]
# [Forth (gforth)](http://www.complang.tuwien.ac.at/forth/gforth/Docs-html/), 87 bytes
```
: f d>s 1- hex ." #"3. do 2 + dup 2 s>number d>s 17 /mod swap 8 > - 1 .r loop decimal ;
```
[Try it online!](https://tio.run/##RY3RCoIwGIXve4rDuozZ1DBNGISy9zA3U9A2NqV6etsK6b85fJz/nNNpO/f03gVZ1ws6SO4QU/TqhYhgT9IIUiPBAXIxXh1/LNNN2d/jGcdJS7hnY5CDgyJGZDFqbSBVO0zNiNL3@mSIz2@jQi0oB/FjrUW5c35GCOaPwHyJscAb1UWcVqeNKlbXabFRkl9Znv29SmQi0PoB "Forth (gforth) – Try It Online")
### Explanation
1. Ignore/truncate first character of input (`#`)
2. Set interpreter to hexadecimal mode
3. Output `#`
4. Loop 3 times, in each loop:
	1. Add 2 to string starting address
	2. Convert next 2 characters in string to a hexadecimal number
	3. Use division and module by 17 (`0x11`) to get closest value for shortened component
	4. Output with no preceding space
5. Set interpreter back to Decimal mode
### Code Explanation
```
: f                    \ start a new word definition
  d>s                  \ convert double-length int to single-length (cheaper drop)
  1- hex               \ subtract 1 from string address, set current base to 10
  ." #"                \ output #
  3. do                \ start a loop from 0 to 2 (inclusive)
    2 + dup            \ add 2 to string starting address and duplicate
    2 s>number         \ parse the next 2 characters to a hexadecimal value
    d>s                \ convert result to single-length value
    17 / mod           \ get the quotient and remainder of dividing by 17
    swap               \ move the remainder to the top of the stack
    8 > -              \ if remainder is greater than 8, add 1 to quotient
    1 .r               \ output result (as hexadecimal) with no space
  loop                 \ end the loop
  decimal              \ set interpreter back to base 10 (decimal)
;                      \ end the word definition
```
[Answer]
# [Stax](https://github.com/tomtheisen/stax), 13 [bytes](https://github.com/tomtheisen/stax/blob/master/docs/packed.md#packed-stax)
```
Ç┤!usτ╓♪╩⌂^÷◙
```
[Run and debug it](https://staxlang.xyz/#p=80b4217573e7d60dca7f5ef60a&i=%23FF0000%0A%2300FF00%0A%23D913C4%0A%23C0DD39%0A%2328A086%0A%23C0CF6F&a=1&m=2)
[Answer]
# [K4](http://kx.com/download), 39 bytes
**Solution:**
```
"#",{x@_1%17%8+16/:x?y}[.Q.nA]@/:3 2#1_
```
**Explanation:**
Uses the same strategy as a lot of these answers (i.e. add 8, divide by 17):
```
"#",{x@_1%17%8+16/:x?y}[.Q.nA]@/:3 2#1_ / the solution
                                     1_ / drop first character
                                 3 2#   / reshape as 3x2 (e.g. "FF", "00", "00")
                              @/:       / apply each-right to left lambda
    {                 }[     ]          / lambda with first argument populated
                        .Q.nA           / "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                   x?y                  / get index of hex character, e.g. "AA" => 10 10
               16/:                     / convert from base-16
             8+                         / add 8
          17%                           / 17 divided by...
        1%                              / 1 divided by...
       _                                / floor
     x@                                 / index into .Q.nA to get hex character
"#",                                    / prepend "#"
```
**Extra:**
* `"#",{x@*16\:a?&/a:abs(17*!16)-16/:x?y}[.Q.nA]@/:3 2#1_` - my original idea for **54 bytes**
]