-
Notifications
You must be signed in to change notification settings - Fork 0
/
sol11a.erl
executable file
·79 lines (71 loc) · 2.07 KB
/
sol11a.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
67
68
69
70
71
72
73
74
75
76
77
78
79
#!/usr/bin/escript
main([]) ->
main(["sol11.data"]);
main([Filename]) ->
{ok, File} = file:read_file(Filename),
Lines = string:lexemes(File, "\r\n"),
State = lists:foldl(fun (X, Acc) -> make_state(X, Acc) end,
#{},
lists:zip(lists:seq(1, length(Lines)), Lines)),
Result = iterate_to_stability(State),
Total = [X || X <- maps:values(Result),
X =:= occupied],
io:format("~B~n", [length(Total)]).
make_state({Y, Line}, Acc0) ->
Seats = binary_to_list(Line),
lists:foldl(fun (S, Acc) -> make_state_seats(S, Y, Acc) end,
Acc0,
lists:zip(lists:seq(1, length(Seats)), Seats)).
make_state_seats({_X, $.}, _Y, Acc) ->
Acc;
make_state_seats({X, $L}, Y, Acc) ->
Acc#{{X, Y} => empty}.
iterate_to_stability(State) ->
io:format("Iterating~n"),
NewState = maps:fold(fun (K, V, Acc) -> next_iter(K, V, State, Acc) end,
#{},
State),
case NewState of
State -> NewState;
_ -> iterate_to_stability(NewState)
end.
next_iter(Pos, empty, State, Acc) ->
case count_occupied(surroundings(Pos, State)) of
0 -> Acc#{Pos => occupied};
_ -> Acc#{Pos => empty}
end;
next_iter(Pos, occupied, State, Acc) ->
case count_occupied(surroundings(Pos, State)) of
N when N >= 4 -> Acc#{Pos => empty};
_ -> Acc#{Pos => occupied}
end.
count_occupied(S) ->
length([X || X <- S, X =:= occupied]).
surroundings({X, Y}, State) ->
[maps:get({X+1, Y+1}, State, floor),
maps:get({X , Y+1}, State, floor),
maps:get({X-1, Y+1}, State, floor),
maps:get({X+1, Y }, State, floor),
maps:get({X-1, Y }, State, floor),
maps:get({X+1, Y-1}, State, floor),
maps:get({X , Y-1}, State, floor),
maps:get({X-1, Y-1}, State, floor)
].
dump_state(State) ->
MaxX = lists:max([X || {X, _} <- maps:keys(State)]),
MaxY = lists:max([Y || {_, Y} <- maps:keys(State)]),
lists:foreach(
fun(Y) ->
lists:foreach(
fun (X) ->
Ch = case maps:get({X, Y}, State, floor) of
empty -> $L;
occupied -> $#;
floor -> $.
end,
io:format("~ts", [[Ch]])
end,
lists:seq(1, MaxX)),
io:format("~n")
end,
lists:seq(1, MaxY)).