Tìm màu lục giác ba chữ số gần nhất


23

Trong CSS, màu sắc có thể được chỉ định bởi "bộ ba hex" - một số thập lục phân ba byte (sáu chữ số) trong đó mỗi byte đại diện cho các thành phần màu đỏ, xanh lục hoặc xanh lam của màu. Ví dụ, #FF0000hoàn toàn màu đỏ và tương đương với rgb(255, 0, 0).

Màu sắc cũng có thể được biểu thị bằng ký hiệu tốc ký sử dụng ba chữ số thập lục phân. Tốc ký mở rộng thành dạng sáu chữ số bằng cách nhân đôi mỗi chữ số. Ví dụ, #ABCtrở thành #AABBCC.

Vì có ít chữ số hơn trong tốc ký lục giác, nên có thể thể hiện ít màu hơn.

Các thách thức

Viết chương trình hoặc hàm lấy mã màu thập lục phân sáu chữ số và xuất mã màu ba chữ số gần nhất.

Đây là một ví dụ:

  • Mã hex đầu vào: # 28a086
  • Thành phần màu đỏ
    • 0x28 = 40 (thập phân)
    • 0x22 = 34
    • 0x33 = 51
    • 0x22 gần hơn, vì vậy chữ số đầu tiên của mã màu được rút ngắn là 2
  • Thành phần xanh
    • 0xa0 = 160
    • 0x99 = 153
    • 0xaa = 170
    • 0x99 gần hơn, vì vậy chữ số thứ hai là 9
  • Thành phần màu xanh
    • 0x86 = 134
    • 0x77 = 119
    • 0x88 = 136
    • 0x88 gần hơn, vì vậy chữ số thứ ba là 8
  • Mã màu được rút ngắn là # 298 (mở rộng thành # 229988)

Chương trình hoặc chức năng của bạn phải chấp nhận làm đầu vào mã màu thập lục phân sáu chữ số được đặt trước #và xuất mã màu ba chữ số được đặt trước #.

Ví dụ

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

Chấm điểm

Đây là một thử thách chơi gôn, vì vậy câu trả lời ngắn nhất trong ngôn ngữ của bạn sẽ thắng! Quy tắc chuẩn áp dụng.


1
"Thêm sự khác biệt giữa từng thành phần của mã màu đầy đủ và thành phần tương ứng của mã màu tốc ký" - phần này gây nhầm lẫn. Không có thêm bất cứ nơi nào, phải không?
Grzegorz Oledzki

3
Lưu ý rằng nếu bạn chỉ cần bỏ các chữ số thay thế thì mỗi màu ngắn biểu thị một số lượng đầy đủ các màu đầy đủ, do đó có thể được xem xét để thể hiện tốt hơn màu gần nhất.
Neil

6
Nhìn thấy điều này trong Sandbox nhưng quên đề cập rằng tôi không nghĩ cần phải #thêm bất cứ điều gì vào thử thách.
Xù xì

2
Chúng ta có thể xuất ra chữ thường không?
Arnauld

2
0x22 là 34, không phải 30
Kruga

Câu trả lời:


4

JavaScript (ES6), 55 byte

s=>s.replace(/\w./g,x=>(('0x'+x)/17+.5|0).toString(16))

Hãy thử trực tuyến!


Sử dụng tốt toString! Tôi đã không nhận ra rằng nó có thể mất một thông số cơ số.
wrymug

8

05AB1E , 13 byte

ćs2ôH8+17÷hJ«

Hãy thử trực tuyến!

Làm sao?

ć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
Tôi cũng nghĩ về việc thực hiện câu trả lời N 05AB1E - trừ khi tôi bỏ lỡ điều gì đó, chuyển đổi thập lục phân trong Jelly mất khá nhiều byte!
Nick Kennedy

1
Vâng, không tích hợp cho bất kỳ chuyển đổi cơ sở văn bản nào trong Jelly.
Jonathan Allan

