Tamamlayıcı renkler


26

#rrggbbOnaltılık formatta bir renk girişi verildiğinde , RGB tamamlayıcısını aynı formatta çıkar.

RGB tamamlayıcı R 2 G 2 B 2 herhangi bir renk R 1 G 1 B 1 R formülüne sahip bir renk olarak tanımlanır 2 değeri 255 - R ' 1 , B 2 değeri 255 - B 1 ve G 2 değeri 255 - G 1 .

Onaltılık rakamlar büyük harf (# FFAA20) veya küçük harf (# ffaa20) olabilir. Giriş ve çıkış durumunun tutarlı olması gerekmez (bu nedenle küçük harfle giriş alabilirsiniz, büyük harfle çıktı alabilirsiniz; bunun tersi de geçerlidir).

Bu olduğundan, bayttaki en kısa kod kazanır.

Test durumları (programınıza / işleve kendi çıktısını vermeniz orijinal girdiyle sonuçlanmalıdır ( test edicidir ), test durumlarının her iki yönde de çalışması gerekir):

In/Out   Out/In
----------------
#ffffff  #000000
#abcdef  #543210
#badcab  #452354
#133742  #ecc8bd
#a1b2c3  #5e4d3c
#7f7f80  #80807f

2
Üzgünüm, ama sRGB bu şekilde çalışmıyor. İlk önce, altıgen kodların girmediği doğrusal alana dönüştürmelisiniz.
John Dvorak

2
@JanDvorak Oh iyi. Meydan okuyuşun durumu cehaletimi yansıtacak, o zaman, çünkü şimdi gerçekten değiştiremiyorum. : P
Doorknob

SRGB'de iki değerin ortalaması alındığında, ayrı bir zorluk olabilir. sRGB = RGB ^ aralığın çoğunda 0.45, ancak aralığın altına doğrusal.
John Dvorak

Yanıtlar:


17

Pyth, 9 8 bayt

-1 bayt için @isaacg'a teşekkürler!

sXz.HM16

Belirli bir rengin değerini 255'ten çıkarmak, onaltılık basamakların her birini 15'ten çıkarmaya eşdeğerdir. Sayının 16a + b olduğunu söyleyin . Ardından rakamlarını 15'ten çıkartarak oluşturulan sayının değeri 16 (15-a) + (15-b) = 255 - (16a + b) olur .

sXz.HM16     implicit: z=input()
      16      
   .HM        map hex representation over range
   .HM16     '0123456789abcdef'
  z           the input string
 X            Translate characters in x1 present in x2 to reversed x2
              that is, '0' becomes f, '1' becomes 'e', and so on.
              The initial '#' is unchanged.
s             That produced a list, so join into a string by reducing +

Burada dene . Test odası.


Güzel cevap! Kullanma fikrini ödünç aldım.'0123456789abcdef'Onaltılık dönüştürmek için ( dec2hexişlev yerine )
Luis Mendo

Bence bağlantın yanlış. ( Kopyala yapıştır FTW). )
PurkkaKoodari

@ Pietu1998 Whoops; Düzelteceğim.
lirtosiast

UGereksizdir - bu örtük tarafından doldurulur oluyor M.
isaacg, 11

6

Retina, 13 10 bayt

T`w`G-A9-0

