Generalise puzzle parts type
This commit is contained in:
parent
8442ce8dba
commit
784e6f2fb2
@ -2,6 +2,8 @@ module Main (main) where
|
|||||||
|
|
||||||
import Pre
|
import Pre
|
||||||
|
|
||||||
|
import Data.Functor.Contravariant
|
||||||
|
import Data.Functor.Identity
|
||||||
import Data.Text.IO qualified as T
|
import Data.Text.IO qualified as T
|
||||||
import Puzzles.Day1 qualified as Day1
|
import Puzzles.Day1 qualified as Day1
|
||||||
import Puzzles.Day10 qualified as Day10
|
import Puzzles.Day10 qualified as Day10
|
||||||
@ -39,7 +41,9 @@ main =
|
|||||||
in
|
in
|
||||||
describe pt do
|
describe pt do
|
||||||
input <- liftIO $ parseFile $ "../inputs/" <> t <> "/" <> pt
|
input <- liftIO $ parseFile $ "../inputs/" <> t <> "/" <> pt
|
||||||
let (os, rs) = applyPuzzleParts input parts
|
let (rs, os) =
|
||||||
|
((unHListF . mapHListF (Const . fst)) &&& (fromHListF . mapHListF (Identity . snd))) $
|
||||||
|
mapHListF (\(Fanout (f, Op o)) -> (o &&& id) $ f input) parts
|
||||||
for_ (zip [1 :: Int ..] rs) $ uncurry $ \(show -> n) ->
|
for_ (zip [1 :: Int ..] rs) $ uncurry $ \(show -> n) ->
|
||||||
it n . pureGoldenTextFile ("../outputs/" <> t <> "/" <> pt <> "/" <> n) . (<> "\n")
|
it n . pureGoldenTextFile ("../outputs/" <> t <> "/" <> pt <> "/" <> n) . (<> "\n")
|
||||||
describe "extra" $ extraTests isRealData ("../outputs/" <> t <> "/" <> pt <> "/extra/") input os
|
describe "extra" $ extraTests isRealData ("../outputs/" <> t <> "/" <> pt <> "/extra/") input os
|
||||||
|
|||||||
@ -41,11 +41,14 @@ module Pre (
|
|||||||
allUnorderedPairs,
|
allUnorderedPairs,
|
||||||
adjacentPairs,
|
adjacentPairs,
|
||||||
sortPair,
|
sortPair,
|
||||||
PuzzleParts,
|
HListF (..),
|
||||||
applyPuzzleParts,
|
mapHListF,
|
||||||
|
fromHListF,
|
||||||
|
unHListF,
|
||||||
(/\),
|
(/\),
|
||||||
(/\\),
|
(/\\),
|
||||||
nil,
|
nil,
|
||||||
|
Fanout (..),
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
@ -73,6 +76,8 @@ import Data.Foldable hiding (foldl1, foldr1, maximum, maximumBy, minimum, minimu
|
|||||||
import Data.Foldable1
|
import Data.Foldable1
|
||||||
import Data.Function
|
import Data.Function
|
||||||
import Data.Functor
|
import Data.Functor
|
||||||
|
import Data.Functor.Contravariant
|
||||||
|
import Data.Functor.Identity
|
||||||
import Data.Kind (Type)
|
import Data.Kind (Type)
|
||||||
import Data.List (List, sortOn, transpose)
|
import Data.List (List, sortOn, transpose)
|
||||||
import Data.List.Extra (dropEnd, enumerate, firstJust, notNull, splitOn)
|
import Data.List.Extra (dropEnd, enumerate, firstJust, notNull, splitOn)
|
||||||
@ -127,32 +132,41 @@ adjacentPairs = \case
|
|||||||
sortPair :: (Ord a) => (a, a) -> (a, a)
|
sortPair :: (Ord a) => (a, a) -> (a, a)
|
||||||
sortPair (a, b) = if a <= b then (a, b) else (b, a)
|
sortPair (a, b) = if a <= b then (a, b) else (b, a)
|
||||||
|
|
||||||
|
type PuzzleParts input = HListF (Fanout ((->) input) (Op Text))
|
||||||
infixr 9 /\\
|
infixr 9 /\\
|
||||||
(/\\) :: (input -> output, output -> Text) -> PuzzleParts input outputs -> PuzzleParts input (output : outputs)
|
(/\\) :: (input -> output, output -> Text) -> PuzzleParts input outputs -> PuzzleParts input (output : outputs)
|
||||||
(/\\) = uncurry PuzzlePartsCons
|
(/\\) (f, o) = HConsF $ Fanout (f, Op o)
|
||||||
infixr 9 /\
|
infixr 9 /\
|
||||||
(/\) :: (Show output) => (input -> output) -> PuzzleParts input outputs -> PuzzleParts input (output : outputs)
|
(/\) :: (Show output) => (input -> output) -> PuzzleParts input outputs -> PuzzleParts input (output : outputs)
|
||||||
(/\) = flip PuzzlePartsCons T.show
|
(/\) f = HConsF $ Fanout (f, Op T.show)
|
||||||
nil :: PuzzleParts input '[]
|
nil :: PuzzleParts input '[]
|
||||||
nil = PuzzlePartsNil
|
nil = HNilF
|
||||||
|
|
||||||
data PuzzleParts (input :: Type) (outputs :: List Type) :: Type where
|
data HListF (f :: Type -> Type) (as :: List Type) :: Type where
|
||||||
PuzzlePartsNil :: PuzzleParts input '[]
|
HNilF :: HListF f '[]
|
||||||
PuzzlePartsCons ::
|
HConsF ::
|
||||||
(input -> output) ->
|
f a ->
|
||||||
(output -> Text) ->
|
HListF f as ->
|
||||||
PuzzleParts input outputs ->
|
HListF f (a ': as)
|
||||||
PuzzleParts input (output ': outputs)
|
|
||||||
applyPuzzleParts ::
|
mapHListF :: (forall a. f a -> g a) -> HListF f as -> HListF g as
|
||||||
forall input outputs.
|
mapHListF t = \case
|
||||||
input ->
|
HNilF -> HNilF
|
||||||
PuzzleParts input outputs ->
|
HConsF x xs -> HConsF (t x) $ mapHListF t xs
|
||||||
(HList outputs, [Text])
|
|
||||||
applyPuzzleParts e = \case
|
fromHListF :: HListF Identity as -> HList as
|
||||||
PuzzlePartsNil -> (HNil, [])
|
fromHListF = \case
|
||||||
PuzzlePartsCons f o ps -> let r = f e in bimap (HCons r) (o r :) $ applyPuzzleParts e ps
|
HNilF -> HNil
|
||||||
|
HConsF (Identity x) xs -> HCons x $ fromHListF xs
|
||||||
|
|
||||||
|
unHListF :: HListF (Const b) as -> List b
|
||||||
|
unHListF = \case
|
||||||
|
HNilF -> []
|
||||||
|
HConsF (Const x) xs -> x : unHListF xs
|
||||||
|
|
||||||
instance Semigroup (TestDefM a b ()) where
|
instance Semigroup (TestDefM a b ()) where
|
||||||
(<>) = (>>)
|
(<>) = (>>)
|
||||||
instance Monoid (TestDefM a b ()) where
|
instance Monoid (TestDefM a b ()) where
|
||||||
mempty = pure ()
|
mempty = pure ()
|
||||||
|
|
||||||
|
newtype Fanout f g a = Fanout (f a, g a)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user