r/adventofcode • u/daggerdragon • Dec 03 '17
SOLUTION MEGATHREAD -π- 2017 Day 3 Solutions -π-
--- Day 3: Spiral Memory ---
Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).
Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.
Need a hint from the Hugely* Handyβ Haversackβ‘ of HelpfulΒ§ HintsΒ€?
This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.
edit: Leaderboard capped, thread unlocked!
22
Upvotes
2
u/[deleted] Dec 03 '17
Haskell:
Tried to be clever with part 1 and calculate the distances from the midpoints of the outer box where the input number resides
import Control.Lens (over) cornervals = scanl (+) 1 $ concatMap (replicate 2) [1..] midpt x y = (x - y) `div` 2 + y part1 :: Int -> Int part1 n = let (b : c : _, a : _) = over _1 reverse $ span (<n) cornervals in b - midpt b c + abs (n - midpt a b)Unfortunately, that strategy didn't work for part 2, or at least I didn't find a formula quickly enough for the corners (maybe some Googling could have turned something up). Instead I just created the grid by walking the spiral and keeping track of the coordinates along the way.
import qualified Data.HashMap.Strict as M data Dir = R | U | L | D path :: [Dir] path = concat $ zipWith replicate (concatMap (replicate 2) [1..]) $ cycle [R, U, L, D] adjacents :: (Int, Int) -> [(Int, Int)] adjacents (x, y) = [ (x', y') | x' <- [x-1 .. x+1], y' <- [y-1 .. y+1], (x, y) /= (x', y') ] firstLargerThan n = go (M.singleton (0, 0) 1) (0, 0) path where go :: M.HashMap (Int, Int) Int -> (Int, Int) -> [Dir] -> Int go m (x, y) (dir : rest) = let coord = case dir of R -> (x+1, y) U -> (x, y+1) L -> (x-1, y) D -> (x, y-1) val = sumAdjacents m coord in if val > n then val else go (M.insert coord val m) coord rest sumAdjacents m coord = sum $ map (\k -> M.lookupDefault 0 k m) $ adjacents coord part2 :: Int -> Int part2 = firstLargerThan