색의 색조


23

색상의 RGB 값이 제공됩니다. 가장 간단한 정의에서 색조를 계산하는 작업이 간단합니다.

최고, 중간 및 최저 값을 가진 채널이 X, Y, Z (빨강, 녹색 또는 파랑)이고 값이 x, y, z라고 가정합니다. 이 색상의 색조는 (h (X) -h (Y)) * (1 + (xy) / (xz)) / 2 + h (Y)입니다. 여기서 :

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

입력 값은 0에서 255까지의 3 개의 정수로 구성되며, 모든 순서가 일치하지는 않습니다. 출력은 부동 소수이거나 올림 또는 내림 된 정수일 수 있으며, 일관성이 없어도됩니다. 출력의 정수 부분이 0 또는 360이면 둘 중 하나를 인쇄 할 수 있습니다.

이미지 조작과 같은 암시 적 변환을 포함하여 색상 공간 변환을 위해 내장을 호출 할 수 없습니다.

이것은 코드 골프입니다. 가장 짧은 코드가 승리합니다.

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)

편집하다

정확한 공식을 따를 필요는 없지만 위 공식과 동일한 결과 만 제공하면됩니다. 또한 수식 자체를 골프화하는 몇 가지 답변을보고 싶습니다.


먼저 sRGB에서 선형 스케일로 변환해야합니까? 우리가해야한다고 생각하지만 지금까지 아무도 가지고 있지 않은 것 같습니다.
John Dvorak

@JanDvorak 작업은 가장 간단한 정의에서 색조를 계산하는 것 입니다. 이 경우 "가장 단순하다"는 입력이 이미 올바른 척도로 가정하고 질문에 제공된 정확한 공식이나 동일한 결과를 제공하는 것을 사용해야한다는 것을 의미합니다.
jimmy23013

그러나 ... 24bpp는 일반적으로 sRGB를 의미합니다. 그렇지 않은 경우 형식 스펙 (사용자)이 다르게 지정해야합니다.
John Dvorak

@JanDvorak RGB 및 색조에 대해이 정의 를 사용해야 합니다 .
jimmy23013

9
huehuehue라고해야합니다.
TheDoctor

답변:


6

Pyth, 27 바이트

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

데모. 테스트 하니스.

Wikipedia 에서 가져온 Fomula .

기본적으로 단계는 다음과 같습니다.

  1. .<QJxQKeSQ: 가장 큰 값을 목록의 앞쪽으로 회전시킵니다.
  2. -Ft: 다른 두 값의 차이를 고려하십시오.
  3. -KhSQ: 최대 값에서 최소값을 뺍니다.
  4. c: 2를 3으로 나눕니다.
  5. + ... yJ 목록에서 최대 값의 인덱스를 두 배 더합니다 (R 인 경우 0, G 인 경우 2, B 인 경우 4).
  6. % ... 6: Mod 6, 부정적인 문제를 해결합니다.
  7. *60: 60을 곱하여도 단위로 변환하고 인쇄합니다.

9

C #을 188 210 206 197 191 바이트

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);}

4 바이트를 절약 한 Sok와 15를 절약 한 SLuck49에 감사합니다!


만 사용할 때 z출력 계산에 한 번, 그리고 앞의 계산에 사용하지 마십시오, 당신은 멀리 변수를 수행하고 출력을 변경 return(int)((c-d)*(1+(x-y)/(double)(x-a[0]))/2+d);하면 4 바이트를 저장.
Sok

당신은 120 밖으로 인수 분해 할 수 cd같은 반환 과제와로를 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)/(double)(x-a[0]))/2+d*120);4 바이트를 저장합니다.
SLuck49

또한 당신은 정말로 캐스트가 필요 double합니까? 그렇게하면 대신 (x-a[0])*1D5 바이트를 더 절약 할 수 있습니다 .
SLuck49

감사합니다! 예, 실제로 캐스트가 필요합니다. 그렇지 않으면 결과가 정확하지 않지만 *1D곱셈은 ​​좋은 트릭입니다!
ProgramFOX

또한 다른 방금 System.Array6 바이트를 정규화하여 사용을 모두 삭제할 수 있습니다 .
SLuck49

8

피스, 41 55 53 51 바이트

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

입력 형식은 다음과 같습니다 r,g,b. 여기에 설명이 있습니다 :

                                                        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)

@Jakube 및 @isaacg 덕분에 4 바이트 절약


@ jimmy23013 고정, 추가 테스트 사례 덕분에
Sok

1
몇 가지 골프 : m*120d-> *L120, 다른 바이트를 저장 eeJ하려면 K인라인으로 저장하십시오.
isaacg 2016 년

