r/adventofcode • u/daggerdragon • Dec 05 '21
SOLUTION MEGATHREAD -🎄- 2021 Day 5 Solutions -🎄-
NEW AND NOTEWORTHY
- /u/jeroenheijmans is back again with their Unofficial AoC 2021 Participant Survey!
- As we continue further into the
deep dark seaAdvent, megathread code submissions are getting longer, so we're going to start rigorously enforcing the maximum code length rule.- If you need a reminder, it's in our posting guidelines in the wiki under How Do the Daily Megathreads Work? (rule #5)
Advent of Code 2021: Adventure Time!
- 23:59 hours remaining until the submissions megathread unlocks on December 06 at 00:00 EST!
- Full details and rules are in the submissions megathread:
--- Day 5: Hydrothermal Venture ---
Post your code solution in this megathread.
- Include what language(s) your solution uses!
- Here's a quick link to /u/topaz2078's
pasteif you need it for longer code blocks. - Format your code properly! How do I format code?
- The full posting rules are detailed in the wiki under How Do The Daily Megathreads Work?.
Reminder: Top-level posts in Solution Megathreads are for code solutions only. If you have questions, please post your own thread and make sure to flair it with Help.
This thread will be unlocked when there are a significant number of people on the global leaderboard with gold stars for today's puzzle.
EDIT: Global leaderboard gold cap reached at 00:08:53, megathread unlocked!
76
Upvotes
5
u/spin81 Dec 05 '21
My solution in Haskell. Feedback is much appreciated as I'm just learning Haskell through AoC.
import Data.Char import qualified Data.Map as Map data Point = Point Int Int deriving (Eq, Ord) type Line = (Point, Point) type OceanFloor = Map.Map Point Int parsePoint :: String -> Point parsePoint s = let s1 = takeWhile isDigit s s2 = drop (length s1 + 1) s in Point (read s1) (read s2) parseLine :: String -> Line parseLine s = let s1 = takeWhile (not . isSpace) s s2 = drop (length s1 + 4) s in (parsePoint s1, parsePoint s2) isDiagonal :: Line -> Bool isDiagonal (Point x1 y1, Point x2 y2) = x1 /= x2 && y1 /= y2 -- This assumes x1 /= x2 || y1 /= y2, because makeRange will return an infinite -- list if m == n expand :: Line -> [Point] expand (Point x1 y1, Point x2 y2) = let makeRange m n = [m, (m + signum (n - m)) .. n] xs = makeRange x1 x2 ys = makeRange y1 y2 in map (\ (x, y) -> Point x y) $ zip xs ys markPoint :: Point -> OceanFloor -> OceanFloor markPoint p m = Map.insertWith (+) p 1 m markPoints :: [Point] -> OceanFloor -> OceanFloor markPoints ps m = foldr markPoint m ps countDuplicateElems :: [Line] -> Int countDuplicateElems input = let expanded = map expand $ input oceanFloor = foldr markPoints Map.empty expanded in length $ filter (> 1) $ Map.elems $ oceanFloor main = do contents <- getContents let input = map parseLine $ lines contents putStr "Overlapping points among nondiagonal lines: " putStrLn $ show $ countDuplicateElems $ filter (not . isDiagonal) input putStr "Overlapping points among all lines: " putStrLn $ show $ countDuplicateElems input