SHOW:
|
|
- or go back to the newest paste.
1 | import Data.Char (ord) | |
2 | - | import qualified Data.Map as M |
2 | + | import qualified Data.Set as S |
3 | import qualified Data.Vector as V | |
4 | ||
5 | - | type Done = M.Map Coord Bool |
5 | + | |
6 | type Done = S.Set Coord | |
7 | type Todo = [Coord] | |
8 | ||
9 | main = putStrLn $ show n | |
10 | - | n = loop 0 [(0,0)] M.empty |
10 | + | |
11 | n = loop 0 [(0,0)] S.empty | |
12 | ||
13 | loop :: Int -> Todo -> Done -> Int | |
14 | - | loop n (t:ts) d = loop (n + count t) (also t d ++ ts) (M.insert t True d) |
14 | + | |
15 | loop n (t:ts) d = loop (n + count t) (also t d ++ ts) (S.insert t d) | |
16 | ||
17 | count :: Coord -> Int | |
18 | count (0,0) = 1 | |
19 | count (0,_) = 4 | |
20 | count (_,0) = 4 | |
21 | count (x,y) = if x == y then 4 else 8 | |
22 | ||
23 | - | also c d = filter (\k -> M.notMember k d) $ |
23 | + | |
24 | also c d = filter (\k -> S.notMember k d) $ | |
25 | filter isAccessible $ | |
26 | filter inQuadrant $ | |
27 | next c | |
28 | ||
29 | isAccessible :: Coord -> Bool | |
30 | isAccessible (x,y) = sumDigits <= 19 | |
31 | - | sumDigits = sum1 x + sum1 y |
31 | + | |
32 | sumDigits = sums V.! x + sums V.! y | |
33 | - | val x = ord x - ord '0' |
33 | + | |
34 | inQuadrant :: Coord -> Bool | |
35 | inQuadrant (x,y) = y <= x | |
36 | ||
37 | next :: Coord -> Todo | |
38 | next (x,y) = [(x+1,y), (x,y+1)] | |
39 | - | next (x,y) = [(x+1,y), (x,y+1)] |
39 | + | |
40 | sums :: V.Vector Int | |
41 | sums = V.generate 300 sum1 | |
42 | where | |
43 | sum1 n = sum $ map val (show n) | |
44 | val x = ord x - ord '0' |