Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Use atoms as square names. Thanks to Kresten Krab Thorup for the idea:

  • Loading branch information...
commit 9c69a9d813a9c5e0b6e41471eb3e3df5ea284a4d 1 parent f092e55
@apauley authored
Showing with 42 additions and 51 deletions.
  1. +7 −13 sudoku.erl
  2. +35 −38 unittests.erl
View
20 sudoku.erl
@@ -9,22 +9,16 @@
squares() ->
%% Returns a list of 81 square names, including "a1" etc.
- ct_expand:term([[X,Y] || X <- ?rows, Y <- ?cols]).
-col_squares() ->
- %% All the square names for each column.
- ct_expand:term([[[X,Y] || X <- ?rows, Y <- [C]] || C <- ?cols]).
-row_squares() ->
- %% All the square names for each row.
- ct_expand:term([[[X,Y] || X <- [R], Y <- ?cols] || R <- ?rows]).
-box_squares() ->
- %% All the square names for each box.
- ct_expand:term([[[X,Y] || X <- R, Y <- C] ||
- R <- ["abc", "def", "ghi"],
- C <- ["123", "456", "789"]]).
+ ct_expand:term([list_to_atom([X,Y]) || X <- ?rows, Y <- ?cols]).
unitlist() ->
%% A list of all units (columns, rows, boxes) in a grid.
- col_squares() ++ row_squares() ++ box_squares().
+ ct_expand:term([[list_to_atom([X,Y]) || X <- ?rows, Y <- [C]] || C <- ?cols]
+ ++ [[list_to_atom([X,Y])
+ || X <- [R], Y <- ?cols] || R <- ?rows]
+ ++ [[list_to_atom([X,Y]) || X <- R, Y <- C] ||
+ R <- ["abc", "def", "ghi"],
+ C <- ["123", "456", "789"]]).
units(Square) ->
%% A list of units for a specific square
View
73 unittests.erl
@@ -1,7 +1,7 @@
-module(unittests).
-import(lists, [all/2, member/2, sort/1]).
-import(sudoku, [cross/2, values/2,
- squares/0, col_squares/0, row_squares/0, box_squares/0,
+ squares/0,
unitlist/0, units/1, peers/1, search/1,
least_valued_unassigned_square/1, stats/1,
clean_grid/1, is_solved/1, eliminate_digits/3,
@@ -38,14 +38,11 @@ test_squares() ->
ok.
test_unitlist() ->
- [["a1","b1","c1","d1","e1","f1","g1","h1","i1"]|_] = col_squares(),
- [["a1","a2","a3","a4","a5","a6","a7","a8","a9"]|_] = row_squares(),
- [["a1","a2","a3","b1","b2","b3","c1","c2","c3"]|_] = box_squares(),
27 = length(unitlist()),
ok.
test_units() ->
- [["a2","b2","c2","d2","e2","f2","g2","h2","i2"]|_] = units("c2"),
+ [[a2,b2,c2,d2,e2,f2,g2,h2,i2]|_] = units(c2),
%% Each square should have exactly 3 units
true = all(fun(Units) -> length(Units) == 3 end,
@@ -63,11 +60,11 @@ test_units() ->
ok.
test_peers() ->
- Peers = sort(["c8", "f2", "g2", "h2", "c7",
- "i2", "a3", "a1", "c9", "a2",
- "b1", "b2", "b3", "c3", "c1",
- "c4", "d2", "c6", "c5", "e2"]),
- Peers = sort(peers("c2")),
+ Peers = sort([c8, f2, g2, h2, c7,
+ i2, a3, a1, c9, a2,
+ b1, b2, b3, c3, c1,
+ c4, d2, c6, c5, e2]),
+ Peers = sort(peers(c2)),
%% Each square should have exactly 20 squares as its peers
true = all(fun(Units) -> length(Units) == 20 end,
@@ -106,28 +103,28 @@ test_parse_grid() ->
%% A parsed grid will already have eliminated the values of some squares
Puzzle = parse_grid(GridString),
- "4" = values(Puzzle, "f2"),
+ "4" = values(Puzzle, f2),
ok.
test_least_valued_unassigned_square() ->
%% Assign something to A1 and eliminate another from A2.
%% A1 should not be considered, it's already assigned.
- Puzzle = assign(eliminate_digits(empty_puzzle(), "a2", "234"), "a1", $1),
+ Puzzle = assign(eliminate_digits(empty_puzzle(), a2, "234"), a1, $1),
false = is_solved(Puzzle),
- {"a2", _} = least_valued_unassigned_square(Puzzle),
+ {a2, _} = least_valued_unassigned_square(Puzzle),
%% Any square can be returned when all values are equally unassigned
- {"a1", _} = least_valued_unassigned_square(empty_puzzle()),
+ {a1, _} = least_valued_unassigned_square(empty_puzzle()),
ok.
test_eliminate() ->
- Puzzle = eliminate(empty_puzzle(), ["a2"], $3),
- "12456789" = values(Puzzle, "a2"),
- NewPuzzle = eliminate_digits(Puzzle, "a2", "13689"),
- "2457" = values(NewPuzzle, "a2"),
+ Puzzle = eliminate(empty_puzzle(), [a2], $3),
+ "12456789" = values(Puzzle, a2),
+ NewPuzzle = eliminate_digits(Puzzle, a2, "13689"),
+ "2457" = values(NewPuzzle, a2),
%% Eliminating the last value from a square should indicate an error
- {false, _} = eliminate_digits(Puzzle, "a2", "123456789"),
+ {false, _} = eliminate_digits(Puzzle, a2, "123456789"),
ok.
test_search_bails_out_early() ->
@@ -147,37 +144,37 @@ test_search_solves_grid() ->
ok.
test_assign() ->
- Puzzle = assign(empty_puzzle(), "a2", $1),
- "1" = values(Puzzle, "a2"),
+ Puzzle = assign(empty_puzzle(), a2, $1),
+ "1" = values(Puzzle, a2),
%% Assigning a different value to an already assigned square should
%% indicate an error.
- {false, _} = assign(Puzzle, "a2", $3),
+ {false, _} = assign(Puzzle, a2, $3),
ok.
test_assign_eliminates_from_peers() ->
- NonPeerValues = values(empty_puzzle(), "d1"),
- Puzzle = assign(empty_puzzle(), "a3", $7),
+ NonPeerValues = values(empty_puzzle(), d1),
+ Puzzle = assign(empty_puzzle(), a3, $7),
%% Now 7 may not be a possible value in any of a3's peers
Fun = fun(Square) -> not (member($7, values(Puzzle, Square))) end,
- true = all(Fun, peers("a3")),
+ true = all(Fun, peers(a3)),
%% After assignment, the non-peers remain unchanged:
- NonPeerValues = values(Puzzle, "d1"),
+ NonPeerValues = values(Puzzle, d1),
ok.
test_recursive_peer_elimination() ->
%% Eliminate all but two values from a peer of a3:
- SetupPuzzle = eliminate_digits(empty_puzzle(), "a2", "2345689"),
- "17" = values(SetupPuzzle, "a2"),
+ SetupPuzzle = eliminate_digits(empty_puzzle(), a2, "2345689"),
+ "17" = values(SetupPuzzle, a2),
%% Assigning one of the above two values in a3 should trigger
%% peer elimination in a2 as well.
- Puzzle = assign(SetupPuzzle, "a3", $7),
- "1" = values(Puzzle, "a2"),
+ Puzzle = assign(SetupPuzzle, a3, $7),
+ "1" = values(Puzzle, a2),
Fun = fun(Square) -> not (member($1, values(Puzzle, Square))) end,
- true = all(Fun, peers("a2")),
+ true = all(Fun, peers(a2)),
ok.
test_automatically_assign_unique_places() ->
@@ -185,18 +182,18 @@ test_automatically_assign_unique_places() ->
GridString = ".....3.17.15..9..8.6.......1....
7.....9...2.....5....4.......2.5..6..34.34.2.....",
Puzzle = parse_grid(GridString),
- "2" = values(Puzzle, "c9"),
+ "2" = values(Puzzle, c9),
ok.
test_places_for_value() ->
GridString = ".45.81376.......................
.................................................",
Puzzle = parse_grid(GridString),
- "29" = values(Puzzle, "a1"),
- "29" = values(Puzzle, "a4"),
- Unit = ["a1","a2","a3","a4","a5","a6","a7","a8","a9"],
- ["a1","a4"] = places_for_value(Puzzle, Unit, $9),
- ["a1","a4"] = places_for_value(Puzzle, Unit, $2),
+ "29" = values(Puzzle, a1),
+ "29" = values(Puzzle, a4),
+ Unit = [a1,a2,a3,a4,a5,a6,a7,a8,a9],
+ [a1,a4] = places_for_value(Puzzle, Unit, $9),
+ [a1,a4] = places_for_value(Puzzle, Unit, $2),
ok.
test_is_solved() ->
@@ -207,7 +204,7 @@ test_is_solved() ->
test_to_string() ->
GridString = ".1736982563215894795872431682543
7169791586432346912758289643571573291684164875293",
- Puzzle = eliminate_digits(parse_grid(GridString), "a1", "12356789"),
+ Puzzle = eliminate_digits(parse_grid(GridString), a1, "12356789"),
[$4|T] = to_string(Puzzle),
[$.|T] = clean_grid(GridString),
ok.
Please sign in to comment.
Something went wrong with that request. Please try again.