Skip to content

Commit 78975a2

Browse files
committed
feat(2024/Day14)
1 parent 2c37997 commit 78975a2

File tree

5 files changed

+605
-0
lines changed

5 files changed

+605
-0
lines changed

2024/Day14/Day14.hs

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
module Main where
2+
3+
import Data.List
4+
import Data.Set (Set)
5+
import Data.Set qualified as S
6+
import Data.Tuple.Extra
7+
import System.Environment
8+
import Text.Regex.TDFA ((=~))
9+
10+
type Input = Set ((Int, Int), (Int, Int))
11+
12+
type Output = Int
13+
14+
parseInput :: String -> Input
15+
parseInput = S.fromList . map parseLine . lines
16+
where
17+
parseLine = (\[p, v] -> (read p, read v)) . map parseTuple . words
18+
parseTuple s = (\[[_, t]] -> "(" ++ t ++ ")") $ ((s =~ "=(-?[0-9]+,-?[0-9]+)") :: [[String]])
19+
20+
moveAround :: (Int, Int) -> Input -> Input
21+
moveAround (w, h) = S.map moveRobot
22+
where
23+
moveRobot ((px, py), (vx, vy)) = (((px + vx) `mod` w, (py + vy) `mod` h), (vx, vy))
24+
25+
getQuadrant :: (Int, Int) -> (Int, Int) -> (Bool, Bool)
26+
getQuadrant (w, h) (x, y) = (x <= div w 2, y <= div h 2)
27+
28+
part1 :: (Int, Int) -> Input -> Output
29+
part1 wh = product . map length . groupByQuadrants . notAtCenterLines . robotsPositions
30+
where
31+
robotsPositions = map fst . S.toList . (!! 100) . iterate (moveAround wh)
32+
midX = (fst wh) `div` 2
33+
midY = (snd wh) `div` 2
34+
notAtCenterLines = filter (\(x, y) -> x /= midX && y /= midY)
35+
groupByQuadrants = groupBy (\e1 e2 -> snd e1 == snd e2) . sortOn snd . map (second (getQuadrant wh) . dupe)
36+
37+
display :: (Int, Int) -> Set (Int, Int) -> [String]
38+
display (w, h) inp = [[if (x, y) `S.member` inp then 'x' else '.' | x <- [0 .. w]] | y <- [0 .. h]]
39+
40+
part2 :: (Int, Int) -> Input -> Output
41+
part2 wh = fst . head . filter (hasLongLine . snd) . zip [0 ..] . iterate (moveAround wh)
42+
where
43+
hasLongLine = (=~ "x{10}") . concat . display wh . S.map fst
44+
45+
showAftern :: (Int, Int) -> Input -> Int -> String
46+
showAftern wh inp n = unlines . display wh . S.map fst . (!! n) $ iterate (moveAround wh) inp
47+
48+
main :: IO ()
49+
main = do
50+
args <- getArgs
51+
content <- readFile (last args)
52+
let input = parseInput content
53+
let wh = (101, 103)
54+
55+
print $ part1 wh input
56+
print $ part2 wh input
57+
58+
-- putStrLn . showAftern wh input $ part2 wh input

2024/Day14/Makefile

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