最も近い3桁の16進数の色を見つける


23

CSSでは、色は「16進トリプレット」(各バイトが色の赤、緑、または青の成分を表す3バイト(6桁)の16進数)で指定できます。たとえば、#FF0000は完全に赤で、と同等rgb(255, 0, 0)です。

色は、3桁の16進数を使用する簡略表記で表すこともできます。速記は、各桁を複製することにより6桁の形式に拡張されます。たとえば、に#ABCなり#AABBCCます。

16進数の短縮形では桁数が少ないため、表現できる色が少なくなります。

チャレンジ

6桁の16進数カラーコードを受け取り、最も近い3桁のカラーコードを出力するプログラムまたは関数を作成します。

以下に例を示します。

  • 入力16進コード:#28a086
  • 赤成分
    • 0x28 = 40(10進数)
    • 0x22 = 34
    • 0x33 = 51
    • 0x22は近いため、短縮されたカラーコードの最初の桁は2です。
  • グリーン成分
    • 0xa0 = 160
    • 0x99 = 153
    • 0xaa = 170
    • 0x99は近いため、2桁目は9です。
  • 青成分
    • 0x86 = 134
    • 0x77 = 119
    • 0x88 = 136
    • 0x88は近いため、3桁目は8です。
  • 短縮カラーコードは#298(#229988に展開されます)

プログラムまたは関数は、先頭に6桁の16進数のカラーコードを入力として受け入れ、先頭に#3桁のカラーコードを追加して出力する必要があります#

  • #FF0000→#F00
  • #00FF00→#0F0
  • #D913C4→#D1C
  • #C0DD39→#BD3
  • #28A086→#298
  • #C0CF6F→#BC7

得点

これはコードゴルフの挑戦なので、あなたの言語の最短回答が勝ちます!標準ルールが適用されます。


1
「フルカラーコードの各コンポーネントと、略記カラーコードの対応するコンポーネントとの差を足し合わせる」-この部分は紛らわしい。どこにも追加する必要はありませんか?
Grzegorz Oledzki

3
単に別の数字を落とすと、各短い色は同数のフルカラーを表すため、最も近い色よりも良い表現になると考えることができます。
ニール

6
これをサンドボックスで見ましたが#、チャレンジに何かを追加する必要があるとは思わないことを言及するのを忘れました。
シャギー

2
小文字で出力できますか?
アーナルド

2
0x22は30ではなく34
Kruga

回答:



8

05AB1E、13 バイト

ćs2ôH8+17÷hJ«

オンラインでお試しください!

どうやって?

ćs2ôH8+17÷hJ« | string, S   e.g. stack: "#B23F08"
ć             | decapitate              "B23F08", "#"
 s            | swap                    "#", "B23F08"
  2           | two                     "#", "B23F08", 2
   ô          | chuncks                 "#", ["B2", "3F", "08"]
    H         | from hexadecimal        "#", [178, 63, 8]
     8        | eight                   "#", [178, 63, 8], 8
      +       | add                     "#", [186, 71, 16]
       17     | seventeen               "#", [186, 71, 16], 17
         ÷    | integer divide          "#", [10, 4, 0]
          h   | to hexadecimal          "#", ["A", "4", "0"]
           J  | join                    "#", "A40"
            « | concatenate             "#A40"
              | print top of stack

1
N 05AB1Eの回答も行うことを考えました-何かを見逃していない限り、Jellyでの16進変換にはかなりのバイトが必要です!
ニックケネディ

1
ええ、ゼリーのテキストベースの変換用の組み込みはありません。
ジョナサンアラン

1
ć斬首する」それは別の言い方です、笑 :Dいい答えだ、私から+1。
ケビンクルーッセン


5

8088アセンブリ、IBM PC DOS、 59 58バイト

組み立てられていないリスト:

BE 0082     MOV  SI, 82H    ; SI to begining of input string 
AC          LODSB           ; load first '#' char into AL 
B4 0E       MOV  AH, 0EH    ; BIOS display char function  
CD 10       INT  10H        ; call BIOS 
B3 11       MOV  BL, 17     ; set up for divide by 17 
B9 0304     MOV  CX, 0304H  ; hex byte loop counter (CH=3), shift counter (CL=4) 
        LOOP_BYTE: 
