Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Emacs spacing

  • Loading branch information...
commit 0cd5cc4b631c905e69e686acee54f1f517d02b48 1 parent 070c6e6
Andreas Pauley authored

Showing 1 changed file with 49 additions and 49 deletions. Show diff stats Hide diff stats

  1. +49 49 sudoku.erl
98 sudoku.erl
... ... @@ -1,8 +1,8 @@
1 1 -module(sudoku).
2 2
3 3 -import(lists,
4   - [member/2, filter/2, map/2, flatmap/2, sort/1, all/2,
5   - sum/1]).
  4 + [member/2, filter/2, map/2, flatmap/2, sort/1, all/2,
  5 + sum/1]).
6 6
7 7 -compile(export_all).
8 8
@@ -17,20 +17,20 @@
17 17 squares() ->
18 18 %% Returns a list of 81 square names, including "a1" etc.
19 19 ct_expand:term([list_to_atom([X, Y])
20   - || X <- ?rows, Y <- ?cols]).
  20 + || X <- ?rows, Y <- ?cols]).
21 21
22 22 unitlist() ->
23 23 %% A list of all units (columns, rows, boxes) in a grid.
24 24 ct_expand:term([[list_to_atom([X, Y])
25   - || X <- ?rows, Y <- [C]]
26   - || C <- ?cols]
27   - ++
28   - [[list_to_atom([X, Y]) || X <- [R], Y <- ?cols]
29   - || R <- ?rows]
30   - ++
31   - [[list_to_atom([X, Y]) || X <- R, Y <- C]
32   - || R <- ["abc", "def", "ghi"],
33   - C <- ["123", "456", "789"]]).
  25 + || X <- ?rows, Y <- [C]]
  26 + || C <- ?cols]
  27 + ++
  28 + [[list_to_atom([X, Y]) || X <- [R], Y <- ?cols]
  29 + || R <- ?rows]
  30 + ++
  31 + [[list_to_atom([X, Y]) || X <- R, Y <- C]
  32 + || R <- ["abc", "def", "ghi"],
  33 + C <- ["123", "456", "789"]]).
34 34
35 35 units(Square) ->
36 36 %% A list of units for a specific square
@@ -40,7 +40,7 @@ peers(Square) ->
40 40 %% A unique list of squares (excluding this one)
41 41 %% that are also part of the units for this square.
42 42 NonUniquePeers = shallow_flatten([S
43   - || S <- units(Square)]),
  43 + || S <- units(Square)]),
44 44 lists:delete(Square, lists:usort(NonUniquePeers)).
45 45
46 46 values(Puzzle, Square) ->
@@ -60,10 +60,10 @@ clean_grid(GridString) ->
60 60
61 61 parse_puzzle(Puzzle, [], []) -> Puzzle;
62 62 parse_puzzle(Puzzle, [Square | Squares],
63   - [Value | GridString]) ->
  63 + [Value | GridString]) ->
64 64 IsDigit = lists:member(Value, ?digits),
65 65 NewPuzzle = assign_if_digit(Puzzle, Square, Value,
66   - IsDigit),
  66 + IsDigit),
67 67 parse_puzzle(NewPuzzle, Squares, GridString).
68 68
69 69 assign_if_digit(Puzzle, Square, Value, true) ->
@@ -77,12 +77,12 @@ empty_puzzle() -> {empty_dict(), 0}.
77 77
78 78 empty_dict() ->
79 79 dict:from_list([{Square, ?digits}
80   - || Square <- squares()]).
  80 + || Square <- squares()]).
81 81
82 82 assign(Puzzle, Square, Digit) ->
83 83 %% Assign by eliminating all values except the assigned value.
84 84 OtherValues = exclude_from(values(Puzzle, Square),
85   - Digit),
  85 + Digit),
86 86 eliminate_digits(Puzzle, Square, OtherValues).
87 87
88 88 eliminate_digits({false, _Count} = False, _, _) ->
@@ -99,7 +99,7 @@ eliminate(Puzzle, [Square | T], Digit) ->
99 99 OldValues = values(Puzzle, Square),
100 100 NewValues = exclude_from(OldValues, Digit),
101 101 NewPuzzle = eliminate(Puzzle, Square, Digit, NewValues,
102   - OldValues),
  102 + OldValues),
