CSS Color Golf!

25

Você é desenvolvedor da Web e seu chefe decidiu atualizar o site da empresa. Ele decidiu que menos cor é melhor, mas ele quer que o site tenha a mesma aparência. Você decide justamente que ele não tem idéia do que está falando, mas vai tentar de qualquer maneira, porque está entediado. Como a empresa possui milhares de páginas da Web e cada uma possui seu próprio CSS, você decide escrever um script para fazer as alterações necessárias. Não é necessário analisar o HTML .

Atualmente, todas as páginas usam uma sequência como rgb(255,0,0)para uma cor. Dadas as três valores decimais que representam os valores RGB de um atributo de cor CSS (nessa ordem), retorno ou imprimir a representação de cadeia mais curta do que a cor, de tal forma que é utilizável para CSS assim: color:<your-result-here>;.

Aqui está uma tabela completa de palavras-chave CSS Color válidas . Eles não diferenciam maiúsculas de minúsculas.

Exemplos:

Observe que as cores podem ser definidas com 12 ou 24 bits. O padrão #ABCé uma versão mais curta do #AABBCC. Chuck Norris é uma cor .

Seu programa terá apenas 3 números inteiros, não uma string (com exceção do "bônus" mencionado posteriormente).

0, 0, 0         ->  #000        (same as #000000, but shorter)
255, 0, 0       ->  red
0, 128, 128     ->  TEAL
139, 0, 0       ->  DarkRed     (OR #8B0000)
72, 61, 139     ->  #483D8B
255, 255, 254   ->  #fffffe
255, 85, 255    ->  #f5f        (same as #ff55ff, but shorter)

Pontuação / Regras

  • O menor código vence!
  • As brechas padrão não são permitidas , com exceção dos embutidos.
  • -50% bytes (o bônus é arredondado para baixo) se você aceitar qualquer * seletor de cores válido e imprimir o menor. Então DarkSlateBlueseria saída #483D8B, #F00saídas red, etc.
    • * Isso inclui apenas RGB, códigos hexadecimais e nomes.
    • Observe que algumas cores têm nomes alternativos devido ao X11 (como Fuchsiae Magenta, ou Cyane Aqua). Os nomes alternativos estão incluídos na lista vinculada de palavras-chave de cores CSS, de acordo com o padrão W3.
  • CSS3 é Turing completo . Isso valeria uma recompensa.

Editar:

  • EXECUTE SEU CÓDIGO NOS CASOS DE TESTE!
mbomb007
fonte
Aqui está uma questão relacionada: codegolf.stackexchange.com/questions/13132/color-rgb-int-to-hex
mbomb007
Uma resposta que deseja obter o bônus de -50% precisa analisar o hsl (...) também? E quanto a rgba (...) e hsla (...)? :)
Timwi
De acordo com este link nas cores em CSS, o branco é # 000000. Como você inventou #000? E se menos de 6 dígitos são permitidos, por que não #0? w3schools.com/cssref/css_colors.asp , o CSS
DavidC
2
@DavidCarraher Consulte stackoverflow.com/q/8318911/791604 para obter uma explicação detalhada. Eu suspeitaria que muitas das respostas aqui não estão produzindo cores mínimas conforme a implementação flexível disponível nos navegadores (mas estão produzindo cores mínimas conforme as especificações fornecidas na pergunta aqui).
Daniel Wagner

Respostas:

5

Perl, 212 - 50% = 106 bytes