AD          LODSW           ; load next two ASCII hex chars into AX 
B7 02       MOV  BH, 2      ; hex chars loop counter
        LOOP_ALPHA:
2C 30       SUB  AL, '0'    ; convert from ASCII 
3C 0A       CMP  AL, 10     ; is digit > 10 (A-F)? 
7C 02       JL   NOT_ALPHA  ; if not, jump to next char
2C 07       SUB  AL, 7      ; ASCII adjust alpha char to binary 
        NOT_ALPHA: 
86 E0       XCHG AH, AL     ; swap first and second chars 
FE CF       DEC  BH         ; decrement loop counter
75 F2       JNZ  LOOP_ALPHA ; loop to next hex char
D2 E0       SHL  AL, CL     ; shift low nibble to high nibble 
02 C4       ADD  AL, AH     ; add first and second nibbles
32 E4       XOR  AH, AH     ; clear AH for add/division
05 0008     ADD  AX, 8      ; add 0.5 (8/16) to round (with overflow) 
F6 F3       DIV  BL         ; divide by 17 
3C 0A       CMP  AL, 10     ; is digit > 10? 
7C 02       JL   DISP_CHAR  ; if not, jump to display digit 
04 07       ADD  AL, 7      ; binary adjust alpha char to ASCII 
        DISP_CHAR: 
04 30       ADD  AL, '0'    ; convert to ASCII 
B4 0E       MOV  AH, 0EH    ; BIOS display char function  
CD 10       INT  10H        ; call BIOS 
FE CD       DEC  CH         ; decrement loop counter 
75 D4       JNZ  LOOP_BYTE  ; loop to next hex byte
C3          RET             ; return to DOS 

スタンドアロンPC DOS実行可能ファイル。入力はコマンドライン経由で、出力はコンソールへです。

DOS / x86マシンコードには組み込みの機能がないため、ほとんどのコード長は必要な16進文字列I / Oからバイトへの変換を処理しています。

I / O:

ここに画像の説明を入力してください

HEXCLR.COMまたはxxdhexdumpをダウンロードしてテストします

0000000: be82 00ac b40e cd10 b311 b904 03ad b702  ................
0000010: 2c30 3c0a 7c02 2c07 86e0 fecf 75f2 d2e0  ,0<.|.,.....u...
0000020: 02c4 32e4 0508 00f6 f33c 0a7c 0204 0704  ..2......<.|....
0000030: 30b4 0ecd 10fe cd75 d4c3                 0......u..

3

Retina 0.8.2、88バイト

(\w)(.)
$1,$2;
[A-F]
1$&
T`L`d
\d+
$*
+`1,
,16$*
,
8$*
(1{17})*1*;
$#1;
T`d`L`1\d
B\B|;

オンラインでお試しください!リンクにはテストケースが含まれます。説明:

(\w)(.)
$1,$2;

16進数をペアにします。

[A-F]
1$&
T`L`d

各桁を個別に10進数に変換します。

\d+
$*

各10進数を単項に変換します。

+`1,
,16$*

数字のペアの16進変換を終了します。

,
8$*
(1{17})*1*;
$#1;

8を追加し、17で除算します。

T`d`L`1\d
B\B|;

16進数に戻します。



3

Pythonの372の 70 68バイト

lambda x:'#'+''.join(f"{(int(x[i:i+2],16)+8)//17:X}"for i in(1,3,5))

オンラインでお試しください!

これは、Grzegorz Oledzkisの最初の回答の移植版で、彼がゴルフをするのを助けました。

Python 3の2つの機能は、バイトの節約に役立ちます。

  • デフォルトでの浮動小数点除算
  • フォーマット文字列リテラル

-Jonathan Allanへの2バイトの感謝


2
(int(x[i:i+2],16)+8)//17セーブ2
ジョナサンアラン



2

Wolfram言語(Mathematica)63 48バイト

