Skip to content

Instantly share code, notes, and snippets.

@magthe
Created December 18, 2017 17:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save magthe/3388140dfd59ff49d573971194bc39d3 to your computer and use it in GitHub Desktop.
Save magthe/3388140dfd59ff49d573971194bc39d3 to your computer and use it in GitHub Desktop.
AoC 2017, day 16
import Control.Applicative
import Data.Monoid
import Data.Vector as V
import Prelude as P
import Text.ParserCombinators.ReadP
spinList :: Int -> Vector Char -> Vector Char
spinList n xs = let (h, t) = V.splitAt (l - n) xs
l = V.length xs
in t <> h
exchangeElementsAt :: Int -> Int -> Vector Char -> Vector Char
exchangeElementsAt i j xs = let m = xs ! i
n = xs ! j
in xs // [(i, n), (j, m)]
swapElements :: Char -> Char -> Vector Char -> Vector Char
swapElements m n xs = let (Just i) = elemIndex m xs
(Just j) = elemIndex n xs
in xs // [(i, n), (j, m)]
readMoves = sepBy readMove (char ',')
readMove = choice [readSpin, readExchange, readPartner]
readSpin = spinList <$> (char 's' *> readS_to_P reads)
readExchange = exchangeElementsAt <$> (char 'x' *> readS_to_P reads) <*> (char '/' *> readS_to_P reads)
readPartner = swapElements <$> (char 'p' *> get) <*> (char '/' *> get)
runMoves ps ms = P.foldr ($) (fromList ps) . P.reverse . fst . P.last $ readP_to_S readMoves ms
-- example use
-- progs = "abcde"
-- moves = "s1,x3/4,pe/b"
-- runMoves progs moves
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment