가장 가까운 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가 가까워 지므로 두 번째 숫자는 9입니다.
  • 청색 성분
    • 0x86 = 134
    • 0x77 = 119
    • 0x88 = 136
    • 0x88이 가까워 지므로 세 번째 숫자는 8입니다.
  • 단축 된 색상 코드는 # 298입니다 (# 229988로 확장).

프로그램 또는 함수는 앞에 6 자리 16 진수 색상 코드를 입력하고 앞에 #3 자리 색상 코드 를 입력해야합니다 #.

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

채점

이것은 코드 골프 도전이므로 귀하의 언어로 가장 짧은 답변이 이깁니다! 표준 규칙이 적용됩니다.


1
"풀 컬러 코드의 각 구성 요소와 속기 컬러 코드의 해당 구성 요소 사이의 차이점을 함께 추가"-이 부분은 혼동됩니다. 어디에도 추가 할 필요가 없습니다.
Grzegorz Oledzki

3
대체 숫자를 단순히 삭제하면 각 짧은 색상이 동일한 수의 전체 색상을 나타내므로 가장 가까운 색상보다 더 잘 표현할 수 있습니다.
Neil

6
샌드 박스에서 이것을 보았지만 #도전 과제에 추가를 요구한다고 생각하지 않는다는 것을 잊어 버렸습니다 .
얽히고 설킨

2
소문자로 출력 할 수 있습니까?
Arnauld

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 진수 변환에는 많은 바이트가 필요합니다!
Nick Kennedy

1
예, 젤리의 텍스트 기반 변환에는 기본 제공 기능이 없습니다.
조나단 앨런

1
" ćdecapitate "그것을 설명하는 또 다른 방법입니다, lol. : D 멋진 대답이지만, 나에게서 +1.
Kevin Cruijssen

6

Japt , 16 바이트

r"%w"²_n16_r17Ãg

사용해 보거나 모든 테스트 사례를 실행하십시오.

r"%w"²_n16_r17Ãg     :Implicit input of string
r                    :Replace
 "%w"                :RegEx /\w/g
     ²               :Duplicate, giving /\w\w/g
      _              :Pass each match through a function
       n16           :  Convert to decimal
          _          :  Pass through the following function, and convert back to hex
           r17       :    Round to the nearest multiple of 17
              Ã      :  End function
               g     :  Get first character

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

레티 나 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

파이썬 3 , 72 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의 두 가지 기능으로 바이트를 절약 할 수 있습니다.

  • 기본적으로 부동 소수점 나누기
  • 문자열 리터럴 형식

Jonathan Allan 에게 -2 바이트 감사


2
(int(x[i:i+2],16)+8)//172
Jonathan Allan



2

Wolfram Language (Mathematica) , 63 48 바이트

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

온라인으로 사용해보십시오!

attinat 덕분에 -15 바이트 ! 장착 StringJoin하여 <>상기 구문 압축.

  1. RGBColor@#입력 문자열을 RGBColor[r, g, b]0..1 범위의 3 개의 부동 소수점 인수가있는 양식 색상으로 변환합니다 .

  2. Round[15 List @@ %]세 개의 인수 목록에 15를 곱하고 가장 가까운 정수로 반올림합니다. 우리는 이제 3 개의 원하는 16 진수에 해당하는 3 개의 정수 값 목록을 가지고 있습니다.

  3. %~IntegerString~16 이 세 개의 정수 목록을 각각 한 문자의 세 개의 16 진 문자열 목록으로 변환합니다.

  4. "#"<>%#문자 앞에 붙고이 모든 문자를 결합합니다.



2

MathGolf , 19 12 바이트

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

문자 목록으로 출력합니다. 이것이 허용되지 않으면 y문자 목록을 문자열에 결합하기 위해 추가 후행 을 추가해야합니다.

@maxb 덕분에 -7 바이트 . 내장 ( 2ô_2<\1>]to 2/) 과거를 보았 기 때문에 .

온라인으로 사용해보십시오.

설명:

              # 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), 45 , 44 , 42 바이트

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

편집 : 우리는 정규식의 두 번째 문자에 대한 문자 그룹이 필요하지 않기 때문에 1 바이트를 절약했습니다 (Neil의 대답에서 영감을 얻음)

편집 2 : 대시 로켓 람다 구문에는 인수 주위에 괄호가 필요하지 않으므로 2 바이트를 절약했습니다.


2
당신은 표준 입력에 입력을 복용하고 7 바이트를 저장할 수 있습니다 사용하여 -p플래그를 사용하여 다른 2 $&: 대신 블록 내부 인자의 tio.run/##KypNqvz/...
요르단

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])-> 69 bytes
movatica

1

펄 5 -p , 35 34 바이트

@nwellnhof는 바이트를 저장

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

온라인으로 사용해보십시오!

표준 입력으로부터 읽어없는 항목의 각 쌍 대신 #가까운을 찾기위한 방법 (17)에 의해 분할을 사용하여 적절한 단일 문자를 암시 적 출력 ( -p) 결과.


1

파이썬 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]]]

온라인으로 사용해보십시오!

현재 Linux 버전의 Red 에는 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

넷째 ( 87 ) , 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. 0x11단축 된 부품에 가장 가까운 값을 얻으려면 17 ( ) 씩 나누기와 모듈을 사용하십시오.
    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.