ค้นหาสีฐานสิบหกสามหลักที่ใกล้เคียงที่สุด


23

ใน CSS สีสามารถระบุได้โดย "hex triplet" - เลขฐานสิบหกสามไบต์ (หกหลัก) ที่แต่ละไบต์แทนองค์ประกอบสีแดงสีเขียวหรือสีน้ำเงินของสี ยกตัวอย่างเช่นเป็นสีแดงอย่างสมบูรณ์และเทียบเท่ากับ#FF0000rgb(255, 0, 0)

สีสามารถแสดงด้วยเครื่องหมายแบบย่อซึ่งใช้เลขฐานสิบหกสามหลัก การจดชวเลขจะขยายเป็นรูปแบบหกหลักโดยทำซ้ำแต่ละหลัก ยกตัวอย่างเช่นจะกลายเป็น#ABC#AABBCC

เนื่องจากมีตัวเลขน้อยลงในการจดชวเลขฐานสิบหกจึงสามารถแสดงสีได้น้อยลง

ความท้าทาย

เขียนโปรแกรมหรือฟังก์ชั่นที่ใช้รหัสสีฐานสิบหกหกหลักและส่งออกรหัสสีสามหลักที่ใกล้เคียงที่สุด

นี่คือตัวอย่าง:

  • ป้อนรหัส hex: # 28a086
  • องค์ประกอบสีแดง
    • 0x28 = 40 (ทศนิยม)
    • 0x22 = 34
    • 0x33 = 51
    • 0x22 ใกล้เคียงกันมากขึ้นดังนั้นรหัสแรกของรหัสสีที่สั้นลงคือ 2
  • องค์ประกอบสีเขียว
    • 0xa0 = 160
    • 0x99 = 153
    • 0xaa = 170
    • 0x99 ใกล้เคียงดังนั้นหลักที่สองคือ 9
  • องค์ประกอบสีน้ำเงิน
    • 0x86 = 134
    • 0x77 = 119
    • 0x88 = 136
    • 0x88 ใกล้เคียงดังนั้นหลักที่สามคือ 8
  • รหัสสีที่สั้นลงคือ # 298 (ซึ่งขยายเป็น # 229988)

โปรแกรมหรือฟังก์ชั่นของคุณจะต้องยอมรับความเป็น input หกบาทรหัสสีฐานสิบหกใช้ได้กับและผลผลิตรหัสสีสามหลักใช้ได้กับ##

ตัวอย่าง

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

เกณฑ์การให้คะแนน

นี่คือความท้าทายของรหัส - กอล์ฟดังนั้นคำตอบที่สั้นที่สุดในภาษาของคุณชนะ ใช้กฎมาตรฐาน


1
"การเพิ่มความแตกต่างระหว่างองค์ประกอบแต่ละส่วนของรหัสสีแบบเต็มและองค์ประกอบที่สอดคล้องกันของรหัสสีแบบย่อ" - ส่วนนี้ทำให้เกิดความสับสน ไม่มีการเพิ่มที่ไหนใช่ไหม?
Grzegorz Oledzki

3
โปรดทราบว่าถ้าคุณเพียงวางตัวเลขสำรองสีสั้น ๆ แต่ละสีจะแสดงจำนวนสีเต็มจำนวนเท่ากันดังนั้นจึงอาจพิจารณาได้ว่าจะให้การแสดงที่ดีกว่าสีที่ใกล้ที่สุด
Neil

6
เห็นสิ่งนี้ในแซนด์บ็อกซ์ แต่ลืมพูดถึงว่าฉันไม่คิดว่าจะต้อง#เพิ่มสิ่งใดในการท้าทาย
Shaggy

2
เราสามารถส่งออกเป็นตัวพิมพ์เล็กได้ไหม
Arnauld

2
0x22 คือ 34 ไม่ใช่ 30
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 ใช้เวลาค่อนข้างมาก!
Nick Kennedy

1
ใช่ไม่มีในตัวสำหรับการแปลงแบบข้อความใด ๆ ใน Jelly
Jonathan Allan

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 Assembly, 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 แบบสแตนด์อโลน อินพุตเป็นผ่านบรรทัดคำสั่งเอาต์พุตคือคอนโซล

ความยาวส่วนใหญ่ของรหัสคือการจัดการการแปลงสตริง hex ที่ต้องการ I / O เป็นไบต์เนื่องจากรหัสเครื่อง DOS / x86 ไม่มีบิวด์อินสำหรับสิ่งนั้น

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;

จับคู่ตัวเลขฐานสิบหก

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

แปลงตัวเลขแต่ละหลักแยกกันเป็นทศนิยม

\d+
$*

แปลงทศนิยมแต่ละหลักเป็นเอก

