diff --git a/.gitignore b/.gitignore index 7065d50..0efe52a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,12 @@ +# Ignore all +* + +# Unignore all with extensions +!*.* + +# Unignore all dirs +!*/ + dist dist-* cabal-dev diff --git a/5-a.hs b/5-a.hs new file mode 100644 index 0000000..de6a838 --- /dev/null +++ b/5-a.hs @@ -0,0 +1,30 @@ +{-# LANGUAGE OverloadedStrings #-} + +import qualified Data.Text as T +import GHC.Utils.Misc (chunkList) +import Data.Char (isSpace, isNumber) + +rotate2DList :: [[a]] -> [[a]] +rotate2DList l = map (\i -> map (!! i) l) [0 .. length l] + +parseState :: String -> [[Char]] +parseState = map (dropWhile isSpace) . rotate2DList . map (map (!! 1) . chunkList 4) . init . lines + +parseInstructions :: String -> [(Int, Int)] +parseInstructions = concatMap ((\[n, a, b] -> replicate n (a, b)) . map read . filter (isNumber . head) . words) . lines + +evaluateState :: [[Char]] -> (Int, Int) -> [[Char]] +evaluateState state (a, b) = newState + where extracted = zipWith (\i l -> (if i == a then tail l else l)) [1..] state + movedChar = head $ state !! (a - 1) + newState = zipWith (\i l -> (if i == b then movedChar : l else l)) [1..] extracted + +executeInstructions :: [[Char]] -> [(Int, Int)] -> [[Char]] +executeInstructions state (instruction:xs) = executeInstructions newState xs + where newState = evaluateState state instruction +executeInstructions state [] = state + +main = interact $ + map head + . (\[state, instructions] -> executeInstructions (parseState state) (parseInstructions instructions)) + . map T.unpack . T.splitOn "\n\n" . T.pack \ No newline at end of file diff --git a/5-b.hs b/5-b.hs new file mode 100644 index 0000000..daec73b --- /dev/null +++ b/5-b.hs @@ -0,0 +1,30 @@ +{-# LANGUAGE OverloadedStrings #-} + +import qualified Data.Text as T +import GHC.Utils.Misc (chunkList) +import Data.Char (isSpace, isNumber) + +rotate2DList :: [[a]] -> [[a]] +rotate2DList l = map (\i -> map (!! i) l) [0 .. length l] + +parseState :: String -> [[Char]] +parseState = map (dropWhile isSpace) . rotate2DList . map (map (!! 1) . chunkList 4) . init . lines + +parseInstructions :: String -> [(Int, Int, Int)] +parseInstructions = map ((\[n, a, b] -> (n, a, b)) . map read . filter (isNumber . head) . words) . lines + +evaluateState :: [[Char]] -> (Int, Int, Int) -> [[Char]] +evaluateState state (n, a, b) = newState + where extracted = zipWith (\i l -> (if i == a then drop n l else l)) [1..] state + movedChars = take n $ state !! (a - 1) + newState = zipWith (\i l -> (if i == b then movedChars ++ l else l)) [1..] extracted + +executeInstructions :: [[Char]] -> [(Int, Int, Int)] -> [[Char]] +executeInstructions state (instruction:xs) = executeInstructions newState xs + where newState = evaluateState state instruction +executeInstructions state [] = state + +main = interact $ + map head + . (\[state, instructions] -> executeInstructions (parseState state) (parseInstructions instructions)) + . map T.unpack . T.splitOn "\n\n" . T.pack \ No newline at end of file diff --git a/clean.sh b/clean.sh index 6d81284..e181557 100755 --- a/clean.sh +++ b/clean.sh @@ -2,7 +2,7 @@ rm ./*-a rm ./*-b -rm ./*-a-v* -rm ./*-b-v* +rm ./*-a-v2 +rm ./*-b-v2 rm ./*.hi rm ./*.o