Skip to content

Commit e7c325f

Browse files
committed
feat(2024/Day19)
1 parent a3b2b5b commit e7c325f

File tree

5 files changed

+513
-0
lines changed

5 files changed

+513
-0
lines changed

2024/Day19/Day19.hs

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
module Main where
2+
3+
import Data.Bits
4+
import Data.List
5+
import Data.List.Split
6+
import Data.List.Unique
7+
import Data.Map (Map)
8+
import Data.Map qualified as M
9+
import Data.Matrix (Matrix, (!))
10+
import Data.Matrix qualified as Mat
11+
import Data.Set (Set)
12+
import Data.Set qualified as S
13+
import Data.Tuple.Extra
14+
import Debug.Trace
15+
import System.Environment
16+
import Text.Regex.TDFA ((=~))
17+
18+
-- TODO: Cleanup imports after day done
19+
20+
type Input = ([String], [String])
21+
22+
type Output = Int
23+
24+
parseInput :: String -> Input
25+
parseInput input = (towels, patterns)
26+
where
27+
[firstLine, rest] = splitOn "\n\n" input
28+
towels = splitOn ", " firstLine
29+
patterns = lines rest
30+
31+
part1 :: Input -> Output
32+
part1 (towels, patterns) = length $ filter (doAble S.empty . S.singleton) patterns
33+
where
34+
doAble :: Set String -> Set String -> Bool
35+
doAble seen patterns
36+
| S.null patterns = False
37+
| [] `S.member` patterns = True
38+
| otherwise = doAble newSeen newPatterns
39+
where
40+
newSeen = S.union seen patterns
41+
newPatterns = (S.\\ newSeen) . S.fromList . concat . map (\patt -> map (\pre -> (drop (length pre) patt)) $ prefixesOf patt) $ S.toList patterns
42+
prefixesOf patt = filter (`isPrefixOf` patt) towels
43+
44+
part2 :: Input -> Output
45+
part2 (towels, patterns) = sum $ map (snd . nbSolutions M.empty) patterns
46+
where
47+
nbSolutions :: Map String Int -> String -> (Map String Int, Int)
48+
nbSolutions seen pattern
49+
| pattern == [] = (seen, 1)
50+
| pattern `M.member` seen = (seen, seen M.! pattern)
51+
| otherwise = (M.insert pattern newRes newSeen, newRes)
52+
where
53+
newPatterns = map (\pre -> (drop (length pre) pattern)) $ filter (`isPrefixOf` pattern) towels
54+
(newSeen, newRes) = foldl (\(s, r) p -> second (+ r) $ nbSolutions s p) (seen, 0) newPatterns
55+
56+
main :: IO ()
57+
main = do
58+
args <- getArgs
59+
content <- readFile (last args)
60+
let input = parseInput content
61+
62+
-- print input
63+
64+
print $ part1 input
65+
print $ part2 input

2024/Day19/Makefile

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
CONTAINER_NAME=haskell-aoc
2+
SRC=./Day19.hs
3+
TARGET=Day19
4+
all: $(TARGET)
5+
6+
$(TARGET): $(SRC)
7+
ghc -O3 $(SRC)
8+
9+
profile: $(SRC)
10+
11+
12+
clean:
13+
$(RM) ./Day19 ./Day19.o ./Day19.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)