-
Notifications
You must be signed in to change notification settings - Fork 0
/
exo96b.erl
66 lines (54 loc) · 2.72 KB
/
exo96b.erl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
-module(exo96b).
-compile(export_all).
exo96() ->
{ok, Data} = file:read_file("p096_sudoku.txt"),
List = binary:split(Data, [<<"\n">>], [global]),
RawGrids = [lists:sublist(List, X+1, 9) || X <- lists:seq(1,length(List),10) ],
SolvedGrids = lists:map(fun solve/1, lists:map(fun store_grid/1, RawGrids)),
lists:foldl(fun(SolvedGrid, Sum) -> Sum + maps:get({1,1}, SolvedGrid)*100 + maps:get({2,1}, SolvedGrid)*10 + maps:get({3,1}, SolvedGrid) end, 0, SolvedGrids).
store_grid(RawGrid) ->
Flattened = lists:flatten(lists:map(fun binary:bin_to_list/1, RawGrid)),
IndexedStr = lists:zip(lists:seq(1, length(Flattened)), Flattened),
IndexedNbr = lists:map(fun({Key, Value}) -> {Int, _} = string:to_integer([Value]), {Key, Int} end, IndexedStr),
maps:from_list(lists:map(fun({Index, Value}) -> {{((Index - 1) rem 9) + 1, ((Index - 1) div 9) + 1}, Value} end, IndexedNbr)).
solve(Grid) ->
EmptyCells = lists:filter(fun({_, Value}) -> Value == 0 end, maps:to_list(Grid)),
%% io:fwrite(integer_to_list(length(EmptyCells))++"~n"),
CalculatedAvailableNumbers = lists:map(fun({{Col, Row}, 0}) -> {{Col, Row}, available_numbers(Col, Row, Grid)} end, EmptyCells),
SortedAvailableNumbers = lists:sort(fun({{_, _}, NumbersA},{{_, _}, NumbersB}) -> length(NumbersA) =< length(NumbersB) end, CalculatedAvailableNumbers),
case SortedAvailableNumbers of
[] -> Grid;
[{{Col, Row}, AvailableNumbers}|_] ->
case try_available_numbers(AvailableNumbers, Col, Row, Grid) of
error -> error;
SolvedGrid -> SolvedGrid
end
end.
try_available_numbers([], _, _, _) ->
error;
try_available_numbers([H|T], Col, Row, Grid) ->
UpdatedGrid = maps:update({Col, Row}, H, Grid),
case solve(UpdatedGrid) of
error -> try_available_numbers(T, Col, Row, UpdatedGrid);
SolvedGrid -> SolvedGrid
end.
extract_row(Row, Grid) ->
[maps:get({X, Row}, Grid) || X <- lists:seq(1,9)].
extract_col(Col, Grid) ->
[maps:get({Col, Y}, Grid) || Y <- lists:seq(1,9)].
extract_square(Col, Row, Grid) ->
[maps:get({X, Y}, Grid) ||
X <- lists:seq(square_index(Col) + 1, square_index(Col) + 3),
Y <- lists:seq(square_index(Row) + 1, square_index(Row) + 3)].
available_numbers(Col, Row, Grid) ->
FilledOnCol = filled_numbers(extract_col(Col, Grid)),
FilledOnRow = filled_numbers(extract_row(Row, Grid)),
FilledOnSquare = filled_numbers(extract_square(Col, Row, Grid)),
Filled = lists:append([FilledOnCol, FilledOnRow, FilledOnSquare]),
lists:filter(fun(X) -> not lists:member(X, Filled) end, lists:seq(1,9)).
filled_numbers(Numbers) ->
lists:filter(fun(Number) -> Number /= 0 end, Numbers).
square_index(Pos) ->
((Pos - 1) div 3)*3.
solve_grid(Grid) ->
Grid.