RGB - Xterm Renk Dönüştürücü


13

256 renkli Xterm uyumlu terminaller, normal 16 sistem renginin üstüne 240 renk ekler. Renkler 16-231, sözlükbilimsel olarak sıralanan 6 düzey (0, 95, 135, 175, 215, 255) kırmızı, yeşil ve mavi kullanır. 232-255 renkleri basitçe 24 gri seviyesidir (8 ... 238 x 10s). Neden bahsettiğim hakkında daha iyi bir fikir edinmek için bu tabloya bakın .

Meydan okuma

Amacınız giriş olarak rgb değerlerini alan ve o rgb değerine en yakın Xterm rengine karşılık gelen sayıyı çıkaran bir program veya işlev yapmaktır. 16 sistem rengi (0-15 renk) genellikle özelleştirilebilir olduğundan, bunları bu dönüşümden hariç tutarsınız.

"En yakın" rengin ne olduğunu daha iyi tanımlamak için kırmızı, yeşil ve mavi bileşenler boyunca Manhattan mesafesini kullanın . Örneğin, çünkü rgb(10, 180, 90)20 birim rgb(0, 175, 95)(renk 35) uzaktır abs(10 - 0) + abs(180 - 175) + abs(90 - 95) == 20. Giriş rengi iki veya daha fazla Xterm rengi arasındaysa, Xterm rengini en yüksek dizine sahip olarak çıkarın.

Örnekler

 R   G   B     Xterm
  0   0   0 ==> 16
 95 135   0 ==> 64
255 255 255 ==> 231
238 238 238 ==> 255

 90 133 140 ==> 66
218 215 216 ==> 188
175 177 178 ==> 249

175   0 155 ==> 127
 75  75  75 ==> 239
 23  23  23 ==> 234
115 155 235 ==> 111