Kodda, backticks ( `) ile ayrılan üç bölüm vardır : Tikinci bölümdeki her bir karakteri üçüncü bölümdeki karşılık gelen karakterle değiştiren transliterat modunu belirtir.

wgeleneksel regex'lerin aynısıdır \wveya _0-9A-Za-zgenişletilir _0123456789ABCDEFGH....

İkinci kısım, GFEDCBA9876543210Retina'nın ters sırada genişleme yeteneği sayesinde genişletildi. Bunları üst üste koyun ve şunu elde ederiz:

_0123456789ABCDEFGH...
GFEDCBA987654321000...
 ^^^^^^^^^^^^^^^^

Son karakterin, 0daha uzun dizenin uzunluğuna uyması için tekrarlandığını unutmayın , ancak sadece çizgi harflerle gösterilen onaltılık karakterleri önemsiyoruz.

Martin Büttner'e bu yaklaşımı önerdiği için teşekkür ederiz.

Test paketini çevrimiçi olarak deneyin.


4

Mermer, 41 bayt

00@0
\\]]\/
-W/\@0
-W
~~
<A+700
+O//]]
+O

Çevrimiçi Tercüman burada. Giriş büyük harf olmalıdır.

açıklama

00ve]] altta (ilk karakteri alıp bunu #) ve altına düşecek ve her şeyden önce outputted.

İlk 3 satır, kalan tüm karakterleri almak için kullanılan bir döngüdür.

İlk önce, altıgen basamaklı karakterleri 0-15 değerine dönüştürmeliyiz, x -= 48, x -= x > 9 ? 7 : 0çünkü'A' - '9' 8 olduğundan) .

Tamamlayıcıyı bulmak için, sadece her basamağa çevirmemiz xgerekir 15-x. Buna eşittir (8 bitlik değerler için)(~x)+16 = ~(x-16) .

Son olarak, bu sayıları yaparak onaltılık hanelere dönüştürmeliyiz. x += x > 9 ? 7 : 0, x += 48 .

Öyleyse şimdi sahibiz x -= 48, x -= x > 9 ? 7 : 0, x = ~(x - 16), x += x > 9 ? 7 : 0, x += 48.

İfadeyi ilk üçlü operatörle kaldırırsak, o zaman giriş haneleri A- Folumsuzlamadan sonra x değerinin negatif çıkacağına dikkat edin.

Böylece önceki ifadeyi x -= 48, x -= 16, x = ~x, x += (x > 9 || x < 0) ? 7 : 0, x += 48şuna değiştirebiliriz : eşittir x -= 64, x = ~x, x += (x > 9 || x < 0) ? 7 : 0, x += 48.

Yukarıdaki kod sadece son ifadenin bir uygulamasıdır. -Wolduğu x -= 32ve +Obir x += 24. Marbelous işaretsiz 8 bit aritmetik, durumu kullandığından <Akapakları hem vakasını x > 9ve x < 0.


Marbelous'u yarattın mı?
Rɪᴋᴇʀ

@RikerW Marbelous, kendim dahil birkaç PPCG kullanıcısı tarafından yaratıldı / canlandı: Burada görün .
es1024

Tamam. Bana bildirdiğiniz için teşekkürler.
Rɪᴋᴇʀ

4

JavaScript ES6, 61 bayt 66 68 48 53 64

@ Cᴏɴᴏʀ O'Bʀɪᴇɴ, @NinjaBearMonkey ve @nderscore sayesinde epeyce bayt kazandırır

s=>"#"+(1e5+(8**8+~('0x'+s.slice(1))).toString(16)).slice(-6)

Otomatik tip dökümden faydalanır. Sıfırları düzeltmek bayt sayısını öldürdü


Yerine eval(`0x${s.slice(1)}`)kullanınparseInt
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Aynı uzunluk mu?
PurkkaKoodari

CᴏɴᴏʀO'Bʀɪᴇɴ sayesinde @, kullandığım - yerine daha kurtardı bayt eval
Downgoat

Ah, otomatik döküm türünü unuttum: D
Conor O'Brien 0

Girişle deneyin #FFFFFF. Döner #0.
Conor O'Brien,

4

JavaScript ES6, 63 58 52 49 bayt

c=>c.replace(/\w/g,x=>(15-`0x${x}`).toString(16))

11 byte tasarruf ettiğin için nderscore'a teşekkürler !


-5 bayt:c=>"#"+[...c].map(x=>"fedcba9876543210"[+('0x'+x)]).join``
08'de 08:06

@ Tam olarak, zaten bunun hakkında düşündüm :) Teşekkürler. Kullanacaktı ama "eval" ile.
nicael

1
ah, bir tane daha var -6:c=>c.replace(/\w/g,x=>"fedcba9876543210"[+('0x'+x)])
nderscore

3

Jolf, 17 bayt

pq#-w^88C Li1~560
pq                pad
         _Li1     the input, w/out the first char
        C    ~5   parsed as a base-16 integer (~5 = 16)
    w^88          8 ^ 8 - 1 (the magic number)
   -              subtract the parsed input from said number
  #               convert result to hexadecimal
               60 pad the result with 6 0's

Burada dene! , Test paketi (Şimdi çalışan tam çalışmayı kullanın.)


3

Julia, 74 49 bayt

h->"#"join([hex(15-parse(Int,i,16))for i=h[2:7]])

Şu anda oldukça uzun ama bu bir başlangıç. Bu, bir dizgeyi kabul eden ve bir dize döndüren bir lambda işlevidir. Çıktı küçük harf olur, ancak girdi ikisinde de olabilir.

Gibi Thomas kaydetti , 255 her 2 basamaklı renk bileşeni çıkarılarak, giriş dizesi üzerinde döngü 15'ten onaltılık girişinde her haneyi çıkararak lider hariç eşdeğerdir #, biz 15 dönüştürmek - çözümlü haneyi onaltılık. Bunların hepsine katılıyoruz, sonra uğraşıp #iyi diyoruz.


3

Japt , 35 32 22 20 16 15 bayt

¡Y?(F-XnG)sG :X

Açıklama:

¡                 //Take input and map (shortcut to "Um@"). Input should in the form of "#123456"
 Y?               //if Y is not 0, then return (F-XnG)sG, otherwise last step...
    F-XnG           //Subtract X, converted from hexadecimal (G is 16) to decimal, from 15
          sG        //convert decimal to hexadecimal
             :X   //...otherwise return X unchanged (happens only with #, the first char)

Güzel bir! Bunu dün gece gördüm ve kendi kendime "Yarın golf oynamak için yardım edeceğim" dedim. Ama şimdiye kadar mümkün düşündüğümden daha fazla golf oynadın. :)
ETHproductions

2

Perl, 30 bayt

için +1 içerir -p

s/\w/sprintf"%x",15&~hex$&/eg

kullanım: echo #000000 | perl -p file.pl
veya echo #000000 | perl -pe 's/\w/sprintf"%x",15&~hex$&/eg'.


2

MATL , 21 bayt

35,5Y216,j6L)!16ZA-)h

Bu 6.0.0 sürümünü kullanır. , zorluktan önceki dil / derleyicinin .

Giriş haneleri büyük harf olmalıdır.

Örnek

Bu Octave'da yapıldı:

>> matl
 > 35,5Y216,j6L)!16ZA-)h
 >
> #FFAA20
#0055DF

Düzenle (12 Haziran 2016)

Kod şimdi çevrimiçi olarak denenebilir . Virgül boşluklarla ve değiştirilmesi gereken 6Ltarafından 4Ldilinde değişikliklere uymak için.

açıklama

35,             % number literal: ASCII code of '#'
5Y2             % '0123456789ABCDEF'
16,             % number literal
j               % input string
6L)             % remove first element
!               % transpose
16ZA            % convert from hex to dec
-               % subtract from 16
)               % index into '0123456789ABCDEF' to convert back to hex
h               % prepend 35, which gets automatically converted into '#'

1

Pyth, 20 19 bayt

Xnor sayesinde 1 bayt .

%"#%06x"-t^8 8itz16

Çevrimiçi deneyin. Test odası.

açıklama

  • z giriş
  • tz kaldırır #
  • itz16 onaltılık bir sayı olarak ayrıştırır
  • t^8 88 8 hesaplar - 1
  • -t^8 8itz168 8 - 1 - girişini hesaplar
  • %"#%06x"-t^2 24itz16 sıfır-yastıklı 6 karakterli altıgen bir dizgeye formatlar #

2 ^ 24 için 8 ^ 8 nasıl?
xnor

1

Haskell, 85 bayt

İlk gönderim, muhtemelen en uzun (85 bayt) olacak, fakat hey, bir yerden başlamalısınız. Haskell'de:

import Numeric;f=('#':).concatMap((flip showHex)"".(15-).fst.head.readHex.(:[])).tail

Diğer insanların kullandıklarını gördüğüm 15 numaradan aynı çıkarmayı kullanıyor.

Ayrıca printf'i diğer numarayla birlikte kullanmayı denedim (8 ^ 8 - 1 çıkarma) ve ghci'de çalışıyor, ancak bir nedenden dolayı derleme yapmıyor:

g=printf "#%06x" .(8^8-1-).fst.head.readHex.tail

Biri bu işi başarabilseydi bu harika olurdu!


Programming Puzzles ve Code Golf'a hoş geldiniz. Bunlar çok güzel cevaplar (Haskell'de yapabileceğimden daha iyi!). Bununla birlikte, Lider Tablosu pasajının yanıtınızı lider panosuna koymasını sağlayan kod golf sorunları için ortak bir cevap formatı vardır. Sizin için düzenleyeceğim; düzenlemeyi kabul edebilir veya reddedebilirsiniz.
wizzwizz4

Diğer kullanıcıların yorumlarını yanıtlamak için yazın @username.
wizzwizz4

@ wizzwizz4 Yardımınız için çok teşekkürler.
lpapez

İstediğin zaman! Bazı zorluklarıma katılmak ister misin? Hilbert eğrisi gerçekten zor olsa da, sandalyenizi analiz edin ve Map string'i Hilbert Curve ' de favorilerim.
wizzwizz4

@ wizzwizz4 Kesinlikle, ne yapabilirim göreceğim.
lpapez

1

Mathematica, 69 60 bayt

"#"<>IntegerString[8^8-#~StringDrop~1~FromDigits~16-1,16,6]&

Bir kez daha, beni burada öldüren string işleme.


1

C, 94 bayt

t(char*b){for(int i;i=*b;++b)*b=i>96&i<103?150-i:i>64&i<71|i>47&i<54?118-i:i>53&i<58?111-i:i;}

İşlev bir karakter dizisinde yer alır, ters değer döndürür. Yanıt için büyük harfler üretir. Kod, her ASCII hex karakterini, geçerli olması durumunda tersine çevirir, aksi halde yoksayar.


iFonksiyondan önce global olarak ilan ederek biraz yer kazanabilirsiniz :i;
Liam

1

𝔼𝕊𝕄𝕚𝕟 2, 18 karakter / 34 bayt

ïē/\w⌿,↪(ḏ-`ᶍ⦃$}”ⓧ

