Skip to content

Commit 7c744da

Browse files
committed
feat(2024/Day23)
1 parent abdab42 commit 7c744da

File tree

5 files changed

+3540
-0
lines changed

5 files changed

+3540
-0
lines changed

2024/Day23/Day23.hs

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
module Main where
2+
3+
import Data.Bits
4+
import Data.Function
5+
import Data.List
6+
import Data.List.Split
7+
import Data.List.Unique
8+
import Data.Map (Map)
9+
import Data.Map qualified as M
10+
import Data.Matrix (Matrix, (!))
11+
import Data.Matrix qualified as Mat
12+
import Data.Set (Set)
13+
import Data.Set qualified as S
14+
import Data.Tuple.Extra
15+
import Debug.Trace
16+
import System.Environment
17+
import Text.Regex.TDFA ((=~))
18+
19+
-- TODO: Cleanup imports after day done
20+
21+
type Input = Map String (Set String)
22+
23+
type Output = Int
24+
25+
parseInput :: String -> Input
26+
parseInput input = foldl (\m (c1, c2) -> M.insertWith (S.union) c1 (S.singleton c2) $ M.insertWith S.union c2 (S.singleton c1) m) M.empty connections
27+
where
28+
connections = map (second (drop 1) . splitAt 2) $ lines input
29+
30+
part1 :: Input -> Output
31+
part1 input = S.size . S.filter (not . S.null . S.filter (isPrefixOf "t")) $ S.fromList triples
32+
where
33+
triples = concat $ map (uncurry tmp) $ M.assocs input
34+
tmp k v = S.toList . S.unions . S.toList $ S.map (\c -> S.map (S.union (S.fromList [k, c])) . S.map S.singleton $ S.intersection v (input M.! c)) v
35+
36+
join :: [a] -> [[a]] -> [a]
37+
join i [] = []
38+
join i (e : l) = foldl (\r e -> r ++ i ++ e) e l
39+
40+
part2 :: Input -> String
41+
part2 input = join "," . sort $ S.toList biggest
42+
where
43+
isLan s = {-# SCC isLan #-} all (\e -> S.isSubsetOf (S.delete e s) $ input M.! e) s
44+
lansOf k = {-# SCC lansOf #-} S.powerSet . S.insert k $ (input M.! k)
45+
lans = {-# SCC lans #-} S.filter isLan . S.unions . map lansOf $ M.keys input
46+
47+
biggest = {-# SCC biggest #-} maximumBy (compare `on` S.size) lans
48+
49+
main :: IO ()
50+
main = do
51+
args <- getArgs
52+
content <- readFile (last args)
53+
let input = parseInput content
54+
55+
-- print input
56+
57+
print $ part1 input -- (== 1154) $
58+
print $ part2 input -- (== "aj,ds,gg,id,im,jx,kq,nj,ql,qr,ua,yh,zn") $

2024/Day23/Makefile

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
CONTAINER_NAME=haskell-aoc
2+
SRC=./Day23.hs
3+
TARGET=Day23
4+
all: $(TARGET)
5+
6+
$(TARGET): $(SRC)
7+
ghc -O3 $(SRC)
8+
9+
profile: $(SRC)
10+
11+
12+
clean:
13+
$(RM) ./Day23 ./Day23.o ./Day23.hi
14+
15+
setup: $(SRC)
16+
docker cp $(SRC) $(CONTAINER_NAME):/home/haskell/Main.hs
17+
docker cp input.txt $(CONTAINER_NAME):/home/haskell/input.txt
18+
docker cp shortinput.txt $(CONTAINER_NAME):/home/haskell/shortinput.txt
19+
20+
profiling: setup
21+
docker exec -it $(CONTAINER_NAME) cabal build --enable-profiling
22+
docker exec -it $(CONTAINER_NAME) ./profile input.txt
23+
24+
run: setup
25+
docker exec -it $(CONTAINER_NAME) cabal build
26+
docker exec -it $(CONTAINER_NAME) ./run input.txt
27+
28+
.PHONY: all $(TARGET) clean setup profiling run

0 commit comments

Comments
 (0)