···77This part needs us to consider each operation on a column. `Data.List.transpose` fortunately makes this very simple. If we are able to massage our input into the form `["+", "1", "2", "3"]`, we can use this simple `solve` function to produce the result. The only motivation to use this format is the ease of pattern-matching over the start of the list.
8899```haskell
1010+solve :: [String] -> Int
1011solve ("+" : rest) = sum . map read $ rest
1112solve ("*" : rest) = product . map read $ rest
1213```
···1415Thus, to solve the first part, we can break up our input using `lines`. `rot` is a simple function that rotates a list forwards to move the last element to the first.
15161617```haskell
1818+rot :: [a] -> [a]
1719rot = liftA2 (:) last init
1820```
1921···2830```
29313032```haskell
3131-3333+p1 :: String -> Int
3234p1 = sum . map solve . align . rot . lines
3335 where
3436 align = transpose . map words
···6971```
70727173```haskell
7474+p2 :: String -> Int
7275p2 = sum . map solve . align . rot . lines
7376 where
7477 align =
···91949295The second part ...
93969494- splitWhen (all isSpace) . transpose . tail
9797+ splitWhen (all (' ' ==)) . transpose . tail
95989699...is used to transpose numbers! Note what happens when we transpose the lines containing numbers, we get:
97100