Day 4: Ceres Search
Megathread guidelines
- Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
- You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL
FAQ
- What is this?: Here is a post with a large amount of details: https://programming.dev/post/6637268
- Where do I participate?: https://adventofcode.com/
- Is there a leaderboard for the community?: We have a programming.dev leaderboard with the info on how to join in this post: https://programming.dev/post/6631465
Haskell
import Control.Arrow import Data.Array.Unboxed import Data.List type Pos = (Int, Int) type Board = Array Pos Char data Dir = N | NE | E | SE | S | SW | W | NW target = "XMAS" parse s = listArray ((1, 1), (n, m)) [l !! i !! j | i <- [0 .. n - 1], j <- [0 .. m - 1]] where l = lines s (n, m) = (length $ head l, length l) move N = first pred move S = first succ move E = second pred move W = second succ move NW = move N . move W move SW = move S . move W move NE = move N . move E move SE = move S . move E check :: Board -> Pos -> Int -> Dir -> Bool check b p i d = i >= length target || ( inRange (bounds b) p && (b ! p) == (target !! i) && check b (move d p) (succ i) d ) checkAllDirs :: Board -> Pos -> Int checkAllDirs b p = length . filter (check b p 0) $ [N, NE, E, SE, S, SW, W, NW] check2 :: Board -> Pos -> Bool check2 b p = all (inRange (bounds b)) moves && ((b ! p) == 'A') && ("SSMM" `elem` rotations) where rotations = rots $ (b !) <$> moves moves = flip move p <$> [NE, SE, SW, NW] rots xs = init $ zipWith (++) (tails xs) (inits xs) part1 b = sum $ checkAllDirs b <$> indices b part2 b = length . filter (check2 b) $ indices b main = getContents >>= print . (part1 &&& part2) . parse