text <- readFile dataFileName
let engine = mkEngine text
let allNums = findNumbers engine
- let partNums = filter (numTouchingSymbols engine) allNums
+ let symbols = findSymbols engine
+ let partNums = filter (touchRegion symbols) allNums
+ -- print partNums
-- print engine
-- print $ findNumbers engine
print $ part1 engine partNums
where partNumValues = map (readNumber engine) partNums
part2 engine partNums = sum $ fmap product gearRatios
- where sts = stars engine
- touchingStars = fmap (adjacentNumbers partNums) sts
+ where stars = findStars engine
+ touchingStars = fmap (possibleGears partNums) stars
gears = filter ((==) 2 . length) touchingStars
gearRatios = [[readNumber engine n | n <- pNs] | pNs <- gears]
neighbours p = [p ^+^ V2 dr dc | dr <- [-1..1], dc <- [-1..1]
, (dr, dc) /= (0, 0) ]
-touchingSymbol :: Engine -> Position -> Bool
-touchingSymbol engine p = any (isEngineSymbol . (engine !)) nbrs
- where nbrs = filter (inRange (bounds engine)) $ neighbours p
-numTouchingSymbols :: Engine -> NumPos -> Bool
-numTouchingSymbols engine ps = any (touchingSymbol engine) ps
+touchPoint :: [Position] -> Position -> Bool
+touchPoint region point = not $ null $ intersect region $ neighbours point
+
+touchRegion :: [Position] -> [Position] -> Bool
+touchRegion region1 region2 = any (touchPoint region2) region1
+
readNumber :: Engine -> NumPos -> Int
readNumber engine ps = read $ map (engine !) ps
-stars :: Engine -> [Position]
-stars engine = filter ((==) '*' . (engine !)) $ indices engine
+findSymbols :: Engine -> [Position]
+findSymbols engine = filter (isEngineSymbol . (engine !)) $ indices engine
-starTouchesNumber :: Position -> NumPos -> Bool
-starTouchesNumber star ps = not $ null $ intersect ps halo
- where halo = neighbours star
+findStars :: Engine -> [Position]
+findStars engine = filter ((==) '*' . (engine !)) $ indices engine
-adjacentNumbers :: [NumPos] -> Position -> [NumPos]
-adjacentNumbers nums star = filter (starTouchesNumber star) nums
+possibleGears :: [NumPos] -> Position -> [NumPos]
+possibleGears nums star = filter (flip touchPoint star) nums