Skip to content

Instantly share code, notes, and snippets.

@paulmr
Created April 19, 2017 14:00
Show Gist options
  • Save paulmr/53d85d5f28794261b8f90883fe8f2821 to your computer and use it in GitHub Desktop.
Save paulmr/53d85d5f28794261b8f90883fe8f2821 to your computer and use it in GitHub Desktop.
Advent of Code 2015, Day 18
-module(advent18).
-export([main/1]).
-record(state, { width, height, lights }).
deltas() ->
[ { X, Y } || X <- lists:seq(-1, 1), Y <- lists:seq(-1, 1), (X =/= 0) or (Y =/= 0) ].
neighbours(X, Y) ->
[ { X + Xd, Y + Yd } || { Xd, Yd } <- deltas() ].
countNeighbours(X, Y, Lights) ->
Ns = [ getLight(Nx, Ny, Lights) || { Nx, Ny } <- neighbours(X, Y) ],
lists:sum(Ns).
nextStateForLight(1, N) ->
case N of
2 -> 1;
3 -> 1;
_ -> 0
end;
nextStateForLight(0, N) ->
case N of
3 -> 1;
_ -> 0
end.
nextStateForLights(State = #state{ width = Width, height = Height }) ->
List = [ nextStateForLight(getLight(X, Y, State), countNeighbours(X, Y, State)) ||
Y <- lists:seq(0, Height - 1), X <- lists:seq(0, Width - 1) ],
State#state{ lights = array:from_list(List) }.
process(0, State) -> State;
process(N, State) -> process(N - 1, nextStateForLights(State)).
% implement the 'broken' lights of part 2
modify(S) ->
H = S#state.height - 1,
W = S#state.width - 1,
Changes = [ { 0, 0, 1 },
{ 0, H, 1 },
{ W, 0, 1 },
{ H, W, 1 } ],
setAll(Changes, S).
process2(0, State) -> State;
process2(N, State) ->
process2(N - 1, modify(nextStateForLights(State))).
countOn(#state{lights = Lights}) ->
lists:sum(array:to_list(Lights)).
setLight(X, Y, On, State) ->
I = Y * State#state.width + X,
State#state{ lights = array:set(I, On, State#state.lights) }.
setAll([], State) -> State;
setAll([ { X, Y, On } | Rest ], State) ->
setAll(Rest, setLight(X,Y,On,State)).
getLight(X, Y, #state{ lights = Lights,
width = Width,
height = Height }
) ->
if (X < 0) or (Y < 0) or (X >= Width) or (Y >= Height) -> 0;
true -> array:get((Y * Width) + X, Lights)
end.
parseFile(Fname) ->
Lines = advent_util:readFile(Fname),
Height = length(Lines),
Width = length(hd(Lines)) - 1,
Lights = array:from_list(
[ case Char of $# -> 1; _ -> 0 end ||
Line <- Lines, Char <- Line, Char =/= $\n ]),
#state{ width = Width, height = Height, lights = Lights }.
part1(Lights) ->
countOn(process(100, Lights)).
part2(Lights) ->
countOn(process2(100, modify(Lights))).
main([]) -> main(["priv/input18.txt"]);
main([Fname]) ->
Input = parseFile(Fname),
Part1 = part1(Input),
Part2 = part2(Input),
io:format("Part1: ~B~nPart2: ~B~n", [ Part1, Part2 ]).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment