Problem:
何色？

ウェブデザイナーを目指す太郎君はただいま修行中。事務所の先輩から「このページの背景色は#ffe085で」と、ウェブデザイン特有の色番号で指示されるのですが、それがどんな色かパッと思い浮かべることができません。

この色番号は光の三原色である赤、緑、青それぞれの強さを表わしています。具体的には2 桁の 16 進数を3 つ組み合わせたもので、色番号を“#RGB”とするとき、R は赤の強さ、G は緑の強さ、は青の強さを表します。それぞれ 00 から ff までの値になります。

色番号にまだ不慣れな太郎君のために、色番号を入力とし、色の表の中からもっとも近い色の名前
を出力するプログラムを作成してください。使用する色の表は以下の通りです。

 

色の名前

赤の強さ

緑の強さ

青の強さ

black

00

00

00

blue

00

00

ff

lime

00

ff

00

aqua

00

ff

ff

red

ff

00

00

fuchsia

ff

00

ff

yellow

ff

ff

00

white

ff

ff

ff

「もっとも近い色」とは、以下のように定義します。与えられた色番号での赤、緑、青の強さをそれぞれ R、G、B とし、表の k 番目の色の赤、緑、青の強さをそれぞれ Rk、Gk、Bk とするとき、次の式で計算する dk の値が最も小さい色がもっとも近い色とします。

なお、dk の値が同じになる色が複数存在する場合は表の中でより上にある色がもっとも近い色になり
ます。

Input

複数のデータセットの並びが入力として与えられます。入力の終わりはゼロひとつの行で示されます。各データセットとして、色番号を表す文字列が、#RGB 形式で１行に与えられます。

データセットの数は 1000 を超えません。

Output

データセット毎に最も近い色の名前を１行に出力します。

Sample Input

#ffe085
#787878
#decade
#ff55ff
0

Output for the Sample Input

white
black
white
fuchsia

Solution in Haskell (judge verdict: Accepted)

import Control.Applicative
import Control.Monad
import Control.Monad.ST
import Data.Functor
import Data.Function
import Data.Monoid
import Data.Maybe
import Data.List
import qualified Data.Foldable as Foldable
import qualified Data.Set as Set
--import qualified Data.Sequence as Sequence
import Data.List.Split
import Data.Bits
import Data.Char
import Data.Ix
import Data.Ratio
import Data.Ord
import Data.Tuple
--import Data.Array
--import Data.Array.Unboxed
import Data.Array.IArray
import Data.Array.MArray
import Data.Array.IO
import Data.Array.ST
import Data.IORef
import Data.STRef
-- import System.IO.Unsafe

-- templete
readInt = read :: String -> Int
readInteger = read :: String -> Integer
readDouble = read :: String -> Double
getInt = readLn :: IO Int
getInts = map readInt . words <$> getLine
getInteger = readLn :: IO Integer
getIntegers = map readInteger . words <$> getLine
getDouble = readLn :: IO Double
sjoin :: (Show a) => [a] -> String
sjoin = unwords . map show
cond :: a -> a -> Bool -> a
cond t f c = if c then t else f
apply2 :: (a -> a -> b) -> [a] -> b
apply2 f [x,y] = f x y
apply3 :: (a -> a -> a -> b) -> [a] -> b
apply3 f [x,y,z] = f x y z
apply4 :: (a -> a -> a -> a -> b) -> [a] -> b
apply4 f [x,y,z,w] = f x y z w
fnTuple :: (a -> b, a -> c) -> a -> (b, c)
fnTuple (f,g) a = (f a, g a)
replace :: (Eq a) => a -> a -> [a] -> [a]
replace x y = map (\z -> if z==x then y else z)
binMap :: (a -> a -> b) -> [a] -> [b]
binMap f (x:xs@(y:_)) = f x y : binMap f xs
binMap _ _ = []
splitRec :: Int -> [a] -> [[a]]
splitRec _ [] = []
splitRec n xs = let (y,ys) = splitAt n xs in y : splitRec n ys
infixl 7 `divCeil`
divCeil :: Integral a => a -> a -> a
x `divCeil` y = (x+y-1) `div` y
-- templete

type ColorCode = (Int,Int,Int)
distC :: ColorCode -> ColorCode -> Int
distC (r,g,b) (r',g',b') = sum $ map (^2) [r-r', g-g', b-b']

type Color = (String, ColorCode)

colorList = [("black", (0,0,0)), ("blue", (0,0,255)), ("lime", (0, 255, 0)), ("aqua", (0, 255, 255)), ("red", (255,0,0)), ("fuchsia", (255,0,255)), ("yellow", (255, 255, 0)), ("white", (255, 255, 255))]

f ['#',rr,r,gg,g,bb,b] = fst $ minimumBy (comparing (distC (red, green, blue) . snd)) colorList
  where
    red = 16 * digitToInt rr + digitToInt r
    green = 16 * digitToInt gg + digitToInt g
    blue = 16 * digitToInt bb + digitToInt b
    

main = takeWhile (/="0") . lines <$> getContents >>= mapM_ (putStrLn . f)