Des couleurs complémentaires

26

Étant donné une entrée d'une couleur au #rrggbbformat hexadécimal, sortez son complément RVB dans le même format.

Le complément RVB R 2 G 2 B 2 de n'importe quelle couleur R 1 G 1 B 1 est défini comme la couleur avec la valeur R 2 255 - R 1 , la valeur B 2 255 - B 1 et la valeur G 2 255 - G 1 .

Les chiffres hexadécimaux peuvent être en majuscules (# FFAA20) ou en minuscules (# ffaa20). Le cas de l'entrée et de la sortie n'a pas besoin d'être cohérent (vous pouvez donc prendre l'entrée en minuscules mais la sortie en majuscules et vice versa).

Puisqu'il s'agit de , le code le plus court en octets l'emporte.

Cas de test (notez que puisque donner à votre programme / fonction sa propre sortie devrait entraîner l'entrée d'origine (elle est involutive ), les cas de test devraient fonctionner dans les deux sens):

In/Out   Out/In
----------------
#ffffff  #000000
#abcdef  #543210
#badcab  #452354
#133742  #ecc8bd
#a1b2c3  #5e4d3c
#7f7f80  #80807f
Poignée de porte
la source
2
Je suis désolé, mais sRGB ne fonctionne pas de cette façon. Vous devez d'abord convertir en espace linéaire, dans lequel les codes hexadécimaux ne sont pas
inclus
2
@JanDvorak Oh bien. L'état du défi reflétera donc mon ignorance, car je ne peux pas vraiment le changer maintenant. : P
Poignée de porte
La moyenne de deux valeurs dans sRGB pourrait être un défi distinct décent, cependant. sRVB = RVB ^ 0,45 sur la majeure partie de la plage, mais linéaire près du bas de la plage.
John Dvorak

Réponses:

17

Pyth, 9 8 octets

Merci à @isaacg pour -1 octet!

sXz.HM16

Soustraire la valeur d'une certaine couleur de 255 équivaut à soustraire chacun de ses chiffres hexadécimaux de 15. Disons qu'un nombre est 16a + b . Ensuite, la valeur du nombre créé en soustrayant ses chiffres de 15 est 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 +

Essayez-le ici . Suite de tests.

lirtosiast
la source
Bonne réponse! J'ai emprunté votre idée d'utiliser '0123456789abcdef'pour convertir en hexadécimal (au lieu de dec2hexfonction)
Luis Mendo
Je pense que votre lien est incorrect. ( Copier-coller FTW. )
PurkkaKoodari
@ Pietu1998 Oups; Je le réparerai.
lirtosiast
Le Un'est pas nécessaire - il est implicitement rempli par M.
isaacg
6

Rétine, 13 10 octets

T`w`G-A9-0

Le code comporte trois parties, séparées par des backticks ( `): Tspécifie le mode de translittération, qui remplace chaque caractère dans la deuxième partie par son caractère correspondant dans la troisième partie.

west le même que les regex traditionnels \w, ou _0-9A-Za-z, qui est étendu à _0123456789ABCDEFGH....

La deuxième partie est étendue à GFEDCBA9876543210, grâce à la capacité astucieuse de Retina à se développer dans l'ordre inverse. Mettez-les les uns sur les autres, et nous obtenons:

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

Notez que le dernier caractère 0,, est répété pour s'adapter à la longueur de la chaîne la plus longue, mais nous ne nous soucions que des caractères hexadécimaux, indiqués par des carets.

Merci à Martin Büttner d'avoir proposé cette approche.

Essayez la suite de tests en ligne.

NinjaBearMonkey
la source
4

Marbelous, 41 octets

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

Interprète en ligne ici. L'entrée doit être en majuscules.

Explication

Le 00et ]]en bas récupérera le premier caractère (le #) et il tombera en bas et sera sorti avant toute autre chose.

Les 3 premières lignes sont une boucle pour récupérer tous les caractères restants.

Nous devons d'abord convertir les caractères hexadécimaux en 0-15, en faisant x -= 48, x -= x > 9 ? 7 : 0(puisque 'A' - '9'c'est 8).

Pour trouver le complément, nous devons simplement convertir chaque chiffre xen 15-x. Cela équivaut à (pour les valeurs 8 bits) (~x)+16 = ~(x-16).

Enfin, nous devons reconvertir ces nombres en chiffres hexadécimaux, en faisant x += x > 9 ? 7 : 0, x += 48.

Alors maintenant, nous l'avons x -= 48, x -= x > 9 ? 7 : 0, x = ~(x - 16), x += x > 9 ? 7 : 0, x += 48.

Notez que si nous supprimons l'expression avec le premier opérateur ternaire, les chiffres entrés A- Fdonneront un x négatif après la négation.

Ainsi, nous pouvons changer l'expression précédente en:, x -= 48, x -= 16, x = ~x, x += (x > 9 || x < 0) ? 7 : 0, x += 48qui est égal à x -= 64, x = ~x, x += (x > 9 || x < 0) ? 7 : 0, x += 48.

Le code ci-dessus n'est qu'une implémentation de la dernière expression. -West x -= 32et +Oest x += 24. Puisque Marbelous utilise une arithmétique 8 bits non signée, la condition <Acouvre à la fois le cas de x > 9et x < 0.

es1024
la source
Avez-vous créé Marbelous?
Rɪᴋᴇʀ
@RikerW Marbelous a été créé / étoffé par plusieurs utilisateurs de PPCG dont moi-même: voir ici .
es1024
D'accord. Merci de me le faire savoir.
Rɪᴋᴇʀ
4

JavaScript ES6, 61 octets 66 68 48 53 64

Enregistre pas mal d'octets grâce à @ Cᴏɴᴏʀ O'Bʀɪᴇɴ, @NinjaBearMonkey et @nderscore

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

Profite de la coulée de type automatique. La correction des zéros a tué le nombre d'octets

Downgoat
la source
Utiliser eval(`0x${s.slice(1)}`)au lieu deparseInt
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ C'est la même longueur?
PurkkaKoodari
@ Merci CᴏɴᴏʀO'Bʀɪᴇɴ, j'ai utilisé - au lieu d'eval qui a sauvé encore plus d'octets
Downgoat
Oh, j'ai oublié le casting de type automatique: D
Conor O'Brien
Essayez-le avec l'entrée #FFFFFF. Retours #0.
Conor O'Brien
4

JavaScript ES6, 63 58 52 49 octets

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

Merci à nderscore pour avoir économisé 11 octets!

nicael
la source
-5 octets:c=>"#"+[...c].map(x=>"fedcba9876543210"[+('0x'+x)]).join``
nderscore
@nder exactement, y ai déjà pensé :) Merci. J'allais l'utiliser, mais avec "eval".
nicael
1
ah, j'en ai encore un -6:c=>c.replace(/\w/g,x=>"fedcba9876543210"[+('0x'+x)])
nderscore
3

Jolf, 17 octets

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

Essayez-le ici! , Suite de tests (utilisez l'exécution complète, qui fonctionne maintenant.)

Conor O'Brien
la source
3

Julia, 74 49 octets

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

Assez long pour le moment mais c'est un début. Il s'agit d'une fonction lambda qui accepte une chaîne et renvoie une chaîne. La sortie sera en minuscules mais l'entrée peut être dans l'un ou l'autre.

Comme Thomas l'a noté , la soustraction de chaque composant de couleur à 2 chiffres de 255 équivaut à soustraire chaque chiffre individuel de l'entrée hexadécimale de 15. En boucle sur la chaîne d'entrée, à l'exclusion de l'interligne #, nous convertissons 15 - le chiffre analysé en hexadécimal. Nous nous joignons à tous, puis plaquons sur un #et le qualifions de bon.

Alex A.
la source
3

Japt , 35 32 22 20 16 15 octets

¡Y?(F-XnG)sG :X

Explication:

¡                 //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
la source
Joli! J'ai vu cela hier soir et je me suis dit: "Demain, je vais aider à jouer au golf." Mais maintenant, vous avez joué au golf plus loin que je ne le pensais possible. :)
ETHproductions
2

Perl, 30 octets

comprend +1 pour -p

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

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

Kenney
la source
2

MATL , 21 octets

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

Cela utilise la version 6.0.0 du langage / compilateur, qui est antérieure au défi.

Les chiffres d'entrée doivent être en majuscules.

Exemple

Cela a été exécuté sur Octave:

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

Edit (12 juin 2016)

Le code peut maintenant être essayé en ligne . Les virgules doivent être remplacées par des espaces et 6Lpar 4Lpour se conformer aux changements de langue.

Explication

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
la source
1

Pyth, 20 19 octets

1 octet grâce à xnor .

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

Essayez-le en ligne. Suite de tests.

Explication

  • z est l'entrée
  • tz supprime le #
  • itz16 analyse comme un nombre hexadécimal
  • t^8 8calcule 8 8 - 1
  • -t^8 8itz16calcule 8 8-1 - entrée
  • %"#%06x"-t^2 24itz16 le formate en une chaîne hexadécimale à six caractères et ajoute le #
PurkkaKoodari
la source
Que diriez-vous de 8 ^ 8 pour 2 ^ 24?
xnor
1

Haskell, 85 octets

Ma première soumission, ce sera probablement la plus longue (85 octets) mais bon, il faut commencer quelque part. À Haskell:

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

Il utilise la même soustraction de 15 tours que j'ai vu utiliser par d'autres personnes.

J'ai également essayé d'utiliser printf avec l'autre astuce (soustrayez 8 ^ 8 - 1) et cela fonctionne dans ghci mais pour une raison quelconque, il ne compile pas:

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

Si quelqu'un pouvait faire ce travail, ce serait génial!

lpapez
la source
Bienvenue dans Programming Puzzles et Code Golf. Ce sont de très bonnes réponses (meilleures que je ne pourrais le faire à Haskell!). Cependant, il existe un format de réponse commun pour les défis de code-golf qui permet à l'extrait de classement de placer votre réponse dans le classement. Je vais le modifier pour vous; vous pouvez accepter ou refuser la modification.
wizzwizz4
Pour répondre aux commentaires des autres utilisateurs, tapez @username.
wizzwizz4
@ wizzwizz4 Merci beaucoup pour votre aide.
lpapez
À tout moment! Voulez-vous vous lancer dans certains de mes défis? Analysez votre chaise et la chaîne de carte pour Hilbert Curve sont mes favoris, bien que la courbe de Hilbert soit vraiment difficile.
wizzwizz4
@ wizzwizz4 Certainement, je vais voir ce que je peux faire.
lpapez
1

Mathematica, 69 60 octets

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

Encore une fois, c'est le traitement des chaînes qui me tue ici.

LegionMammal978
la source
1

C, 94 octets

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

La fonction prend un tableau de caractères, renvoie une valeur inverse. Produit des lettres majuscules pour la réponse. Le code retourne chaque caractère hexadécimal ASCII à son inverse s'il est valide, l'ignore sinon.

Dave P.
la source
Vous pouvez économiser de l'espace en déclarant globalement iavant la fonction:i;
Liam
1

𝔼𝕊𝕄𝕚𝕟 2, 18 caractères / 34 octets

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

Try it here (Firefox only).

Utilisation d'une version créée après le challenge.

Explication

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

Solution non compétitive, 15 caractères / 29 octets

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

Utilise la translittération.

Mama Fun Roll
la source
Pouvez-vous également ajouter une version compétitive, afin que nous puissions voir comment la langue se compare?
lirtosiast
Sûr. Voir nouvelle édition.
Mama Fun Roll du
Belle utilisation du symbole APL .
lirtosiast
Héhé, ce symbole était celui qui avait le plus de sens /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])

Premier code de golf, veuillez donner des avis :)

Meow Mix
la source
Vous êtes autorisé à exiger que l'entrée soit en "quotes"btw, donc ça input()marche. Vous n'avez pas besoin de la nouvelle ligne et du retrait sur la boucle for, et cela rangefonctionne très bien. Il y a aussi quelques espaces que vous pouvez supprimer.
Rɪᴋᴇʀ
int("ff", 16)peut être remplacé par juste 255.
Poignée de porte
Avez-vous besoin des parenthèses à l'intérieur des crochets après chaque x?
Bleu
0

CJam, 16 octets

qA,'G,65>+s_W%er

C'est assez long car CJam gère les changements de base différemment, il était donc plus court de ne faire que la translittération. Voir ma réponse Retina pour plus d'informations sur la translittération.

Essayez-le en ligne.

Explication

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
la source
0

Python 3, 44 octets

A l' origine je 256^3puis 16^6. Ensuite, j'ai vu Pietu1998 8^8et maintenant cette solution l'utilise à la place.

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

Java, 95 90 octets

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

XOR au niveau du bit.

SuperJedi224
la source
0

Bash + tr, 35 octets

tr 0-9A-Fa-f fedcba9876543210543210

La sortie est toujours en minuscules.

Malheureusement, "tr" ne prend pas les plages dans l'ordre inverse, j'ai donc dû les préciser.

Glenn Randers-Pehrson
la source
0

C, 147 octets

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

Utilisé strtol pour convertir de la chaîne hexadécimale en int, puis soustrait le nombre de 255 pour obtenir le compliment comme le poste d'origine l'a dit. Je me demande cependant s'il existe un moyen de passer une plage de caractères de s à strtol, donc je n'ai pas à perdre un tas d'octets à copier dans une nouvelle chaîne?

Danwakeem
la source
Je ne pense pas que les compilateurs appliquent généralement les retours de fonction et la valeur par défaut à int, donc vous omettez probablement le voidtype de retour?
Liam
0

R, 62 octets

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

sed, 48 octets

y/0123456789ABCDEFabcdef/fedcba9876543210543210/

Ou 36 octets si vous ne devez prendre en charge qu'un seul cas.

Neil
la source
Vous n'avez pas besoin de prendre en charge les minuscules et les majuscules.
Martin Ender
@ MartinBüttner, la question semble nécessiter un support pour les deux cas en entrée, mais pas en sortie. Comme ma solution bash + tr, cette solution prend en charge les deux en entrée mais écrit uniquement les sorties en minuscules.
Glenn Randers-Pehrson
Vous avez un extra 0dans votre code, entre le 9et A(le nombre d'octets est correct cependant, doit être une erreur de copie).
Hobbs du
La question dit que vous pouvez choisir dans quel cas vos entrées et sorties sont.
lirtosiast
0

PowerShell, 48 octets

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

Prend nécessairement l'entrée via param($a)comme une chaîne, délimitée par 'ou ", car C:\Tools\Scripts\Golfing> .\complementary-colors #a1b2c3sur la ligne de commande PowerShell traitera#a1b2c3 comme un commentaire et l'ignorera sommairement.

De gauche à droite, les "#{0:x6}"-f(...)formats de nos calculs de sortie sont de nouveau en hexadécimal avec 6 caractères garantis (pour tenir compte de l'entrée #ffffff). À l'intérieur des parens, nous soustrayons notre numéro d'entrée de 0xffffff. Pour ce faire, nous exploitons le fait que PowerShell analyse les nombres hexadécimaux au format 0xNNN, nous construisons donc un nombre hexadécimal au format approprié à partir de notre numéro d'entrée $a. (Notez que la concaténation plus .Trim()est plus courte .Replace()qu'ici d'un octet.) Nous utilisons également l' MBopérateur unaire via 16MB-1pour construire à la 16777215place de 0xffffff.

AdmBorkBork
la source
0

TeaScript, 24 octets

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

Les bugs dans l'interpréteur ne me permettent pas de raccourcir ceci :(

Essayez-le en ligne

Downgoat
la source
Explication de downvote? Cela fonctionne pour tous les cas de test
Downgoat