6
\$\begingroup\$

Ok, I found myself with a nice little problem:

you will get from stdin a string. In this string you will find some hex colors (like #ff00dd). You must return the string with the colors inverted (#ff00dd inverted is #00ff11).

A sample input/output could be:

ascscasad #ff00ff csdcas dcs c#001122 #qq5500
ascscasad #00ff00 csdcas dcs c#ffeedd #qq5500

As I am proficient in Haskell, I tackled the problem with it. Came up with this code, and I think it's the best I can do. Do you see any way to improve it / a completely different way to make it shorter?

import Text.Regex.Posix ( (=~) )

main = getLine >>= putStrLn . f

f [] = []
f x = let (b, q, p) = x =~ "#[0-f]{6}"
          c = '#' : ['0'..'f'] ++ "#"
          a = zip c (reverse c)
          r = map ( (maybe '@' id) . (flip lookup $ a) ) q
      in b ++ r ++ f p

I am also interested to compare other languages to Haskell, so post in other languages are welcome, too!

\$\endgroup\$
3
  • 9
    \$\begingroup\$ Shouldn't the inverse of #ff00dd be #00ff22? \$\endgroup\$ Mar 8, 2013 at 23:21
  • 1
    \$\begingroup\$ main = interact f \$\endgroup\$ Mar 11, 2013 at 10:13
  • 1
    \$\begingroup\$ Can we assume #ff00 is equivalent to #00ff00 (since it is)? \$\endgroup\$
    – Griffin
    Mar 14, 2013 at 9:33

3 Answers 3

3
\$\begingroup\$

Perl, 44 chars

Two different tweaks can get it to this length, one suggested by Primo:

s/#\K[\da-f]{6}/sprintf"%06x",~hex ff.$&/eg

Another one by playing around with the /ee modifier:

s/#\K[\da-f]{6}/"sprintf'%06x',~0xff$&"/eeg

Requires -p command line switch (1 char included in count).

Works for lower-case hex numbers (as in example). An i switch added to the regex would make it work for upper-case as well (though not preserving the case of the original number).

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Very nice solution. I see only one minor improvement: (~0>>8)-hex$& can be replaced by ~hex ff.$&. \$\endgroup\$
    – primo
    Mar 12, 2013 at 4:31
2
\$\begingroup\$

APL 86

Index origin zero. Takes either a single colour hex string or multiple space separated colour strings as screen input via ←⍞

,' ',h[⊃16,¨,¨⍉¨(⊂16 16)⊤¨255-16⊥¨⍉¨(⊂3 2)⍴¨(⊂h←'0123456789abcdef#')⍳¨(c≠' ')⊂c←⍞~'#']


input: #ff00dd  output: #00ff22

input: #ff00dd #00ff22 output: #00ff22 #ff00dd
\$\endgroup\$
1
  • \$\begingroup\$ APL strikes again... :) Nice solution though! \$\endgroup\$
    – tomsmeding
    Mar 9, 2013 at 22:04
1
\$\begingroup\$

Ruby, 46 bytes

gets.gsub(/#(\h+)/){"#%06x"%(0xffffff^$1.hex)}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.