103 103 eliminate(NewPuzzle, T, Digit).
104 104
105 105 eliminate({_, Count}, _, _, [], _) ->
@@ -109,10 +109,10 @@ eliminate(Puzzle, _, _, Vs, Vs) ->
109 109 %% NewValues and OldValues are the same, already eliminated.
110 110 Puzzle;
111 111 eliminate({ValuesDict, Eliminations}, Square, Digit,
112   - NewValues, _) ->
  112 + NewValues, _) ->
113 113 NewDict = dict:store(Square, NewValues, ValuesDict),
114 114 NewPuzzle = peer_eliminate({NewDict, Eliminations + 1},
115   - Square, NewValues),
  115 + Square, NewValues),
116 116 %% Digit have been eliminated from this Square.
117 117 %% Now see if the elimination has created a unique place for a digit
118 118 %% to live in the surrounding units of this Square.
@@ -134,14 +134,14 @@ assign_unique_place(Puzzle, [Unit | T], Digit) ->
134 134 %% assign it.
135 135 Places = places_for_value(Puzzle, Unit, Digit),
136 136 NewPuzzle = assign_unique_place_for_digit(Puzzle,
137   - Places, Digit),
  137 + Places, Digit),
138 138 assign_unique_place(NewPuzzle, T, Digit).
139 139
140 140 assign_unique_place_for_digit({_, Count}, [], _) ->
141 141 %% Contradiction: no place for Digit found
142 142 {false, Count};
143 143 assign_unique_place_for_digit(Puzzle, [Square],
144   - Digit) ->
  144 + Digit) ->
145 145 %% Unique place for Digit found, assign
146 146 assign(Puzzle, Square, Digit);
147 147 assign_unique_place_for_digit(Puzzle, _, _) ->
@@ -151,7 +151,7 @@ assign_unique_place_for_digit(Puzzle, _, _) ->
151 151 places_for_value(Puzzle, Unit, Digit) ->
152 152 [Square
153 153 || Square <- Unit,
154   - lists:member(Digit, values(Puzzle, Square))].
  154 + lists:member(Digit, values(Puzzle, Square))].
155 155
156 156 solve(GridString) -> search(parse_grid(GridString)).
157 157
@@ -163,29 +163,29 @@ search(Puzzle, true) ->
163 163 Puzzle;
164 164 search(Puzzle, false) ->
165 165 {Square, Values} =
166   - least_valued_unassigned_square(Puzzle),
  166 + least_valued_unassigned_square(Puzzle),
167 167 first_valid_result(Puzzle, Square, Values).
168 168
169 169 %% Returns the first valid puzzle, otherwise the last puzzle
170 170 first_valid_result({_, Count}, _, []) -> {false, Count};
171 171 first_valid_result(Puzzle, Square,
172   - [Digit | _T] = Digits) ->
  172 + [Digit | _T] = Digits) ->
173 173 PuzzleOrFalse = search(assign(Puzzle, Square, Digit)),
174 174 first_valid_result(Puzzle, Square, Digits,
175   - PuzzleOrFalse).
  175 + PuzzleOrFalse).
176 176
177 177 first_valid_result({Dict, ValidCount}, Square, [_ | T],
178   - {false, InvalidCount}) ->
  178 + {false, InvalidCount}) ->
179 179 first_valid_result({Dict,
180   - ValidCount + (InvalidCount - ValidCount)},
181   - Square, T);
  180 + ValidCount + (InvalidCount - ValidCount)},
  181 + Square, T);
182 182 first_valid_result(_, _, _, Puzzle) -> Puzzle.
183 183
184 184 least_valued_unassigned_square({ValuesDict, _}) ->
185 185 Lengths = [least_valued_unassigned_square_2(V)
186   - || V <- dict:to_list(ValuesDict)],
  186 + || V <- dict:to_list(ValuesDict)],
187 187 Unassigned = [V1
188   - || V1 <- Lengths, least_valued_unassigned_square_1(V1)],
  188 + || V1 <- Lengths, least_valued_unassigned_square_1(V1)],
