From 371bddf748f3f82a51463817baa1a65735116b34 Mon Sep 17 00:00:00 2001 From: George Thomas Date: Mon, 8 Dec 2025 12:48:49 +0000 Subject: [PATCH] Use custom prelude --- haskell/Main.hs | 14 ++----- haskell/Pre.hs | 84 +++++++++++++++++++++++++++++++++++++++++ haskell/Puzzle.hs | 14 ------- haskell/Puzzles/Day1.hs | 11 ++---- haskell/Puzzles/Day2.hs | 12 ++---- haskell/Puzzles/Day3.hs | 14 ++----- haskell/Puzzles/Day4.hs | 21 ++--------- haskell/Puzzles/Day5.hs | 13 ++----- haskell/aoc.cabal | 2 +- 9 files changed, 106 insertions(+), 79 deletions(-) create mode 100644 haskell/Pre.hs delete mode 100644 haskell/Puzzle.hs diff --git a/haskell/Main.hs b/haskell/Main.hs index c9ef696..80a6c42 100644 --- a/haskell/Main.hs +++ b/haskell/Main.hs @@ -1,21 +1,15 @@ module Main (main) where -import Data.Bool -import Data.ByteString.Lazy qualified as BL -import Data.Functor -import Data.List.Extra +import Pre + import Data.Text.IO qualified as T -import Data.Text.Lazy.Encoding (encodeUtf8) -import Puzzle +import Data.Text.Lazy.Encoding qualified as TL import Puzzles.Day1 qualified as Day1 import Puzzles.Day2 qualified as Day2 import Puzzles.Day3 qualified as Day3 import Puzzles.Day4 qualified as Day4 import Puzzles.Day5 qualified as Day5 -import Test.Tasty -import Test.Tasty.Golden (goldenVsString) import Test.Tasty.Ingredients.ConsoleReporter -import Text.Megaparsec hiding (Pos) main :: IO () main = @@ -42,6 +36,6 @@ main = testGroup pt $ ( zip (map show [1 :: Int ..]) parts <&> \(n, pp) -> goldenVsString n ("../outputs/" <> t <> "/" <> pt <> "/" <> n) $ - encodeUtf8 . pp <$> input + TL.encodeUtf8 . pp <$> input ) <> [testGroup "extra" $ extraTests isRealData ("../outputs/" <> t <> "/" <> pt <> "/extra/") input] diff --git a/haskell/Pre.hs b/haskell/Pre.hs new file mode 100644 index 0000000..b2c44d4 --- /dev/null +++ b/haskell/Pre.hs @@ -0,0 +1,84 @@ +{-# LANGUAGE PackageImports #-} + +module Pre ( + module BasePrelude, + module Control.Applicative, + module Control.Monad, + module Control.Monad.Loops, + module Control.Monad.State, + module Data.Bifunctor, + module Data.Bool, + module Data.Char, + module Data.Foldable, + module Data.Foldable1, + module Data.Functor, + module Data.List, + module Data.List.Extra, + module Data.List.NonEmpty, + module Data.Maybe, + module Data.Ord, + module Data.Sequence, + module Data.Stream.Infinite, + module Data.Text, + module Data.Text.Encoding, + module Data.Void, + module Data.Word, + module Linear, + module Test.Tasty, + module Test.Tasty.Golden, + module Test.Tasty.HUnit, + module Text.Megaparsec, + module Text.Megaparsec.Char, + module Text.Megaparsec.Char.Lexer, + Puzzle (..), +) +where + +import "base" Prelude as BasePrelude hiding ( + foldl1, + foldr1, + head, + init, + last, + maximum, + minimum, + tail, + unzip, + ) + +import Control.Applicative +import Control.Monad +import Control.Monad.Loops +import Control.Monad.State +import Data.Bifunctor +import Data.Bool +import Data.Char +import Data.Foldable hiding (foldl1, foldr1, maximum, maximumBy, minimum, minimumBy) +import Data.Foldable1 +import Data.Functor +import Data.List (sortOn) +import Data.List.Extra (dropEnd, enumerate) +import Data.List.NonEmpty (NonEmpty ((:|)), nonEmpty, some1) +import Data.Maybe +import Data.Ord +import Data.Sequence (Seq) +import Data.Stream.Infinite (Stream ((:>))) +import Data.Text (Text) +import Data.Text.Encoding (encodeUtf8) +import Data.Text.Lazy qualified as TL +import Data.Void +import Data.Word +import Linear (V2 (..)) +import Test.Tasty +import Test.Tasty.Golden hiding (Always) +import Test.Tasty.HUnit +import Text.Megaparsec hiding (Pos, State, Stream, many, some) +import Text.Megaparsec.Char +import Text.Megaparsec.Char.Lexer (decimal) + +data Puzzle = forall input. Puzzle + { number :: Word + , parser :: Parsec Void Text input + , parts :: [input -> TL.Text] + , extraTests :: Bool -> FilePath -> IO input -> [TestTree] + } diff --git a/haskell/Puzzle.hs b/haskell/Puzzle.hs deleted file mode 100644 index c301d90..0000000 --- a/haskell/Puzzle.hs +++ /dev/null @@ -1,14 +0,0 @@ -module Puzzle where - -import Data.Text (Text) -import Data.Text.Lazy qualified as TL -import Data.Void -import Test.Tasty -import Text.Megaparsec - -data Puzzle = forall input. Puzzle - { number :: Word - , parser :: Parsec Void Text input - , parts :: [input -> TL.Text] - , extraTests :: Bool -> FilePath -> IO input -> [TestTree] - } diff --git a/haskell/Puzzles/Day1.hs b/haskell/Puzzles/Day1.hs index 6eddab0..b14e3bb 100644 --- a/haskell/Puzzles/Day1.hs +++ b/haskell/Puzzles/Day1.hs @@ -1,19 +1,14 @@ module Puzzles.Day1 (puzzle) where -import Control.Monad.State -import Data.Bifunctor -import Data.Functor +import Pre + import Data.Text.Lazy qualified as TL -import Puzzle -import Text.Megaparsec hiding (Pos) -import Text.Megaparsec.Char -import Text.Megaparsec.Char.Lexer qualified as Lex puzzle :: Puzzle puzzle = Puzzle { number = 1 - , parser = flip sepEndBy newline $ (,) <$> ((char 'L' $> L) <|> (char 'R' $> R)) <*> (Inc <$> Lex.decimal) + , parser = flip sepEndBy newline $ (,) <$> ((char 'L' $> L) <|> (char 'R' $> R)) <*> (Inc <$> decimal) , parts = [ TL.show . sum diff --git a/haskell/Puzzles/Day2.hs b/haskell/Puzzles/Day2.hs index 26a7b12..f3820d2 100644 --- a/haskell/Puzzles/Day2.hs +++ b/haskell/Puzzles/Day2.hs @@ -1,21 +1,15 @@ module Puzzles.Day2 (puzzle) where -import Control.Monad -import Data.Functor -import Data.Maybe -import Data.Text (Text) +import Pre + import Data.Text qualified as T import Data.Text.Lazy qualified as TL -import Puzzle -import Text.Megaparsec -import Text.Megaparsec.Char -import Text.Megaparsec.Char.Lexer qualified as Lex puzzle :: Puzzle puzzle = Puzzle { number = 2 - , parser = (<* newline) $ flip sepBy (char ',') $ (,) <$> (Lex.decimal <* char '-') <*> Lex.decimal + , parser = (<* newline) $ flip sepBy (char ',') $ (,) <$> (decimal <* char '-') <*> decimal , parts = [ TL.show . sum diff --git a/haskell/Puzzles/Day3.hs b/haskell/Puzzles/Day3.hs index 1a5613b..e2661f0 100644 --- a/haskell/Puzzles/Day3.hs +++ b/haskell/Puzzles/Day3.hs @@ -1,17 +1,9 @@ module Puzzles.Day3 (puzzle) where -import Control.Monad.Loops (unfoldrM) -import Data.Char (digitToInt) -import Data.Foldable1 -import Data.List.Extra (dropEnd) -import Data.List.NonEmpty (NonEmpty ((:|)), nonEmpty, some1) +import Pre + import Data.List.NonEmpty qualified as NE -import Data.Maybe import Data.Text.Lazy qualified as TL -import Data.Word -import Puzzle -import Text.Megaparsec -import Text.Megaparsec.Char (digitChar, newline) puzzle :: Puzzle puzzle = @@ -38,7 +30,7 @@ newtype Battery = Battery Word8 -- maximal n-digit subsequence -- returns `Nothing` if list isn't long enough (>= n) maxBatteries :: Int -> Bank -> Maybe [Battery] -maxBatteries n0 (Bank bs0) = flip unfoldrM (n0, NE.toList bs0) \case +maxBatteries n0 (Bank bs0) = flip unfoldrM (n0, toList bs0) \case (0, _) -> pure Nothing (n, bs) -> do (b, i) <- findMax <$> nonEmpty (dropEnd (n - 1) bs) diff --git a/haskell/Puzzles/Day4.hs b/haskell/Puzzles/Day4.hs index e4290dd..c4aa270 100644 --- a/haskell/Puzzles/Day4.hs +++ b/haskell/Puzzles/Day4.hs @@ -1,25 +1,12 @@ module Puzzles.Day4 (puzzle) where -import Control.Applicative -import Control.Monad -import Data.Bifunctor -import Data.Foldable -import Data.Functor -import Data.List.Extra -import Data.Sequence (Seq) +import Pre + import Data.Sequence qualified as Seq -import Data.Stream.Infinite (Stream ((:>))) import Data.Stream.Infinite qualified as S import Data.Text.Lazy qualified as TL -import Data.Text.Lazy.Encoding (encodeUtf8) +import Data.Text.Lazy.Encoding qualified as TL import Data.Text.Lazy.IO qualified as TL -import Linear -import Puzzle -import Test.Tasty -import Test.Tasty.Golden -import Test.Tasty.HUnit -import Text.Megaparsec hiding (Stream, some) -import Text.Megaparsec.Char puzzle :: Puzzle puzzle = @@ -45,7 +32,7 @@ puzzle = nFrames = if isRealData then 58 else 9 in ( [0 .. nFrames] <&> \n -> goldenVsString (show n) (path <> "frames/" <> show n) $ - encodeUtf8 . maybe "frame list too short!" drawGrid . Seq.lookup n <$> frames + TL.encodeUtf8 . maybe "frame list too short!" drawGrid . Seq.lookup n <$> frames ) <> [ testCase "end" do Just g <- Seq.lookup nFrames <$> frames diff --git a/haskell/Puzzles/Day5.hs b/haskell/Puzzles/Day5.hs index 6a07f97..c0df55d 100644 --- a/haskell/Puzzles/Day5.hs +++ b/haskell/Puzzles/Day5.hs @@ -1,22 +1,17 @@ module Puzzles.Day5 (puzzle) where -import Control.Monad -import Data.List -import Data.Ord +import Pre + import Data.Text.Lazy qualified as TL -import Puzzle -import Text.Megaparsec hiding (some) -import Text.Megaparsec.Char -import Text.Megaparsec.Char.Lexer qualified as Lex puzzle :: Puzzle puzzle = Puzzle { number = 5 , parser = do - ranges <- flip sepEndBy newline $ Range <$> Lex.decimal <* single '-' <*> Lex.decimal + ranges <- flip sepEndBy newline $ Range <$> decimal <* single '-' <*> decimal void newline - vals <- sepEndBy Lex.decimal newline + vals <- sepEndBy decimal newline pure (ranges, vals) , parts = [ \(ranges, vals) -> diff --git a/haskell/aoc.cabal b/haskell/aoc.cabal index e9d713c..67722d0 100644 --- a/haskell/aoc.cabal +++ b/haskell/aoc.cabal @@ -9,7 +9,7 @@ executable aoc main-is: Main.hs hs-source-dirs: . other-modules: - Puzzle + Pre Puzzles.Day1 Puzzles.Day2 Puzzles.Day3