mirror of
https://codeberg.org/JasterV/aoc2024-haskell.git
synced 2026-04-26 18:10:05 +00:00
feat: day5 part one
This commit is contained in:
parent
05900411a2
commit
76db862cb0
5 changed files with 1469 additions and 0 deletions
|
|
@ -28,6 +28,7 @@ library
|
|||
Day1
|
||||
Day2
|
||||
Day3
|
||||
Day5
|
||||
other-modules:
|
||||
Paths_aoc2024
|
||||
autogen-modules:
|
||||
|
|
@ -37,7 +38,9 @@ library
|
|||
ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints
|
||||
build-depends:
|
||||
base >=4.7 && <5
|
||||
, containers
|
||||
, regex-tdfa >=1.3.2 && <1.4
|
||||
, text >=2.0.2
|
||||
default-language: Haskell2010
|
||||
|
||||
test-suite aoc2024-test
|
||||
|
|
@ -47,6 +50,7 @@ test-suite aoc2024-test
|
|||
Day1Spec
|
||||
Day2Spec
|
||||
Day3Spec
|
||||
Day5Spec
|
||||
Paths_aoc2024
|
||||
autogen-modules:
|
||||
Paths_aoc2024
|
||||
|
|
@ -57,6 +61,8 @@ test-suite aoc2024-test
|
|||
QuickCheck >=2.14.3 && <2.15
|
||||
, aoc2024
|
||||
, base >=4.7 && <5
|
||||
, containers
|
||||
, hspec >=2.0.0
|
||||
, regex-tdfa >=1.3.2 && <1.4
|
||||
, text >=2.0.2
|
||||
default-language: Haskell2010
|
||||
|
|
|
|||
1366
input/day5.txt
Normal file
1366
input/day5.txt
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -22,6 +22,8 @@ description: Please see the README on GitHub at <https://github.com/githubuser/a
|
|||
dependencies:
|
||||
- base >= 4.7 && < 5
|
||||
- regex-tdfa ^>= 1.3.2
|
||||
- text >= 2.0.2
|
||||
- containers
|
||||
|
||||
ghc-options:
|
||||
- -Wall
|
||||
|
|
|
|||
55
src/Day5.hs
Normal file
55
src/Day5.hs
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
module Day5 (ParseError, partOne, partTwo) where
|
||||
|
||||
import qualified Data.Bifunctor as BF
|
||||
import Data.List (sortBy)
|
||||
import Data.Set (Set, fromList, member)
|
||||
import qualified Data.Text as T
|
||||
import Data.Text.Read (decimal)
|
||||
|
||||
data ParseError = ParseIntError String | ParseRuleError T.Text | ParseInputError
|
||||
deriving (Show, Eq)
|
||||
|
||||
type Rule = (Int, Int)
|
||||
|
||||
type Update = [Int]
|
||||
|
||||
partOne :: String -> Either ParseError Int
|
||||
partOne input = do
|
||||
(rules, updates) <- parseInput input
|
||||
return $ sum $ map middleElem $ filter (isValidUpdate rules) updates
|
||||
where
|
||||
isValidUpdate rules update = sortBy (compareByRules rules) update == update
|
||||
compareByRules rules x y = if member (x, y) rules then LT else GT
|
||||
middleElem update = update !! (length update `div` 2)
|
||||
|
||||
partTwo :: String -> Either ParseError Int
|
||||
partTwo _ = Right 0
|
||||
|
||||
parseInput :: String -> Either ParseError (Set Rule, [Update])
|
||||
parseInput content = case T.splitOn separator text of
|
||||
[left, right] -> do
|
||||
rules <- parseRules left
|
||||
updates <- parseUpdates right
|
||||
return (rules, updates)
|
||||
_ -> Left ParseInputError
|
||||
where
|
||||
text = T.pack content
|
||||
separator = T.pack "\n\n"
|
||||
|
||||
parseRules :: T.Text -> Either ParseError (Set Rule)
|
||||
parseRules rules = fromList <$> mapM parseRule (T.lines rules)
|
||||
where
|
||||
parseRule rule = case T.split (== '|') rule of
|
||||
[left, right] -> do
|
||||
leftNum <- parseInt left
|
||||
rightNum <- parseInt right
|
||||
return (leftNum, rightNum)
|
||||
_ -> Left (ParseRuleError rule)
|
||||
|
||||
parseUpdates :: T.Text -> Either ParseError [Update]
|
||||
parseUpdates updates = mapM parseUpdate $ T.lines updates
|
||||
where
|
||||
parseUpdate = mapM parseInt . T.split (== ',')
|
||||
|
||||
parseInt :: T.Text -> Either ParseError Int
|
||||
parseInt v = fst <$> BF.first ParseIntError (decimal v)
|
||||
40
test/Day5Spec.hs
Normal file
40
test/Day5Spec.hs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
module Day5Spec (spec) where
|
||||
|
||||
import Day5 (partOne)
|
||||
import Test.Hspec
|
||||
|
||||
spec :: Spec
|
||||
spec = do
|
||||
describe "PartOne" $ do
|
||||
it "works" $ do
|
||||
partOne input `shouldBe` Right 143
|
||||
where
|
||||
input =
|
||||
"47|53\n\
|
||||
\97|13\n\
|
||||
\97|61\n\
|
||||
\97|47\n\
|
||||
\75|29\n\
|
||||
\61|13\n\
|
||||
\75|53\n\
|
||||
\29|13\n\
|
||||
\97|29\n\
|
||||
\53|29\n\
|
||||
\61|53\n\
|
||||
\97|53\n\
|
||||
\61|29\n\
|
||||
\47|13\n\
|
||||
\75|47\n\
|
||||
\97|75\n\
|
||||
\47|61\n\
|
||||
\75|61\n\
|
||||
\47|29\n\
|
||||
\75|13\n\
|
||||
\53|13\n\
|
||||
\\n\
|
||||
\75,47,61,53,29\n\
|
||||
\97,61,53,29,13\n\
|
||||
\75,29,13\n\
|
||||
\75,97,47,61,53\n\
|
||||
\61,13,29\n\
|
||||
\97,13,75,29,47"
|
||||
Loading…
Reference in a new issue