Ticket #1013: A.hs

File A.hs, 2.4 KB (added by dons, 8 years ago)

Crashing file.

Line 
1module Spiral where
2
3import Data.Maybe
4import Data.List
5
6data Dir = R | D | L | U deriving (Show, Eq, Enum)
7type Spiral = ([[Int]], Int, Dir) -- (rows, current row, next direction)
8
9rows :: Spiral -> [[Int]]
10rows (rs, i, d) = rs
11currentrow :: Spiral -> Int
12currentrow (rs, i, d) = i
13nextdir :: Spiral -> Dir
14nextdir (rs, i, d) = d
15
16getrow :: Int -> [[Int]] -> Maybe [Int]
17getrow i sp = if i < 0 || i >= length sp then Nothing else Just (sp!!i)
18
19ndir :: Dir -> Dir
20ndir d = if d == U then R else succ d
21
22newsp :: Spiral
23newsp = ([[1]], 0, R)
24
25makeSpiral :: Int -> Spiral
26makeSpiral i = makeSpiral' 2 newsp
27    where makeSpiral' j sp = if j > i
28                             then sp
29                             else makeSpiral' (j+1) (update j sp)
30
31update :: Int -> Spiral -> Spiral
32update i (sp, cr, d) = (sp', cr', d')
33    where oldrow  = if (d == U && cr' == cr && cr == 0) ||
34                    (d == D && cr' == length sp)
35                    then []
36                    else fromJust $ getrow cr' sp
37          cr'    | d == L || d == R = cr
38                 | d == U = if cr == 0 then 0 else cr-1
39                 | otherwise = cr+1
40          cr''   = if d == U && cr == 0 then -1 else cr'
41          sp'    = insertrow cr'' newrow sp
42          newrow = case d of
43                          R -> oldrow++[i]
44                          D -> oldrow++[i]
45                          L -> i:oldrow
46                          U -> i:oldrow
47          d' | d == R || d == L = if length oldrow == maximum (map length sp)
48                                  then ndir d
49                                  else d
50             | d == U = if cr'' == -1 then ndir d else d
51             | otherwise = if cr' == length sp then ndir d else d
52
53
54
55insertrow :: Int -> [Int] -> [[Int]] -> [[Int]]
56insertrow i r rs = if i == -1 then r:rs else front++[r]++back
57    where (front, rest) = splitAt i rs
58          back = if null rest then [] else tail rest
59
60printSpiral :: Spiral -> IO ()
61printSpiral (sp, i, d) = putStrLn (concat $ intersperse "\n" (map show sp))
62
63sumdiags :: Spiral -> Int
64sumdiags (sp, i, d) = (sumdiags' 0 0 (+1)) + (sumdiags' 0 end (subtract 1)) - centre
65    where row1 = sp!!0
66          end = length row1 - 1
67          halfx = (length row1 `div` 2)
68          halfy = (length sp `div` 2)
69          centre = (sp!!halfy)!!halfx
70          sumdiags' row col f = if row == length sp
71                                then 0
72                                else (sp!!row)!!col + sumdiags' (row+1) (f col) f
73