WIP: Solve 2024-06

This commit is contained in:
Alexander Kobjolke 2024-12-07 21:34:29 +01:00
parent efeaf96999
commit b703638344
8 changed files with 361 additions and 59 deletions

View file

@ -1,6 +1,6 @@
cabal-version: 2.0
-- This file has been generated from package.yaml by hpack version 0.35.2.
-- This file has been generated from package.yaml by hpack version 0.36.1.
--
-- see: https://github.com/sol/hpack

10
data/Y2024/D06/example Normal file
View file

@ -0,0 +1,10 @@
....#.....
.........#
..........
..#.......
.......#..
..........
.#..^.....
........#.
#.........
......#...

View file

@ -0,0 +1,130 @@
.......................#....#....................#....#..##.##.........................................#...........#...........#..
.............#........................................#....................#............#.......................#............#....
.........#.............#..#....#..........................#.......#.#.......#...............................................##....
..........#....#....................................................#....................#...........#....#.......................
.............#...#....................#...........#.........#...........................#............#............................
..........................................................................................#.....#.......#...................##....
...............................................#.#......#..............#...#...................##...........#....#..#...#.........
..#.................#......#........#......................#.......#...............................#..............................
.........................#...............#.....................................#....#..#..#............................#..........
......................#.................................................................#..........#..............#...#......#....
............................#.....##..........#.....................#..........#..#.......#.......................................
......#...###...........#.................................................................#.......................................
......................#.#..#................#..........#................#...........#............#..............#...#.........#...
....#.........................#..#...............................................#....#.............#.............................
..#............#...#............#..........#...............#.....#....##.........................#........#.......................
..................#............#..............#..........................................................#..#..#........#.........
.......#...#............#..........................................................#..............................#.............#.
..#................#....................#.#...#.................................#.........#....................#.........#........
...................................#..#..........................#........#.....#.........................................#.......
...........##.................##............#................#...#..................................##...#........................
..............#..................#....................................................................#...........................
.#...#....#..........##..................................#.............................................................#......#...
......#.....#................................#...............................................................#......#.............
..........#.............................................#............................##....#.........................#............
..........#......#.................#...#........#...........#.#..........#........#....................................#..........
.#..................#.#............................#.......................#.........#.......#....................................
.....................#....#..................#..................................................##..#................#............
......#......................#..#..............##.......#..................................................#..............#.......
..........................................................................#........#...#..............#.................#.........
....................##....#.......................#........#...................#.............##.......#...........................
.........#............#..................................................................................#........................
........................................................................#................#........................#.............#.
............#.......#.................................#............#..............................................................
.#.............#...............................................#....#.........#....#..................................#.#.........
.......................................#.....................................................................................#....
........#........................................#...............#........................................................#.......
...............................#.........#........#...........#.......................................................#.........#.
.....................##...#....................................................#............#..................#..#..........##...
................#..........#...#............................................................#...##................................
...................#........#...............................#.................#.........#.........................................
.................................................................................................................#................
............................#......................................................#.....................................#......#.
......#................#............................#.............................................................................
..#...........#.....#.........#....#................#............................................#................................
..................................#.......#.......#...........#.........#................#.....................................#.#
...............................................#............................................#.#.....................#.......##....
..............................#...............#..............................#...#...#.............................#...........#..
.......#...........#..........................................................#........#..#.........#.....#.....#...#.............
......................................................#.#............#.........#.#...........#........##.....#....................
...........................................................................#..........#.........................#.........#.......
....#.........................#.....................................................................................#...#......#..
...#.......#............................................................#...............................#....................##.#.
.................................#.....#................................................................#.........................
.....................................#........................#....................................#..............................
..............#.......................................................................#.......#....................#..........#...
................................#..........................................#.................................#.....#..............
...........#.......................................................#...............#.....................#..............#......#..
..................................#..........................#.................................................................#..
.............##......#....................................................#......#...............................................#
#.......#...................#..........#...................#.................#..................................................#.
.......#..........#.....##...........#.......................#............#..............................#.............#..........
.............#...................##......................................................................................#........
#.............................#...................................................................#...............................
.#...................................#....##..................................................................................#...
.................................#.#..................#..#..#..........................#.......#..................................
..................#....#....#....................................................#....................................#........#..
..........................................#...#.....#...........#.........#............#............#..........................#..
...............................................................................#..............................................#...
.............................#......#....................#....#....................................................#.#.#..........
................##......#........#........#...........#..........................#......................#..............#..........
.....................#.....#..#.............................................................................................#.....
.......#..#...........#................................................................#..........................................
#.......................................................................................................#...#.....................
.#..........................................................#.....................................................#...............
#.....#...#...............#..#......#........#..#...................#...................#.................#.......................
..#.................................................................................#.#......................#....................
.......................#.............#..........#.......................#...................................#.....................
.................#......#......#...#.#.#.............................#.......................................................#....
..#...........................................................................................................#...................
.................................#..................#.....#........#.........................................................#....
.............#......................#...............................................#...#.............................#...#....#..
.#............................#..........................#.#...........................#..........................#.#.............
.............................#.........#.................##............................#...................#......................
.........#......#....#.........#..............................................................................................#..#
.....................#......#.................#..#..........................#..................#..............................#.#.
........................................................#......................#............#.......#......#......................
........................................#....##.#........#......#..............................#..........#..........#.##.........
.............#.......#.......#......................#..........................................#.........#............#...#...#.#.
..................#........................................................#...............................#.....#.....#..........
.........#.................#........#..............^..............#.................##......#...................................#.
....#...................#.#.................................#...#.................................................#...............
.................#.............................................#................#.....#......#.......#...................#........
...............#...............................................................................#..#...............#...............
........................................##..........................................................................##............
............................................#...................#........#...#...#....#.........#...................#.............
.....#...#...................#....................................#......#...........#...............#............................
........................#..................#.....................#.................................................#......##......
...#.................#....................#..................................#.#.........................#.......#................
....................#............#..................................#...#......#....................#...............#.............
.....#...............#.......###........#............#......................#.......#....#........................................
....................#........#...........#..................................#..#................#.............#...................
.....#..................#...................#.#..................................#.......#..#.....................................
..#..#.......#........................................#.................................................................#.........
.......#............#...#....#.......................#.#...................................#.........................#..#.#.......
..............#......................................................................................................#............
............#....................#........................#.........#...#.........................................................
...................................#..............................#.........................................................#.....
......##...........#.#........................#.........................................................................#.........
..........................#.....................................................#..............................#..............#...
.........................#...#.....................#..#................#................................................#....#....
...#.................................#...#.......#...............................................................#................
..................................#....................................#...........................##..#.#.....................#..
.#.............#.....#...............................................................#...............#...............#..#.........
.........#.............................#........................#.............#......................#........#............#......
...................................#..#...#.....................................#.................................................
........................................##..........#..............................................#.....................#........
......#...........................................#....#.....................#...................#..#.........#...................
.#....#.....#........##..................................#......#................................................#....#..##.......
..........#....................................................................##.........................#...........#...........
...........#.#......#.......#..................#............#...............................................#...#..............#..
.................................................................#.......#.........#.....#........#....##....#..........#.........
.............................#......................................................#.....#...#...#....#...........#..........#.#.
.....................#........#.........................#......................................#................#...............#.
.........................................................................#...................................................#....
..............#...#..#................#....................................#.......#....#.#...............#.........#.............
.......#......#.#............................................#.......#............................................................
##......................................................#..#.................................##...................#..#...........#
...........#.#...#........#............#..............................#........................#.........................#..#.....
................................................##.........................................#.................#....................
............................#....................................................#...#........................#.#......#........#.

