mirror of
https://codeberg.org/JasterV/aoc2024-haskell.git
synced 2026-04-26 18:10:05 +00:00
day 8
This commit is contained in:
parent
a65720daaf
commit
68f6a8e6f7
4 changed files with 82 additions and 22 deletions
|
|
@ -25,6 +25,7 @@ source-repository head
|
||||||
|
|
||||||
library
|
library
|
||||||
exposed-modules:
|
exposed-modules:
|
||||||
|
Data.List.Extra
|
||||||
Data.Matrix
|
Data.Matrix
|
||||||
Day1
|
Day1
|
||||||
Day2
|
Day2
|
||||||
|
|
@ -62,6 +63,7 @@ test-suite aoc2024-test
|
||||||
Day5Spec
|
Day5Spec
|
||||||
Day6Spec
|
Day6Spec
|
||||||
Day7Spec
|
Day7Spec
|
||||||
|
Day8Spec
|
||||||
Paths_aoc2024
|
Paths_aoc2024
|
||||||
autogen-modules:
|
autogen-modules:
|
||||||
Paths_aoc2024
|
Paths_aoc2024
|
||||||
|
|
|
||||||
14
src/Data/List/Extra.hs
Normal file
14
src/Data/List/Extra.hs
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
module Data.List.Extra (combinations, pairs) where
|
||||||
|
|
||||||
|
import Data.List (subsequences)
|
||||||
|
import Data.Maybe (mapMaybe)
|
||||||
|
|
||||||
|
combinations :: Int -> [a] -> [[a]]
|
||||||
|
combinations k xs = filter ((== k) . length) $ subsequences xs
|
||||||
|
|
||||||
|
pairs :: [a] -> [(a, a)]
|
||||||
|
pairs xs = mapMaybe parse $ combinations 2 xs
|
||||||
|
where
|
||||||
|
parse :: [a] -> Maybe (a, a)
|
||||||
|
parse [x, y] = Just (x, y)
|
||||||
|
parse _ = Nothing
|
||||||
61
src/Day8.hs
61
src/Day8.hs
|
|
@ -1,34 +1,51 @@
|
||||||
module Day8 (partOne, partTwo) where
|
module Day8 (partOne, partTwo) where
|
||||||
|
|
||||||
import Data.List (nub, subsequences)
|
import Data.List (nub)
|
||||||
|
import Data.List.Extra (pairs)
|
||||||
import qualified Data.Map.Lazy as Map
|
import qualified Data.Map.Lazy as Map
|
||||||
import Data.Matrix (Position)
|
import Data.Matrix (Matrix, Position)
|
||||||
import qualified Data.Matrix as M
|
import qualified Data.Matrix as M
|
||||||
import Data.Maybe (mapMaybe)
|
|
||||||
|
|
||||||
type AntiNode = (Int, Int)
|
type Node = (Int, Int)
|
||||||
|
|
||||||
partOne :: String -> Int
|
partOne :: String -> Int
|
||||||
partOne input = length $ filter (`M.isInBounds` matrix) $ nub $ concatMap (uncurry getAntiNodes) combinations
|
partOne input = length $ filter (`M.isInBounds` grid) $ nub antiNodes
|
||||||
where
|
where
|
||||||
matrix = M.buildMatrix (lines input)
|
grid = M.buildMatrix (lines input)
|
||||||
noDotsMatrix = M.filter (/= '.') matrix
|
antiNodes = concatMap (uncurry getAntiNodes) $ nodePairs grid
|
||||||
pointGroups = Map.elems $ M.groupByWith (\(position, value) -> (value, position)) noDotsMatrix
|
|
||||||
combinations = concatMap pairs pointGroups
|
getAntiNodes x y = case distance x y of
|
||||||
|
(0, 0) -> []
|
||||||
|
d -> [add x d, substract y d]
|
||||||
|
|
||||||
partTwo :: String -> Int
|
partTwo :: String -> Int
|
||||||
partTwo input = undefined
|
partTwo input = length antiNodes
|
||||||
|
|
||||||
pairs :: [a] -> [(a, a)]
|
|
||||||
pairs xs = mapMaybe parse $ subsequences xs
|
|
||||||
where
|
where
|
||||||
parse :: [a] -> Maybe (a, a)
|
matrix = M.buildMatrix (lines input)
|
||||||
parse [x, y] = Just (x, y)
|
combinations = nodePairs matrix
|
||||||
parse _ = Nothing
|
antiNodes = nub $ concatMap (uncurry getAntiNodes) combinations
|
||||||
|
|
||||||
getAntiNodes :: Position -> Position -> [AntiNode]
|
getAntiNodes x y = case distance x y of
|
||||||
getAntiNodes (xrow, xcol) (yrow, ycol) = case distance of
|
(0, 0) -> []
|
||||||
(0, 0) -> []
|
d -> computePointsAtDistance x d add ++ computePointsAtDistance y d substract
|
||||||
(drow, dcol) -> [(xrow + drow, xcol + dcol), (yrow - drow, ycol - dcol)]
|
|
||||||
where
|
computePointsAtDistance point dist f =
|
||||||
distance = (xrow - yrow, xcol - ycol)
|
let point' = f point dist
|
||||||
|
in if M.isInBounds point matrix
|
||||||
|
then point : computePointsAtDistance point' dist f
|
||||||
|
else []
|
||||||
|
|
||||||
|
nodePairs :: Matrix Char -> [(Node, Node)]
|
||||||
|
nodePairs 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)
|
||||||
|
|
|
||||||
27
test/Day8Spec.hs
Normal file
27
test/Day8Spec.hs
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
module Day8Spec (spec) where
|
||||||
|
|
||||||
|
import Day8 (partOne, partTwo)
|
||||||
|
import Test.Hspec
|
||||||
|
|
||||||
|
spec :: Spec
|
||||||
|
spec = do
|
||||||
|
describe "PartOne" $ do
|
||||||
|
it "works" $ do
|
||||||
|
partOne input `shouldBe` 14
|
||||||
|
describe "PartTwo" $ do
|
||||||
|
it "works" $ do
|
||||||
|
partTwo input `shouldBe` 34
|
||||||
|
where
|
||||||
|
input =
|
||||||
|
"............\n\
|
||||||
|
\........0...\n\
|
||||||
|
\.....0......\n\
|
||||||
|
\.......0....\n\
|
||||||
|
\....0.......\n\
|
||||||
|
\......A.....\n\
|
||||||
|
\............\n\
|
||||||
|
\............\n\
|
||||||
|
\........A...\n\
|
||||||
|
\.........A..\n\
|
||||||
|
\............\n\
|
||||||
|
\............"
|
||||||
Loading…
Reference in a new issue