···11+## Day 6
22+33+This day is largely string munging, which is quite boring, but also quite easy to do with Haskell!
44+55+### Part 1
66+77+This 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.
88+99+```haskell
1010+solve ("+" : rest) = sum . map read $ rest
1111+solve ("*" : rest) = product . map read $ rest
1212+```
1313+1414+Thus, 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. By doing `rot . lines` upon our input, we have a list of the form `["+ *", "1 2 3", "4 5 6"]`. Next, we define an `align` function to line up the colums. This method simply breaks each item in the list by spaces, and then transposes them, so we end up with `[["+", "1", "2", "3"], ["*", "4", "5", "6"]]`:
1515+1616+```haskell-top
1717+import Data.Char (isSpace)
1818+import Data.List (transpose)
1919+import Data.List.Split (splitWhen)
2020+```
2121+2222+```haskell
2323+rot = liftA2 (:) last init
2424+2525+p1 = sum . map solve . align . rot . lines
2626+ where
2727+ align = transpose . map words
2828+```
2929+3030+### Part 2
3131+3232+We are now tasked with lining up the digits in a columnar fashion to for a number:
3333+3434+ 123 ...
3535+ 45 ...
3636+ 6 ...
3737+ * ...
3838+3939+Here, the numbers to operate on are 356, 24 and 1. Unfortunately, we can no longer employ `words` as it breaks on all whitespace. We must now transpose our list as-is, to make sense of the digits. Ignore the last row for a second, and only consider the first 3 rows:
4040+4141+ 123
4242+ 45
4343+ 6
4444+4545+Upon transposing this, we get:
4646+4747+ 1
4848+ 24
4949+ 356
5050+5151+This is exactly what we need!
5252+5353+Let us start with a similar base, using `lines` to break things up, and `rot` to move the line of operators to the start. Our `align` function can now be defined as below.
5454+5555+```haskell
5656+p2 = sum . map solve . align . rot . lines
5757+ where
5858+ align =
5959+ zipWith (:)
6060+ <$> (words . head)
6161+ <*> (splitWhen (all isSpace) . transpose . tail)
6262+```
6363+6464+We first start with `zipWith (:)` to join the operation `"+"` with the rest of the numbers to produce:
6565+6666+ ["+", "1", "2", ...]
6767+6868+Remember that this is the format `solve` accepts!
6969+7070+We are using `<*>` to perform "sequential application". The first part ...
7171+7272+ words . head
7373+7474+... is used to split up the operator line into a list of operators.
7575+7676+The second part ...
7777+7878+ splitWhen (all isSpace) . transpose . tail
7979+8080+...is used to transpose numbers! Note what happens when we transpose the lines containing numbers, we get:
8181+8282+ ["1 ","24 ","356"," ","369","248","8 ", ...]
8383+8484+There is an element containing all spaces (which was present between each column), `Data.List.Split.splitWhen` is employed to detect and chunk our list into runs of valid numbers.
8585+8686+8787+Finally, a main function to wrap it all up:
8888+8989+```haskell
9090+main = do
9191+ n <- getContents
9292+ print $ p1 n
9393+ print $ p2 n
9494+```