72
flake.lock generated
View file

@ -3,11 +3,11 @@
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1673956053,
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
@ -21,29 +21,11 @@
"systems": "systems"
},
"locked": {
"lastModified": 1694529238,
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_2": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1685518550,
"narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
@ -60,11 +42,11 @@
]
},
"locked": {
"lastModified": 1660459072,
"narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=",
"lastModified": 1709087332,
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "a20de23b925fd8264fd7fad6454652e142fd7f73",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
"type": "github"
},
"original": {
@ -75,11 +57,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1701290038,
"narHash": "sha256-mcbPGHxG9c7Og+SkKYTAtOJwDERGx5kvTVH0BH1PNXE=",
"lastModified": 1733601786,
"narHash": "sha256-FOrDlgoS2m3RMXLTX6+nEVwyWo92/aIti9Er4yWFwAw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "231ffe19425544deb8da37b1362b545ef90bcb40",
"rev": "df05b65b13fe802eac0f449108974c05456229ce",
"type": "github"
},
"original": {
@ -90,16 +72,16 @@
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1685801374,
"narHash": "sha256-otaSUoFEMM+LjBI1XL/xGB5ao6IwnZOXc47qhIgJe8U=",
"lastModified": 1730741070,
"narHash": "sha256-edm8WG19kWozJ/GqyYx2VjW99EdhjKwbY3ZwdlPAAlo=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c37ca420157f4abc31e26f436c1145f8951ff373",
"rev": "d063c1dd113c91ab27959ba540c0d9753409edf3",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-23.05",
"ref": "nixos-24.05",
"repo": "nixpkgs",
"type": "github"
}
@ -107,7 +89,6 @@
"pre-commit-hooks": {
"inputs": {
"flake-compat": "flake-compat",
"flake-utils": "flake-utils_2",
"gitignore": "gitignore",
"nixpkgs": [
"nixpkgs"
@ -115,11 +96,11 @@
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1700922917,
"narHash": "sha256-ej2fch/T584b5K9sk1UhmZF7W6wEfDHuoUYpFN8dtvM=",
"lastModified": 1733318908,
"narHash": "sha256-SVQVsbafSM1dJ4fpgyBqLZ+Lft+jcQuMtEL3lQWx2Sk=",
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"rev": "e5ee5c5f3844550c01d2131096c7271cec5e9b78",
"rev": "6f4e2a2112050951a314d2733a994fbab94864c6",
"type": "github"
},
"original": {
@ -149,21 +130,6 @@
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",

View file

@ -17,7 +17,7 @@
overlay = final: prev: { aoc = final.callCabal2nix "aoc" ./. { }; };
haskellPackages = pkgs.haskell.packages.ghc942.extend overlay;
haskellPackages = pkgs.haskell.packages.ghc94.extend overlay;
in {
packages.default = haskellPackages.aoc;
@ -35,13 +35,13 @@
checks = {
pre-commit-check = pre-commit-hooks.lib.${system}.run {
src = ./.;
settings = { ormolu.defaultExtensions = [ "GHC2021" ]; };
tools.fourmolu = haskellPackages.fourmolu;
hooks = {
nixfmt.enable = true;
nixfmt-rfc-style.enable = true;
fourmolu.enable = true;
hpack.enable = true;
hlint.enable = true;
ormolu.defaultExtensions = [ "GHC2021" ];
doctest = {
enable = false;
name = "Run documentation tests";

View file

@ -1,5 +1,8 @@
-- | Internal module in order to facilitate testability.
module AoC.Util (solveRiddle, readFileUtf8) where
module AoC.Util (solveRiddle, readFileUtf8, module A, mkMatrix, Matrix) where
import Data.Array (Array)
import Data.Array qualified as A
readFileUtf8 :: (MonadIO m) => FilePath -> m Text
readFileUtf8 = fmap (decodeUtf8With lenientDecode) . readFileBS
@ -9,3 +12,19 @@ solveRiddle file solver = do
results <- solver <$> readFileUtf8 file
forM_ (results `zip` [1 :: Int ..]) $ \(solution, part) ->
putTextLn $ " solution to part-" <> show part <> ": " <> solution
type Matrix a = Array (Int, Int) a
mkMatrix :: [[a]] -> Matrix a
mkMatrix vss =
A.array
((1, 1), (w, h))
[ ((x, y), v)
| (y, vs) <- zip [1 ..] vss
, (x, v) <- zip [1 ..] vs
]
where
w = case vss of
[] -> 0
(vs : _) -> length vs
h = length vss

View file

@ -1,6 +1,179 @@
{- HLINT ignore "Use bimapF" -}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedRecordDot #-}
{-# LANGUAGE RecordWildCards #-}
module AoC.Y2024.D06 (solve) where
import AoC.Riddle
import AoC.Util
import Data.Array ((!), (//))
import Data.Array qualified as A
import Data.String (lines)
import Prelude hiding (lines)
data Direction
= U
| R
| D
| L
deriving stock (Show, Eq, Enum)
data Tile
= Free
| Obstruction
| Visited
| Guard Direction
deriving stock (Show, Eq)
type Position = (Int, Int)
directionToVector :: Direction -> Position
directionToVector = \case
U -> (0, -1)
R -> (1, 0)
D -> (0, 1)
L -> (-1, 0)
parseTile :: Char -> Maybe Tile
parseTile = \case
'.' -> pure Free
'#' -> pure Obstruction
'^' -> pure $ Guard U
'>' -> pure $ Guard R
'v' -> pure $ Guard D
'<' -> pure $ Guard L
_ -> Nothing
data MapState where
MapState ::
{ labMap :: Matrix Tile
, guardPosition :: Maybe (Position, Direction)
, candidatesForLoop :: [Position]
} ->
MapState
deriving stock (Show)
parseMap :: Riddle -> Maybe (Matrix Tile)
parseMap riddle = do
let
vss :: [[Char]]
vss = lines . toString $ riddle
vss' :: [Maybe [Tile]]
vss' = mapM parseTile <$> vss
mkMatrix <$> sequence vss'
newMapState :: Matrix Tile -> MapState
newMapState labMap =
MapState labMap (locateGuard labMap) []
locateGuard :: Matrix Tile -> Maybe (Position, Direction)
locateGuard = getFirst . foldMap checkGuard . A.assocs
where
checkGuard :: (Position, Tile) -> First (Position, Direction)
checkGuard (pos, Guard d) = pure (pos, d)
checkGuard _ = mempty
parse :: Riddle -> Maybe MapState
parse riddle = newMapState <$> parseMap riddle
movePosition :: Position -> Direction -> Position
movePosition (x, y) d =
let (dx, dy) = directionToVector d
in (x + dx, y + dy)
getTile :: Matrix Tile -> Position -> Maybe Tile
getTile m pos =
guard (A.inRange (A.bounds m) pos) >> Just (m ! pos)
turnRight :: Direction -> Direction
turnRight = \case
U -> R
R -> D
D -> L
L -> U
moveGuard :: MapState -> MapState
moveGuard s@MapState{..} = case guardPosition of
Nothing -> s
Just (pos, d) ->
let
newPos = movePosition pos d
in
case getTile labMap newPos of
Just Obstruction -> do
let
newDirection = turnRight d
s
{ labMap = labMap // [(pos, Guard newDirection)]
, guardPosition = Just (pos, newDirection)
}
Just Visited ->
let
s' =
s
{ labMap = labMap // [(pos, Visited), (newPos, Guard d)]
, guardPosition = Just (newPos, d)
}
newPos' = movePosition newPos d
in
case getTile labMap newPos' of
Nothing -> s'
Just Obstruction -> s'
Just _ -> s'{candidatesForLoop = newPos' : s'.candidatesForLoop}
Just _ ->
s
{ labMap = labMap // [(pos, Visited), (newPos, Guard d)]
, guardPosition = Just (newPos, d)
}
Nothing ->
s
{ labMap = labMap // [(pos, Visited)]
, guardPosition = Nothing
}
updateGuard :: Maybe (Position, Direction) -> MapState -> MapState
updateGuard Nothing s =
case s.guardPosition of
Nothing -> s
Just (pos, _) ->
s
{ labMap = s.labMap // [(pos, Visited)]
, guardPosition = Nothing
}
updateGuard g@(Just (pos, dir)) s =
case s.guardPosition of
Nothing ->
s
{ labMap = s.labMap // [(pos, Guard dir)]
, guardPosition = g
}
Just (pos', _) ->
s
{ labMap = s.labMap // [(pos', Visited), (pos, Guard dir)]
, guardPosition = g
}
guardLeftTheMap :: MapState -> Bool
guardLeftTheMap MapState{..} = isNothing guardPosition
moveGuardUntilSheLeaves :: MapState -> Maybe MapState
moveGuardUntilSheLeaves =
viaNonEmpty head . dropWhile (not . guardLeftTheMap) . iterate moveGuard
part1 :: Riddle -> Maybe Int
part1 riddle = do
MapState{..} <- parse riddle >>= moveGuardUntilSheLeaves
pure $ length $ filter (\(_, t) -> t == Visited) (A.assocs labMap)
part2 :: Riddle -> Maybe Int
part2 riddle = do
MapState{..} <- parse riddle >>= moveGuardUntilSheLeaves
pure $ length candidatesForLoop
solve :: (MonadIO m) => Text -> m (Either Text Solution)
solve _ = pure $ Left "not yet implemented"
solve riddle = pure $ Right [fromIntegral $ fromMaybe 0 (part1 riddle), fromIntegral $ fromMaybe 0 (part2 riddle)]

View file

@ -24,3 +24,7 @@ spec = do
describe "Day 5" do
it "calculates correctly" do
runAoC Y2024 D05 `shouldReturn` Right [5452, 4598]
describe "Day 6" do
it "calculates correctly" do
runAoC Y2024 D05 `shouldReturn` Right [5453, 0]