wvogel日記

自分用の技術備忘録が多めです.

codeforces

久しぶりにcodeforces.
この問題
を解いてみた。

import Data.List

main = do
 cs <- getContents
 case answer.map read.take 6.words $ cs of
   [a,b,c,d] -> putStrLn (show a ++ " " ++ show b)
                >> putStrLn (show c ++ " " ++ show d)
   [] -> putStrLn "-1"

answer :: [Int] -> [Int]
answer (r1:r2:xs)
 = take 4.concat.filter f
          $ concat.map (check xs $ touples r1) $ touples r2
  where
    f ls = length ls == (length.group.sort) ls && all (< 10) ls
     
touples :: Int -> [(Int,Int)]
touples n = zip [1..] [n-1,n-2..1]

check :: [Int] -> [(Int,Int)] -> (Int,Int) -> [[Int]]
check [c1,c2,d1,d2] xs k = map g $ filter (f k) xs
 where
   f (c,d) (a,b)= checkC c1 c2 [a,b,c,d] && checkD d1 d2 [a,b,c,d]
   g x = [fst x,snd x,fst k,snd k]

checkC c1 c2 [a,b,c,d] = a+c==c1 && b+d==c2

checkD d1 d2 [a,b,c,d] = a+d==d1 && b+c==d2

まず、r1,r2の条件を満たすタプル群を求め、
それらが横方向、斜め方向でも成立するか調べていきます。

アルゴリズムはすぐ思いついたのだけれど、
思いのほか手間取った.....


もっと練習しないと

というわけで、14日(土曜)はこの問題を解いてみた

main = do
 str <- getLine
 putStrLn.check (head str).format $ abs' str

check c str@(x:xs)
 = if x == ',' then f c xs else f c str
  where
    f c xs = if c == '-' then "($"++xs++")" else '$':xs

abs' (x:xs) = if x == '-' then xs else (x:xs)

format :: String -> String
format str = let intPart = takeWhile (/='.') str
                 floatPart = drop (1+length intPart) str
             in  intStr intPart ++ floatStr floatPart

floatStr str = "."++(take 2 $ take 2 str ++ repeat '0')

intStr :: String -> String
intStr str
 = let p = take (mod (length str) 3) str
   in f . (:) p . dataList $ drop (length p) str
 where
  f = init.concat.map (\a -> a++",")

dataList :: String -> [String]
dataList [] = []
dataList str = a: dataList b
 where
  (a,b) = splitAt 3 str

もっとスマートに書けそう...