"#"<>Round[15List@@RGBColor@#]~IntegerString~16&

オンラインでお試しください!

attinatのおかげで-15バイト!交換StringJoin<>と構文を圧縮します。

  1. RGBColor@#入力文字列をRGBColor[r, g, b]、範囲0.1.1の3つの浮動小数点引数を持つフォームの色に変換します。

  2. Round[15 List @@ %]3つの引数のリストに15を乗算し、それらを最も近い整数に丸めます。これで、目的の3桁の16進数に対応する3つの整数値のリストができました。

  3. %~IntegerString~16 この3つの整数のリストを、それぞれ1文字の3つの16進文字列のリストに変換します。

  4. "#"<>%#文字を追加し、これらすべての文字を結合します。



2

MathGolf19 12 バイト

╞2/¢8+F/¢'#▌

文字リストとして出力します。これが許可されていない場合はy、文字リストを文字列に結合するために追加の末尾を追加する必要があります。

@maxbのおかげで、組み込みバイト(2ô_2<\1>]to 2/)を過ぎたので-7バイトに感謝します。

オンラインでお試しください。

説明:

              # Remove the first character from the (implicit) input-string
 2/            # Split the string into parts of size 2
   ¢           # Convert each part from hexadecimal to integer
    8+         # Add 8 to each integer
      F/       # Integer-divide each integer by 17
        ¢      # Then convert back from integer to hexadecimal
         '#▌  '# Prepend '#' in front of the list
               # (which is output implicitly as result)

2

ルビー(2.5.3)、4544、42のバイト

->a{a.gsub(/\w./){|b|"%X"%((8+b.hex)/17)}}

編集:正規表現の2番目の文字に文字グループが必要ないため、1バイトを節約しました(Neilの答えに触発されました)

編集2:ダッシュロケットのラムダ構文は引数を囲む括弧を必要としないため、2バイトを節約しました


2
stdinで入力を取得し、ブロック内の引数の代わりにフラグと別の2 を使用して、-p 7バイトを保存できます。tio.run$& / ##KypNqvz
Jordan

1
@ジョーダンありがとう!どちらも知らなかったので、これは今後のゴルフの試みの本当の助けになります
DaveMongoose

1

パイソン2(109 101 97 85 83 74バイト)

lambda x:'#'+''.join(hex(int(int(x[i:i+2],16)/17.+.5))[2:]for i in[1,3,5])

「最近接距離」は、17による除算と丸めによって処理されます。

改善点:

int(...+.5)代わりにトリックを使用して-8バイトint(round(...))

の代わりにリスト内包表記を使用して-4バイト map()

#出力にハードコーディングして-1バイト(@movaticaに感謝)

re.findall("..",...)明示的な文字列スプライシングを優先して使用しないため、-10バイト

-2バイト、リスト内包表記を使用せず、インラインジェネレータ式を使用join(@movaticaに感謝)

:7青色部分の終わりをつなぎ合わせずに-1バイト

-9バイトの色の繰り返しを改善-実際の文字ではなく、インデックスの繰り返し(@movaticaに感謝)


1
@movatica-あなたは正しいです、追加しました
Grzegorz Oledzki

1
'#'代わりにハードコーディングして1バイト節約しますx[0]
movatica

1
''.join(...)ジェネレーター式も処理するため、リスト内の内包表記はスキップできます。を削除して、[]さらに2バイトを保存します:)
movatica

1
ありがとう!range(1,6,2)さらに良いとある[1,3,5]
グジェゴシOledzki

1
Jonathan Allenは、mz Pzthon3バージョンでの丸めの別のトリックを提案しました。ここでも同様に適用されlambda x:'#'+''.join(hex((int(x[i:i+2],16)+8)/17)[2:]for i in[1,3,5])ます
。-

1

Perl 5の -p35の 34バイト

@nwellnhofがバイトを保存しました

s|\w.|sprintf'%X',.5+(hex$&)/17|ge

オンラインでお試しください!

STDINから読み取り、#17除算法を使用して最も近いものを見つけるために適切な単一文字ではないアイテムの各ペアを置換し-p、結果を暗黙的に出力()します。


1

Python 3、67バイト

f=lambda x:(f(x[:-2])if x[3:]else"#")+f'{(int(x[-2:],16)+8)//17:X}'

