ตัวแปลงสี RGB เป็น Xterm


13

หน้าจอเทอร์มินัลที่รองรับ Xterm 256 สีเพิ่ม 240 สีด้านบนของสีระบบ 16 สีปกติ สี 16-231 ใช้ 6 ระดับ (0, 95, 135, 175, 215, 255) สีแดงสีเขียวและสีน้ำเงินเรียงคำศัพท์ สี 232-255 เป็นสีเทาเพียง 24 ระดับ (8 ... 238 คูณ 10 วินาที) เพื่อให้ได้แนวคิดที่ดีขึ้นเกี่ยวกับสิ่งที่ฉันกำลังพูดถึงดูตารางนี้

ความท้าทาย

เป้าหมายของคุณคือสร้างโปรแกรมหรือฟังก์ชั่นที่ใช้ป้อนค่า rgb และส่งออกหมายเลขที่สอดคล้องกับสี Xterm ที่ใกล้เคียงที่สุดกับค่า rgb นั้น เนื่องจากสีของระบบ 16 สี (สี 0-15) มักจะสามารถปรับแต่งได้คุณจะไม่รวมค่าเหล่านี้จากการแปลงนี้

เพื่อกำหนดสิ่งที่สี "ใกล้เคียงที่สุด" ให้ใช้ระยะทางแมนฮัตตันตามส่วนประกอบสีแดงสีเขียวและสีน้ำเงิน ยกตัวอย่างเช่นrgb(10, 180, 90)เป็น 20 หน่วยออกไปจากrgb(0, 175, 95)(สี 35) abs(10 - 0) + abs(180 - 175) + abs(90 - 95) == 20เพราะ หากสีอินพุตมีค่าเท่ากันระหว่างสี Xterm สองสีหรือมากกว่าให้เอาต์พุตสี Xterm พร้อมกับดัชนีสูงสุด

ตัวอย่าง

 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

กฎระเบียบ

  • ช่องโหว่มาตรฐานเป็นสิ่งต้องห้าม
  • โปรแกรมหรือฟังก์ชั่นของคุณได้รับอนุญาตให้รับค่า rgb ในรูปแบบที่เหมาะสมรวมถึง:
    • แยกอาร์กิวเมนต์สำหรับสีแดงสีเขียวและสีน้ำเงิน
    • รายการ tuple พจนานุกรมหรือที่คล้ายกัน
    • สตริงหรือ stdin ที่คั่นด้วยตัวคั่น
    • สีหกเหลี่ยม (เช่น#ff8000)
  • คุณอาจคิดว่าค่า r, g และ b ทั้งหมดจะเป็นจำนวนเต็มตั้งแต่ 0 ถึง 255
  • เนื่องจากสีของระบบ 16 จะถูกแยกออกจากการทำแผนที่ผลลัพธ์ทั้งหมดควรอยู่ในช่วง 16 ... 255

นี่คือดังนั้นรหัสที่สั้นที่สุดจึงชนะ

คำตอบ:


4

Haskell , 132 ไบต์

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

ลองออนไลน์!

[red, green, blue]จะเข้าเป็นรายการของจำนวนเต็ม

การใช้งานที่ตรงไปตรงมาเป็นธรรม ก่อนอื่นฉันสร้างรายการสี Xterm ที่เราใช้กับความเข้าใจสองรายการที่ต่อกัน ครั้งแรกที่จัดการสี 16-231 โดยทำซ้ำสามครั้งvซึ่งมีค่าสีที่ใช้ อันที่สองแค่วนซ้ำค่าสีเทาและใส่ไว้ในช่องทั้งสาม จากนั้นฉันสร้างดัชนีด้วย zip (เริ่มต้นที่ 16) และสร้างคู่ที่มีระยะทางแมนฮัตตัน (เมื่อตะกี้) และดัชนีนั้นและใช้ค่าสูงสุด -ผมใช้สูงสุดเพราะเราผูกหมดในดัชนีที่ใหญ่ที่สุดและด้วยวิธีนี้กำลังช่วยฉันหนึ่งเป็นพิเศษ


3

Ruby , 280 180 166 164 155 ไบต์

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

ลองออนไลน์!

แลมบ์ดาที่ใช้สีอินพุตเป็นอาร์เรย์ของจำนวนเต็ม

ฉันมีปัญหาในการสร้างสี Xterm มากกว่าที่คาดไว้! ผมเตรียมที่จะ outgolfed เปิ่นสุภาพในพื้นที่นั้น ฉันใช้การแปลงฐานเป็นการบีบอัดชนิดแต่วิธีเดียวที่ฉันรู้ใน Ruby คือการผ่านInteger#to_sซึ่งค่อนข้างอึดอัดเล็กน้อย

-100 ไบต์: อ่านปัญหาให้ละเอียดยิ่งขึ้นและละเว้นสีของระบบ 16 สี ^ _ ^;

-14 ไบต์: ใช้การแปลงฐานมือแทน .to_s(6)

-2 ไบต์: ข้ามวงเล็บเหลี่ยมเมื่อประกาศอาร์เรย์

-9 ไบต์: สร้างรายการของสี Xterm มีเพียงหนึ่งmap; นอกจากนี้ยังช่วยประหยัดเครื่องหมายบวกและคู่ของ parens

->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 สี บางทีฉันควรทำให้ชัดเจนขึ้นในคำอธิบาย
Beefster

โอ้วนั่นจะช่วยฉันสักหน่อย! ฉันพลาดแน่นอนในถ้อยคำคำถามเดิม
benj2240

1

Kotlin , 299 290 267 265 bytes

(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

เชิดชู

(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

ทดสอบ

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

แบตช์ 266 ไบต์

@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) 202 192 157 150 (141 บั๊ก) 138 134 ไบต์

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;}

ขอบคุณ @ceilingcat

ลองออนไลน์!


1
ปัญหาไม่ได้ถูกกำหนดโดยการทดสอบ (ซึ่งระบุไว้อย่างชัดเจนว่าเป็นตัวอย่าง) ดังนั้นโปรดเพิ่มการทดสอบใหม่แทน
Ton Hospel

1
@ TonHospel ฉันแก้ไขข้อผิดพลาดในขณะนี้และลดลง -3 bytes แต่ขอบคุณสำหรับคำตอบ
PrincePolka
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.