1
" ćdecapit " Đó là một cách khác để mô tả nó, lol. : D Câu trả lời hay, +1 từ tôi.
Kevin Cruijssen

6

Japt , 16 byte

r"%w"²_n16_r17Ãg

Hãy thử nó hoặc chạy tất cả các trường hợp thử nghiệm

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

Hội 8088, IBM PC DOS, 59 58 byte

Danh sách chưa được phân loại:

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 độc lập thực thi. Đầu vào là thông qua dòng lệnh, đầu ra là giao diện điều khiển.

Hầu hết độ dài mã đang xử lý việc chuyển đổi I / O chuỗi hex cần thiết thành byte, vì mã máy DOS / x86 không có sẵn cho việc đó.

Tôi / O:

nhập mô tả hình ảnh ở đây

Tải xuống và kiểm tra HEXCLR.COM hoặc 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

Võng mạc 0.8.2 , 88 byte

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

Hãy thử trực tuyến! Liên kết bao gồm các trường hợp thử nghiệm. Giải trình:

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

Ghép các chữ số hex.

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

Chuyển đổi từng chữ số riêng sang thập phân.

\d+
$*

Chuyển đổi từng chữ số thập phân thành đơn nguyên.

+`1,
,16$*

Kết thúc chuyển đổi thập lục phân của cặp chữ số.

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

Thêm 8 và chia cho 17.

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

Chuyển đổi trở lại thập lục phân.






2

Ngôn ngữ Wolfram (Mathicala) , 63 48 byte

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

Hãy thử trực tuyến!

-15 byte nhờ attinat ! Thay thế StringJoinbằng <>và nén cú pháp.

  1. RGBColor@#chuyển đổi chuỗi đầu vào thành màu của biểu mẫu RGBColor[r, g, b]với ba đối số dấu phẩy động trong phạm vi 0..1.

  2. Round[15 List @@ %]nhân danh sách của ba đối số với 15 và làm tròn chúng thành số nguyên gần nhất. Bây giờ chúng ta có một danh sách ba giá trị nguyên tương ứng với ba chữ số thập lục phân mong muốn.

  3. %~IntegerString~16 chuyển đổi danh sách ba số nguyên này thành một danh sách gồm ba chuỗi thập lục phân của mỗi một ký tự.

  4. "#"<>%chuẩn bị một #nhân vật và tham gia tất cả các nhân vật này với nhau.



2

MathGolf , 19 12 byte

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

Đầu ra dưới dạng danh sách nhân vật. Nếu điều này không được phép, một dấu vết bổ sung yphải được thêm vào để nối danh sách ký tự thành một chuỗi.

-7 byte nhờ @maxb , vì tôi đã xem qua một nội trang ( 2ô_2<\1>]đến 2/).

Hãy thử trực tuyến.

Giải trình:

              # 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

Ruby (2.5.3), 45 , 44 , 42 byte

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

EDIT: đã lưu một byte vì chúng ta không cần một nhóm ký tự cho ký tự thứ hai trong biểu thức chính quy (lấy cảm hứng từ câu trả lời của Neil)

EDIT 2: đã lưu 2 byte vì cú pháp lambda dash dash không cần dấu ngoặc quanh đối số


2
Bạn có thể lưu 7 byte bằng cách lấy đầu vào trên stdin và sử dụng -pcờ và 2 cái khác bằng cách sử dụng $&thay vì một đối số bên trong khối: tio.run/##KypNqvz/ Kẻ
Jordan

1
@Jordan Cảm ơn! Tôi đã không biết về một trong những điều đó vì vậy đó là một sự trợ giúp thực sự cho những nỗ lực chơi gôn trong tương lai
DaveMongoose

1

Python 2 ( 109 101 97 85 83 74 byte)

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

"Khoảng cách gần nhất" được xử lý bằng cách chia cho 17 và làm tròn.

Cải tiến:

-8 byte bằng cách sử dụng int(...+.5)thủ thuật thay vìint(round(...))

-4 byte bằng cách sử dụng hiểu danh sách thay vì map()

-1 byte bằng cách mã hóa # trong đầu ra (cảm ơn @movatica)

-10 byte bằng cách không sử dụng re.findall("..",...) để tạo chuỗi nối rõ ràng

-2 byte bằng cách không sử dụng hiểu danh sách, nhưng một biểu thức tạo nội tuyến trong join (cảm ơn @movatica)

-1 byte bằng cách không nối :7 kết thúc cho phần màu xanh

-9 byte bằng cách lặp tốt hơn màu sắc - tức là lặp qua các chỉ số, không phải ký tự thực tế (cảm ơn @movatica)


1
@movatica - bạn nói đúng, đã thêm nó
Grzegorz Oledzki

1
Lưu 1 byte bằng mã hóa '#'thay vì x[0].
Movatica

1
Bạn có thể bỏ qua việc hiểu danh sách bên trong ''.join(...), vì nó cũng xử lý một biểu thức trình tạo. Chỉ cần xóa []và lưu thêm 2 byte :)
Movatica

1
Cảm ơn! range(1,6,2)thậm chí còn tốt hơn với[1,3,5]
Grzegorz Oledzki

1
Jonathan Allen đã đề xuất một mẹo khác để làm tròn trong phiên bản mz Pzthon3. Nó cũng áp dụng ở đây: lambda x:'#'+''.join(hex((int(x[i:i+2],16)+8)/17)[2:]for i in[1,3,5])-> 69 byte
Movatica

1

Perl 5 -p , 35 34 byte

@nwellnhof đã lưu một byte

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

Hãy thử trực tuyến!

Đọc từ STDIN, thay thế từng cặp vật phẩm không #có ký tự đơn phù hợp bằng cách sử dụng phương pháp chia theo 17 để tìm kết quả gần nhất, sau đó ngầm đưa ra kết quả ( -p).


1

Python 3, 67 byte

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

Chào mừng bạn Xem xét thêm mô tả, giải thích hoặc liên kết đến một trình thông dịch trực tuyến, chẳng hạn như TIO nơi chúng tôi có thể chạy mã của bạn. Các câu trả lời chỉ có mã có xu hướng tự động được gắn cờ là chất lượng thấp. Xem các câu trả lời hiện có khác cho ví dụ.
mbomb007

0

Màu đỏ , 103 byte

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]]]

Hãy thử trực tuyến!

Hóa ra phiên bản Linux hiện tại của Red không có triển khai hex-to-rgbchức năng, đó là lý do tại sao tôi thực hiện chuyển đổi cơ bản "thủ công" :)

Điều này hoạt động tốt trong bảng điều khiển GUI đỏ trên Windows:

Màu đỏ , 94 byte

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

Than , 22 byte

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

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Giải trình:

#                       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 byte

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

Hãy thử trực tuyến!

Giải trình

  1. Bỏ qua / cắt bớt ký tự đầu tiên của input ( #)
  2. Đặt trình thông dịch sang chế độ thập lục phân
  3. Đầu ra #
  4. Lặp lại 3 lần, trong mỗi vòng lặp:
    1. Thêm 2 vào địa chỉ bắt đầu chuỗi
    2. Chuyển đổi 2 ký tự tiếp theo trong chuỗi thành số thập lục phân
    3. Sử dụng phép chia và mô đun cho 17 ( 0x11) để lấy giá trị gần nhất cho thành phần được rút ngắn
    4. Đầu ra không có không gian trước
  5. Đặt trình thông dịch trở lại chế độ thập phân

Giải thích mã

: 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 byte

Dung dịch:

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

Giải trình:

Sử dụng chiến lược giống như nhiều câu trả lời trong số này (ví dụ: thêm 8, chia cho 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 "#"

Thêm:

  • "#",{x@*16\:a?&/a:abs(17*!16)-16/:x?y}[.Q.nA]@/:3 2#1_- ý tưởng ban đầu của tôi cho 54 byte
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.