色の色相


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から線形スケールに変換する必要がありますか?私たちはそうすべきだと思うが、今のところ誰も持っていないようだ。
ジョンドヴォルザーク

@JanDvorakタスクは、最も単純な定義で色相を計算することです。この場合、「最も簡単な」とは、入力がすでに正しいスケールであると仮定し、質問で与えられた正確な式または同じ結果を与えるものを使用することを意味します。
jimmy23013

しかし... 24 bppは通常sRGBを意味します。そうでない場合は、フォーマット仕様(ユーザー)が別の方法で指定する必要があります。
ジョンドヴォルザーク

@JanDvorak この定義は、RGBと色相に使用する必要があります。
jimmy23013

9
それは言わなければならない:ヒューエフエ。
TheDoctor

回答:


6

Pyth、27バイト

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

デモンストレーション。 テストハーネス。

ウィキペディアから取られたフォミュラ。

基本的に、手順は次のとおりです。

  1. .<QJxQKeSQ:最大値をリストの先頭に移動します。
  2. -Ft:他の2つの値の差を取ります。
  3. -KhSQ:最大値から最小値を減算します。
  4. c:2を3で除算します。
  5. + ... yJ リストの最大値のインデックスを2回追加します(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バイト節約できます。
ソク

あなたは外の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])*1Dにこれを使用して、さらに5バイトを節約できます。
SLuck49

@ SLuck49ありがとう!はい、実際にキャストが必要です。そうでない場合、不正確な結果が得られますが、その*1D乗算は素晴らしいトリックです!
ProgramFOX

また、(ちょうど気づいた)System.Array別の6バイトを完全に修飾することにより、使用をすべてドロップできます。
–SLuck49

8

Pyth、 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修正、追加のテストケースに感謝
ソク

1
golfsのカップル:m*120d- > *L120、保存eeJするためにK別のバイトを保存するためにインライン化。
isaacg

@isaacg L演算子がintの範囲を自動的に生成することを知りませんでした、毎日がクールな日です:o)ありがとう!
ソク

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、およびETHproductionsに感謝します。

JSFiddle with tests。Firefoxでお試しください。

関数宣言の削除がh=有効でない場合は、2バイトを追加してください。


「var」といくつかのバイトを削除できます。
ヴァスアダリ

ES6Fiddleには何らかの理由でvar宣言が必要であり、FirefoxでES6を試すまでそれが必要でないことに気づきませんでした
DankMemes

1
中括弧を括弧に、セミコロンをコンマに置き換え、return。を削除することにより、6バイトを節約できます。関数宣言(h=)を削除することも合法であり、合計が100に下がると
思います。– ETHproductions

これは強迫観念になるかもしれません(それでは、すべてが良いゴルファーではありませんか?;))、カッコ%6)*60とそのパートナーを反対側で取り除くことで、さらに2バイト節約できます。また、(最後に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、非常に賢い、これは90(または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

オクターブ、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)でない限り、最初の色相値はゼロになります
  • 次に使用(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、匿名関数が定義された直後に変数を使用できるので、関数定義を完了するために割り当ては不要です。1つの課題(codegolf.stackexchange.com/questions/54945)では、既存のMatlabライブラリ関数のハンドルが完全なソリューションとして投稿されました。
pawel.boczarski

@ pawel.boczarskiうわー、それは...ただ...悪:DIはルイスが関与することを知っているべきだった。元のコードに戻りans、サンプルで使用します。再度、感謝します!
ビーカー

5

Pyth、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)

フー少年、私はこれを歩くことができるかどうか見てみましょう。以来\n数と同じ;、私は明確にするためで改行を残しました。

最初の行は入力を3として受け取り$args、に保存します$r, $g, $b。実際には$b後で使用するだけですが、3つすべてが必要|sortなので、適切に動作します。これにより$z, $y, $x、入力引数が最小から最大になります。

次の2行は$c$d複数のindex-in-an-an-array呼び出しを使用してセットアップし、数値を適切に設定します。場合は、外部からの作業$xである-eqUALがに$g(すなわち、緑が最も大きかった)、私たちは設定$c=1...他に、場合$xである-nOT 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]
ソク

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-Prolog、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 = RU = 0。そうでなければMax = GU = 2。その他U = 4
  • もしMax = RI = GJ = B。それ以外の場合Max = GI = BおよびJ = R。エルスI = RJ = G
  • Z = U + (I - J)/(Max - Min)
  • HueZまたはのいずれかZ + 360です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);}

ヒント:Hcode-golfの場合、スタンドアロン関数は完全なプログラムに相当する正当な答えであるため、関数の答えをそのままにしておくことができます。メタディスカッション:meta.codegolf.stackexchange.com/questions/2419/…を参照してください。これにより、回答の競争力が高まります(ケースで100バイトを節約)。テストを簡素化するために、ソリューションの下に「フル」バージョンのプログラムを残すことをお勧めします。
pawel.boczarski

2番目のテストケースで127 247 103は、の-120代わりに無効な値が生成されます110
pawel.boczarski

1

R、125バイト

ビーカーのオクターブソリューションに非常に似ています。浮動小数点出力。

コード:

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

Python、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

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

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