@@ -9,10 +9,13 @@ module Structures
9
9
, isFinalMatrix
10
10
, editMatrixCell
11
11
, findCellByValue
12
+ , getAdjacents
12
13
) where
13
14
14
15
import Data.Char (isDigit )
15
16
import Data.List
17
+ import Data.Set (Set , lookupMin , lookupMax )
18
+ import qualified Data.Set as Set
16
19
17
20
data Cell = Cell { row :: Int
18
21
, column :: Int
@@ -33,20 +36,23 @@ instance Show Cell where
33
36
34
37
instance Read Cell where
35
38
readsPrec _ input =
36
- let (opar: rest1) = input
39
+ let (opar : rest1) = input
37
40
(rows, rest2) = span isDigit rest1
38
41
(comma1: rest3) = rest2
39
42
(columns, rest4) = span isDigit rest3
40
- (comma2: rest5) = rest4
43
+ (comma2 : rest5) = rest4
41
44
(values, rest6) = span isDigit rest5
42
- (cpar: rest7) = rest6
45
+ (cpar : rest7) = rest6
43
46
row = read rows :: Int
44
47
column = read columns :: Int
45
48
value = read values :: Int
46
49
in
47
50
[(Cell row column value, rest7) |
48
51
opar == ' (' && comma1 == comma2 && comma2 == ' ,' && cpar == ' )' ]
49
52
53
+ getAdjacents :: Cell -> Int -> Int -> Int -> [Cell ]
54
+ getAdjacents (Cell r c v) rs cs s = [Cell nr nc s | dr <- [- 1 , 0 , 1 ], dc <- [- 1 , 0 , 1 ], let (nr, nc) = (r + dr, c + dc), nr > 0 , nr <= rs, nc > 0 , nc <= cs]
55
+
50
56
isAdjacent :: Cell -> Cell -> Bool
51
57
isAdjacent (Cell f1 c1 v1) (Cell f2 c2 v2)
52
58
| Cell f1 c1 v1 == Cell f2 c2 v2 = False
@@ -63,21 +69,34 @@ getCellChar (Cell _ _ value) size
63
69
valueStr = show value
64
70
lenValueStr = length $ show value
65
71
72
+ cellEqual :: Cell -> Cell -> Bool
73
+ cellEqual x y = row x == row y && column x == column y && value x == value y
74
+
75
+ cellEquals' :: [Cell ] -> [Cell ] -> Bool -> Bool
76
+ callEquals' _ _ False = False
77
+ cellEquals' [] [] x = x && True
78
+ cellEquals' _ [] _ = False
79
+ cellEquals' [] _ _ = False
80
+ cellEquals' (x: xs) (y: ys) b = cellEquals' xs ys (cellEqual x y)
81
+
82
+ cellEquals :: [Cell ] -> [Cell ] -> Bool
83
+ cellEquals xs ys = cellEquals' xs ys True
84
+
66
85
data Matrix = Matrix { rows :: Int
67
86
, columns :: Int
68
- , matrix :: [ Cell ]
87
+ , matrix :: Set Cell
69
88
}
70
89
71
90
instance Eq Matrix where
72
- m1 == m2 = rows m1 == rows m2 && columns m1 == columns m2 && sort ( matrix m1) == sort ( matrix m2)
91
+ m1 == m2 = rows m1 == rows m2 && columns m1 == columns m2 && cellEquals ( Set. elems $ matrix m1) ( Set. elems $ matrix m2)
73
92
74
93
showMatrixRow :: [Cell ] -> Int -> String
75
94
showMatrixRow rowCells size = unwords [getCellChar cell size | cell <- rowCells ]
76
95
77
96
instance Show Matrix where
78
- show m = " {" ++ intercalate " \n " [ showMatrixRow (sort (filter (\ (Cell crow _ _) -> crow == row) (matrix m))) maxSize |
97
+ show m = " {" ++ intercalate " \n " [ showMatrixRow (sort (filter (\ (Cell crow _ _) -> crow == row) (Set. elems $ matrix m))) maxSize |
79
98
row <- [1 .. (rows m)]] ++ " }\n " where
80
- maxSize = maximum [length (getCellChar cell 0 ) | cell <- matrix m]
99
+ maxSize = maximum [length (getCellChar cell 0 ) | cell <- Set. elems $ matrix m]
81
100
82
101
parseMatrixCell :: String -> (Int , String )
83
102
parseMatrixCell " " = (- 2 , " " )
@@ -88,23 +107,23 @@ parseMatrixCell (s:rest)
88
107
| s == ' x' = (- 1 , rest)
89
108
| otherwise = (- 2 , s: rest)
90
109
91
- parseMatrixRowRecursive :: Int -> Int -> String -> ([ Cell ] , String )
110
+ parseMatrixRowRecursive :: Int -> Int -> String -> (Set Cell , String )
92
111
parseMatrixRowRecursive rowNum columnNum input =
93
112
let (_, rinput) = span (' ' == ) input
94
113
(value, rest1) = parseMatrixCell rinput
95
- in if value == - 2 then ([] , rest1) else
96
- let (parsedCells, frest) = parseMatrixRowRecursive rowNum (columnNum+ 1 ) rest1
114
+ in if value == - 2 then (Set. empty , rest1) else
115
+ let (parsedCells, frest) = parseMatrixRowRecursive rowNum (columnNum + 1 ) rest1
97
116
parsedCell = Cell rowNum columnNum value
98
- in (parsedCell: parsedCells, frest)
117
+ in (Set. insert parsedCell parsedCells, frest)
99
118
100
119
parseMatrixRow rowNum = parseMatrixRowRecursive rowNum 1
101
120
102
- parseMatrixRecursive :: Int -> String -> ([ Cell ] , String )
121
+ parseMatrixRecursive :: Int -> String -> (Set Cell , String )
103
122
parseMatrixRecursive rowNum (s: rest)
104
123
| (s == ' {' && rowNum == 1 ) || s == ' \n ' = let (parsedRow, rest1) = parseMatrixRow rowNum rest
105
- (parsedRows, rest2) = parseMatrixRecursive (rowNum+ 1 ) rest1
106
- in (parsedRow ++ parsedRows, rest2)
107
- | s == ' }' = ([] , rest)
124
+ (parsedRows, rest2) = parseMatrixRecursive (rowNum + 1 ) rest1
125
+ in (Set. union parsedRow parsedRows, rest2)
126
+ | s == ' }' = (Set. empty , rest)
108
127
109
128
parseMatrix = parseMatrixRecursive 1
110
129
@@ -124,29 +143,29 @@ isValidMatrix m = let allCells = length (matrix m) == rows m * columns m
124
143
(matrix m)
125
144
in correctValues && allCells
126
145
127
- isFinalMatrix :: Matrix -> Bool
128
- isFinalMatrix (Matrix rows columns cells)
129
- | or [ value cell == 0 | cell <- cells ] = False
130
- | not (and [ countInMatrix val (Matrix rows columns cells) == 1
131
- | val <- [1 .. (rows * columns - countObstacles (Matrix rows columns cells))]
132
- ]) = False
133
- | not (and [ or [ value cell1 + 1 == value cell2 | cell2 <- cells, isAdjacent cell1 cell2 ]
134
- | cell1 <- cells,
146
+ isFinalMatrix :: Matrix -> Int -> Int -> Bool
147
+ isFinalMatrix m@ (Matrix rows columns cells) step obs
148
+ | step < notObs = False
149
+ | or [ value cell == 0 | cell <- Set. elems cells ] = False
150
+ | not (and [ countInMatrix val m == 1 | val <- [1 .. notObs] ]) = False
151
+ | not (and [ or [ value cell1 + 1 == value cell2 | cell2 <- Set. elems cells, isAdjacent cell1 cell2 ]
152
+ | cell1 <- Set. elems cells,
135
153
value cell1 /= fvalue,
136
154
value cell1 /= (- 1 ) ]) = False
137
- | otherwise = True
138
- where fvalue = maximum [value cell | cell <- cells]
155
+ | otherwise = True
156
+ where fvalue = maximum [value cell | cell <- Set. elems cells]
157
+ notObs = rows * columns - obs
139
158
140
159
instance Read Matrix where
141
160
readsPrec _ input =
142
161
let (matrixCells, rest) = parseMatrix input
143
- rowNum = maximum [ row cell | cell <- matrixCells ]
144
- columnNum = maximum [ column cell | cell <- matrixCells ]
162
+ rowNum = maximum [ row cell | cell <- Set. elems matrixCells ]
163
+ columnNum = maximum [ column cell | cell <- Set. elems matrixCells ]
145
164
theMatrix = Matrix rowNum columnNum matrixCells
146
165
in [(theMatrix, rest) | isValidMatrix theMatrix]
147
166
148
167
editMatrixCell :: Matrix -> Cell -> Matrix
149
- editMatrixCell (Matrix r c cells) newCell = Matrix r c [ if cell == newCell then newCell else cell | cell <- cells ]
168
+ editMatrixCell (Matrix r c cells) newCell = Matrix r c ( Set. fromList ( [ if cell == newCell then newCell else cell | cell <- Set. elems cells ]) :: Set Cell )
150
169
151
- findCellByValue :: Matrix -> Int -> [ Cell ]
152
- findCellByValue m val = [ cell | cell <- matrix m, value cell == val ]
170
+ findCellByValue :: Matrix -> Int -> Set Cell
171
+ findCellByValue m val = Set. filter ( \ cell -> value cell == val) $ matrix m
0 commit comments