|
1 | 1 | module Day09.Main (day09) where |
2 | 2 |
|
3 | | -import AOC (submit) |
| 3 | +import AOC (submit) |
| 4 | +import AOC.Utils (isInRange) |
4 | 5 |
|
5 | | -type Input = String |
| 6 | +type Point = (Int, Int) |
| 7 | +type Segment = (Point, Point) |
| 8 | +type Polygon = [Segment] |
| 9 | + |
| 10 | +type Input = [Point] |
6 | 11 | type Output = Int |
7 | 12 |
|
8 | 13 | parseInput :: String -> Input |
9 | | -parseInput = undefined |
| 14 | +parseInput = map (\x -> read $ "(" ++ x ++ ")") . lines |
| 15 | + |
| 16 | +area :: (Int, Int) -> (Int, Int) -> Int |
| 17 | +area (a, b) (c, d) = (abs (a - c) + 1) * (abs (b - d) + 1) |
10 | 18 |
|
11 | 19 | partOne :: Input -> Output |
12 | | -partOne = undefined |
| 20 | +partOne tiles = maximum [area x y | x <- tiles, y <- tiles, x < y] |
| 21 | + |
| 22 | +getLoop :: Input -> Polygon |
| 23 | +getLoop tiles = zip tiles $ tail (cycle tiles) |
| 24 | + |
| 25 | +getRectangleEdges :: (Point, Point) -> Polygon |
| 26 | +getRectangleEdges ((x1, y1), (x2, y2)) = [(a, b) |
| 27 | + | a@(x , y ) <- corners |
| 28 | + , b@(x', y') <- corners |
| 29 | + , a < b, x == x' || y == y' |
| 30 | + ] |
| 31 | + where corners = [(minX, minY), (maxX, minY), (minX, maxY), (maxX, maxY)] |
| 32 | + (minX, maxX) = (min x1 x2 + 1, max x1 x2 - 1) |
| 33 | + (minY, maxY) = (min y1 y2 + 1, max y1 y2 - 1) |
| 34 | + |
| 35 | +edgeIntersects :: Segment -> Segment -> Bool |
| 36 | +edgeIntersects ((x1, y1), (x2, y2)) ((x3, y3), (x4, y4)) |
| 37 | + | den == 0 = False |
| 38 | + | otherwise = isInRange px (min x1 x2, max x1 x2) && isInRange py (min y1 y2, max y1 y2) |
| 39 | + && isInRange px (min x3 x4, max x3 x4) && isInRange py (min y3 y4, max y3 y4) |
| 40 | + where den = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4) |
| 41 | + numPx = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4) |
| 42 | + numPy = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4) |
| 43 | + px = numPx `div` den |
| 44 | + py = numPy `div` den |
| 45 | + |
| 46 | +intersectsPolygon :: Polygon -> Segment -> Bool |
| 47 | +intersectsPolygon poly segment = any (edgeIntersects segment) poly |
13 | 48 |
|
14 | 49 | partTwo :: Input -> Output |
15 | | -partTwo = undefined |
| 50 | +partTwo tiles = maximum |
| 51 | + . map (uncurry area) |
| 52 | + . filter (not . any (intersectsPolygon loop) . getRectangleEdges) |
| 53 | + $ rects |
| 54 | + where rects = [(x, y) | x <- tiles, y <- tiles, x < y] |
| 55 | + loop = getLoop tiles |
16 | 56 |
|
17 | 57 | day09 :: String -> String -> IO () |
18 | 58 | day09 "parse" = print . parseInput |
|
0 commit comments