@isaacg 나는 L연산자가 int에 자동으로 범위를 생성하는 것을 몰랐다. 매일은 냉정한 날이다 : o) 감사합니다!
Sok

8

자바 (ES6) 145 115 108 100 97 90 바이트

수레를 반환합니다. 사용할 함수에 할당하십시오.

(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)

모든 것을 단일 삼항 연산자 시퀀스로 인라인하고 끝이 0-360으로 정상화 될 때까지 대기하여 30 바이트를 절약했습니다.

더 많은 바이트를 절약 할 수있는 edc65, Vasu Adari 및 ETH 프로덕션 덕분입니다.

테스트가있는 JSFiddle . Firefox에서 사용해보십시오.

함수 선언 제거 h=가 유효하지 않은 경우 2 바이트를 추가하십시오.


'var'과 일부 바이트를 제거 할 수 있습니다.
Vasu Adari

ES6Fiddle은 어떤 이유로 var 선언이 필요하며 firefox에서 ES6을 시도하기 전까지는 필요하지 않다는 것을
몰랐습니다

1
중괄호를 괄호로 바꾸고 세미콜론을 쉼표로 바꾸고를 제거하여 6 바이트를 절약 할 수 있습니다 return. 함수 선언 ( h=)을 제거하는 것도 합법적이며 총계는 100으로 줄었습니다.
ETHproductions

이것은 강박 적 일 수 있지만 (다시 모든 골퍼가 아니십니까?;)) 괄호를 없애고 %6)*60상대방을 제거하면 두 바이트를 더 절약 할 수 있습니다. 또한 마지막에 6을 추가하는 대신 추가에 무차별 강제를 사용하면 실제로 현재 설정보다 1 바이트가 절약됩니다. (((x==r?(g-b)/m:x==g?2+(b-r)/m:4+(r-g)/m)+6)%6)*60될 것 (x==r?6+(g-b)/m:x==g?8+(b-r)/m:10+(r-g)/m)%6*60입니다.
ETHproductions

1
정렬에 +1, 매우 (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)
영리함

6

옥타브, 65 60 50 바이트

편집 : pawel.boczarski 덕분에 10 바이트를 절약했습니다.

근사한 해결책 ...

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

시운전

@(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

옥타브, 107 바이트

내 원래 (정확한) 솔루션 ...

암호:

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);

설명 :

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);

이 함수는 R, G, B 값을 포함하는 벡터를 입력으로 취하고 c입력을 오름차순으로 정렬합니다

  • b 정렬 된 값을 포함합니다. [z, y, x]
  • i b의 각 값과 관련된 RGB 평면을 포함합니다.

벡터 h는 값으로 채워집니다

  • 60*[6, 2, 4]= [360, 120, 240](그러나 3 바이트 더 짧음)
  • 가장 낮은 값이 파란색 ( i(1) == 3)이 아닌 경우 첫 번째 색조 값이 0이됩니다.
  • 다음 사용 (i)재 배열 h[h(Z), h(Y), h(X)]순서

거기에서 그것은 공식의 직접적인 전사 일뿐입니다. 여기서 시도해 볼 수 있습니다 .


힌트 : 익명 함수 표기법을 사용하여 더 많은 바이트를 짜십시오 . 키워드를 @(c)mod(atan2d(.866*c*[0;1;-1],c*[2;-1;-1]/2),360)사용한 정의보다 10 바이트가 짧습니다 function.
pawel.boczarski

@ pawel.boczarski 함수 헤더를 완전히 제거 할 수 있을지 궁금했지만 그것이 합법적인지 모르겠습니다. 그러나 팁 주셔서 감사합니다! : D
비커

@ pawel.boczarski 이것을 되돌아 보면 r=, 익명 함수를 호출하기 위해서는 여전히 함수 가 필요합니다 .
비이커

익명 함수가 게시되는 솔루션이 많이 있습니다. 또한 다음과 같이 정의 된 함수를 호출 (@(c)mod(atan2d(.866*c*[0;1;-1],c*[2;-1;-1]/2),360))([127 247 103])하거나 ans익명 함수가 정의 된 직후 변수 를 사용할 수 있으므로 함수 정의를 완료하는 데 할당이 필요하지 않다고 주장 할 수 있습니다. 한 가지 도전 과제 ( codegolf.stackexchange.com/questions/54945 )에서 기존 Matlab 라이브러리 함수 핸들이 전체 솔루션으로 게시되었습니다.
pawel.boczarski

@ pawel.boczarski 와우, 그건 .. 그냥 ... 악 : DI가 루이스가 관여 할 줄 알았어 야 했어. 원래 코드로 되돌리고 ans샘플에서 사용하겠습니다 . 다시 감사합니다!
비이커

5

피시스, 55