kurallar

  • Standart boşluklar yasaktır
  • Programınızın veya fonksiyonunuzun rgb değerlerini makul bir formatta almasına izin verilir, örneğin:
    • Kırmızı, yeşil ve mavi için ayrı argümanlar
    • Liste, grup, sözlük veya benzeri
    • Sınırlayıcı ile ayrılmış dize veya stdin
    • Onaltılık renkler (örn. #ff8000)
  • Tüm r, g ve b değerlerinin 0 ile 255 arasında bir tamsayı olacağını varsayabilirsiniz.
  • 16 sistem rengi eşlemeden çıkartılacağından, tüm çıktılar 16 ... 255 aralığında olmalıdır.

Bu , bu yüzden en kısa kod kazanır.

Yanıtlar:


4

Haskell , 132 bayt

v=0:[95,135..255]
f c=snd$maximum[(-sum(abs<$>zipWith(-)c x),i)|(i,x)<-zip[16..]$[[r,g,b]|r<-v,g<-v,b<-v]++[[g,g,g]|g<-[8,18..238]]]

Çevrimiçi deneyin!

Girdiyi tamsayıların bir listesi olarak alır [red, green, blue].

Oldukça basit uygulama. İlk olarak, birlikte sıralanan iki liste kavrayışı ile kullandığımız Xterm renklerinin bir listesini oluşturuyorum. Bunlardan ilki, vrenklerin kullandığı değerleri içeren üçlü yinelemeyle 16-231 arasındaki renkleri işler . İkincisi, gri değerlerin üzerinde tekrarlar ve bunları her üç yuvaya da koyar. Sonra zip (16 ile başlayan) ile dizin ve manhattan mesafe (negatif) ve bu endeksi ile bir çift yapmak ve maksimum almak. Maksimum kullandım çünkü en büyük endekse bağlantımız var ve bu şekilde beni fazladan kurtarıyor -.


3

Yakut , 280 180 166 164 155 bayt

->c{d=0,95,135,175,215,255
a=(0..239).map{|n|n<216?[d[n/36],d[(n%36)/6],d[n%6]]:[n*10-2152]*3}.map{|t|t.zip(c).map{|a,b|(a-b).abs}.sum}
a.rindex(a.min)+16}

Çevrimiçi deneyin!

Giriş rengini tamsayılar dizisi olarak alan lambda.

Xterm renklerini üretmekten beklediğimden daha fazla sorun yaşadım! O bölgede utanç verici bir şekilde alçakgönüllü olmaya hazırım . Baz dönüşümünü bir tür sıkıştırma olarak kullandım, ancak Ruby'de bunu yapmanın tek yoluInteger#to_s biraz garip.

-100 bayt: Sorunu daha dikkatli okuyun ve 16 sistem rengini dikkate almayın ^ _ ^;

-14 bayt: El tabanı dönüşümünü kullanın .to_s(6)

-2 bayt: Dizi bildirirken köşeli parantezleri atla

-9 bayt: Xterm renklerinin tek bir listesini oluşturun map; bu ayrıca bir artı işareti ve bir çift paren tasarrufu sağlar.

->c{
  d=0,95,135,175,215,255                 # d is the set of possible RGB values
  a=(0..239).map{|n|                     # Create the array of Xterm triplets
    n<216 ? [d[n/36],d[(n%36)/6],d[n%6]] # Convert x from base 6 to base d, or
          : [n*10-2152]*3                #   create a uniform triplet
  }.map{|t|
    t.zip(c).map{|a,b|(a-b).abs}.sum     # Map from triplets to Manhattan distance
  }
  a.rindex(a.min) +                      # Find the last index of the lowest distance
  16                                     # Offset for the exluded system colors
}

1
BTW, 16 sistem rengini eşlemenize gerek yoktur. Belki bunu açıklamada daha açık hale getirmeliyim.
Beefster

Ooh, bu bana biraz yardımcı olacak! Orijinal soru ifadelerinde kesinlikle kaçırdım.
benj2240

1

Kotlin , 299 290 267 265 bayt

(16..255).associate{it to if(it<232)(it-16).let{i->listOf(0,95,135,175,215,255).let{l->listOf(l[i/36],l[(i/6)%6],l[i%6])}}else(8..238 step 10).toList()[it-232].let{listOf(it,it,it)}}.minBy{(k,v)->(it.zip(v).map{(a,b)->kotlin.math.abs(a-b)}.sum()*256)+(256-k)}!!.key

Beautified

(16..255).associate {
    it to if (it < 232) (it - 16).let { i ->
            listOf(0, 95, 135, 175, 215, 255).let { l ->
                listOf(
                        l[i / 36],
                        l[(i / 6) % 6],
                        l[i % 6])
            }
        } else (8..238 step 10).toList()[it - 232].let { listOf(it, it, it) }
}.minBy { (k, v) ->
    (it.zip(v).map { (a, b) -> kotlin.math.abs(a - b) }.sum() * 256) + (256 - k)
}!!.key

Ölçek

data class Test(val r: Int, val g: Int, val b: Int, val out: Int)

val test = listOf(
        Test(0, 0, 0, 16),
        Test(95, 135, 0, 64),
        Test(255, 255, 255, 231),
        Test(238, 238, 238, 255),

        Test(90, 133, 140, 66),
        Test(218, 215, 216, 188),
        Test(175, 177, 178, 249),

        Test(175, 0, 155, 127),
        Test(75, 75, 75, 239),
        Test(23, 23, 23, 234),
        Test(115, 155, 235, 111)
)
fun z(it:List<Int>): Int =
(16..255).associate{it to if(it<232)(it-16).let{i->listOf(0,95,135,175,215,255).let{l->listOf(l[i/36],l[(i/6)%6],l[i%6])}}else(8..238 step 10).toList()[it-232].let{listOf(it,it,it)}}.minBy{(k,v)->(it.zip(v).map{(a,b)->kotlin.math.abs(a-b)}.sum()*256)+(256-k)}!!.key

fun main(args: Array<String>) {
    for (i in test) {
        val r = z(listOf(i.r, i.g, i.b))
        println("$i ${i.out} ==> $r")
    }
}

TIO

TryItOnline


1

Toplu, 266 bayt

@set/ax=15,m=999
@set s=for %%b in (0 95 135 175 215 255)do @
@%s:b=r%%s:b=g%%s%call:c %* %%r %%g %%b
@for /l %%g in (8,10,238)do @call:c %* %%g %%g %%g
@echo %n%
:c
@set/ax+=1,r=%4-%1,g=%5-%2,b=%6-%3
@set/ad=%r:-=%+%g:-=%+%b:-=%
@if %d% leq %m% set/an=x,m=d


1

C (gcc), 2021921515150 (141 hata çıktı) 138 134 bayt

l,m,t,i;a(c,x){x=abs(c-=i>215?i*10-2152:x*40+!!x*55);}f(r,g,b){for(i=l=240;i--;t=a(r,i/36)+a(g,i/6%6)+a(b,i%6),t<l?l=t,m=i:1);i=m+16;}

Teşekkürler @ceilingcat

Çevrimiçi deneyin!


1
Sorun testler tarafından tanımlanmamıştır (bunlar açıkça örnek olarak etiketlenmiştir), bu yüzden lütfen bunun yerine yeni bir test ekleyin.
Ton Hospel

1
@TonHospel Hatayı şimdi düzelttim ve -3 bayt kestim, ancak cevap için teşekkürler
PrincePolka
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.