Odcień koloru


23

Otrzymujesz wartości RGB koloru. Twoje zadanie jest proste: obliczyć odcień w najprostszej definicji.

Powiedz, że kanały o najwyższej, środkowej i najniższej wartości to X, Y, Z (które są albo czerwone, zielone lub niebieskie), a ich wartości to x, y, z. Odcień tego koloru to (h (X) -h (Y)) * (1 + (xy) / (xz)) / 2 + h (Y), gdzie:

h(red) = 0 (or 360 if one of X or Y is blue)
h(green) = 120
h(blue) = 240

Dane wejściowe składają się z 3 liczb całkowitych od 0 do 255, które nie wszystkie są równe, w dowolnej spójnej kolejności. Wyjściem mogą być zmiennoprzecinkowe lub liczby całkowite zaokrąglone w górę lub w dół, co nie musi być spójne. Jeśli całkowita liczba wyjściowa wynosi 0 lub 360, możesz wydrukować jedną z nich.

Nie można wywoływać wbudowanych funkcji konwersji przestrzeni kolorów, w tym konwersji niejawnych, na przykład podczas manipulacji obrazem.

To jest golf golfowy. Najkrótszy kod wygrywa.

Przykłady

Input:  0 182 255
Output: 197 (or 198)

Input:  127 247 103
Output: 110

Input:  0 0 1
Output: 240

Input:  255 165 245
Output: 307 (or 306)

Edytować

Nie musisz stosować się do dokładnej formuły, a jedynie dać taki sam wynik jak powyższa formuła. Chciałbym również zobaczyć niektóre odpowiedzi dotyczące samej formuły.


Czy najpierw powinniśmy przekonwertować z sRGB na skalę liniową? Myślę, że powinniśmy, ale wydaje się, że nikt dotąd nie miał.
— John Dvorak,

@JanDvorak Zadaniem jest obliczenie odcienia w najprostszej definicji . W tym przypadku „najprostszy” oznacza, że ​​powinieneś założyć, że dane wejściowe są już w odpowiedniej skali i użyć dokładnej formuły podanej w pytaniu lub czegokolwiek, co daje ten sam wynik.
— jimmy23013,

Ale ... 24 pb zwykle oznacza sRGB. Jeśli nie, specyfikacja formatu (ty) powinna określać inaczej.
— John Dvorak,

@JanDvorak Tej definicji należy użyć dla RGB i odcienia.
— jimmy23013,

9
Trzeba powiedzieć: huehuehue.
— TheDoctor,

Odpowiedzi:


6

Pyth, 27 bajtów

*60%+c-Ft.<QJxQKeSQ-KhSQyJ6

Demonstracja. Uprząż testowa.

Fomula pochodzi z Wikipedii .

Zasadniczo kroki są następujące:

  1. .<QJxQKeSQ: Roate największa wartość na początku listy.
  2. -Ft: Weź różnicę z pozostałych dwóch wartości.
  3. -KhSQ: Odejmij wartość minimalną od wartości maksymalnej.
  4. c: Podziel 2 przez 3.
  5. + ... yJ Dodaj dwukrotnie indeks maksymalnej wartości z listy (0, jeśli R, 2, jeśli G, 4, jeśli B).
  6. % ... 6: Mod 6, aby naprawić problemy z negatywami.
  7. *60: Pomnóż przez 60, aby przeliczyć na stopnie i wydrukować.

9

C #, 188 210 206 197 191 bajtów

int H(int r,int g,int b){int[]a={r,g,b};System.Array.Sort(a);int x=a[2],y=a[1],c=x==g?1:(x==b?2:(y==b?3:0)),d=y==g?1:(y==b?2:(x==b?3:0));return(int)((c-d)*120*(1+(x-y)*1D/(x-a[0]))/2+d*120);}

Dzięki Sok za uratowanie 4 bajtów i SLuck49 za uratowanie 15!


Ponieważ używasz tylko zraz w obliczeniach wyjściowych i nie używasz go w poprzednich obliczeniach, usuwasz zmienną i zmieniasz dane wyjściowe na return(int)((c-d)*(1+(x-y)/(double)(x-a[0]))/2+d);, oszczędzając ci 4 bajty.
— Sok

Można współczynnik 120 OUT ci dzadań oraz do zwrotu jak ta c=x==g?1:(x==b?2:(y==b?3:0)),d=y==g?1:(y==b?2:(x==b?3:0)), a następnie return(int)((c-d)*120*(1+(x-y)/(double)(x-a[0]))/2+d*120);zapisać 4 bajty.
— SLuck49,