+`1,
,16$*

เสร็จสิ้นการแปลงเลขฐานสิบหกของคู่ของตัวเลข

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

เพิ่ม 8 และหารด้วย 17

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

แปลงกลับเป็นเลขฐานสิบหก



3

Python 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 ช่วยเราประหยัดไบต์:

  • การหารจุดลอยตัวโดยค่าเริ่มต้น
  • จัดรูปแบบตัวอักษรของสตริง

-2 ไบต์ thanx ถึงJonathan Allan


2
(int(x[i:i+2],16)+8)//17ประหยัด 2
โจนาธานอัลลัน



2

ภาษา Wolfram (Mathematica) , 63 48 ไบต์

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

ลองออนไลน์!

-15 ไบต์ขอบคุณattinat ! แทนที่StringJoinด้วย<>และบีบอัดไวยากรณ์

  1. RGBColor@#แปลงสตริงอินพุตให้เป็นสีของฟอร์มRGBColor[r, g, b]ด้วยอาร์กิวเมนต์ floating-point สามตัวในช่วง 0..1

  2. Round[15 List @@ %]คูณรายการของสามอาร์กิวเมนต์ด้วย 15 และปัดเศษเป็นจำนวนเต็มที่ใกล้ที่สุด ตอนนี้เรามีรายการค่าจำนวนเต็มสามค่าที่ตรงกับตัวเลขฐานสิบหกสามหลักที่ต้องการ

  3. %~IntegerString~16 แปลงรายการจำนวนเต็มสามจำนวนนี้ให้เป็นรายการของสตริงเลขฐานสิบหกสามตัวของอักขระหนึ่งตัว

  4. "#"<>%เติม#อักขระและรวมอักขระทั้งหมดเข้าด้วยกัน



2

MathGolf , 19 12 ไบต์

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

เอาท์พุทเป็นรายการตัวละคร หากไม่ได้รับอนุญาตyจะต้องเพิ่มส่วนท้ายเพิ่มเติมเพื่อเข้าร่วมรายการอักขระไปยังสตริง

-7 ไบต์ขอบคุณ@maxbเนื่องจากฉันมองผ่าน builtin ( 2ô_2<\1>]ไป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)}}

แก้ไข: บันทึกหนึ่งไบต์เพราะเราไม่ต้องการกลุ่มตัวละครสำหรับตัวละครที่สองใน regex (แรงบันดาลใจจากคำตอบของ Neil)

แก้ไข 2: บันทึกไว้ 2 ไบต์เพราะไวยากรณ์แลมบ์ดา rocket lambda ไม่จำเป็นต้องใช้วงเล็บรอบอาร์กิวเมนต์


2
คุณสามารถบันทึกได้ 7 ไบต์โดยใช้อินพุตบน stdin และใช้-pแฟล็กและอีก 2 โดยใช้$&แทนอาร์กิวเมนต์ภายในบล็อก: tio.run/##KypNqvz/ …
จอร์แดน

1
@ จอร์แดนขอบคุณ! ฉันไม่รู้เกี่ยวกับสิ่งเหล่านี้ดังนั้นจึงเป็นความช่วยเหลือที่แท้จริงสำหรับความพยายามในการเล่นกอล์ฟในอนาคต
DaveMongoose

1

Python 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 และการปัดเศษ

การปรับปรุง:

-8 ไบต์โดยใช้int(...+.5)เคล็ดลับแทนint(round(...))

-4 ไบต์โดยใช้ list comprehension แทน map()

-1 ไบต์โดยการเข้ารหัส#ในเอาต์พุต (ขอบคุณ @movatica)

-10 ไบต์โดยไม่ใช้re.findall("..",...)ในความโปรดปรานของการประกบ String ชัดเจน

-2 ไบต์โดยไม่ใช้ list comprehension แต่เป็นนิพจน์ตัวสร้างอินไลน์ในjoin(ขอบคุณ @movatica)

-1 ไบต์โดยไม่ต่อ:7ท้ายจุดสีฟ้า

-9 ไบต์โดยการทำซ้ำมากกว่าสี - เช่นวนซ้ำดัชนีไม่ใช่อักขระจริง (ขอบคุณ @movatica)


1
@movatica - คุณพูดถูกเพิ่มเข้ามาแล้ว
Grzegorz Oledzki

1
บันทึก 1 ไบต์โดย hardcoding แทน'#' x[0]
movatica

1
คุณสามารถข้ามรายการความเข้าใจภายใน''.join(...)เนื่องจากยังจัดการนิพจน์ตัวสร้าง เพียงแค่ลบ[]และบันทึกเพิ่มเติมอีก 2 ไบต์ :)
movatica

1
ขอบคุณ! range(1,6,2)ดียิ่งขึ้นอีกด้วย[1,3,5]
Grzegorz Oledzki

1
โจนาธานอัลเลนเสนอเคล็ดลับที่แตกต่างกันสำหรับการปัดเศษในรุ่น mz Pzthon3 มันใช้ที่นี่เช่นกัน: lambda x:'#'+''.join(hex((int(x[i:i+2],16)+8)/17)[2:]for i in[1,3,5])-> 69 ไบต์
movatica

1

Perl 5 -p , 35 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ฟังก์ชั่นนั่นคือเหตุผลที่ฉันทำแปลงฐาน "ด้วยตนเอง" :)

ใช้งานได้ดีในคอนโซลRed GUI บน Windows:

สีแดง 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

Pyth , 20 ไบต์

+\#sm.H/+8id16 17c3t

ลองที่นี่

หมายเหตุ: ในกรณีที่ลิงค์ด้านบนยกขึ้นให้ImportErrorไปที่นี่แทน ขณะนี้ยังไม่มีข้อผิดพลาดในหน้า "ข้าราชการ" และนี่คือวิธีการแก้ปัญหาชั่วคราวโดยMaltysen ลิงค์นี้อาจหยุดทำงานหลังจากที่มีการแก้ไข


0

ออกมา (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. ตั้งล่ามเป็นโหมดเลขฐานสิบหก
  3. เอาท์พุต #
  4. วนซ้ำ 3 ครั้งในแต่ละวง:
    1. เพิ่ม 2 ไปยังที่อยู่เริ่มต้นของสตริง
    2. แปลงอักขระ 2 ตัวถัดไปในสตริงเป็นตัวเลขฐานสิบหก
    3. ใช้การหารและโมดูลโดย 17 ( 0x11) เพื่อรับค่าที่ใกล้เคียงที่สุดสำหรับคอมโพเนนต์ที่สั้นลง
    4. เอาต์พุตที่ไม่มีพื้นที่ก่อนหน้า
  5. ตั้งล่ามกลับเป็นโหมดทศนิยม

รหัสคำอธิบาย

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