Advertisement
Guest User

Untitled

a guest
May 28th, 2015
242
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.40 KB | None | 0 0
  1. import Control.Monad
  2. import Text.Printf
  3. import Control.Applicative
  4. import Data.List
  5.  
  6. type Quaternion = (Integer, Integer, Integer, Integer)
  7.  
  8. i :: Quaternion
  9. i = (0, 1, 0, 0)
  10.  
  11. j :: Quaternion
  12. j = (0, 0, 1, 0)
  13.  
  14. k :: Quaternion
  15. k = (0, 0, 0, 1)
  16.  
  17. multi :: Quaternion -> Quaternion -> Quaternion
  18. multi (a1, a2, a3, a4) (b1, b2, b3, b4) = (c1, c2, c3, c4)
  19. where c1 = a1*b1 - a2*b2 - a3*b3 - a4*b4
  20. c2 = a1*b2 + a2*b1 + a3*b4 - a4*b3
  21. c3 = a1*b3 + a3*b1 + a4*b2 - a2*b4
  22. c4 = a1*b4 + a4*b1 + a2*b3 - a3*b2
  23.  
  24. main :: IO()
  25. main = do
  26. testCase <- readLn
  27. forM_ [1..testCase] $ \i -> do
  28. [l, x] <- map read . words <$> getLine
  29. q <- getLine
  30. let ans = slv (l, x) q
  31. printf "Case #%d: %s\n" (i :: Int) ans
  32.  
  33. slv :: (Integer, Integer) -> String -> String
  34. slv (l, n) q | l * n <= 2 || length (group q) < 2 = "NO"
  35. | answer qPowerVal = ansStr n (take (10000 * 4 * 2) q) -- 入力文字10000文字の4セットの倍見れば大丈夫
  36. | otherwise = "NO"
  37. where qPowerVal = power qVal n
  38. qVal = slvQVal q
  39.  
  40. ansStr :: Integer -> String -> String
  41. ansStr n q | checkI && checkJ && checkK = "YES"
  42. | otherwise = "NO"
  43. where (iq, checkI, it) = dropIJK 'i' ' ' q (n-1, q)
  44. (ijq, checkJ, ijt) = dropIJK 'j' ' ' iq it
  45. (ijkq, checkK, ijkt) = dropIJK 'k' ' ' ijq ijt
  46.  
  47. dropIJK :: Char -> Char -> String -> (Integer, String) -> (String, Bool, (Integer, String))
  48. dropIJK q now [] t@(0, tmp) = ([], q == now, t)
  49. dropIJK q now [] t@(n, tmp) | q == now = ([], True, t)
  50. | otherwise = dropIJK q now tmp (n-1, tmp)
  51. dropIJK q now str@(x:xs) t | q == now = (str, True, t)
  52. | otherwise = dropIJK q (convMap (now, x)) xs t
  53. where convMap ('i', 'j') = 'k'
  54. convMap ('i', 'k') = 'j'
  55. convMap ('j', 'i') = 'k'
  56. convMap ('j', 'k') = 'i'
  57. convMap ('k', 'i') = 'j'
  58. convMap ('k', 'j') = 'i'
  59. convMap (_, c) = c
  60.  
  61. slvQVal :: String -> Quaternion
  62. slvQVal qStr = slvQVal' qStr (1, 0, 0, 0)
  63. where slvQVal' [] ret = ret
  64. slvQVal' (q:qs) ret = slvQVal' qs (multi ret (str2Q q))
  65.  
  66. str2Q :: Char -> Quaternion
  67. str2Q 'i' = i
  68. str2Q 'j' = j
  69. str2Q 'k' = k
  70. str2Q _ = error "no match char"
  71.  
  72. answer :: Quaternion -> Bool
  73. answer (-1, 0, 0, 0) = True
  74. answer _ = False
  75.  
  76. power :: Quaternion -> Integer -> Quaternion
  77. power qu n = foldr multi (1, 0, 0, 0) ([(1, 0, 0, 0)] ++ replicate (fromIntegral m) qu)
  78. where m = n `mod` 4
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement