Дополнительные цвета

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 +

Попробуй это здесь . Тестирование.

lirtosiast
источник
Хороший ответ! Я позаимствовал вашу идею использовать '0123456789abcdef'для преобразования в гекс (вместо dec2hexфункции)
Луис Мендо
Я думаю, что ваша ссылка неверна. ( Copy-paste FTW. )
PurkkaKoodari
@ Pietu1998 Упс; Я исправлю это.
lirtosiast
Это Uне нужно - оно неявно заполнено M.
Исаак
6

Сетчатка, 13 10 байт

T`w`G-A9-0

Код состоит из трех частей, разделенных backticks ( `): Tуказывает режим транслитерации, который заменяет каждый символ во второй части соответствующим символом в третьей части.

wтакой же, как традиционные регулярные выражения \w, или _0-9A-Za-z, который расширяется до _0123456789ABCDEFGH....

Вторая часть расширена GFEDCBA9876543210, благодаря изящной способности Retina расширяться в обратном порядке. Поместите их друг на друга, и мы получим:

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

Обратите внимание, что последний символ, 0повторяется, чтобы соответствовать длине более длинной строки, но мы заботимся только о шестнадцатеричных символах, показанных символами вставки.

Спасибо Мартину Бюттнеру за предложенный подход.

Попробуйте тестовый набор онлайн.

NinjaBearMonkey
источник
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.

es1024
источник
Вы создали 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)

Использует преимущества автоматического набора типов. Исправление нулей убило количество байтов

Downgoat
источник
Используйте eval(`0x${s.slice(1)}`)вместоparseInt
Конор О'Брайен
@ CᴏɴᴏʀO'Bʀɪᴇɴ Это такая же длина?
PurkkaKoodari
@ CᴏɴᴏʀO'Bʀɪᴇɴ спасибо, я использовал - вместо eval, который сохранил еще больше байтов
Downgoat
Ой, забыл про автоматическое приведение типа: D
Конор О'Брайен
Попробуйте это с вводом #FFFFFF. Возвращает #0.
Конор О'Брайен
4

JavaScript ES6, 63 58 52 49 байт

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

Спасибо nderscore за сохранение 11 байтов!

nicael
источник
-5 байт:c=>"#"+[...c].map(x=>"fedcba9876543210"[+('0x'+x)]).join``
nderscore
@ Точно, уже думал об этом :) Спасибо. Собирался им пользоваться, но с "eval".
nicael
1
ах, у меня есть еще один -6:c=>c.replace(/\w/g,x=>"fedcba9876543210"[+('0x'+x)])
nderscore
3

Джольф, 17 байт

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

Попробуй это здесь! , Набор тестов (Использовать полный прогон, который в настоящее время работает.)

Конор О'Брайен
источник
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)
nicael
источник
Хороший! Я видел это прошлой ночью и сказал себе: «Завтра я помогу сыграть в гольф». Но сейчас вы играете в гольф дальше, чем я думал. :)
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 языка / компилятора, которая является более ранней, чем проблема.

Входные цифры должны быть в верхнем регистре.

пример

Это было выполнено в Октаве:

>> 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 форматирует его в шестнадцатеричную строку, дополненную нулями, и добавляет #
PurkkaKoodari
источник
Как насчет 8 ^ 8 для 2 ^ 24?
xnor
1

Haskell, 85 байт

Мое первое представление, оно, вероятно, будет самым длинным (85 байт), но эй, ты должен начать где-нибудь. В Хаскеле:

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

Он использует то же самое вычитание из 15 трюков, что и другие люди.

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

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

Если бы кто-то мог сделать эту работу, это было бы здорово!

lpapez
источник
Добро пожаловать в Программирование головоломок и Code Golf. Это очень хорошие ответы (лучше, чем я мог сделать в Хаскеле!). Тем не менее, существует общий формат ответов для задач по коду-гольфу, который позволяет фрагменту таблицы лидеров поместить ваш ответ в таблицу лидеров. Я отредактирую это для вас; Вы можете принять или отклонить редактирование.
wizzwizz4
Чтобы ответить на комментарии других пользователей, введите @username.
wizzwizz4
@ wizzwizz4 Большое спасибо за вашу помощь.
1
В любой момент! Вы хотите попробовать свои силы? Проанализируйте свой стул и строку «Карта» для кривой Гильберта - мои любимые, хотя кривая Гильберта действительно сложна.
wizzwizz4
@ wizzwizz4 Конечно, я посмотрю, что я могу сделать.
1
1

Mathematica, 69 60 байт

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

Еще раз, это обработка строки, которая убивает меня здесь.

LegionMammal978
источник
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;}

Функция принимает массив символов, возвращает обратное значение. Производит заглавные буквы для ответа. Код переворачивает каждый шестнадцатеричный символ 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⌿,↪(ḏ-`ᶍ⦃$}”ⓧ

Использует транслитерацию.

Mama Fun Roll
источник
Можете ли вы также добавить конкурентоспособную версию, чтобы мы могли видеть, как складывается язык?
lirtosiast
Конечно. Смотрите новое редактирование.
Mama Fun Roll
Хорошее использование символа APL .
lirtosiast
Хе-хе, этот символ был тем, который имел больше всего смысла /g.
Мама 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"кстати, так что input()работает. Вам не нужны перевод строки и отступ в цикле for, и он rangeработает просто отлично. Есть также пара пробелов, которые вы можете удалить.
Rɪᴋᴇʀ
int("ff", 16)можно заменить просто 255.
Дверная ручка
Вам нужны скобки внутри скобок после каждого х?
Blue
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
NinjaBearMonkey
источник
0

Python 3, 44 байта

Первоначально я использовал 256^3тогда 16^6. Тогда я видел Pietu1998, 8^8и теперь это решение использует это вместо.

"#{:06x}".format(8**8-1-int(input()[1:],16))
Sherlock9
источник
0

Ява, 95 90 байт

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

Побитовый XOR.

SuperJedi224
источник
0

Баш + тр, 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, чтобы мне не пришлось тратить кучу байтов, копируя в новую строку?

Danwakeem
источник
Я не думаю, что компиляторы обычно принудительно возвращают функции и по умолчанию имеют значение int, так что вы, вероятно, не указали voidтип возвращаемого значения?
Лиам
0

R, 62 байта

f=function(a)sprintf('#%06x',(8^8-1)-strtoi(substr(a,2,7),16))
mnel
источник
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.

AdmBorkBork
источник
0

TeaScript, 24 байта

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

Ошибки в интерпретаторе не позволяют мне сократить это :(

Попробуйте онлайн

Downgoat
источник
Объяснение Downvote? Это работает для всех тестовых случаев
Downgoat