Доповнення кольорів


26

З огляду на введення кольору в #rrggbbшестигранному форматі, виведіть його RGB-доповнення в тому ж форматі.

RGB-доповнення R 2 G 2 B 2 будь-якого кольору R 1 G 1 B 1 визначається як колір зі значенням R 2 значення 255 - R 1 , B 2 зі значенням 255 - B 1 і G 2 зі значенням 255 - G 1 .

Шістнадцяткові цифри можуть бути великими літерами (# FFAA20) або малими літерами (# ffaa20). Випадок введення та виведення не повинен бути узгодженим (тому ви можете приймати введення в малі регістри, але вихід у великі регістри, і навпаки).

Оскільки це , виграє найкоротший код у байтах.

Тестові (зверніть увагу , що з моменту надання вашої програми / функціонувати свій власний вихід повинен привести до первісного входу (це інволютивними ), тестові приклади повинні працювати в обох напрямках):

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

2
Вибачте, але sRGB не працює таким чином. Спершу слід перетворитись у лінійний простір, у якому немає шестнадцяткових кодів.
Джон Дворак

2
@JanDvorak Ну добре. Стан виклику буде відображати моє невігластво, тому я не можу реально змінити його зараз. : P
Дверна ручка

Однак усереднення двох значень sRGB може бути гідною окремою проблемою. sRGB = RGB ^ 0,45 у більшій частині діапазону, але лінійний біля нижньої частини діапазону.
Іван Дворак

Відповіді:


17

Pyth, 9 8 байт

Дякуємо @isaacg за -1 байт!

sXz.HM16

Віднімання значення певного кольору від 255 еквівалентно відніманню кожної його шістнадцяткової цифри від 15. Скажімо, число є 16a + b . Тоді значення числа, утвореного відніманням його цифр від 15, дорівнює 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 +

Спробуйте тут . Тестовий набір.


Гарна відповідь! Я запозичив вашу ідею використання '0123456789abcdef'для конвертації в шістнадцятковий (замість dec2hexфункції)
Луїс Мендо

Я думаю, що ваше посилання неправильне. ( Скопіюйте-вставте FTW. )
PurkkaKoodari

@ Pietu1998 Whoops; Я це виправлю.
lirtosiast

UНепотрібно - це неявно заповнюється M.
isaacg

6

Сітківка, 13 10 байт

T`w`G-A9-0

До коду є три частини, розділені за допомогою backticks ( `): Tвказує режим транслітерації, який замінює кожен символ у другій частині відповідним символом у третій частині.

w- це те саме, що і традиційні регулярні вирази \w, або _0-9A-Za-z, що розширено на _0123456789ABCDEFGH....

Друга частина розширена до GFEDCBA9876543210, завдяки чудовій здатності Retina розширюватися у зворотному порядку. Покладіть їх один на одного, і ми отримаємо:

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

Зауважимо, що останній символ 0,, повторюється, щоб відповідати довжині довшого рядка, але ми дбаємо лише про шістнадцяткові символи, показані каретами.

Дякую Мартіну Бюттнеру за те, що він запропонував такий підхід.

Спробуйте тестовий набір в Інтернеті.


4

Marbelous, 41 байт

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

Інтернет-перекладач тут. Введіть великі літери.

Пояснення

00І ]]на дні буде отримувати перший символ ( #) , і він буде падати на дно і виводитися насамперед.

Перші 3 рядки - це цикл для отримання всіх решти символів.

Спочатку нам потрібно перетворити шістнадцяткову цифру в 0-15, виконавши x -= 48, x -= x > 9 ? 7 : 0(оскільки 'A' - '9'це 8).

Щоб знайти доповнення, нам просто потрібно перетворити кожну цифру xв 15-x. Це еквівалентно (для 8-бітних значень) (~x)+16 = ~(x-16).

Нарешті, ми повинні перетворити ці числа назад у шістнадцяткові цифри x += x > 9 ? 7 : 0, x += 48.

Отже, тепер у нас є x -= 48, x -= x > 9 ? 7 : 0, x = ~(x - 16), x += x > 9 ? 7 : 0, x += 48.

Зауважте, що якщо ми видалимо вираз з першим потрійним оператором, то введення цифр A- Fце призведе до негативного x після заперечення.

Таким чином, ми можемо змінити попередній вираз на:, x -= 48, x -= 16, x = ~x, x += (x > 9 || x < 0) ? 7 : 0, x += 48який дорівнює x -= 64, x = ~x, x += (x > 9 || x < 0) ? 7 : 0, x += 48.

Вищевказаний код є лише реалізацією останнього виразу. -Wє x -= 32і +Oє x += 24. Оскільки Marbelous використовує непідписану 8-бітну арифметику, умова <Aохоплює обидва випадкиx > 9 і x < 0.


Ви створили Marbelous?
Rɪᴋᴇʀ

@RikerW Marbelous був створений / розроблений декількома користувачами PPCG, включаючи мене: Дивіться тут .
es1024

Гаразд. Дякую, що повідомив мені.
Rɪᴋᴇʀ

4

JavaScript ES6, 61 байт 66 68 48 53 64

Заощаджує досить багато байтів завдяки @ Cᴏɴᴏʀ O'Bʀɪᴇɴ, @NinjaBearMonkey та @nderscore

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

Скористається автоматичним литтям типу. Виправлення нулів вбило кількість байтів


Використовуйте eval(`0x${s.slice(1)}`)замістьparseInt
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Це однакова довжина?
PurkkaKoodari

@ CᴏɴᴏʀO'Bʀɪᴇɴ спасибі, я використав - замість eval, що врятувало ще більше байтів
Пуховик

О, забув про автоматичний кастинг типів: D
Conor O'Brien

Спробуйте це з введенням #FFFFFF. Повертається #0.
Conor O'Brien

4

JavaScript ES6, 63 58 52 49 байт

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

Завдяки nderscore за економію 11 байт!


-5 байт:c=>"#"+[...c].map(x=>"fedcba9876543210"[+('0x'+x)]).join``
nderscore

@nder точно, про це вже подумав :) Дякую. Збирався використовувати його, але з "eval".
nicael

1
ах, у мене є ще один -6:c=>c.replace(/\w/g,x=>"fedcba9876543210"[+('0x'+x)])
nderscore


3

Юлія, 74 49 байт

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

На даний момент досить довго, але це початок. Це лямбда-функція, яка приймає рядок і повертає рядок. Вихід буде малі, але вхід може бути будь-яким.

Як зазначав Томас , віднімання кожної двозначної кольорової складової з 255 еквівалентно відніманню кожної окремої цифри в шістнадцятковому вході з 15. Перемістивши вхідний рядок, виключаючи провідну #, ми перетворюємо 15 - проаналізовану цифру в шістнадцяткову. Ми приєднуємось до всього цього, а потім вирішуємо #і називаємо це добре.


3

Japt , 35 32 22 20 16 15 байт

¡Y?(F-XnG)sG :X

Пояснення:

¡                 //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)

Хороший! Я бачив це вчора ввечері і сказав собі: "Завтра я допоможу гольфу". Але на даний момент ви вже пограли далі, ніж я вважав можливим. :)
ETHproductions

2

Perl, 30 байт

включає +1 для -p

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

використання: echo #000000 | perl -p file.pl
або echo #000000 | perl -pe 's/\w/sprintf"%x",15&~hex$&/eg'.


2

MATL , 21 байт

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

Для цього використовується випуск 6.0.0 мови / компілятора, що є раніше, ніж виклик.

Вхідні цифри повинні бути великими літерами.

Приклад

Це було виконано на Octave:

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

Редагувати (12 червня 2016 р.)

Код тепер можна спробувати в Інтернеті . Коми повинні бути замінені пробілами, і 6Lвід того 4L, щоб відповідати змінам в мові.

Пояснення

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 байт

1 байт завдяки xnor .

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

Спробуйте в Інтернеті. Тестовий набір.

Пояснення

  • z є вхід
  • tz видаляє #
  • itz16 розбирає як шістнадцяткове число
  • t^8 8обчислює 8 8 - 1
  • -t^8 8itz16обчислює 8 8 - 1 - вхід
  • %"#%06x"-t^2 24itz16 формує його в 6-символьний шістнадцятковий рядок і додає #

Як щодо 8 ^ 8 для 2 ^ 24?
xnor

1

Haskell, 85 байт

Моє перше подання, воно, мабуть, буде найдовшим (85 байт), але ей, ви повинні десь почати. У Haskell:

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

Це використання того ж віднімання з трюку, який я бачив, як користуються інші.

Я також спробував використовувати printf разом з іншим трюком (відніміть 8 ^ 8 - 1), і він працює в ghci, але чомусь він не компілюється:

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

Якби хтось міг зробити цю роботу, це було б чудово!


Ласкаво просимо до головоломки програмування та коду для гольфу. Це дуже хороші відповіді (краще, ніж я міг би зробити в Haskell!). Однак існує загальний формат відповідей на проблеми з кодовим гольфом, який дозволяє фрагменту таблиці лідерів помістити свою відповідь у таблицю лідерів. Я відредагую це для вас; ви можете прийняти або заборонити редагування.
wizzwizz4

Щоб відповісти на коментарі інших користувачів, введіть @username.
wizzwizz4

@ wizzwizz4 Дякую за допомогу.
lpapez

Будь-який час! Чи хочете ви ходити на деякі мої виклики? Проаналізуйте своє крісло та рядок Карти до Гільбертської кривої - мої фаворити, хоча криву Гільберта справді важко.
wizzwizz4

@ wizzwizz4 Звичайно, я побачу, що я можу зробити.
lpapez

1

Математика, 69 60 байт

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

Ще раз мене тут вбиває струнна обробка.


1

C, 94 байти

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

Функція займає масив char, повертає обернене значення. Створює великі літери для відповіді. Код перевертає кожен шістнадцятковий символ ASCII до його зворотного, якщо він дійсний, ігнорує його інакше.


Ви можете заощадити простір, оголосивши глобально iперед функцією:i;
Ліам

1

𝔼𝕊𝕄𝕚𝕟 2, 18 символів / 34 байти

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

Try it here (Firefox only).

Використання версії, створеної після виклику.

Пояснення

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

Неконкурентне рішення, 15 символів / 29 байт

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

Використовує транслітерацію.


Чи можете ви також додати конкурентоздатну версію, щоб ми могли бачити, як зберігається мова?
lirtosiast

Звичайно. Дивіться нову редакцію.
Mama Fun Roll

Гарне використання символу APL .
lirtosiast

Хе-хе, цей символ був тим, який мав найбільше сенсу /g.
Mama Fun Roll

1

Пітона, 96

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

Перший код гольфу, будь ласка, дайте думки :)


Вам дозволяється вимагати введення в "quotes"btw, тому input()працює. Вам не потрібні рядки та відступи на циклі for, і він rangeпрацює чудово. Також є кілька пробілів, які можна видалити.
Rɪᴋᴇʀ

int("ff", 16)можна замінити просто 255.
Дверна ручка

Чи потрібні дужки у дужках після кожного x?
Блакитний

0

CJam, 16 байт

qA,'G,65>+s_W%er

Це досить довго, оскільки CJam обробляє базу по-різному, тому транслітерацію було коротше. Дивіться мою відповідь Retina для отримання додаткової інформації про транслітерацію.

Спробуйте в Інтернеті.

Пояснення

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 байти

Спочатку я 256^3тоді використовував 16^6. Тоді я побачив Pietu1998, 8^8і тепер це рішення використовує це.

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

0

Java, 95 90 байт

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

Побітовий XOR.


0

Bash + tr, 35 байт

tr 0-9A-Fa-f fedcba9876543210543210

Вихід завжди малі.

На жаль, "tr" не приймає діапазони у зворотному порядку, тому мені довелося їх прописати.


0

C, 147 байт

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

Використовували strtol для перетворення з шістнадцяткових рядків в int, потім віднімали число від 255, щоб отримати комплімент, як сказав початковий пост. Мене, однак, цікавить, чи є спосіб передати діапазон символів від s до strtol, тому мені не доведеться витрачати купу байтів, копіюючи в новий рядок?


Я не думаю, що компілятори зазвичай примусово повертають функцію та за замовчуванням int, тож ви, мабуть, опускаєте voidтип повернення?
Ліам


0

sed, 48 байт

y/0123456789ABCDEFabcdef/fedcba9876543210543210/

Або 36 байт, якщо вам потрібно підтримати лише один випадок.


Вам не потрібно підтримувати як малі, так і великі регістри.
Мартін Ендер

@ MartinBüttner питання, схоже, вимагає підтримки обох випадків на вході, але не у виході. Як і моє рішення bash + tr, це рішення підтримує як на вході, але записує лише малі регістри.
Гленн Рендерс-Перхсон

У вас є додатковий 0код, між 9і A(кількість байтів правильна, хоча має бути помилка копіювання).
варення

У запитанні сказано, що ви можете вибрати, у якому випадку вхідні та вихідні дані.
lirtosiast

0

PowerShell, 48 байт

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

Обов'язково приймає вхід через param($a)як рядок, розмежований 'або ", оскількиC:\Tools\Scripts\Golfing> .\complementary-colors #a1b2c3 в командному рядку PowerShell буде оброблено#a1b2c3 як коментар і, як правило, ігнорувати його.

Зліва направо, "#{0:x6}"-f(...)формати наших вихідних обчислень повертаються в шістнадцятковий з гарантованими 6 символами (для врахування введення #ffffff). Всередині паронів ми віднімаємо вхідне число від 0xffffff. Ми робимо це, використовуючи той факт, що PowerShell аналізує шістнадцяткові числа у форматі 0xNNN, тому ми будуємо шістнадцятковий номер належного формату з нашого вхідного номера $a. (Зверніть увагу, що конкатенація плюс .Trim()коротша, ніж .Replace()тут, на один байт.) Ми також використовуємо MBодинарний оператор через, 16MB-1щоб будувати 16777215замість 0xffffff.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.