Skip to content

Instantly share code, notes, and snippets.

@skatenerd
Last active December 3, 2024 01:29
Show Gist options
  • Save skatenerd/15b37c0357f7f0285acb4338ed1512ed to your computer and use it in GitHub Desktop.
Save skatenerd/15b37c0357f7f0285acb4338ed1512ed to your computer and use it in GitHub Desktop.
2024 Day Two
{-# LANGUAGE OverloadedStrings #-}
module DayTwo (partOne, partTwo, isSafeWithSingleModification, allVariations) where
import qualified Data.Set as S
import qualified Data.Text as T
import qualified Text.Read as TR
import Topograph (pairs)
readText :: T.Text -> Int
readText = TR.read . T.unpack
parseLine :: T.Text -> [Int]
parseLine line = map readText $ T.words line
partOne :: [T.Text] -> Int
partOne reports = length safeReports
where
safeReports = filter isSafe parsedReports
parsedReports = map parseLine reports
partTwo :: [T.Text] -> Int
partTwo reports = length safeReports
where
safeReports = filter isSafeWithSingleModification parsedReports
parsedReports = map parseLine reports
allVariations :: [Int] -> [[Int]]
allVariations [] = []
allVariations (h:t) = t:recursiveAnswers
where recursiveAnswers = [h:answer | answer <- allVariations t]
isSafe :: [Int] -> Bool
isSafe report = isMonotonic report && (all pairIsValidSize (pairs report))
where pairIsValidSize = isValidSize . magnitude
isValidSize x = (x >= 1) && (x <= 3)
magnitude (a, b) = abs $ a - b
isSafeWithSingleModification :: [Int] -> Bool
isSafeWithSingleModification report = isSafe report || (any isSafe $ allVariations report)
isMonotonic :: [Int] -> Bool
isMonotonic items = not $ illegal allSigns
where
allSigns = S.fromList $ map pairSign $ pairs items
illegal signs = (1 `elem` signs) && ((negate 1) `elem` signs)
pairSign (a,b) = signum (b - a)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment