Problem 98

http://projecteuler.net/index.php?section=problems&id=98
アナグラムかつ平方数になる文字の組のうち、最大の平方数を求める。
先頭0だめを忘れていた。

import Data.List
import Data.Function
import qualified Data.Map as Map

findAnagrams xs = map (map snd).filter((>1).length).groupBy((==)`on`  fst).sort.zip (map sort xs) $ xs

setNum x = filter uniNum.zip (repeat x) .filter((n==).length.nub) $ sqr (length x)
    where n = length.nub$x
          uniNum (x,y)=all((==1).length). map (nub.map snd).filter((>1).length).groupBy((==) `on` fst).sort$zip y x

subst x (y,n) = [m a|a<-x]
    where m = (Map.!) $Map.fromList$zip y n

sqrtAnagram [x,y] = foldl max 0 [max (read n) .read.subst x $ (y',n)|(y',n)<-setNum y,vail.subst x $(y',n)]
    where vail (x:xs) = x/='0' && (isSqrt.read) (x:xs)
          isSqrt x = x== ((^2).floor.sqrt.fromIntegral)x

main = do f <- readFile "words.txt"
          let anagrams = concatMap (flip comb 2).findAnagrams.(read::String->[String])$"["++f++"]"
          print.maximum.map sqrtAnagram$anagrams

sqr (n+1) = map show.takeWhile(<10^(n+1)).dropWhile(<10^n).map (^2) $ [1..]

comb _ 0 = [[]]
comb [] _ = []
comb (x:xs) (n+1) = map (x:) (comb xs n) ++ comb xs (n+1)

行は少ないが、列が多いな。
可読性の低下が懸念されます。