use aliased Graphics::ColorNames,G;sub c{tie%c,G,CSS;$_=pop;$c={reverse%c}->{$_=sprintf'%02x'x(@0=/(\d+, ?)((?1))(\d+)/)||$c{s/#(.)(.)(.)$|#/\1\1\2\2\3\3/r},@0};s/(.)\1(.)\2(.)\3|/#\1\2\3/;y///c>length$c&&$c||$_}

Com novas linhas adicionadas:

use aliased Graphics::ColorNames,G;
sub c{
  tie%c,G,CSS;$_=pop;
  $c={reverse%c}->{
    $_=sprintf'%02x'x(@0=/(\d+, ?)((?1))(\d+)/)||$c{s/#(.)(.)(.)$|#/\1\1\2\2\3\3/r},@0
  };
  s/(.)\1(.)\2(.)\3|/#\1\2\3/;
  y///c>length$c&&$c||$_
}

Casos de teste

use feature say;

say c '#f00';
say c '#FF0000';
say c '#112233';
say c '#f0ffff';
say c 'azure';
say c 'DARKSLATEBLUE';
say c 'rgb(255, 127, 80)';
say c 'rgb(255, 255, 254)';
say c 'rgb(255,228,196)';

Saída

red
red
#123
azure
azure
#483d8b
coral
#fffffe
bisque

Perl, sem bônus, 144 bytes

use aliased Graphics::ColorNames,G;sub c{tie%c,G,CSS;$c={reverse%c}->{$_=sprintf'%02x'x3,@_};s/(.)\1(.)\2(.)\3|/#\1\2\3/;y///c>length$c&&$c||$_}

Com novas linhas adicionadas:

use aliased Graphics::ColorNames,G;
sub c{
  tie%c,G,CSS;
  $c={reverse%c}->{
    $_=sprintf'%02x'x3,@_
  };
  s/(.)\1(.)\2(.)\3|/#\1\2\3/;
  y///c>length$c&&$c||$_
}

Graphics::ColorNames não é um módulo básico, mas existe desde 2001. Pode ser necessário instalá-lo via:

cpan install Graphics::ColorNames
cpan install Graphics::ColorNames::CSS

A representação hexadecimal é preferida se o nome da cor tiver o mesmo comprimento.


Casos de teste

use feature say;

say c 0, 0, 0;
say c 255, 0, 0;
say c 0, 128, 128;
say c 139, 0, 0;
say c 72, 61, 139;
say c 255, 255, 254;
say c 255, 85, 255;

Saída

#000
red
teal
#8b0000
#483d8b
#fffffe
#f5f
primo
fonte
Alguma chance de você cortar 4 bytes para o empate?
mbomb007
@ mbomb007 6 bytes, de fato.
Primo
Ouço mais 4? Esta competição é dura.
mbomb007
1
@ mbomb007 raise.
Primo
10

C # 6277 bytes / 2 bônus = 264

EDIT: Woot! Finalmente recebi a resposta bônus com uma pontuação mais baixa que a resposta básica!

Eu escrevi apenas uma função. Requer uma usingdeclaração (incluída).

O C # possui uma boa lista de cores conhecidas para trabalhar, mas insiste em incluir o canal Alpha. As cores conhecidas também incluem todas as cores do sistema, duas das quais com nomes com menos de 7 caracteres, portanto, elas precisam ser removidas.

Aqui está a solução bônus, suportando formatos como:

  • 12, 34, 56
  • #123
  • #123456
  • DarkSlateBlue

Completamente jogado:

using System.Drawing;int H(string s,int i,int l)=>Convert.ToInt32(s.Substring(i*l+1,l),16)*(l<2?17:1);string D(string a){int i=17,j=a.Length/3,n;var d=a.Split(',');Color k,c=a[0]<36?Color.FromArgb(H(a,0,j),H(a,1,j),H(a,2,j)):Color.FromName(a);c=c.A>0?c:Color.FromArgb(int.Parse(d[0]),int.Parse(d[1]),int.Parse(d[2]));j=c.R%i+c.G%i+c.B%i<1?3:6;n=c.ToArgb();a="#"+(j<6?c.R/i<<8|c.G/i<<4|c.B/i:n&0xffffff).ToString("x"+j);for(i=26;i++<167;k=Color.FromKnownColor((KnownColor)i),a=n==k.ToArgb()&k.Name.Length<=j?k.Name:a);return a;}

Recuo e novas linhas para maior clareza:

using System.Drawing;
int H(string s,int i,int l)=>Convert.ToInt32(s.Substring(i*l+1,l),16)*(l<2?17:1);
string C(string a){
    int i=17,j=a.Length/3,n;
    var d=a.Split(',');
    Color k,c=a[0]<36
        ?Color.FromArgb(H(a,0,j),H(a,1,j),H(a,2,j))
        :Color.FromName(a);
    c=c.A>0?c:Color.FromArgb(int.Parse(d[0]),int.Parse(d[1]),int.Parse(d[2]));
    j=c.R%i+c.G%i+c.B%i<1?3:6;
    n=c.ToArgb();
    a="#"+(j<6?c.R/i<<8|c.G/i<<4|c.B/i:n&0xffffff).ToString("x"+j);
    for(i=26;i++<167;
        k=Color.FromKnownColor((KnownColor)i),
        a=n==k.ToArgb()&k.Name.Length<=j?k.Name:a
    );
    return a;
}

C #, 265 bytes

Aqui está a solução básica.

using System.Drawing;string C(int r,int g,int b){int i=17,c=r<<16|g<<8|b,j=r%i+g%i+b%i<1?3:6;var o="#"+(j<6?r/i<<8|g/i<<4|b/i:c).ToString("x"+j);for(i=26;i++<167;){var k=Color.FromKnownColor((KnownColor)i);o=c<<8==k.ToArgb()<<8&k.Name.Length<=j?k.Name:o;}return o;}

Recuo e novas linhas para maior clareza:

using System.Drawing;

string C(int r,int g,int b){
    int i=17,
        c=r<<16|g<<8|b,
        j=r%i+g%i+b%i<1?3:6;
    var o="#"+(j<6?r/i<<8|g/i<<4|b/i:c).ToString("x"+j);
    for(i=26;i++<167;){
        var k=Color.FromKnownColor((KnownColor)i);
        o=c<<8==k.ToArgb()<<8&k.Name.Length<=j?k.Name:o;
    }
    return o;
}
Mão-E-Comida
fonte
@ mbomb007: O código funciona para mim.
raznagul 6/10
8

Mathematica 207 242 500-250 = 250 bytes

Atualização:
funciona com entradas que consistem em triplos rgb, nomes de cores ou números hexadecimais.

A saída com profundidade de cor (12 bits) agora funciona bem, graças a um excelente artigo sobre Redução de profundidade de bit de cor . A idéia básica é que, se um RGB triplo {r, g, b}, em que r, g e b estiverem no intervalo de 0 a 255, (por exemplo, hex 00-ff), possa ser representado sem perda como um número em o intervalo de 0 a 15 (ou seja, 0-f), pode-se usar o número hexadecimal de 3 dígitos em vez do número de 6 dígitos. Acontece que isso ocorrerá sempre que 17 (ie 255/15) divide r, g e b.

Somente funções internas são usadas. O Mathematica possui regras para substituir nomes de cores HTML por triplos RGB. Por exemplo, uma regra é "Teal"-> RGBColor[0, 128, 128]. Quando essas regras são invertidas, os valores rgb (recalibrados para o intervalo, {0, 255}) podem ser substituídos por nomes de cores.

q=ColorData["HTML","ColorRules"];
j=q/.{(c_ -> RGBColor[r_,g_,b_]):> (Floor[255{r,g,b}]-> c)};
k=Reverse/@j;
v@l_:=And@@IntegerQ/@(l/17);
y@l_:=If[v@l,l/17,l];
h@l_:="#"<>(IntegerString[#,16,If[v@l,1,2]]&/@y@l)
o@h_:=Module[{c=(StringLength[h1=StringDrop[h,1]]==6)},FromDigits[#,16]&/@StringPartition[h1,If[c,2,1]]*If[c,1,17]]
u@l_:=ToString[l/.j]
m@s_:=s/.q/.RGBColor[r_,g_,b_]:>Floor[255{r,g,b}]
f@n_:=SortBy[{u@n,h@n},StringLength][[1]]
z@d_:= (If[StringQ@d,If[StringTake[d,1]=="#",e=o@d,e=m@d],e=d];f@e)

Exemplos

z /@ {{0, 0, 0}, {255, 0, 0}, {0, 128, 128}, {139, 0, 0}, {255, 255, 
   255}, {72, 61, 139}, {255, 255, 254}, {255, 85, 255}}

{"# 000", "Vermelho", "Cerceta", "# 8b0000", "#fff", "# 483d8b", "#fffffe", "# f5f"}


z /@ {"Red", "DarkSlateBlue", "Teal", "Black"}

{"Vermelho", "# 483c8b", "Verde-azulado", "# 000"}


z /@ {"#000", "#f00", "#008080", "#8b0000", "#fff", "#483d8b", "#fffffe", "#f5f"}

{"# 000", "Vermelho", "Cerceta", "# 8b0000", "#fff", "# 483d8b", "#fffffe", \ "# f5f"}


Código não comentado e comentado

(* regras para substituir um nome de cor por uma amostra de cor, por exemplo, RGBColor{255,17,0}

q=ColorData["HTML","ColorRules"];

(* regras para substituir uma lista de 3 números inteiros pelo respectivo nome de cor, se houver um. E as mesmas regras, invertidas. *)

rulesListsToColorNames=(q)/.{(c_ -> RGBColor[r_,g_,b_]):> (Floor[255{r,g,b}]-> c)};

rulesColorsToLists=Reverse/@rulesListsToColorNames;

(* testa se uma cor hexadecimal de 24 bits pode ser representada como uma cor de 12 bits sem perda. reducepode alterar a expressão de 24 bits para uma expressão de 12 bits. *)

depthReducible[l_List]:=And@@IntegerQ/@(l/17);
reduce[l_List]:=If[depthReducible@l,l/17,l];

(* A lista RGB foi alterada para um número hexadecimal *)

fromListToHex[l_List]:="#"<>(IntegerString[#,16,If[depthReducible@l,1,2]]&/@reduce[l])

(* Número hexadecimal alterado para lista RGB. *)

fromHexToList[h_String]:=Module[{c=(StringLength[h1=StringDrop[h,1]]==6)},
FromDigits[#,16]&/@StringPartition[h1,If[c,2,1]]*If[c,1,17]
]

(* Mais conversões *)

fromListToColorName[l_List]:=ToString[l/.rulesListsToColorNames]
fromColorNameToHex[s_String]:=fromListToHex[s/.rulesColorsToLists]
fromColorNameToList[s_String]:=s/.q/.RGBColor[r_,g_,b_]:>Floor[255{r,g,b}]

(* escolhe a menor expressão CSS válida de uma cor *)

f@n_List:=SortBy[{fromListToColorName[n],fromListToHex[n]},StringLength][[1]]

(* converte qualquer entrada em uma lista RGB e chama f *)

returnShortestColor[d_]:= 
 (If[StringQ[d],
   If[StringTake[d,1]=="#",
     e=fromHexToList@d,
     e=fromColorNameToList@d],
   e=d];
f@e)
DavidC
fonte
255 na base 10 não é igual FFna Base 16? Então isso deve fazer #FFFFFF, que é mais longo que o branco. Estou achando #000incomum, mas analisarei as peculiaridades do CSS para ter certeza.
DavidC
3
@DavidCarraher: as cores CSS podem ser especificadas como 24 bits ou 12 bits. #FFFé igual a #FFFFFF(todos os bits um) que é igual a white. Além disso, #0é inválido porque não é nem 24 bits nem 12 bits
slebetman
slebetman, Obrigado pelo esclarecimento, que confirma a observação de @ mbomb007.
21415
5

CoffeeScript, 411 404 388 384 382/2 = 191

UPD: Certeza de que é o resultado final

Espero que esteja tudo bem de usar window.document.*. Verifique a rgbfunção e evalligue.

s=(c,rgb=(r,g,b)->(2**24+(r<<16)+(g<<8)+b).toString 16)->d=y=document.body;r=(q=(a)->y.style.color=a;d[b='#'+eval(getComputedStyle(y).color)[1...].replace /(.)\1(.)\2(.)\3/,'$1$2$3']=a;b) c;(d='NavyGreenTealIndigoMaroonPurpleOliveGraySiennaBrownSilverPeruTanOrchidPlumVioletKhakiAzureWheatBeigeSalmonLinenTomatoCoralOrangePinkGoldBisqueSnowIvoryRed'.match /.[a-z]+/g).map(q);d[r]||r

Resultado dos testes

rgb(   0,   0,   0 ) -> #000
rgb( 255,   0,   0 ) -> Red
rgb(   0, 128, 128 ) -> Teal
rgb( 139,   0,   0 ) -> #8b0000
rgb(  72,  61, 139 ) -> #483d8b
rgb( 255, 255, 254 ) -> #fffffe
rgb( 255,  85, 255 ) -> #f5f
darkslateblue        -> #483d8b
indigo               -> Indigo
#f00                 -> Red

Código comentado

s = ( c,
    rgb = ( r, g, b ) ->
        return ( 2 ** 24 + ( r << 16 ) + ( g << 8 ) + b )
        .toString( 16 )
) ->

Isso economizará alguns bytes.

    d = y = document.body

qA função colocará a cor de entrada document.body.style.colore será compilada como rgb(...). Também armazenará o resultado como hexColor:inputColorem d. Observe o evaluso. rgb(100,100,100)é uma chamada de função JavaScript válida com três argumentos numéricos. rgbA função converterá argumentos em uma notação HEX 24/12 única (como #fff, #f0f0f0).

    r = (
        q = ( a ) ->
            y.style.color = a
            b = '#' + eval( getComputedStyle( y ).color )[ 1... ].replace( /(.)\1(.)\2(.)\3/, '$1$2$3' )
            d[ b ] = a
            return b
    )( c )

Divida a string em uma matriz de nomes de cores, crie um objeto de pesquisa.

    ( d = 'NavyGreenTeal...'.match( /.[a-z]+/g )).map( q )

E retorne HEX se não houver uma variante mais curta d.

    return d[ r ] or r
argh-argh
fonte
4

Caneta, 238 234/2 = 117

Mais solução semelhante a CSS! A caneta já possui um ótimo suporte para manipulação de cores, portanto, a função desejada é muito pequena e não é muito praticada.

f(c){for n in split(' ''navy green teal indigo maroon purple olive gray sienna brown silver peru tan orchid plum violet khaki azure wheat beige salmon linen tomato coral orange pink gold bisque snow ivory red'){lookup(n)==c?c=s(n):c}}

Teste aqui

body
  color f(rgb(0, 0, 0))
  color f(rgb(255, 0, 0))
  color f(rgb(0, 128, 128))
  color f(rgb(139, 0, 0))
  color f(rgb(72, 61, 139))
  color f(rgb(255, 255, 254))
  color f(rgb(255, 85, 255))
  color f(darkslateblue)
  color f(indigo)
  color f(#f00)
  color f(rgba(255,0,0,1))
  color f(rgba(255,0,0,0.5))
argh-argh
fonte
Bem-vindo ao PPCG! Essa é uma solução muito boa!
mbomb007
não jogou muito . É melhor tentar jogar um pouco mais se quiser ganhar. Alguém está batendo em você por um.
mbomb007
@ mbomb007, tudo bem, jogou um pouco de golfe.
Argh-argh
Parece que você foi espancado. Talvez você possa tentar juntar as cores sem espaços, mas preenchidas com cinco caracteres, depois dividir a cada cinco e aparar? Não tem certeza se isso salvaria bytes?
mbomb007
3

Matlab 617

Muito pré-processamento e codificação. O conjunto mínimo de nomes de cores que você deve considerar são esses. Pena que o Matlab não possui nomes de cores integrados = /

function s=f(r,g,b);
t=255;
c=[r,g,b];
a=[0 t t;240 t t;245 245 220;t 228 196;0 0 t;165 42 42;t 127 80;0 t t;t 215 0;75 0 130;t t 240;240 230 140;0 t 0;250 240 230;t 165 0;218 112 214;205 133 63;t 192 203;221 160 221;t 0 0;250 128 114;160 82 45;t 250 250;210 180 140;t 99 71;238 130 238;245 222 179;t t t;t t 0];
s=textscan('aqua azure beige bisque blue brown coral cyan gold indigo ivory khaki lime linen orange orchid peru pink plum red salmon sienna snow tan tomato violet wheat white yellow','%s');
i=find(ismember(a,c,'rows'));
k=1;
if i>0;s=s{1}{i};elseif ~any(mod(c,16));k=16;end;d=dec2hex(c/k,2-(k>1))';s=['#',d(:)']
flawr
fonte
Você deixou o código codificado r=0;g=16;b=0;lá, embora não seja contado na sua pontuação.
Hand-E-Food
Oh, colei a versão errada, obrigado por me informar!
flawr
2

Python 3, 857 795 bytes

A necessidade de especificar manualmente todas as cores aceitas necessárias aumentou a contagem de bytes neste: /

c(a)leva um argumento,, aque vem na forma de rgb(#,#,#). A partir disso, o rgb e os colchetes são removidos e a sequência é dividida por vírgulas em uma matriz. c(x,y,z)leva 3 ints, os valores r, g e b da cor rgb para processar. Reunimos essas informações em uma matriz a. Em seguida, usamos a função interna do Python, hexque converte um número da Base 10 em um número da Base 16 em nossa matriz e criamos uma string hexadecimal (isso é feito no forloop). As ifinstruções convertem cores como 000000para 000e substituem as cores conhecidas usando um dicionário.

Aqui está (obrigado a @undergroundmonorail pela dica sobre ;Python):

def c(x,y,z):
  a=[x,y,z];b="";
  for i in a:
    i=hex(i)[2:]
    if len(i)<2:i="0"+i;
    b+=i
  k={"00ffff":"AQUA","f0ffff":"AZURE","f5f5dc":"BEIGE","ffe4c4":"BISQUE","0000ff":"BLUE","a52a2a":"BROWN","ff7f50":"CORAL","ffd700":"GOLD","808080":"GRAY","008000":"GREEN","4b0082":"INDIGO","fffff0":"IVORY","f0e68c":"KHAKI","00ff00":"LIME","faf0e6":"LINEN","800000":"MAROON","000080":"NAVY","808000":"OLIVE","ffa500":"ORANGE","da70d6":"ORCHID","cd853f":"PERU","ffc0cb":"PINK","dda0dd":"PLUM","800080":"PURPLE","ff0000":"RED","fa8072":"SALMON","a0522d":"SIENNA","c0c0c0":"SILVER","fffafa":"SNOW","d2b48c":"TAN","008080":"TEAL","ff6347":"TOMATO","ee82ee":"VIOLET","f5deb3":"WHEAT","ffff00":"YELLOW"}
  if b[:3]==b[3:]:b=b[:3];
  if b in k:b=k[b];
  else:b="#"+b;
  return b

Versão antiga:

def c(a):
  a=a[4:-1].split(",")
  b=""
  for i in a:
    i=hex(int(i))[2:]
    if len(i)<2:
      i="0"+i
    b+=i
  k = {"00ffff":"AQUA","f0ffff":"AZURE","f5f5dc":"BEIGE","ffe4c4":"BISQUE","0000ff":"BLUE","a52a2a":"BROWN","ff7f50":"CORAL","ffd700":"GOLD","808080":"GRAY","008000":"GREEN","4b0082":"INDIGO","fffff0":"IVORY","f0e68c":"KHAKI","00ff00":"LIME","faf0e6":"LINEN","800000":"MAROON","000080":"NAVY","808000":"OLIVE","ffa500":"ORANGE","da70d6":"ORCHID","cd853f":"PERU","ffc0cb":"PINK","dda0dd":"PLUM","800080":"PURPLE","ff0000":"RED","fa8072":"SALMON","a0522d":"SIENNA","c0c0c0":"SILVER","fffafa":"SNOW","d2b48c":"TAN","008080":"TEAL","ff6347":"TOMATO","ee82ee":"VIOLET","f5deb3":"WHEAT","ffff00":"YELLOW"}
  if b[:3]==b[3:]:
    b=b[:3]
  if b in k:
    b=k[b]
  else:
    b="#"+b
  return "color:"+b+";"

Talvez eu adicione o bônus, ainda não sei. Definitivamente poderia fazer com 50% de bytes de desconto!

-Toastrackenigma

Toastrackenigma
fonte
2
dicas gerais sobre golfe em python: muitas de suas novas linhas podem ser substituídas ;, salvando o recuo. por exemplo: a=a[4:-1].split(",");b="". qualquer if, else, for, whilebloco, etc com apenas uma linha pode ser escrita como if b in k:b=k[b].Finalmente, você pode perder muito do seu espaço em branco no meio de linhas, por exemplo k = {-> k={e return "color:->return"color:
undergroundmonorail
também, bem-vindo ao PPCG :)
undergroundmonorail
2
Esse literal k é enorme. Como todos os códigos de cores estão em letras minúsculas e todos os nomes de cores estão em maiúsculas, você pode escrevê-lo como uma única sequência e analisá-lo com re.findall()(também será necessário import re): pastebin.com/rQHqgxXS
manatwork
@undergroundmonorail Obrigado por isso, deve economizar muito espaço: D
Toastrackenigma 8/15
@ mbomb007 OK, eu não tinha muita certeza de como você queria a saída ou a entrada - fiquei um pouco confuso: o PI executou o código nos casos de teste para garantir que funcione corretamente. Deseja que eu envie meus resultados?
Toastrackenigma
1

JavaScript (ES6), 499611

Editar Adicionados os casos de teste na pergunta

Nota: Eu mantive apenas os nomes de cores menores que o equivalente hexadecimal.

Nota 2: isso certamente pode ser jogado mais ...

f=(r,g,b,k='#'+(r%17|g%17|b%17?1<<24|r<<16|g<<8|b:4096|(r*256+g*16+b)/17).toString(16).slice(1))=>
("#d2b48cTAN#f00RED#ff7f50CORAL#f5deb3WHEAT#ff6347TOMATO#ffd700GOLD#008000GREEN#faf0e6LINEN#f5f5dcBEIGE#da70d6ORCHID#4b0082INDIGO#ffc0cbPINK#f0e68cKHAKI#008080TEAL#ee82eeVIOLET#dda0ddPLUM#fa8072SALMON#ffa500ORANGE#a0522dSIENNA#800000MAROON#800080PURPLE#ffe4c4BISQUE#f0ffffAZURE#fffff0IVORY#cd853fPERU#808000OLIVE#c0c0c0SILVER#fffafaSNOW#a52a2aBROWN#000080NAVY#808080GRAY"
.match(k+'([A-Z]+)')||[,k])[1]

// TEST
;[[0,0,0,'#000'],[255,0,0,'red'],[0,128,128,'TEAL'],[139,0,0,'#8B0000'],[72,61,139,'#483D8B'],[255,255,254,'#fffffe'],[255,85,255,'#f5f']]
.forEach(([r,g,b,t])=>(x=f(r,g,b),o+=r+','+g+','+b+' -> '+x+' '+(x.toUpperCase()==t.toUpperCase()?'ok':'error('+t+')')+'\n'),o='')
O.innerHTML=o

function go()
{
  var r,g,b
  [r,g,b] = I.value.match(/\d+/g)
  O.innerHTML=r+','+g+','+b+' -> '+f(r,g,b)+'\n'+O.innerHTML
}
R,G,B: <input id=I><button onclick="go()">--></button>
<pre id=O></pre>

Menos golfe

f=(r,g,b) => (
   k='#'+(
     r%17|g%17|b%17
     ? 1<<24|r<<16|g<<8|b
     : 4096|r/17<<8|g/17<<4|b/17
    ).toString(16).slice(1),
   s = "#d2b48cTAN#f00RED#ff7f50CORAL#f5deb3WHEAT#ff6347TOMATO#ffd700GOLD#008000GREEN#faf0e6LINEN#f5f5dcBEIGE#da70d6ORCHID#4b0082INDIGO#ffc0cbPINK#f0e68cKHAKI#008080TEAL#ee82eeVIOLET#dda0ddPLUM#fa8072SALMON#ffa500ORANGE#a0522dSIENNA#800000MAROON#800080PURPLE#ffe4c4BISQUE#f0ffffAZURE#fffff0IVORY#cd853fPERU#808000OLIVE#c0c0c0SILVER#fffafaSNOW#a52a2aBROWN#000080NAVY#808080GRAY",
   m = s.match(k+'([A-Z]+)'), // names are upper, hex codes are lower
   (m || [,k])[1] // if no match use the code
)
edc65
fonte
Esses sublinhados ... Segundo minha contagem, seriam mais curtos sem eles. Apenas citar os códigos que começam com um dígito e manter os outros sem aspas: {f00:"red";"008000":"green"}.
manatwork
@manatwork bom truque. Mas um objeto literal raramente é uma boa opção para o código de golfe. Uma seqüência simples é melhor
edc65
Corrigir. Eu já fiz um comentário nesse sentido ao nosso novo companheiro de site.
manatwork
1
@ mbomb007 Casos de teste adicionados. O snippet não funcionará no Chrome, sendo o EcmaScript 6, e o Chrome não é totalmente compatível (bastante cansado de repetir isso de novo e de novo). Teste no Firefox.
Edc65 # 6/15