Czy naprawdę potrzebujesz obsady double? Jeśli tak, możesz użyć tego zamiast tego, (x-a[0])*1Daby zapisać kolejne 5 bajtów.
— SLuck49,

@ SLuck49 Dzięki! Tak, naprawdę potrzebuję obsady, w przeciwnym razie daje niedokładne wyniki, ale to *1Dpomnożenie jest fajną sztuczką!
— ProgramFOX,

Również (właśnie zauważyłem) możesz porzucić używanie wszystkich razem, w pełni kwalifikując się System.Arrayna kolejne 6 bajtów.
— SLuck49,

8

Pyth 41 55 53 51 bajtów

A.)JohN,VQ*L120?qeQhSQ3j312T+/*-HKeeJhc-GheJ-GhhJ2K

Dane wejściowe są oczekiwane w formularzu r,g,b. Oto wyjaśnienie:

                                                        Implicit: Q=eval(input()), evaluates to (r,g,b)
               ?qeQhSQ                                  Is b the smallest?
                      3j312T                            Choose [0,1,2] or [3,1,2] based on above
          *L120                                         Convert to [0,120,240] or [360,120,240]
       ,VQ                                              Pair -> [[r,0/360],[g,120],[b,240]]
   JohN                                                 Order by 1st element in each pair, store in J
A.)J                                                    Pop biggest from J, set G = x, H = h(X)
                                                        Output calculation:
                                       -GheJ                x - y
                                            -GhhJ           x - z
                                     hc                     Divide and increment
                                 KeeJ                       Set K = h(Y)
                              *-HK                          Multiply by (h(X) - h(Y))
                             /                   2          Integer division by 2
                            +                     K         Add h(Y)

Zaoszczędź 4 bajty dzięki @Jakube i @isaacg


@ jimmy23013 Naprawiono, dziękuję za dodatkowy przypadek testowy
— Sok

1
Kilka golfów: m*120d-> *L120, zapisz eeJdo Kinline, aby zapisać kolejny bajt.
— isaacg,

@isaacg Nie wiedziałem, że Loperator automatycznie wygenerował zakres na int, każdy dzień wydaje się świstym dniem: o) Dzięki!
— Sok

8

JavaScript (ES6), 145 115 108 100 97 90 bajtów

Zwraca liczbę zmiennoprzecinkową. Przypisz do funkcji, której chcesz użyć.

(r,g,b)=>([x,y,z]=[r,g,b].sort((a,b)=>b-a),m=x-z,(x-r?x-g?r-g+4*m:b-r+2*m:g-b+6*m)/m%6*60)

Zaoszczędzono 30 bajtów, umieszczając wszystko w jednej sekwencji operatora trójskładnikowego i czekając do końca na normalizację do 0-360.

Dzięki edc65, Vasu Adari i produktom ETH dla oszczędności jeszcze większej liczby bajtów.

JSFiddle z testami. Wypróbuj w przeglądarce Firefox.

Jeśli usunięcie deklaracji funkcji h=jest niezgodne z prawem, dodaj 2 bajty.


Możesz usunąć „var” i niektóre bajty.
— Vasu Adari,

ES6Fiddle z jakiegoś powodu potrzebuje deklaracji var i nie zdawałem sobie sprawy, że nie było to konieczne, dopóki nie wypróbowałem ES6 w
— firefoxie

1
Możesz zapisać 6 bajtów, zastępując nawiasy klamrowe nawiasami, średnik przecinkiem i usuwając return. h=
— Wydaje

Może to być obsesyjne (z drugiej strony, czyż nie wszyscy są dobrymi golfistami?;)), Ale można zaoszczędzić jeszcze dwa bajty, pozbywając się nawiasu %6)*60i partnera po drugiej stronie. Ponadto użycie brutalnej siły przy dodawaniu (zamiast dodawania 6 na końcu) pozwoliłoby zaoszczędzić jeden bajt w stosunku do bieżącej konfiguracji. (((x==r?(g-b)/m:x==g?2+(b-r)/m:4+(r-g)/m)+6)%6)*60stałby się (x==r?6+(g-b)/m:x==g?8+(b-r)/m:10+(r-g)/m)%6*60.
— ETHprodukcje

1
+1 za sortowanie, bardzo sprytne, To jest 90 (lub 92)(r,g,b)=>([m,_,M]=[r,g,b].sort((a,b)=>a-b),C=M-m,(M-r?M-g?r-g+4*C:b-r+2*C:g-b+6*C)/C%6*60)
— edc65

6

Oktawa, 65 60 50 bajtów

Edycja: Zapisane 10 bajtów dzięki pawel.boczarski

Przybliżone rozwiązanie ...

@(c)mod(atan2d(.866*c*[0;1;-1],c*[2;-1;-1]/2),360)

Testowe uruchomienie

@(c)mod(atan2d(.866*c*[0;1;-1],c*[2;-1;-1]/2),360)
ans([0   182   255])
ans =  196.14

@(c)mod(atan2d(.866*c*[0;1;-1],c*[2;-1;-1]/2),360)
ans([127   247   103])
ans =  111.05

@(c)mod(atan2d(.866*c*[0;1;-1],c*[2;-1;-1]/2),360)
ans([0   0   1])
ans =  240.00

@(c)mod(atan2d(.866*c*[0;1;-1],c*[2;-1;-1]/2),360)
ans([255   165   245])
ans =  305.82

Oktawa, 107 bajtów

Moje oryginalne (dokładnie takie) rozwiązanie ...

Kod:

function H=r(c) [b,i]=sort(c);h=60*[6*(i(1)~=3),2,4](i);H=(h(3)-h(2))*(1+(b(3)-b(2))/(b(3)-b(1)))/2+h(2);

Wyjaśnił:

function H=r(c)
   [b,i]=sort(c);
   h=60*[6*(i(1)~=3),2,4](i);
   H=(h(3)-h(2))*(1+(b(3)-b(2))/(b(3)-b(1)))/2+h(2);

Ta funkcja przyjmuje na wejściu wektor zawierający wartości R, G, B ci sortuje dane wejściowe w porządku rosnącym

  • b zawiera posortowane wartości [z, y, x]
  • i zawiera płaszczyznę RGB związaną z każdą wartością w b

Wektor hjest zapełniany wartościami

  • 60*[6, 2, 4]= [360, 120, 240](ale 3 bajty krótsze)
  • chyba że najniższą wartością jest Blue ( i(1) == 3), w którym to przypadku pierwsza wartość odcienia staje się zero
  • następnie użyj, (i)aby zmienić kolejność hw [h(Z), h(Y), h(X)]kolejności

Stamtąd jest to prosta transkrypcja formuły. Możesz spróbować tutaj .


Wskazówka: użyj anonimowej notacji funkcji, aby wycisnąć więcej bajtów: @(c)mod(atan2d(.866*c*[0;1;-1],c*[2;-1;-1]/2),360)jest dziesięć bajtów krótszych niż definicja ze functionsłowem kluczowym.
— pawel.boczarski

@ pawel.boczarski Zastanawiałem się, czy mógłbym całkowicie pozbyć się nagłówka funkcji, ale nie wiem, czy to prawda. Ale dziękuję za wskazówkę! : D
— zlewka

@ pawel.boczarski Patrząc wstecz, wciąż potrzebuję r=przed anonimową funkcją, aby ją nazwać, prawda?
— zlewka

Istnieje wiele rozwiązań, w których wysyłane są anonimowe funkcje. Co więcej, możesz wywołać tak zdefiniowaną funkcję nawet w ten sposób: (@(c)mod(atan2d(.866*c*[0;1;-1],c*[2;-1;-1]/2),360))([127 247 103])lub argumentować, że możesz użyć anszmiennej zaraz po zdefiniowaniu funkcji anonimowej, aby przypisanie nie było konieczne do zakończenia definicji funkcji. W jednym z wyzwań ( codegolf.stackexchange.com/questions/54945 ) uchwyt istniejącej funkcji biblioteki Matlaba został opublikowany jako pełne rozwiązanie.
— pawel.boczarski

@ pawel.boczarski Wow, to ... po prostu ... zło: DI powinien wiedzieć, że Luis będzie w to zamieszany. Powrócę do pierwotnego kodu i użyję go answ próbce. Dzięki jeszcze raz!
— zlewka

5

Pyth, 55

Wiem, że odpowiedź @ Soka przewyższa moją, ale ponieważ skończyłem moją zaraz po tym, jak on / ona opublikował, pomyślałem, że nadal będę pisać. To był mój pierwszy raz w Pythonie, więc jestem pewien, że popełniłem oczywiste błędy.

DlZK*120ZRKJSQFNJ=Y+YxQN)=kl@Y1+k/*-leYk+1c-eJ@J1-eJhJ2

Dane wejściowe powinny być r, g, b. Możesz spróbować tutaj .


Nie działa dla 255,165,245.
— jimmy23013,

5

PowerShell, 232 226 222 161 bajtów

Zobacz historię zmian poprzednich wersji

$z,$y,$x=($r,$g,$b=$args)|sort
$c=((2,(0,3)[$y-eq$b])[$x-ne$b],1)[$x-eq$g]
$d=((2,(0,3)[$x-eq$b])[$y-ne$b],1)[$y-eq$g]
(($c-$d)*120*(1+($x-$y)/($x-$z))/2+$d*120)

Hoo chłopcze, zobaczmy, czy dam radę przez to przejść. Ponieważ \nliczy się tak samo, jak ;zostawiłem, linia łamie się dla jasności.

Pierwszy wiersz przyjmuje dane wejściowe jako trzy $argsi zapisuje je w $r, $g, $b. Naprawdę będziemy używać $bdopiero później, ale potrzebujemy wszystkich trzech, więc wszystko |sortdziała poprawnie. To sprawia, że $z, $y, $xod najmniejszych do największych argumentów wejściowych.

Kolejne dwie linie ustawiają $ci $dza pomocą wielu wywołań indeksu do tablicy, aby odpowiednio ustawić liczby. Praca z zewnątrz w, jeśli $xjest -eqseksualnego do $g(czyli zielony był największy), ustawiamy $c=1... else, jeśli $xjest -not equal do $b(czyli niebieski nie był największy) $cjest albo 0czy 3w zależności czy niebieski był drugim co do wielkości ... indziej $c=2. Podobne zestawy logiczne $d.

Następnie obliczamy i drukujemy dane wyjściowe w następujący sposób, który jest tylko algorytmem gry w golfa.

(($c-$d)*120*(1+($x-$y)/($x-$z))/2+$d*120)

1
Nie znam PowerShell, więc popraw mnie, jeśli się mylę ... Nie używasz $zpodczas obliczania $club $d, i używasz go tylko raz w obliczeniach wyjściowych, więc możesz się go $zcałkowicie pozbyć i zastąpić $a[0]?
— Sok

4

Ruby, 117 96 94 bajtów

Kod:

h=->r,g,b{z,y,x=[r,g,b].sort;v=x-z.to_f;({r=>(g-b)/v,g=>2+(b-r)/v,b=>4+(r-g)/v}[x]%6*60).to_i}
  • Zaoszczędzono 21 bajtów poprzez usunięcie ()i użycie zmiennych r, g, b.
  • Przyjmowanie modułu 6 w celu konwersji wartości ujemnej i pomnożenie go przez 60 w celu konwersji na stopnie, które pozwoliły zaoszczędzić 2 bajty.

Przykłady:

irb(main):274:0> h.call 0,182,255
=> 197
irb(main):275:0> h.call 127,247,103
=> 110
irb(main):276:0> h.call 0,0,1
=> 240
irb(main):277:0> h.call 255,165,245
=> 306

3

SWI-Prolog, 133 bajty

a(L,H):-L=[R,G,B],max_list(L,X),min_list(L,Y),member(X:I:J:U,[R:G:B:0,G:B:R:2,B:R:G:4]),Z is 60*(U+(I-J)/(X-Y)),(Z<0,H is Z+360;H=Z).

Przykład: a([255,165,245],Hue). wyjściaHue = 306.666666666666 .

Wykorzystuje się następującą formułę:

  • Max = max(R,G,B), Min = min(R,G,B).
  • Jeśli Max = R, U = 0. Else if Max = G, U = 2. Indziej U = 4.
  • Jeśli Max = R, I = Gi J = B. Else if Max = G, I = Bi J = R. W przeciwnym razie I = Ri J = G.
  • Z = U + (I - J)/(Max - Min)
  • Huejest albo Zalbo Z + 360jeśli Z < 0.

Zaokrąglanie jest opcjonalne.
— jimmy23013,

@ jimmy23013 Zaktualizowano, dziękuję.
— Fatalize

3

Perl 5, 138 132 119 bajtów

Kod:

($m,$c,$M)=sort@A=($R,$G,$B)=@ARGV;print 60*(6+$M>$m?($G>$c?$B-$R:$B>$c?$R-$G:$G-$B)/($M-$m)+($G>$c?2:$B>$c?4:0):0)%360

Uwagi:

Z pewnością Perl nie może wygrać takiego wyzwania z całym golfem w Pyth'oresque. Ale zastanawiałem się, czy można to zrobić tylko z 1 krokiem obliczeniowym. Dzięki modułowi, który dobrze się sprawdził. :)

Test:

$ perl hue.pl 0 182 255
197
$ perl hue.pl 127 247 103
110
$ perl hue.pl 0 0 1
240
$ perl hue.pl 255 165 245
307

w porównaniu do wartości środkowej zamiast maksymalnej wygolonej niektóre bajty. (== versus>)
— LukStorms

1

C ++ 276 bajtów

#include <iostream>
int H(int r,int g,int b){int m,n=120,o=240,l=r>g?r>b?g>b?m=r-b,o=n,n=-n,r-g:m=r-g,r-b:m=b-g,o+=n,n=-n,b-r:g>b?r>b?(m=g-b,o=0,g-r):m=g-r,n=-n,g-b:(m=b-r,o-=n,b-g);return (int)n*((float)l/m+1)/2+o;}int main(){int r,g,b;std::cin>>r>>g>>b;std::cout<<H(r,g,b);}

Podpowiedź: możesz opuścić Hfunkcję sama odpowiedź, jak w code-golf funkcja samodzielna jest uzasadniony odpowiedź ekwiwalent pełnego programu vide meta dyskusja: meta.codegolf.stackexchange.com/questions/2419/... . To sprawi, że twoja odpowiedź będzie bardziej konkurencyjna (w twoim przypadku zaoszczędź 100 bajtów). Nadal zachęcamy do pozostawienia „pełnej” wersji programu pod rozwiązaniem, aby uprościć testowanie.
— pawel.boczarski

Drugi przypadek testowy 127 247 103zwraca niepoprawną wartość -120zamiast 110.
— pawel.boczarski

1

R, 125 bajtów

Bardzo podobny do roztworu Octave zlewki. Wyjście zmiennoprzecinkowe.

Kod:

h=function(x){
  o=seq(3)[order(-x)];
  y=c(60*c(6*(o[3]!=3),2,4)[o],x[o]);
  return((y[1]-y[2])*(1+(y[4]-y[5])/(y[4]-y[6]))/2+y[2]);
}

Przykłady:

> h(c(0,182,255))
[1] 197.1765
> h(c(127,247,103))
[1] 110
> h(c(0,0,1))
[1] 240
> h(c(255,165,245))
[1] 306.6667

1

Python, 154 bajty

def h(c):r=c[:];c.sort();c=c[::-1];x,y,z=c;i,j=[120if n==r[1]else 240if n==r[2]else 0if z==r[2]else 360for n in[x,y]];print ((i-j)*(1+(x-y+0.)/(x-z))/2)+j

Akceptuje listę wartości. Nie jestem pewien, czy można to dalej rozbić. Tutaj nie jest golfem:

def hue(color):
 rgb=color[:]  # copy list
 color.sort()  # sort list
 color=color[::-1]  # reverse sort
 x,y,z=color   # pull out x,y,z

 # The line 
 #   i,j=[120if n==r[1]else 240if n==r[2]else 0if z==r[2]else 360for n in[x,y]]
 # is basically the following, twice, once for x/hx and the second time for y/hy

 if x==rgb[1]: # if x is green
  hx = 120
 else:
  if x==rgb[2]: # if x is blue
   hx = 240
  else:
   if z==rgb[2]: # if z is blue and x is red
    hx = 0
   else:       # if x is red and y is blue
    hx = 1

 print ((hx-hy)*(1+(x-y+0.)/(x-z))/2)+hy  # calculate, print

0

JavaScript 108

Metoda alternatywna.

function H(r,g,b){a=[r,g,b].sort(),M=a[2],c=M-a[0],h=M==r?(g-b)/c%6:M==g?(b-r)/c+2:(r-g)/c+4
return h*60|0;}

JavaScript 194

Przy użyciu przykładowej metody.

Array.prototype.i=[].indexOf
function H(r,g,b,a){a=[r,g,b].sort(),i=[a.i(r),a.i(g),a.i(b)],x=[i[2]?360:0,120,240],hx=x[i.i(2)]|0,hy=x[i.i(1)]|0
return (hx-hy)*(1+(a[2]-a[1])/(a[2]-a[0]))/2+hy|0}

var input = document.getElementById("input").innerHTML;
var output = document.getElementById("output");
var html = "";

input.replace(/(\d+)\,(\d+)\,(\d+)/g, function(m, r, g, b) {
  html += H(r, g, b) + "\n";
});

output.innerHTML = html;
<pre id="input">
0,182,255
127,247,103
0,0,1
255,165,245
</pre>

<pre id="output">

</pre>

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.