En yakın üç haneli onaltılık rengi bulun


23

CSS'de renkler, bir "altıgen üçlüsü" ile belirtilebilir - her bir baytın rengin kırmızı, yeşil veya mavi bileşenlerini temsil ettiği üç bayt (altı basamaklı) onaltılık bir sayı. Örneğin #FF0000, tamamen kırmızı ve eşittir rgb(255, 0, 0).

Renkler ayrıca üç onaltılık rakam kullanan kestirme gösterim ile de gösterilebilir. Kısa yol her basamağı çoğaltarak altı basamaklı forma genişletir. Örneğin, #ABColur #AABBCC.

Onaltılı stenoda daha az rakam bulunduğundan, daha az renk gösterilebilir.

Meydan okuma

Altı basamaklı onaltılık renk kodunu alan ve en yakın üç basamaklı renk kodunu veren bir program veya işlev yazın.

İşte bir örnek:

  • Onaltılık kod girişi: # 28a086
  • Kırmızı bileşen
    • 0x28 = 40 (ondalık)
    • 0x22 = 34
    • 0x33 = 51
    • 0x22 daha yakın, bu nedenle kısaltılmış renk kodunun ilk basamağı 2
  • Yeşil bileşen
    • 0xa0 = 160
    • 0x99 = 153
    • 0xaa = 170
    • 0x99 daha yakın, bu yüzden ikinci rakam 9
  • Mavi bileşen
    • 0x86 = 134
    • 0x77 = 119
    • 0x88 = 136
    • 0x88 daha yakın, bu yüzden üçüncü hane 8
  • Kısaltılmış renk kodu # 298'dir (# 229988'e genişler)

Programınız veya işleviniz önceden hazırlanmış altı basamaklı onaltılık renk kodunu girmeli #ve önceden hazırlanmış üç basamaklı renk kodunu çıkarmalıdır #.

Örnekler

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

puanlama

Bu bir kod golf mücadelesidir, bu nedenle dilinizde en kısa cevap kazanır! Standart kurallar geçerlidir.


1
"tam renk kodunun her bir bileşeni ile kısa renk kodunun karşılık gelen bileşeni arasındaki farkı bir araya getirmek" - bu bölüm kafa karıştırıcıdır. Hiçbir yere ekleme yok, değil mi?
Grzegorz Oledzki

3
Alternatif basamakları basitçe bırakırsanız, her kısa rengin eşit sayıda tam rengi temsil ettiğini, bu nedenle en yakın renkten daha iyi bir sunum sağlayabileceği düşünülebilir.
Neil,

6
Bunu Sandbox'ta gördüm, ancak #meydan okumaya bir şey eklemek istediğimi düşünmediğimi söylemeyi unuttum .
Shaggy

2
Küçük harflerle çıktı alabilir miyiz?
Arnauld,

2
0x22 34, 30 değil
Kruga

Yanıtlar:



8

05AB1E , 13 bayt

ćs2ôH8+17÷hJ«

Çevrimiçi deneyin!

Nasıl?

ć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
Ben de N 05AB1E cevabı yapmayı düşündüm - bir şeyi kaçırmadığım sürece Jelly'de onaltılık dönüşüm oldukça fazla bayt alır!
Nick Kennedy

1
Evet, Jelly’deki herhangi bir metinsel dönüşüm için yerleşik değil.
Jonathan Allan,

1
" ćkesinleştirmek " Bunu tarif etmenin başka bir yolu, lol. : D Güzel cevap olsa da, benden +1.
Kevin Cruijssen

6

Japt , 16 bayt

r"%w"²_n16_r17Ãg

Deneyin veya tüm test durumlarını çalıştırın

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 Meclisi, IBM PC DOS, 59 58 bayt

Demonte listeleme:

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 

Bağımsız PC DOS çalıştırılabilir. Giriş komut satırı üzerinden, çıkış ise konsola verilir.

Kod uzunluğunun çoğu, gerekli onaltılık dizge I / O'nun baytlara dönüştürülmesiyle ilgilidir, çünkü DOS / x86 makine kodunda bunun için yerleşik bir yer yoktur.

I / O:

enter image description here

HEXCLR.COM veya hexdump'ı indirin ve test edinxxd :

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 bayt

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

Çevrimiçi deneyin!Link, test durumlarını içerir. Açıklama:

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

Altıgen rakamları eşleştirin.

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

Her basamağı ayrı ayrı ondalık basamağa dönüştürün.

\d+
$*

Her ondalık basamağı birliğe dönüştür.

