29 lines
		
	
	
		
			1.1 KiB
		
	
	
	
		
			Haskell
		
	
	
	
	
	
		
		
			
		
	
	
			29 lines
		
	
	
		
			1.1 KiB
		
	
	
	
		
			Haskell
		
	
	
	
	
	
|  | import Data.Char | ||
|  | import Data.List | ||
|  | 
 | ||
|  | -- findBegin :: ((Int, Int), Char) -> [((Int, Int), Char)] -> ((Int, Int), Char) | ||
|  | findBegin s@((x,y), c) dict = case filter (\(p,_) -> p == (x,y-1)) dict of | ||
|  |   [] -> s | ||
|  |   n:xs -> findBegin n dict | ||
|  | 
 | ||
|  | main :: IO () | ||
|  | main = do | ||
|  |   inputLines <- lines <$> getContents | ||
|  | 
 | ||
|  |   let distances = concat (map (\x -> (map (\y -> (x,y)) [-1..1])) [-1..1]) | ||
|  | 
 | ||
|  |   let numInputLines = zip [0..] (map (zip [0..]) inputLines) | ||
|  |   let charCoords = concat (map (\(x, l) -> (map (\(y, c) -> ((x,y),c)) l)) numInputLines) | ||
|  |   let symbols = map (\(p, c) -> p) (filter (\(_,c) -> not (c == '.' || isDigit c)) charCoords) | ||
|  |   let digits = filter (\(_,c) -> isDigit c) charCoords | ||
|  |   let serialChars = filter (\((x,y),_) -> any (\x -> elem x symbols) (map (\(x1,y2) -> (x + x1, y + y2)) distances)) digits | ||
|  |   let serialBegins = nub $ map (\x -> findBegin x digits) serialChars | ||
|  |   let serialNumbers = map (\((x,y), c) -> read (takeWhile isDigit (drop y (inputLines!!x))) :: Integer) serialBegins | ||
|  |   -- print charCoords  | ||
|  |   -- print symbols | ||
|  |   print (sum serialNumbers) | ||
|  |   -- convert input to [((x,y), Char)] | ||
|  | 
 | ||
|  |   -- mapM_ putStrLn inputLines | ||
|  | 
 |