ようこそ。コードを実行できるTIOなどのオンラインインタープリターへの説明、説明、またはリンクの追加を検討してください。コードのみの回答は、低品質として自動的にフラグが立てられる傾向があります。例については、他の既存の回答を参照してください。
mbomb007

0

、103バイト

func[c][r: to 1 c to #1 rejoin reverse collect[loop 3[keep to-hex/size r % 256 + 8 / 17 1 r: r / 256]]]

オンラインでお試しください!

Redの現在のLinuxバージョンにはhex-to-rgb関数の実装がないことが判明したため、「手動で」基本変換を行うのはこのためです:)

これは、WindowsのRed GUIコンソールで正常に機能します。

、94バイト

f: func[c][r: hex-to-rgb c to #1 rejoin collect[repeat n 3[keep to-hex/size r/:n + 8 / 17 1]]]


0

、22バイト

#F⪪⮌…⮌S⁶¦²⍘÷⁺⁸⍘ι¹⁶¦¹⁷φ

オンラインでお試しください!リンクは、コードの詳細バージョンです。説明:

#                       Literal `#`
      S                 Input string
     ⮌                  Reversed
    …  ⁶                Truncated to length 6
   ⮌                    Reversed
  ⪪      ²              Split into pairs of characters
 F                      Loop over each pair
               ι        Current pair
              ⍘ ¹⁶      Convert from base 16
            ⁺⁸          Add 8
           ÷       ¹⁷   Integer divide by 17
          ⍘          φ  Convert to large base
                        Implicitly print



0

Forth(gforth)、87バイト

: f d>s 1- hex ." #"3. do 2 + dup 2 s>number d>s 17 /mod swap 8 > - 1 .r loop decimal ;

オンラインでお試しください!

説明

  1. 入力の最初の文字を無視/切り捨てます(#
  2. インタープリターを16進モードに設定します
  3. 出力 #
  4. 各ループで3回ループします。
    1. 文字列の開始アドレスに2を追加します
    2. 文字列の次の2文字を16進数に変換します
    3. 17(0x11)の除算とモジュールを使用して、短縮されたコンポーネントに最も近い値を取得します
    4. 先行スペースなしの出力
  5. インタープリターを10進数モードに戻す

コードの説明

: f                    \ start a new word definition
  d>s                  \ convert double-length int to single-length (cheaper drop)
  1- hex               \ subtract 1 from string address, set current base to 10
  ." #"                \ output #
  3. do                \ start a loop from 0 to 2 (inclusive)
    2 + dup            \ add 2 to string starting address and duplicate
    2 s>number         \ parse the next 2 characters to a hexadecimal value
    d>s                \ convert result to single-length value
    17 / mod           \ get the quotient and remainder of dividing by 17
    swap               \ move the remainder to the top of the stack
    8 > -              \ if remainder is greater than 8, add 1 to quotient
    1 .r               \ output result (as hexadecimal) with no space
  loop                 \ end the loop
  decimal              \ set interpreter back to base 10 (decimal)
;                      \ end the word definition


0

K4、39バイト

溶液:

"#",{x@_1%17%8+16/:x?y}[.Q.nA]@/:3 2#1_

説明:

これらの回答の多くと同じ戦略を使用します(つまり、8を追加し、17で除算します)。

"#",{x@_1%17%8+16/:x?y}[.Q.nA]@/:3 2#1_ / the solution
                                     1_ / drop first character
                                 3 2#   / reshape as 3x2 (e.g. "FF", "00", "00")
                              @/:       / apply each-right to left lambda
    {                 }[     ]          / lambda with first argument populated
                        .Q.nA           / "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                   x?y                  / get index of hex character, e.g. "AA" => 10 10
               16/:                     / convert from base-16
             8+                         / add 8
          17%                           / 17 divided by...
        1%                              / 1 divided by...
       _                                / floor
     x@                                 / index into .Q.nA to get hex character
"#",                                    / prepend "#"

追加:

  • "#",{x@*16\:a?&/a:abs(17*!16)-16/:x?y}[.Q.nA]@/:3 2#1_-54バイトの元のアイデア
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.