@Sok의 답변이 제게 맞는다는 것을 알고 있지만 게시 후 바로 완료 한 후에도 게시 할 것이라고 생각했습니다. Pyth를 처음 사용했기 때문에 명백한 실수를 저지른 것 같습니다.

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

입력은 r, g, b입니다. 여기서 시도해 볼 수 있습니다 .


작동하지 않습니다 255,165,245.
jimmy23013

5

PowerShell을 232 226 222 161 바이트

이전 버전의 개정 내역보기

$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 boy, 이걸 살펴볼 수 있는지 봅시다. 내가 떠난 \n것과 동일하게 계산 되므로 ;명확성을 위해 줄 바꿈이 발생합니다.

첫 번째 줄은 입력을 3으로 받아서에 $args저장합니다 $r, $g, $b. 우리는 실제로 $b나중에 사용할 것입니다. 그러나 우리는 3 가지가 모두 필요합니다 |sort. 이것은 $z, $y, $x입력 인수 중 가장 작은 것부터 가장 큰 것까지입니다.

다음 두 줄의 설정 $c$d적절하게 번호를 설정하는 여러 인덱스에-AN-배열 전화를 사용하여. 경우에 외부에서 근무 $x입니다 -eq연간가 $g(즉, 녹색은 가장 큰했다), 우리는 설정 $c=1... 다른, 경우 $x입니다 -n해주 eQUAL에 $b(즉, 파란색은 가장 큰 아니었다) $c중 하나입니다 0또는 3파란색 두 번째로 큰 있었다면 따라 ... 그렇지 않으면 $c=2. 비슷한 로직 세트 $d.

그런 다음 다음과 같은 결과를 계산하고 인쇄합니다. 이는 도전 과제의 알고리즘에 불과합니다.

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

1
내가 PowerShell을 모르는, 그래서 내가 틀렸다면 ... 당신은 사용하지 않는 날 수정 $z계산할 때 $c또는 $d그래서 당신은 제거 할 수, 당신은 출력 계산에 한 번 사용 $z완전히와로 교체 $a[0]?
Sok

4

루비, 117 96 94 바이트

암호:

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}
  • ()r, g, b 변수 를 제거 하고 사용하여 21 바이트를 절약했습니다 .
  • 6의 계수를 사용하여 음수 값을 변환하고 60을 곱하여 2 바이트를 절약 한 각도로 변환합니다.

예 :

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- 프롤로그, 133 바이트

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).

예: a([255,165,245],Hue). 출력Hue = 306.666666666666 .

이것은 다음 공식을 사용합니다.

  • Max = max(R,G,B), Min = min(R,G,B) .
  • 만약 Max = R, U = 0. 그렇지 않은 경우 Max = G,U = 2 . 그렇지 않으면 U = 4.
  • 만약 Max = R, I = G하고 J = B. 만약 그렇지 Max = G, I = B하고 J = R. 다른 I = RJ = G.
  • Z = U + (I - J)/(Max - Min)
  • HueZ또는 Z + 360if 중 하나 Z < 0입니다.

반올림은 선택 사항입니다.
jimmy23013 년

@ jimmy23013 감사합니다.
치명적

3

펄 5 138 132 119 바이트

암호:

($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

비고 :

확실히 Perl은 모든 Pyth'oresque 골프에서 그러한 도전을 이길 수 없습니다. 그러나 이것이 1 계산 단계로만 가능한지 궁금했습니다. 잘 작동하는 계수 덕분입니다. :)

테스트:

$ 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

최대 바이트 대신 중간 값과 비교하여 일부 바이트를 면도했습니다. (== 대>)
LukStorms에서

1

C ++ 276 바이트

#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);}

힌트 : 당신은 떠날 수 H: 독립 기능 전체 프로그램에 해당 합법적 인 대답, 보라 메타 토론입니다 코드 골프로,이 질문에 대해 단독으로 기능을 meta.codegolf.stackexchange.com/questions/2419/... . 이렇게하면 답변의 경쟁력이 향상됩니다 (귀하의 경우 100 바이트를 절약하십시오). 테스트를 단순화하기 위해 "풀"버전의 프로그램을 솔루션에 그대로 두는 것이 좋습니다.
pawel.boczarski

두 번째 테스트 사례는 대신에 127 247 103잘못된 값을 산출 합니다. -120110
pawel.boczarski

1

R, 125 바이트

비커의 Octave 솔루션과 매우 유사합니다. 부동 소수점 출력.

암호:

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]);
}

예 :

> 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

파이썬, 154 바이트

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

값 목록을 승인합니다. 이것이 더 나눌 수 있는지 확실하지 않습니다. 여기에 골퍼가 없습니다 :

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

자바 스크립트 108

다른 방법.

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;}

자바 스크립트 194

예제 방법을 사용합니다.

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>

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.