mirror of
https://codeberg.org/JasterV/aoc2024-haskell.git
synced 2026-04-26 18:10:05 +00:00
finish day8 and refactor
This commit is contained in:
parent
68f6a8e6f7
commit
c081936a7d
6 changed files with 65 additions and 53 deletions
|
|
@ -27,6 +27,7 @@ library
|
|||
exposed-modules:
|
||||
Data.List.Extra
|
||||
Data.Matrix
|
||||
Data.Point
|
||||
Day1
|
||||
Day2
|
||||
Day3
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
module Data.Matrix
|
||||
( Matrix,
|
||||
Position,
|
||||
buildMatrix,
|
||||
lookupValue,
|
||||
lookup,
|
||||
|
|
@ -21,12 +20,11 @@ import Data.List (find)
|
|||
import Data.Map.Lazy (Map)
|
||||
import qualified Data.Map.Lazy as Map
|
||||
import Data.Maybe
|
||||
import Data.Point (Point)
|
||||
import Prelude hiding (filter, lookup)
|
||||
|
||||
newtype Matrix v = Matrix (Map (Int, Int) v)
|
||||
|
||||
type Position = (Int, Int)
|
||||
|
||||
buildMatrix :: [[a]] -> Matrix a
|
||||
buildMatrix xs = Matrix (go xs 0 Map.empty)
|
||||
where
|
||||
|
|
@ -43,22 +41,22 @@ buildMatrix xs = Matrix (go xs 0 Map.empty)
|
|||
size :: Matrix v -> Int
|
||||
size (Matrix hmap) = Map.size hmap
|
||||
|
||||
isInBounds :: Position -> Matrix v -> Bool
|
||||
isInBounds :: Point -> Matrix v -> Bool
|
||||
isInBounds pos (Matrix hmap) = Map.member pos hmap
|
||||
|
||||
filterWithKey :: (Position -> v -> Bool) -> Matrix v -> Matrix v
|
||||
filterWithKey :: (Point -> v -> Bool) -> Matrix v -> Matrix v
|
||||
filterWithKey f (Matrix hmap) = Matrix (Map.filterWithKey f hmap)
|
||||
|
||||
filter :: (v -> Bool) -> Matrix v -> Matrix v
|
||||
filter f (Matrix hmap) = Matrix (Map.filter f hmap)
|
||||
|
||||
lookup :: Position -> Matrix v -> Maybe v
|
||||
lookup :: Point -> Matrix v -> Maybe v
|
||||
lookup position (Matrix hmap) = Map.lookup position hmap
|
||||
|
||||
lookupMultiple :: [Position] -> Matrix v -> [v]
|
||||
lookupMultiple :: [Point] -> Matrix v -> [v]
|
||||
lookupMultiple positions matrix = mapMaybe (`lookup` matrix) positions
|
||||
|
||||
insert :: Position -> v -> Matrix v -> Matrix v
|
||||
insert :: Point -> v -> Matrix v -> Matrix v
|
||||
insert position value (Matrix hmap) =
|
||||
Matrix $
|
||||
if Map.member position hmap
|
||||
|
|
@ -69,7 +67,7 @@ insert position value (Matrix hmap) =
|
|||
Search for the given value on the matrix.
|
||||
Return the position of the first match if found and nothing if it doens't exist.
|
||||
--}
|
||||
lookupValue :: (Eq v) => v -> Matrix v -> Maybe Position
|
||||
lookupValue :: (Eq v) => v -> Matrix v -> Maybe Point
|
||||
lookupValue v (Matrix hmap) =
|
||||
let entries = Map.toAscList hmap
|
||||
mEntry = find ((== v) . snd) entries
|
||||
|
|
@ -80,7 +78,7 @@ Group elements given a function.
|
|||
The function receives an entry of the matrix and returns a pair of key -> value.
|
||||
The values are grouped in order.
|
||||
--}
|
||||
groupByWith :: forall v a b. (Ord a) => ((Position, v) -> (a, b)) -> Matrix v -> Map a [b]
|
||||
groupByWith :: forall v a b. (Ord a) => ((Point, v) -> (a, b)) -> Matrix v -> Map a [b]
|
||||
groupByWith f (Matrix hmap) =
|
||||
let sortedEntries = Map.toAscList hmap
|
||||
in foldr (insert' . f) Map.empty sortedEntries
|
||||
|
|
|
|||
18
src/Data/Point.hs
Normal file
18
src/Data/Point.hs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
module Data.Point
|
||||
( Point,
|
||||
substract,
|
||||
add,
|
||||
distance,
|
||||
)
|
||||
where
|
||||
|
||||
type Point = (Int, Int)
|
||||
|
||||
substract :: Point -> (Int, Int) -> (Int, Int)
|
||||
substract (x, y) (dx, dy) = (x - dx, y - dy)
|
||||
|
||||
add :: Point -> (Int, Int) -> (Int, Int)
|
||||
add (x, y) (dx, dy) = (x + dx, y + dy)
|
||||
|
||||
distance :: Point -> Point -> (Int, Int)
|
||||
distance (xrow, xcol) (yrow, ycol) = (xrow - yrow, xcol - ycol)
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
module Day6 (partOne, partTwo) where
|
||||
|
||||
import qualified Data.HashSet as HashSet
|
||||
import Data.Matrix (Matrix, Position)
|
||||
import Data.Matrix (Matrix)
|
||||
import qualified Data.Matrix as M
|
||||
import Data.Point (Point)
|
||||
import Day6.Guard (Guard (..))
|
||||
import qualified Day6.Guard as G
|
||||
|
||||
|
|
@ -21,8 +22,8 @@ partTwo input = do
|
|||
let labMap = parseLabMap input
|
||||
guard <- findGuard labMap
|
||||
route <- predictGuardsRoute guard labMap
|
||||
let initialPosition = position guard
|
||||
candidates = filter (/= initialPosition) route
|
||||
let initialPoint = position guard
|
||||
candidates = filter (/= initialPoint) route
|
||||
|
||||
return $
|
||||
length $
|
||||
|
|
@ -52,7 +53,7 @@ findGuard matrix =
|
|||
[_, _, _, Just pos] -> Right (Guard pos G.Left)
|
||||
_ -> Left GuardNotFoundError
|
||||
|
||||
predictGuardsRoute :: Guard -> LabMap -> Either Error [Position]
|
||||
predictGuardsRoute :: Guard -> LabMap -> Either Error [Point]
|
||||
predictGuardsRoute initialGuard labMap = go initialGuard HashSet.empty HashSet.empty
|
||||
where
|
||||
go guard visited acc =
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
module Day6.Guard (Guard (..), Direction (..), moveForward, turnRight) where
|
||||
|
||||
import Data.Hashable
|
||||
import Data.Matrix (Position)
|
||||
import Data.Point (Point)
|
||||
import GHC.Generics (Generic)
|
||||
import Prelude hiding (Left, Right)
|
||||
|
||||
|
|
@ -12,7 +12,7 @@ data Direction = Up | Down | Left | Right
|
|||
|
||||
instance Hashable Direction
|
||||
|
||||
data Guard = Guard {position :: Position, directon :: Direction}
|
||||
data Guard = Guard {position :: Point, directon :: Direction}
|
||||
deriving (Eq, Generic)
|
||||
|
||||
instance Hashable Guard
|
||||
|
|
|
|||
68
src/Day8.hs
68
src/Day8.hs
|
|
@ -1,51 +1,45 @@
|
|||
module Day8 (partOne, partTwo) where
|
||||
|
||||
import Data.List (nub)
|
||||
import Data.List.Extra (pairs)
|
||||
import qualified Data.List.Extra as LE
|
||||
import qualified Data.Map.Lazy as Map
|
||||
import Data.Matrix (Matrix, Position)
|
||||
import Data.Matrix (Matrix)
|
||||
import qualified Data.Matrix as M
|
||||
|
||||
type Node = (Int, Int)
|
||||
import Data.Point (Point)
|
||||
import qualified Data.Point as P
|
||||
|
||||
partOne :: String -> Int
|
||||
partOne input = length $ filter (`M.isInBounds` grid) $ nub antiNodes
|
||||
where
|
||||
grid = M.buildMatrix (lines input)
|
||||
antiNodes = concatMap (uncurry getAntiNodes) $ nodePairs grid
|
||||
|
||||
getAntiNodes x y = case distance x y of
|
||||
(0, 0) -> []
|
||||
d -> [add x d, substract y d]
|
||||
|
||||
partTwo :: String -> Int
|
||||
partTwo input = length antiNodes
|
||||
partOne input = length $ filter (`M.isInBounds` matrix) $ nub antiNodes
|
||||
where
|
||||
matrix = M.buildMatrix (lines input)
|
||||
combinations = nodePairs matrix
|
||||
antiNodes = nub $ concatMap (uncurry getAntiNodes) combinations
|
||||
pairs = pairNodes matrix
|
||||
antiNodes = concatMap (uncurry getAntiNodes) pairs
|
||||
|
||||
getAntiNodes x y = case distance x y of
|
||||
(0, 0) -> []
|
||||
d -> computePointsAtDistance x d add ++ computePointsAtDistance y d substract
|
||||
getAntiNodes x y =
|
||||
case P.distance x y of
|
||||
(0, 0) -> []
|
||||
d -> [P.add x d, P.substract y d]
|
||||
|
||||
computePointsAtDistance point dist f =
|
||||
let point' = f point dist
|
||||
in if M.isInBounds point matrix
|
||||
then point : computePointsAtDistance point' dist f
|
||||
else []
|
||||
partTwo :: String -> Int
|
||||
partTwo input = length (nub antiNodes)
|
||||
where
|
||||
matrix = M.buildMatrix (lines input)
|
||||
pairs = pairNodes matrix
|
||||
antiNodes = concatMap (uncurry getAntiNodes) pairs
|
||||
|
||||
nodePairs :: Matrix Char -> [(Node, Node)]
|
||||
nodePairs matrix =
|
||||
getAntiNodes x y =
|
||||
let distance = P.distance x y
|
||||
in go x distance P.add ++ go y distance P.substract
|
||||
where
|
||||
go _ (0, 0) _ = []
|
||||
go point distance f =
|
||||
let point' = f point distance
|
||||
in if M.isInBounds point matrix
|
||||
then point : go point' distance f
|
||||
else []
|
||||
|
||||
pairNodes :: Matrix Char -> [(Point, Point)]
|
||||
pairNodes matrix =
|
||||
let noDotsMatrix = M.filter (/= '.') matrix
|
||||
pointGroups = Map.elems $ M.groupByWith (\(position, value) -> (value, position)) noDotsMatrix
|
||||
in concatMap pairs pointGroups
|
||||
|
||||
substract :: Position -> (Int, Int) -> (Int, Int)
|
||||
substract (x, y) (dx, dy) = (x - dx, y - dy)
|
||||
|
||||
add :: Position -> (Int, Int) -> (Int, Int)
|
||||
add (x, y) (dx, dy) = (x + dx, y + dy)
|
||||
|
||||
distance :: Position -> Position -> (Int, Int)
|
||||
distance (xrow, xcol) (yrow, ycol) = (xrow - yrow, xcol - ycol)
|
||||
in concatMap LE.pairs pointGroups
|
||||
|
|
|
|||
Loading…
Reference in a new issue