this repo has no description
1module Lib
2 ( doSpin
3 , doExchange
4 , doPartner
5 , performDance
6 , parseMoves
7 , programStart
8 , loopsAt
9 ) where
10
11import Data.List
12import Data.List.Split (splitOn)
13
14programStart :: String
15programStart = "abcdefghijklmnop"
16
17parseMoves :: [String] -> [(String -> String)]
18parseMoves = map parseMove
19
20parseMove :: String -> (String -> String)
21parseMove m = case head m of
22 's' -> doSpin (strToInt $ tail m)
23 'x' -> doExchange (strToInt $ head . splitOn "/" $ tail m)
24 (strToInt $ last . splitOn "/" $ tail m)
25 'p' -> doPartner (head . head . splitOn "/" $ tail m)
26 (last . last . splitOn "/" $ tail m)
27 _ -> id
28
29performDance :: [(String -> String)] -> String -> String
30performDance moves start = foldl' (\r f -> f r) start moves
31
32strToInt :: String -> Int
33strToInt s = (read s :: Int)
34
35doSpin :: Int -> String -> String
36doSpin x ps = drop (length ps - x) ps ++ take (length ps - x) ps
37
38doExchange :: Int -> Int -> String -> String
39doExchange pos1 pos2 ps =
40 let firstPos = min pos1 pos2
41 secondPos = max pos1 pos2
42 p1 = ps !! firstPos
43 p2 = ps !! secondPos
44 in take firstPos ps ++ [p2]
45 ++ (take (secondPos - firstPos - 1) . drop (firstPos + 1) $ ps)
46 ++ [p1] ++ drop (secondPos + 1) ps
47
48doPartner :: Char -> Char -> String -> String
49doPartner p1 p2 ps = case elemIndex p1 ps of
50 Just pos1 -> case elemIndex p2 ps of
51 Just pos2 -> doExchange pos1 pos2 ps
52 Nothing -> ps
53 Nothing -> ps
54
55loopsAt :: [String] -> Int
56loopsAt = length . takeWhile (/= programStart)