+`1,
,16$*

Hane çiftinin onaltılık dönüşümünü tamamlayın.

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

8 ekleyin ve 17'ye bölün.

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

Onaltılık geri dönüştürün.






2

Wolfram Dili (Mathematica) , 63 48 bayt

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

Çevrimiçi deneyin!

Attinat sayesinde -15 bayt ! Sözdizimi StringJoinile değiştirme <>ve sıkıştırma.

  1. RGBColor@#giriş dizesini, formda bir renge dönüştürür ve RGBColor[r, g, b]0..1 aralığında üç kayan nokta argümanı bulunur.

  2. Round[15 List @@ %]Üç argüman listesini 15 ile çarpar ve en yakın tamsayıya yuvarlar. Şimdi, istenen üç onaltılık haneye karşılık gelen üç tamsayı değerinin bir listesine sahibiz.

  3. %~IntegerString~16 Bu üç tamsayının listesini, her biri bir karakterden oluşan onaltılık üç dizgenin listesine dönüştürür.

  4. "#"<>%bir #karakter hazırlar ve tüm bu karakterleri bir araya getirir.



2

MathGolf , 19 12 bayt

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

Karakter listesi olarak çıktı. Buna izin verilmiyorsa, ek bir izy karakter listesini bir dizeye eklemek için eklenmelidir.

-7 sayesinde bayt @maxb I (a yerleşiğine geçmiş görünüyordu beri, 2ô_2<\1>]hiç2/ ).

Çevrimiçi deneyin.

Açıklama:

              # 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

Yakut (2.5.3), 45 , 44 , 42 bayt

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

EDIT: bir bayt kurtardı çünkü regex'teki ikinci karakter için bir karakter grubuna ihtiyacımız yok (Neil'in cevabından esinlenerek)

EDIT 2: 2 bayt kaydetti çünkü çizgi roket lambda sözdizimi argüman etrafında parantez gerektirmez


2
Stdin'e girdi alarak ve bloğu içindeki bir argüman yerine flag ve diğer 2'yi kullanarak-p 7 bayt kazanabilirsiniz$& : tio.run/##KypNqvz/…
Ürdün

1
@ Jordan Teşekkürler! Bunlardan hiçbirini bilmiyordum, bu yüzden gelecekteki golf denemeleri için gerçek bir yardım
DaveMongoose

1

Python 2 ( 109 101 97 85 83 74 bayt)

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

"En yakın mesafe", 17'ye bölünerek ve yuvarlama ile gerçekleştirilir.

İyileştirmeler:

-8 bayt int(...+.5)yerine hile kullanarakint(round(...))

-4 bayt yerine liste anlama kullanarak map()

#Çıktıda kodlama ile -1 bayt (teşekkürler @movatica)

-10 bayt re.findall("..",...)açık lehine kullanmayarak dize yapıştırma

-2 listesi kavrama kullanarak değil, satır içi bir jeneratör ifadesi kullanarak (bayt jointeşekkürler @movatica)

-1 bayt :7, mavi kısım için bitişi ekleyerek değil

Renkler üzerinden daha iyi yineleme ile -9 bayt - yani, indeksler üzerinden yineleme, gerçek karakterler değil (teşekkürler @movatica)


1
@movatica - haklısın, ekledi
Grzegorz Oledzki

1
Yerine, 1 byte '#'yerine kod yazarak kaydedin x[0].
movatica

1
''.join(...)Bir jeneratör ifadesini de idare ettiği için içindeki listedeki anlayışı atlayabilirsiniz . Sadece kaldırın []ve 2 bayt daha kaydedin :)
movatica

1
Teşekkürler! range(1,6,2)daha da iyidir[1,3,5]
Grzegorz Oledzki

1
Jonathan Allen, mz Pzthon3 versiyonunda yuvarlama için farklı bir numara önerdi. Burada da geçerlidir: lambda x:'#'+''.join(hex((int(x[i:i+2],16)+8)/17)[2:]for i in[1,3,5])-> 69 bayt
movatica

1

Perl 5 -p , 35 34 bayt

@nwellnhof bir bayt kaydetti

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

Çevrimiçi deneyin!

STDIN'den okur, en yakını #bulmak için 17 yöntemiyle bölmeyi kullanarak uygun tek karaktere sahip olmayan her bir öğe çiftini değiştirir , ardından -psonucu örtük olarak verir ( ).


1

Python 3, 67 bayt

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

Hoşgeldiniz. Kodunuzu çalıştırabileceğimiz TIO gibi bir çevrimiçi tercümana açıklama, açıklama veya bağlantı eklemeyi düşünün . Yalnızca kod yanıtları, otomatik olarak düşük kaliteli olarak işaretlenme eğilimindedir. Örnekler için mevcut diğer cevaplara bakınız.
mbomb007

0

Kırmızı , 103 bayt

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

Çevrimiçi deneyin!

Red'in mevcut Linux sürümünün bir uygulamasının bulunmadığı ortaya çıktı.hex-to-rgb fonksiyonun , bu yüzden temel dönüşümü "elle" yapıyorum :)

Bu kırmızı iyi çalışıyor , Windows'taki GUI konsolunda :

Kırmızı , 94 bayt

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

Kömür , 22 bayt

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

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı bir versiyonudur. Açıklama:

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

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

Burada dene.

NOT: Yukarıdaki link bir an yükseltirse ImportError, buraya gidin ; Şu anda "resmi" sayfada bir hata var ve bu Maltysen tarafından geçici bir çözüm . Bu bağlantı resmi olan sabitlendikten sonra çalışmayı durdurabilir.


0

İleri (gforth) , 87 bayt

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

Çevrimiçi deneyin!

açıklama

  1. Girişin ilk karakterini yoksay / kes# ) '
  2. Tercümanı onaltılık moda ayarlayın
  3. Çıktı #
  4. Her döngüde 3 kez döngü yapın:
    1. Dize başlangıç ​​adresine 2 ekleyin
    2. Dizedeki sonraki 2 karakteri onaltılık bir sayıya dönüştürme
    3. Bölüm ve modülü 17'ye kadar kullan (0x11Kısaltılmış bileşene en yakın değeri elde etmek için ) kullanın
    4. Öncesinde boşluk olmayan çıktı
  5. Tercümanı Ondalık moda ayarlayın

Kod Açıklaması

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

Çözüm:

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

Açıklama:

Bu cevapların çoğuyla aynı stratejiyi kullanır (ör. 8, 17'ye böl).

"#",{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 "#"

Ekstra:

  • "#",{x@*16\:a?&/a:abs(17*!16)-16/:x?y}[.Q.nA]@/:3 2#1_- 54 bayt için orijinal fikrim
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.