189 189 {_, Square, Values} = lists:min(Unassigned),
190 190 {Square, Values}.
191 191
@@ -197,7 +197,7 @@ least_valued_unassigned_square_2({S, Values}) ->
197 197
198 198 solve_all(GridList) ->
199 199 PidGrids = [{spawn(fun server/0), Grid}
200   - || Grid <- GridList],
  200 + || Grid <- GridList],
201 201 [solve_all_1(V) || V <- PidGrids],
202 202 [receiveSolution(V1) || V1 <- PidGrids].
203 203
@@ -209,27 +209,27 @@ receiveSolution({Pid, Grid}) ->
209 209 server() ->
210 210 receive
211 211 {From, solve, GridString} ->
212   - From ! {self(), GridString, solve(GridString)}
  212 + From ! {self(), GridString, solve(GridString)}
213 213 end.
214 214
215 215 is_solved(Puzzle) ->
216 216 lists:all(fun (Unit) -> is_unit_solved(Puzzle, Unit)
217   - end,
218   - unitlist()).
  217 + end,
  218 + unitlist()).
219 219
220 220 is_unit_solved(Puzzle, Unit) ->
221 221 UnitValues = lists:flatmap(fun (S) -> values(Puzzle, S)
222   - end,
223   - Unit),
  222 + end,
  223 + Unit),
224 224 lists:sort(UnitValues) =:= (?digits).
225 225
226 226 to_string(Puzzle) ->
227 227 {ValuesDict, _} = Puzzle,
228 228 Fun = fun ({_, [V]}) -> [V];
229   - ({_, _}) -> "."
230   - end,
  229 + ({_, _}) -> "."
  230 + end,
231 231 lists:flatmap(Fun,
232   - lists:sort(dict:to_list(ValuesDict))).
  232 + lists:sort(dict:to_list(ValuesDict))).
233 233
234 234 from_file(Filename, Seperator) ->
235 235 {ok, BinData} = file:read_file(Filename),
@@ -238,12 +238,12 @@ from_file(Filename, Seperator) ->
238 238 to_file(Filename, Solutions) ->
239 239 GridStrings = [[to_string(S) | "\n"] || S <- Solutions],
240 240 ok = file:write_file(Filename,
241   - list_to_binary(GridStrings)).
  241 + list_to_binary(GridStrings)).
242 242
243 243 solve_file(Filename, Seperator) ->
244 244 Solutions = solve_all(from_file(Filename, Seperator)),
245 245 OutFilename = [filename:basename(Filename, ".txt")
246   - | ".out"],
  246 + | ".out"],
247 247 ok = to_file(OutFilename, Solutions),
248 248 Solutions.
249 249
@@ -252,20 +252,20 @@ print_results(Filename) ->
252 252
253 253 print_results(Filename, Seperator) ->
254 254 {Time, Solutions} = timer:tc(sudoku, solve_file,
255   - [Filename, Seperator]),
  255 + [Filename, Seperator]),
256 256 Solved = [Puzzle
257   - || Puzzle <- Solutions, is_solved(Puzzle)],
  257 + || Puzzle <- Solutions, is_solved(Puzzle)],
258 258 TimeInSeconds = Time / 1000000,
259 259 Eliminations = [Count || {_, Count} <- Solutions],
260 260 {Total, Avg, Med, Max, Min, NumberPuzzles} =
261   - stats(Eliminations),
  261 + stats(Eliminations),
262 262 Hz = NumberPuzzles / TimeInSeconds,
263 263 Msg = "Solved ~p of ~p puzzles from ~s in ~f "
264   - "secs (~.2f Hz)\n (~p total eliminations, "
265   - "avg ~.2f, median ~p, max ~p, min ~p).~n",
  264 + "secs (~.2f Hz)\n (~p total eliminations, "
  265 + "avg ~.2f, median ~p, max ~p, min ~p).~n",
266 266 io:format(Msg,
267   - [length(Solved), NumberPuzzles, Filename, TimeInSeconds,
268   - Hz, Total, Avg, Med, Max, Min]).
  267 + [length(Solved), NumberPuzzles, Filename, TimeInSeconds,
  268 + Hz, Total, Avg, Med, Max, Min]).
269 269
270 270 stats(List) ->
271 271 Total = lists:sum(List),

0 comments on commit 0cd5cc4

Please sign in to comment.
Something went wrong with that request. Please try again.