Kolory uzupełniające

26

Biorąc pod uwagę wejście koloru w #rrggbbformacie szesnastkowym, wypisz jego dopełnienie RGB w tym samym formacie.

RGB dopełniacza R 2 G 2 B 2 dowolnego koloru R 1 G 1 B 1 jest zdefiniowany jako kolor z R 2 wartości 255 - R 1 , B 2 wartości 255 - B 1 i G 2 wartości 255 - G 1 .

Cyfry szesnastkowe mogą być pisane dużymi literami (# FFAA20) lub małymi literami (# ffaa20). Przypadek wejścia i wyjścia nie musi być spójny (więc możesz brać dane wejściowe małymi literami, ale dane wyjściowe dużymi literami i odwrotnie).

Ponieważ jest to , wygrywa najkrótszy kod w bajtach.

Przypadki testowe (zwróć uwagę, że ponieważ nadanie programowi / funkcji własnego wyniku powinno dawać oryginalne dane wejściowe (jest to ewolwenta ), przypadki testowe powinny działać w obu kierunkach):

In/Out   Out/In
----------------
#ffffff  #000000
#abcdef  #543210
#badcab  #452354
#133742  #ecc8bd
#a1b2c3  #5e4d3c
#7f7f80  #80807f
Klamka
źródło
2
Przepraszam, ale sRGB nie działa w ten sposób. Najpierw powinieneś przekonwertować na przestrzeń liniową, w której nie ma kodów szesnastkowych.
John Dvorak
2
@JanDvorak No cóż. Stan wyzwania odzwierciedla zatem moją niewiedzę, ponieważ tak naprawdę nie mogę tego teraz zmienić. : P
Klamka
Uśrednienie dwóch wartości w sRGB może być jednak całkiem osobnym wyzwaniem. sRGB = RGB ^ 0,45 w większości zakresu, ale liniowo w pobliżu dolnej granicy zakresu.
John Dvorak

Odpowiedzi:

17

Pyth, 9 8 bajtów

Dzięki @isaacg za -1 bajt!

sXz.HM16

Odejmowanie wartości określonego koloru od 255 jest równoważne odejmowaniu każdej jego szesnastkowej cyfry od 15. Powiedzmy, że liczba to 16a + b . Zatem wartość liczby utworzonej przez odjęcie jej cyfr od 15 wynosi 16 (15-a) + (15-b) = 255 - (16a + b) .

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 +

Wypróbuj tutaj . Zestaw testowy.

lirtosiast
źródło
Niezła odpowiedź! Pożyczyłem twój pomysł użycia '0123456789abcdef'do konwersji na hex (zamiast dec2hexfunkcji)
Luis Mendo
Myślę, że twój link jest nieprawidłowy. ( Kopiuj-wklej FTW. )
PurkkaKoodari
@ Pietu1998 Whoops; Naprawię to.
lirtosiast
Jest Uto niepotrzebne - jest domyślnie wypełnione przez M.
isaacg
6

Siatkówka, 13 10 bajtów

T`w`G-A9-0

Kod składa się z trzech części oddzielonych znakami wstecznymi ( `): Tokreśla tryb transliteracji, który zastępuje każdy znak w drugiej części odpowiednim znakiem w trzeciej części.

wjest taki sam jak tradycyjne wyrażenia regularne \w, lub _0-9A-Za-z, który jest rozwinięty do _0123456789ABCDEFGH....

Druga część została rozszerzona GFEDCBA9876543210, dzięki sprytnej zdolności Retiny do ekspansji w odwrotnej kolejności. Połóż je jeden na drugim, a otrzymamy:

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

Zauważ, że ostatni znak, 0powtarza się, aby dopasować długość dłuższego łańcucha, ale dbamy tylko o znaki szesnastkowe, pokazane przez daszki.

Podziękowania dla Martina Büttnera za zasugerowanie takiego podejścia.

Wypróbuj zestaw testowy online.

NinjaBearMonkey
źródło
4

Cudowny, 41 bajtów

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

Tłumacz online tutaj. Dane wejściowe powinny być pisane wielkimi literami.

Wyjaśnienie

00I ]]na dole pobiera pierwszy znak (the #) i spadnie na dno i być wyprowadzane zanim cokolwiek innego.

Pierwsze 3 wiersze to pętla do pobrania wszystkich pozostałych znaków.

Najpierw musimy przekonwertować znaki szesnastkowe na 0-15, wykonując x -= 48, x -= x > 9 ? 7 : 0(ponieważ 'A' - '9'jest to 8).

Aby znaleźć uzupełnienie, musimy po prostu przekonwertować każdą cyfrę xna 15-x. Jest to równoważne (dla wartości 8-bitowych) (~x)+16 = ~(x-16).

Na koniec musimy przekonwertować te liczby z powrotem na cyfry szesnastkowe x += x > 9 ? 7 : 0, x += 48.

Więc teraz mamy x -= 48, x -= x > 9 ? 7 : 0, x = ~(x - 16), x += x > 9 ? 7 : 0, x += 48.

Zauważ, że jeśli usuniemy wyrażenie z pierwszym operatorem trójskładnikowym, wówczas wprowadź cyfry A- Fspowoduje negację x po negacji.

W ten sposób możemy zmienić poprzednie wyrażenie na:, x -= 48, x -= 16, x = ~x, x += (x > 9 || x < 0) ? 7 : 0, x += 48co jest równe x -= 64, x = ~x, x += (x > 9 || x < 0) ? 7 : 0, x += 48.

Powyższy kod jest tylko implementacją ostatniego wyrażenia. -Wjest x -= 32i +Ojest x += 24. Ponieważ Marbelous używa 8-bitowej arytmetyki bez znaku, warunek <Aobejmuje zarówno przypadek, jak x > 9i x < 0.

es1024
źródło
Czy stworzyłeś Marbelous?
Rɪᴋᴇʀ
@RikerW Marbelous został stworzony / rozwinięty przez kilku użytkowników PPCG, w tym przeze mnie: Zobacz tutaj .
es1024
W porządku. Dzięki, że dałeś mi znać.
Rɪᴋᴇʀ
4

JavaScript ES6, 61 bajtów 66 68 48 53 64

Oszczędza sporo bajtów dzięki @ Cᴏɴᴏʀ O'Bʀɪᴇɴ, @NinjaBearMonkey i @nderscore

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

Korzysta z automatycznego odlewania. Naprawienie zer zabiło liczbę bajtów

Downgoat
źródło
Użyj eval(`0x${s.slice(1)}`)zamiastparseInt
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ To ta sama długość?
PurkkaKoodari
@ CᴏɴᴏʀO'Bʀɪᴇɴ dzięki, użyłem - zamiast eval, co pozwoliło zaoszczędzić jeszcze więcej bajtów
Downgoat
Och, zapomniałem o automatycznym castowaniu: D
Conor O'Brien
Wypróbuj z wejściem #FFFFFF. Powraca #0.
Conor O'Brien
4

JavaScript ES6, 63 58 52 49 bajtów

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

Dzięki nderscore za zapisanie 11 bajtów!

Nicość
źródło
-5 bajtów:c=>"#"+[...c].map(x=>"fedcba9876543210"[+('0x'+x)]).join``
nderscore
@ dokładnie dokładnie, myślałem o tym już :) Dzięki. Miałem go użyć, ale z „eval”.
nicael
1
ah, mam jeszcze jedną -6:c=>c.replace(/\w/g,x=>"fedcba9876543210"[+('0x'+x)])
nderscore
3

Jolf, 17 bajtów

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

Wypróbuj tutaj! , Zestaw testowy (użyj pełnego uruchomienia, które teraz działa.)

Conor O'Brien
źródło
3

Julia, 74 49 bajtów

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

W tej chwili dość długo, ale to dopiero początek. Jest to funkcja lambda, która przyjmuje ciąg i zwraca ciąg. Dane wyjściowe będą pisane małymi literami, ale dane wejściowe mogą znajdować się w jednym z nich.

Jak zauważył Thomas , odejmowanie każdej dwucyfrowej składowej koloru od 255 jest równoważne odejmowaniu każdej pojedynczej cyfry w danych szesnastkowych od 15. Pętlę nad łańcuchem wejściowym, z wyłączeniem wiodącego #, konwertujemy 15 - parsowaną cyfrę na szesnastkową. Łączymy je wszystkie, a następnie wybieramy #i nazywamy to dobrym.

Alex A.
źródło
3

Japt , 35 32 22 20 16 15 bajtów

¡Y?(F-XnG)sG :X

Wyjaśnienie:

¡                 //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)
Nicość
źródło
Niezłe! Widziałem to ostatniej nocy i powiedziałem sobie: „Jutro pomogę zagrać w golfa”. Ale teraz grałeś w golfa dalej, niż myślałem, że to możliwe. :)
ETHproductions
2

Perl, 30 bajtów

zawiera +1 dla -p

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

użycie: echo #000000 | perl -p file.pl
lub echo #000000 | perl -pe 's/\w/sprintf"%x",15&~hex$&/eg'.

Kenney
źródło
2

MATL , 21 bajtów

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

Korzysta z wersji 6.0.0 języka / kompilatora, która jest wcześniejsza niż wyzwanie.

Wprowadzane cyfry powinny być pisane wielkimi literami.

Przykład

Zostało to wykonane w Octave:

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

Edytuj (12 czerwca 2016 r.)

Kod można teraz wypróbować online . Przecinki muszą zostać zastąpione przez przestrzenie, a 6Lprzez 4L, w celu dostosowania się do zmian na języku.

Wyjaśnienie

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 '#'
Luis Mendo
źródło
1

Pyth, 20 19 bajtów

1 bajt dzięki xnor .

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

Wypróbuj online. Zestaw testowy.

Wyjaśnienie

  • z jest wejściem
  • tz usuwa #
  • itz16 parsuje jako liczbę szesnastkową
  • t^8 8oblicza 8 8 - 1
  • -t^8 8itz16oblicza 8 8-1 - wejście
  • %"#%06x"-t^2 24itz16 formatuje go do 6-znakowego szesnastkowego łańcucha z zerami i dodaje #
PurkkaKoodari
źródło
Co powiesz na 8 ^ 8 za 2 ^ 24?
xnor
1

Haskell, 85 bajtów

Moje pierwsze zgłoszenie będzie prawdopodobnie najdłuższe (85 bajtów), ale hej, musisz gdzieś zacząć. W Haskell:

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

Używa tego samego odejmowania od 15 lew, których widziałem innych ludzi.

Próbowałem także użyć printf wraz z drugą sztuczką (odejmij 8 ^ 8 - 1) i działa w ghci, ale z jakiegoś powodu nie kompiluje się:

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

Gdyby ktoś mógł sprawić, by to zadziałało, byłoby świetnie!

lpapez
źródło
Witamy w Programowaniu zagadek i Code Golf. To są bardzo dobre odpowiedzi (lepsze niż mógłbym zrobić w Haskell!). Istnieje jednak wspólny format odpowiedzi na wyzwania związane z golfem, który pozwala fragmentowi tablicy wyników umieścić twoją odpowiedź w tabeli wyników. Zmienię to dla ciebie; możesz zaakceptować lub odrzucić edycję.
wizzwizz4
Aby odpowiedzieć na komentarze innych użytkowników, wpisz @username.
wizzwizz4
@ wizzwizz4 Wielkie dzięki za pomoc.
lpapez
W każdej chwili! Chcesz wypróbować niektóre z moich wyzwań? Przeanalizuj swoje krzesło i ciąg mapy do krzywej Hilberta są moimi ulubionymi, chociaż krzywa Hilberta jest naprawdę trudna.
wizzwizz4
@ wizzwizz4 Z pewnością zobaczę, co da się zrobić.
lpapez
1

Mathematica, 69 60 bajtów

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

Po raz kolejny zabija mnie tutaj przetwarzanie łańcuchów.

LegionMammal978
źródło
1

C, 94 bajty

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

Funkcja przyjmuje tablicę char, zwraca wartość odwrotną. Tworzy wielkie litery na odpowiedź. Kod odwraca każdy znak szesnastkowy ASCII na jego odwrotność, jeśli jest poprawny, ignoruje go inaczej.

Dave P.
źródło
Możesz zaoszczędzić trochę miejsca, deklarując globalnie iprzed funkcją:i;
Liam,
1

𝔼𝕊𝕄𝕚𝕟 2, 18 znaków / 34 bajty

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

Try it here (Firefox only).

Korzystanie z wersji utworzonej po wyzwaniu.

Wyjaśnienie

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

Niekonkurencyjne rozwiązanie, 15 znaków / 29 bajtów

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

Wykorzystuje transliterację.

Mama Fun Roll
źródło
Czy możesz również dodać wersję konkurencyjną, abyśmy mogli zobaczyć, jak się układa język?
lirtosiast
Pewnie. Zobacz nową edycję.
Mama Fun Roll
Ładne użycie symbolu APL .
lirtosiast
Hehe, ten symbol był najbardziej sensowny /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])

Pierwszy kod golfa, proszę o opinie :)

Meow Mix
źródło
Możesz wymagać, aby dane wejściowe były w "quotes"btw, więc input()działa. Nie potrzebujesz nowej linii i wcięcia w pętli for, i rangedziała dobrze. Istnieje również kilka spacji, które można usunąć.
Rɪᴋᴇʀ
int("ff", 16)można zastąpić przez just 255.
Klamka
Czy potrzebujesz nawiasów w nawiasach po każdym x?
Blue
0

CJam, 16 bajtów

qA,'G,65>+s_W%er

Jest to dość długie, ponieważ CJam inaczej obsługuje zmiany bazy, więc krótsza była transliteracja. Zobacz moją odpowiedź Retina, aby uzyskać więcej informacji na temat transliteracji.

Wypróbuj online.

Wyjaśnienie

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
NinjaBearMonkey
źródło
0

Python 3, 44 bajty

Pierwotnie 256^3wtedy użyłem 16^6. Potem zobaczyłem Pietu1998 8^8i teraz to rozwiązanie używa tego zamiast tego.

"#{:06x}".format(8**8-1-int(input()[1:],16))
Sherlock9
źródło
0

Java, 95 90 bajtów

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

Bitowy XOR.

SuperJedi224
źródło
0

Bash + tr, 35 bajtów

tr 0-9A-Fa-f fedcba9876543210543210

Dane wyjściowe są zawsze małe.

Niestety „tr” nie przyjmuje zakresów w odwrotnej kolejności, więc musiałem je przeliterować.

Glenn Randers-Pehrson
źródło
0

C, 147 bajtów

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

Użyłem strtol do konwersji z ciągu szesnastkowego na int, a następnie odejmowałem liczbę od 255, aby uzyskać komplement, tak jak powiedział oryginalny post. Zastanawiam się jednak, czy istnieje sposób na przekazanie szeregu znaków od s do strtol, więc nie muszę marnować wiązki bajtów na nowy ciąg?

Danwakeem
źródło
Nie sądzę, że kompilatory zwykle wymuszają zwrot funkcji i domyślnie int, więc prawdopodobnie pomijasz voidtyp zwracany?
Liam,
0

R, 62 bajty

f=function(a)sprintf('#%06x',(8^8-1)-strtoi(substr(a,2,7),16))
mnel
źródło
0

sed, 48 bajtów

y/0123456789ABCDEFabcdef/fedcba9876543210543210/

Lub 36 bajtów, jeśli potrzebujesz obsługiwać tylko jedną sprawę.

Neil
źródło
Nie musisz obsługiwać zarówno małych, jak i wielkich liter.
Martin Ender
@ MartinBüttner pytanie wydaje się wymagać obsługi obu przypadków na wejściu, ale nie na wyjściu. Podobnie jak moje rozwiązanie bash + tr, to rozwiązanie obsługuje oba na wejściu, ale zapisuje tylko małe litery.
Glenn Randers-Pehrson
W 0kodzie jest dodatkowy kod między 9i A(liczba bajtów jest prawidłowa, musi to być błąd kopiowania).
hobbs
Pytanie mówi, że możesz wybrać, który przypadek ma mieć dane wejściowe i wyjściowe.
lirtosiast
0

PowerShell, 48 bajtów

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

Koniecznie pobiera dane wejściowe param($a)jako ciąg, rozdzielany znakami 'lub ", ponieważ C:\Tools\Scripts\Golfing> .\complementary-colors #a1b2c3w wierszu polecenia programu PowerShell będzie on traktowany #a1b2c3jako komentarz i zostanie zignorowany.

Od lewej do prawej "#{0:x6}"-f(...)formatuje nasze obliczenia wyjściowe z powrotem do postaci szesnastkowej z gwarantowanymi 6 znakami (w celu uwzględnienia danych wejściowych #ffffff). Wewnątrz parens odejmujemy nasz numer wejściowy 0xffffff. Robimy to, wykorzystując fakt, że PowerShell analizuje liczby szesnastkowe w formacie 0xNNN, więc konstruujemy liczbę szesnastkową w odpowiednim formacie z naszej liczby wejściowej $a. (Zauważ, że konkatenacja plus .Trim()jest krótsza niż .Replace()tutaj o jeden bajt.) Wykorzystujemy również MBjednoargumentowy operator poprzez 16MB-1konstruowanie 16777215zamiast 0xffffff.

AdmBorkBork
źródło
0

TeaScript, 24 bajty

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

Błędy w tłumaczu nie pozwalają mi się skrócić :(

Wypróbuj online

Downgoat
źródło
Wyjaśnij swoje wyjaśnienie? Działa dla wszystkich przypadków testowych
Downgoat