import Data.Text ()
import qualified Data.Text.IO as TIO
-import Data.Attoparsec.Text
+import Data.Attoparsec.Text hiding (take)
import Control.Applicative
import qualified Data.Map.Strict as M
print $ part1 trace
print $ part2 trace
-part1 trace = M.size $ M.filter (> 1) diagramHV
- where hLines = map expandLineH $ filter isHoriz trace
- vLines = map expandLineV $ filter isVert trace
- diagramH = addLines M.empty hLines
- diagramHV = addLines diagramH vLines
-
-part2 trace = M.size $ M.filter (> 1) diagram4
- where hLines = map expandLineH $ filter isHoriz trace
- vLines = map expandLineV $ filter isVert trace
- pdLines = map expandLinePD $ filter isPDiag trace
- ndLines = map expandLineND $ filter isNDiag trace
- diagram1 = addLines M.empty hLines
- diagram2 = addLines diagram1 vLines
- diagram3 = addLines diagram2 pdLines
- diagram4 = addLines diagram3 ndLines
+part1 trace = M.size $ M.filter (> 1) diagram
+ where hvLines = map expandLine $ filter isHorizOrVert trace
+ diagram = addLines M.empty hvLines
+part2 trace = M.size $ M.filter (> 1) diagram
+ where allLines = map expandLine trace
+ diagram = addLines M.empty allLines
isHoriz :: Line -> Bool
isVert :: Line -> Bool
isVert (Line (V2 _x0 y0) (V2 _x1 y1)) = y0 == y1
--- x and y increasing together
-isPDiag :: Line -> Bool
-isPDiag (Line (V2 x0 y0) (V2 x1 y1)) =
- (x0 /= x1)
- && (y0 /= y1)
- && ((x1 - x0) == (y1 - y0))
-
--- x increasing, y decreasing
-isNDiag :: Line -> Bool
-isNDiag (Line (V2 x0 y0) (V2 x1 y1)) =
- (x0 /= x1)
- && (y0 /= y1)
- && ((x1 - x0) == (y0 - y1))
-
-
--- horizOrVert :: Line -> Bool
--- horizOrVert line = isHoriz line || isVert line
-
-
--- hovLines = filter horizOrVert
-
-expandLineH :: Line -> [Point]
-expandLineH (Line (V2 x0 y0) (V2 _x1 y1)) = -- x0 == x1
- [V2 x0 y | y <- [yMin..yMax]]
- where yMin = min y0 y1
- yMax = max y0 y1
-
-expandLineV :: Line -> [Point]
-expandLineV (Line (V2 x0 y0) (V2 x1 _y1)) = -- y0 == y1
- [V2 x y0 | x <- [xMin..xMax]]
- where xMin = min x0 x1
- xMax = max x0 x1
-
--- x and y increasing together
-expandLinePD :: Line -> [Point]
-expandLinePD (Line (V2 x0 y0) (V2 x1 y1)) = map (uncurry V2) coords
- where xMin = min x0 x1
- xMax = max x0 x1
- yMin = min y0 y1
- yMax = max y0 y1
- coords = zip [xMin..xMax] [yMin..yMax]
-
--- x increasing, y decreasing
-expandLineND :: Line -> [Point]
-expandLineND (Line (V2 x0 y0) (V2 x1 y1)) = map (uncurry V2) coords
- where xMin = min x0 x1
- xMax = max x0 x1
- yMin = min y0 y1
- yMax = max y0 y1
- yMax1 = yMax - 1
- coords = zip [xMin..xMax] [yMax, yMax1..yMin]
+isHorizOrVert :: Line -> Bool
+isHorizOrVert line = (isHoriz line) || (isVert line)
+
+expandLine :: Line -> [Point]
+expandLine line@(Line p0 _p1) = take numPoints $ iterate (^+^ delta) p0
+ where numPoints = findLen line + 1
+ delta = findDelta line
+
+findLen :: Line -> Int
+findLen (Line (V2 x0 y0) (V2 x1 y1)) =
+ max (abs (x1 - x0)) (abs (y1 - y0))
+findDelta :: Line -> Point
+findDelta (Line (V2 x0 y0) (V2 x1 y1)) = (V2 dx dy)
+ where dx = signum (x1 - x0)
+ dy = signum (y1 - y0)
addLines :: Grid -> [[Point]] -> Grid
-addLines diagram expandedLines = foldr insertLine diagram expandedLines
+-- addLines diagram expandedLines = foldr insertLine diagram expandedLines
+addLines = foldr insertLine
where insertPoint p d = M.insertWith (+) p 1 d
insertLine l d = foldr insertPoint d l