module Main where


-- import Data.List.Split (splitOn)
import Data.List (nubBy)


part1 :: IO ()
part1 = readFile "input" >>= print . length . remDups . move

part2 :: IO ()
part2 = readFile "input" >>= print . length . remDups . roboMove

move :: String -> [[Int]]
move s = go [0, 0] s [[0, 0]]
    where go cs [] result = result
          go cs (s:ss) result
            | s == '>' = go [x+1, y] ss ([x+1, y]:result)  
            | s == '<' = go [x-1, y] ss ([x-1, y]:result)
            | s == '^' = go [x, y+1] ss ([x, y+1]:result)
            | s == 'v' = go [x, y-1] ss ([x, y-1]:result)
                where x = cs !! 0
                      y = cs !! 1

listEq :: [Int] -> [Int] -> Bool
listEq xs ys = if xs !! 0 == ys !! 0 && xs !! 1 == ys !! 1 then True else False

remDups :: [[Int]] -> [[Int]]
remDups xs = nubBy listEq xs

roboMove :: String -> [[Int]] -- am i gross
roboMove s = go [0, 0] [0, 0] s [[0, 0]] 0
    where go cs rcs [] result acc = result
          go cs rcs (s:ss) result acc
            | s == '>' && even acc = go [x+1, y] rcs ss ([x+1, y]:result) (acc + 1)
            | s == '<' && even acc = go [x-1, y] rcs ss ([x-1, y]:result) (acc + 1)
            | s == '^' && even acc = go [x, y+1] rcs ss ([x, y+1]:result) (acc + 1)
            | s == 'v' && even acc = go [x, y-1] rcs ss ([x, y-1]:result) (acc + 1)
            | s == '>' = go cs [rx+1, ry] ss ([rx+1, ry]:result) (acc + 1)
            | s == '<' = go cs [rx-1, ry] ss ([rx-1, ry]:result) (acc + 1)
            | s == '^' = go cs [rx, ry+1] ss ([rx, ry+1]:result) (acc + 1)
            | s == 'v' = go cs [rx, ry-1] ss ([rx, ry-1]:result) (acc + 1)
            | otherwise = result
                where x = cs !! 0
                      y = cs !! 1
                      rx = rcs !! 0
                      ry = rcs !! 1


main :: IO ()
main = do
  part1
  part2