I struggled a lot more when doing list slices that I would've liked to
Haskell
import Data.List qualified as List
collectDiagonal :: [String] -> Int -> Int -> String
collectDiagonal c y x
| length c > y && length (c !! y) > x = c !! y !! x : collectDiagonal c (y+1) (x+1)
| otherwise = []
part1 c = do
let forwardXMAS = map (length . filter (List.isPrefixOf "XMAS") . List.tails) $ c
let backwardXMAS = map (length . filter (List.isPrefixOf "XMAS") . List.tails . reverse) $ c
let downwardXMAS = map (length . filter (List.isPrefixOf "XMAS") . List.tails ) . List.transpose $ c
let upwardXMAS = map (length . filter (List.isPrefixOf "XMAS") . List.tails . reverse ) . List.transpose $ c
let leftSideDiagonals = map (\ y -> collectDiagonal c y 0) [0..length c]
let leftTopDiagonals = map (\ x -> collectDiagonal c 0 x) [1..(length . List.head $ c)]
let leftDiagonals = leftSideDiagonals ++ leftTopDiagonals
let rightSideDiagonals = map (\ y -> collectDiagonal (map List.reverse c) y 0) [0..length c]
let rightTopDiagonals = map (\ x -> collectDiagonal (map List.reverse c) 0 x) [1..(length . List.head $ c)]
let rightDiagonals = rightSideDiagonals ++ rightTopDiagonals
let diagonals = leftDiagonals ++ rightDiagonals
let diagonalXMAS = map (length . filter (List.isPrefixOf "XMAS") . List.tails) $ diagonals
let reverseDiagonalXMAS = map (length . filter (List.isPrefixOf "XMAS") . List.tails . reverse) $ diagonals
print . sum $ [sum forwardXMAS, sum backwardXMAS, sum downwardXMAS, sum upwardXMAS, sum diagonalXMAS, sum reverseDiagonalXMAS]
return ()
getBlock h w c y x = map (take w . drop x) . take h . drop y $ c
isXBlock b = do
let diagonal1 = collectDiagonal b 0 0
let diagonal2 = collectDiagonal (map List.reverse b) 0 0
diagonal1 `elem` ["SAM", "MAS"] && diagonal2 `elem` ["SAM", "MAS"]
part2 c = do
let lineBlocks = List.map (getBlock 3 3 c) [0..length c - 1]
let groupedBlocks = List.map (flip List.map [0..(length . head $ c) - 1]) lineBlocks
print . sum . map (length . filter isXBlock) $ groupedBlocks
return ()
main = do
c <- lines <$> getContents
part1 c
part2 c
return ()