Try it here (Firefox only).

Mücadeleden sonra oluşturulan bir sürümü kullanarak.

açıklama

ïē/\w⌿,↪(ḏ-`ᶍ⦃$}”ⓧ // implicit: ï=input, ḏ=15
ïē/\w⌿,             // replace all alphanumeric chars in ï with:
       ↪(ḏ-`ᶍ⦃$}”ⓧ // (15 - char's decimal form) converted to hex
                    // implicit output

Rekabetçi olmayan çözüm, 15 karakter / 29 bayt

ïē/\w⌿,↪(ḏ-`ᶍ⦃$}”ⓧ

Harf çevirisi kullanır.


Rekabetçi bir sürüm ekleyebilir misiniz, böylece dilin nasıl yığıldığını görebiliriz?
lirtosiast

Emin. Yeni düzenlemeye bakın.
Mama Fun Roll

APL sembolünün güzel kullanımı .
lirtosiast

Hehe, bu sembol en mantıklı olanıydı /g.
Mama Fun Roll

1

Python, 96

x=input()
print("#")
for i in range(3):
    print(hex(255-int(x[(1+2*i)]+x[(2+2*i)],16))[2:4])

İlk kod golf, lütfen görüşlerini bildirin :)


Girişin "quotes"btw cinsinden olmasına izin verilir , bu yüzden input()işe yarar . Newline ve forent döngüsüne girintiye ihtiyacınız yok ve rangegayet iyi çalışıyor. Ayrıca kaldırabileceğiniz birkaç boşluk var.
Rɪᴋᴇʀ

int("ff", 16)sadece ile değiştirilebilir 255.
Doorknob

Her x'ten sonra parantez içindeki parantezlere mi ihtiyacınız var?
Mavi

0

CJam, 16 bayt

qA,'G,65>+s_W%er

Bu oldukça uzundur, çünkü CJam baz değişimlerini farklı şekilde ele alır, bu yüzden sadece harf çevirisi yapmak daha kısadır. Retina cevabımı görHarf çevirisi hakkında daha fazla bilgi için .

Çevrimiçi deneyin.

açıklama

q      e# Get the input
A,     e# Push [0 1 ... 8 9]
'G,65> e# Push "ABCDEF"
+s     e# Combine and convert to string
_W%    e# Make a copy and reverse it
er     e# Replace each character in the first string with
       e# the corresponding character in the second

0

Python 3, 44 bayt

Başlangıçta kullandığım 256^3sonra 16^6. Sonra Pietu1998'leri gördüm 8^8ve şimdi bu çözüm onun yerine kullanıyor.

"#{:06x}".format(8**8-1-int(input()[1:],16))

0

Java, 95 90 bayt

String f(String v){return v.format("#%06x",0xFFFFFF^Integer.parseInt(v.substring(1),16));}

Bitsel XOR.


0

Bash + tr, 35 bayt

tr 0-9A-Fa-f fedcba9876543210543210

Çıkış her zaman küçük harf olur.

Maalesef "tr" sırayla aralıkları almıyor, bu yüzden onları hecelemek zorunda kaldım.


0

C, 147 bayt

void p(char s[]){char c[3];int i=1;printf("#");while(i<6){strncpy(c,s+i++,2);i++;int x=255-strtol(c,NULL,16);x<10?printf("0%x",x):printf("%x",x);}}

Onaltılı dizeden int'ye dönüştürmek için strtol kullanılır, ardından orijinal yazıdaki gibi iltifat almak için sayı 255'ten çıkarılır. Bununla birlikte, s'den strtol'e bir dizi karakter iletmenin bir yolu olup olmadığını merak ediyorum, bu yüzden yeni bir dizgiye kopyalayarak bir sürü bayt harcamam gerekmiyor mu?


Derleyicilerin genellikle işlev iadelerini zorladığını ve int komutunu varsayılan olarak kullandıklarını sanmıyorum, bu yüzden muhtemelen voidgeri dönüş türünü atlıyorsunuzdur ?
Liam,

0

R, 62 bayt

f=function(a)sprintf('#%06x',(8^8-1)-strtoi(substr(a,2,7),16))

0

sed, 48 bayt

y/0123456789ABCDEFabcdef/fedcba9876543210543210/

Ya da yalnızca bir vakayı desteklemeniz gerekiyorsa 36 bayt.


Hem küçük hem de büyük harf desteklemeniz gerekmez.
Martin Ender

@ MartinBüttner sorusu, girdideki her iki durumda da desteğe ihtiyaç duyuyor ancak çıktıda değil. Bash + tr çözümüm gibi, bu çözüm de hem girişi destekliyor hem de sadece küçük harfli çıktı yazıyor.
Glenn Randers-Pehrson

Fazladan var 0arasına, kodunuzda 9ve A(bayt sayısı doğru olsa, bir kopyalama hatası olmalıdır).
Ocaklar

Soru, giriş ve çıkışınızın hangi durumda olacağını seçebileceğinizi söylüyor.
lirtosiast

0

PowerShell, 48 bayt

param($a)"#{0:x6}"-f(16MB-1-("0x"+$a.Trim('#')))

Mutlaka veya param($a)ile ayrılmış bir dize olarak giriş yapar , çünkü'"C:\Tools\Scripts\Golfing> .\complementary-colors #a1b2c3 davranacak PowerShell komut satırında#a1b2c3 yorum olarak ve özetle bunu görmezden.

Soldan sağa, "#{0:x6}"-f(...)çıktı hesaplamaları garantili 6 karakterle (girişi hesaba katan) onaltılık biçimde biçimlendirir #ffffff. Ebeveynlerin içinde giriş numaramızı çıkardık 0xffffff. Bunu, PowerShell'in onaltılık sayıları biçiminde ayrıştırma gerçeğinden yararlanarak yaparız 0xNNN, bu nedenle giriş numaramızdan uygun biçimde bir altıgen sayı oluştururuz $a. (Birleştirme artı burada bir bayttan .Trim()daha kısa olduğuna dikkat edin .Replace().) Ayrıca, MBunary operatörünü bunun yerine 16MB-1inşa etmek için 16777215kullanırız 0xffffff.


0

TeaScript, 24 bayt

"#"+S(8**8-1-xS1)t16))x6

Bugs in the interpreter aren't letting me get this shorter :(

Try it online


Downvote explanation? It works for all the test cases
Downgoat
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.