색의 색조


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 밖으로 인수 분해 할 수 c와 d같은 반환 과제와로를 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 = R과 J = 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.