Skip to content

Commit 2131f05

Browse files
committed
finished day 2
1 parent 28bbd47 commit 2131f05

File tree

5 files changed

+222
-16
lines changed

5 files changed

+222
-16
lines changed

2016/day1/santa.erl

+15-16
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
% Santa Server
2+
13
-module(santa).
24
-behavior(gen_server).
3-
-export([start_link/0,move/3,stop/1,where_am_i/1,get_hq/1,init/1,handle_call/3,handle_cast/2,handle_info/2,terminate/2,code_change/3]).
5+
-export([start_link/0,move/3,where_am_i/1,get_hq/1,stop/1]).
6+
-export([init/1,handle_call/3,handle_cast/2,handle_info/2,terminate/2,code_change/3]).
47

5-
start_link() ->
6-
gen_server:start_link(?MODULE, [], []).
8+
start_link() -> gen_server:start_link(?MODULE, [], []).
79

810
%% Calls
911
move(Pid, Turn, Distance) -> gen_server:cast(Pid, {move, Turn, Distance}).
@@ -28,6 +30,16 @@ handle_cast({move, Turn, Distance}, {Direction, Position, Visited, HQ}) ->
2830
{NewVisited, NewHQ, NewPosition} = walk(NewDirection, Distance, Position, Visited, HQ),
2931
{noreply, {NewDirection, NewPosition, NewVisited, NewHQ}}.
3032

33+
handle_info(Msg, State) ->
34+
io:format("Unexpected message: ~p~n", [Msg]),
35+
{noreply, State}.
36+
37+
terminate(normal, _State) -> ok.
38+
39+
% We don't have any state migration.
40+
code_change(_OldVsn, State, _Extra) -> {ok, State}.
41+
42+
%%% Private
3143
visit({X, Y}, Visited, notfound) ->
3244
NewHQ = case lists:member({X, Y}, Visited) of
3345
true -> {X, Y};
@@ -37,19 +49,6 @@ visit({X, Y}, Visited, notfound) ->
3749
{NewVisited, NewHQ};
3850

3951
visit(_, Visited, HQ) -> {Visited, HQ}.
40-
41-
handle_info(Msg, State) ->
42-
io:format("Unexpected message: ~p~n", [Msg]),
43-
{noreply, State}.
44-
45-
terminate(normal, _State) ->
46-
ok.
47-
48-
code_change(_OldVsn, State, _Extra) ->
49-
% We don't have any state migration.
50-
{ok, State}.
51-
52-
%%% Private
5352
turn(north, left) -> west;
5453
turn(west, left) -> south;
5554
turn(south, left) -> east;

2016/day2/day2

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#!/usr/bin/env escript
2+
%%! -sname day2
3+
4+
main([]) -> main(["input.txt"]);
5+
main([Filename]) ->
6+
compile:file("keypad.erl"),
7+
Instructions = load_input(Filename),
8+
run_mode(standard, Instructions),
9+
run_mode(weird, Instructions).
10+
11+
run_mode(Mode, Instructions) ->
12+
Pids = run(Mode, 0, Instructions),
13+
Numbers = receive_loop(Pids),
14+
Sorted = lists:sort(fun({Ia, _}, {Ib, _}) -> Ia =< Ib end, Numbers),
15+
io:format("Results for ~p mode: ~p~n", [Mode, [ N || {_, N} <- Sorted]]).
16+
17+
receive_loop([]) -> [];
18+
receive_loop(Pids) ->
19+
receive
20+
{ done, { I, From, Key } } ->
21+
NewPids = lists:delete(From, Pids),
22+
List = receive_loop(NewPids),
23+
[ {I, Key} | List ]
24+
end.
25+
26+
run(_, _, []) -> [];
27+
run(Mode, I, [ Instrs | Rest ]) ->
28+
% Create a process to handle this line. Why a process per line? Because I can. It's probably stupid.
29+
Self = self(),
30+
Pid = spawn_link(fun() -> run_single(Mode, I, Instrs, Self) end),
31+
List = run(Mode, I + 1, Rest),
32+
[ Pid | List ].
33+
34+
run_single(Mode, I, Instrs, Parent) ->
35+
{ok, Pid} = keypad:start_link(Mode),
36+
ok = dispatch(Pid, Instrs),
37+
Key = keypad:getkey(Pid),
38+
Parent ! { done, {I, self(), Key} },
39+
keypad:stop(Pid).
40+
41+
dispatch(_, []) -> ok;
42+
dispatch(Pid, [ Direction | Rest ]) ->
43+
keypad:move(Pid, Direction),
44+
dispatch(Pid, Rest).
45+
46+
load_input(Filename) ->
47+
{ok, File} = file:open(Filename, [read]),
48+
lists:reverse(load_input(File, [])).
49+
50+
load_input(File, List) ->
51+
case file:read_line(File) of
52+
{ok, Line} -> NewList = [ parse_line(Line) | List ],
53+
load_input(File, NewList);
54+
eof -> List
55+
end.
56+
57+
parse_line(Line) -> lists:reverse(parse_line_inner(Line, [])).
58+
59+
parse_line_inner("U" ++ Rest, List) -> parse_line_inner(Rest, [ up | List ]);
60+
parse_line_inner("R" ++ Rest, List) -> parse_line_inner(Rest, [ right | List ]);
61+
parse_line_inner("D" ++ Rest, List) -> parse_line_inner(Rest, [ down | List ]);
62+
parse_line_inner("L" ++ Rest, List) -> parse_line_inner(Rest, [ left | List ]);
63+
parse_line_inner("\n", List) -> List.

2016/day2/example.txt

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
ULL
2+
RRDDD
3+
LURDL
4+
UUUUD

2016/day2/input.txt

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
RDLRUUULRRDLRLLRLDDUDLULULDDULUDRRUURLRLLUULDURRULLRULDRRDLLULLRLLDRLDDRRRRLLRLURRRDRDULRDUULDDDULURUDDRRRUULUDRLLUUURLUDRUUUDRDUULLRLLUDDRURRDDDRDLUUURLRLLUDRURDUDUULDDLLRDURULLLURLDURLUUULDULDDULULLLRRUDLRUURDRDLLURLUDULDUUUURRLDLUDRULUDLDLLDRLDDDRRLLDUDLLRRDDDRLUDURLLLDRUDDLDDRRLUDRRDUDLRRLULDULURULDULUULDRLLDRUUDDRLLUDRULLRRRLRDLRLUDLRULDRDLRDRLRULUDUURRUUULLDDDDUDDLDDDDRRULRDLRDDULLDLDLLDLLDLLDRRDDDRDDLRRDDDRLLLLURRDLRRLDRURDDURDULDDRUURUDUDDDRDRDDRLRRLRULLDRLDLURLRLRUDURRRDLLLUDRLRDLLDDDLLUDRLDRRUUDUUDULDULLRDLUDUURLDDRUDR
2+
URULDDLDDUDLLURLUUUUUULUDRRRDDUDURDRUURLLDRURLUULUDRDRLLDRLDULRULUURUURRLRRDRUUUDLLLLRUDDLRDLLDUDLLRRURURRRUDLRLRLLRULRLRLRDLRLLRRUDDRLRUDULDURDLDLLLRDRURURRULLLDLLRRDRLLDUUDLRUUDDURLLLDUUDLRDDURRDRRULLDRLRDULRRLLRLLLLUDDDRDRULRRULLRRUUDULRRRUDLLUUURDUDLLLURRDDUDLDLRLURDDRRRULRRUDRDRDULURULRUDULRRRLRUDLDDDDRUULURDRRDUDLULLRUDDRRRLUDLRURUURDLDURRDUUULUURRDULLURLRUUUUULULLDRURULDURDDRRUDLRLRRLLLLDDUURRULLURURRLLDRRDDUUDLLUURRDRLLLLRLUDUUUDLRLRRLDURDRURLRLRULURLDULLLRRUUUDLLRRDUUULULDLLDLRRRDUDDLRULLULLULLULRU
3+
DURUUDULRRLULLLDDUDDLRRDURURRRDDRRURDRURDRLULDUDUDUULULDDUURDDULRDUDUDRRURDRDDRLDRDRLDULDDULRULLDULURLUUDUDULRDDRRLURLLRRDLLDLDURULUDUDULDRLLRRRUDRRDDDRRDRUUURLDLURDLRLLDUULLRULLDDDDRULRRLRDLDLRLUURUUULRDUURURLRUDRDDDRRLLRLLDLRULUULULRUDLUDULDLRDDDDDRURDRLRDULRRULRDURDDRRUDRUDLUDLDLRUDLDDRUUULULUULUUUDUULDRRLDUDRRDDLRUULURLRLULRURDDLLULLURLUDLULRLRRDDDDDRLURURURDRURRLLLLURLDDURLLURDULURUUDLURUURDLUUULLLLLRRDUDLLDLUUDURRRURRUUUDRULDDLURUDDRRRDRDULURURLLDULLRDDDRRLLRRRDRLUDURRDLLLLDDDDLUUURDDDDDDLURRURLLLUURRUDLRLRRRURULDRRLULD
4+
LLUUURRDUUDRRLDLRUDUDRLRDLLRDLLDRUULLURLRRLLUDRLDDDLLLRRRUDULDLLLDRLURDRLRRLURUDULLRULLLURRRRRDDDLULURUDLDUDULRRLUDDURRLULRRRDDUULRURRUULUURDRLLLDDRDDLRRULRDRDRLRURULDULRRDRLDRLLDRDURUUULDLLLRDRRRLRDLLUDRDRLURUURDLRDURRLUDRUDLURDRURLRDLULDURDDURUUDRLULLRLRLDDUDLLUUUURLRLRDRLRRRURLRULDULLLLDLRRRULLUUDLDURUUUDLULULRUDDLLDLDLRLDDUDURDRLLRRLRRDDUDRRRURDLRLUUURDULDLURULUDULRRLDUDLDDDUUDRDUULLDDRLRLLRLLLLURDDRURLDDULLULURLRDUDRDDURLLLUDLLLLLUDRDRDLURRDLUDDLDLLDDLUDRRDDLULRUURDRULDDDLLRLDRULURLRURRDDDRLUUDUDRLRRUDDLRDLDULULDDUDURRRURULRDDDUUDULLULDDRDUDRRDRDRDLRRDURURRRRURULLLRRLR
5+
URLULLLDRDDULRRLRLUULDRUUULDRRLLDDDLDUULLDRLULRRDRRDDDRRDLRRLLDDRDULLRRLLUDUDDLDRDRLRDLRDRDDUUDRLLRLULLULRDRDDLDDDRLURRLRRDLUDLDDDLRDLDLLULDDRRDRRRULRUUDUULDLRRURRLLDRDRRDDDURUDRURLUDDDDDDLLRLURULURUURDDUDRLDRDRLUUUULURRRRDRDULRDDDDRDLLULRURLLRDULLUUDULULLLLRDRLLRRRLLRUDUUUULDDRULUDDDRRRULUDURRLLDURRDULUDRUDDRUURURURLRDULURDDDLURRDLDDLRUDUUDULLURURDLDURRDRDDDLRRDLLULUDDDRDLDRDRRDRURRDUDRUURLRDDUUDLURRLDRRDLUDRDLURUDLLRRDUURDUDLUDRRL

2016/day2/keypad.erl

+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
% Keypad Server
2+
3+
-module(keypad).
4+
-behavior(gen_server).
5+
-export([start_link/1,stop/1,move/2,getkey/1]).
6+
-export([init/1,handle_call/3,handle_cast/2,handle_info/2,terminate/2,code_change/3]).
7+
8+
start_link(Mode) -> gen_server:start_link(?MODULE, [Mode], []).
9+
10+
%% Calls
11+
move(Pid, Direction) -> gen_server:cast(Pid, {move, Direction}).
12+
stop(Pid) -> gen_server:call(Pid, stop).
13+
getkey(Pid) -> gen_server:call(Pid, getkey).
14+
15+
%%% Server Functions
16+
init([Mode]) -> {ok, {5, Mode}}.
17+
18+
handle_call(getkey, _From, {Pos, Mode}) -> {reply, Pos, {Pos, Mode}};
19+
handle_call(stop, _From, {Pos, Mode}) -> {stop, normal, ok, {Pos, Mode}};
20+
handle_call(Msg, _From, State) -> io:format("Unknown Message: ~p", [Msg]), {stop, unknown_message, State}.
21+
22+
handle_cast({move, Direction}, {Pos, Mode}) -> {noreply, {next_key(Mode, Pos, Direction), Mode}};
23+
handle_cast(Msg, State) -> io:format("Unknown Message: ~p", [Msg]), {stop, unknown_message, State}.
24+
25+
handle_info(Msg, State) -> io:format("Unknown Message: ~p", [Msg]), {stop, unknown_message, State}.
26+
27+
terminate(normal, _State) -> ok.
28+
29+
% We don't have any state migration.
30+
code_change(_OldVsn, State, _Extra) -> {ok, State}.
31+
32+
%%% Private
33+
34+
% Performs the move. A bit cheaty, but it's how I'd legit do it... lookup tables ftw. There's probably an algorithm but why waste the effort :)
35+
next_key(standard, 1, up) -> 1;
36+
next_key(standard, 1, right) -> 2;
37+
next_key(standard, 1, down) -> 4;
38+
next_key(standard, 1, left) -> 1;
39+
next_key(standard, 2, up) -> 2;
40+
next_key(standard, 2, right) -> 3;
41+
next_key(standard, 2, down) -> 5;
42+
next_key(standard, 2, left) -> 1;
43+
next_key(standard, 3, up) -> 3;
44+
next_key(standard, 3, right) -> 3;
45+
next_key(standard, 3, down) -> 6;
46+
next_key(standard, 3, left) -> 2;
47+
next_key(standard, 4, up) -> 1;
48+
next_key(standard, 4, right) -> 5;
49+
next_key(standard, 4, down) -> 7;
50+
next_key(standard, 4, left) -> 4;
51+
next_key(standard, 5, up) -> 2;
52+
next_key(standard, 5, right) -> 6;
53+
next_key(standard, 5, down) -> 8;
54+
next_key(standard, 5, left) -> 4;
55+
next_key(standard, 6, up) -> 3;
56+
next_key(standard, 6, right) -> 6;
57+
next_key(standard, 6, down) -> 9;
58+
next_key(standard, 6, left) -> 5;
59+
next_key(standard, 7, up) -> 4;
60+
next_key(standard, 7, right) -> 8;
61+
next_key(standard, 7, down) -> 7;
62+
next_key(standard, 7, left) -> 7;
63+
next_key(standard, 8, up) -> 5;
64+
next_key(standard, 8, right) -> 9;
65+
next_key(standard, 8, down) -> 8;
66+
next_key(standard, 8, left) -> 7;
67+
next_key(standard, 9, up) -> 6;
68+
next_key(standard, 9, right) -> 9;
69+
next_key(standard, 9, down) -> 9;
70+
next_key(standard, 9, left) -> 8;
71+
72+
next_key(weird, 1, up) -> 1;
73+
next_key(weird, 1, right) -> 1;
74+
next_key(weird, 1, down) -> 3;
75+
next_key(weird, 1, left) -> 1;
76+
77+
next_key(weird, 2, up) -> 2;
78+
next_key(weird, 2, right) -> 3;
79+
next_key(weird, 2, down) -> 6;
80+
next_key(weird, 2, left) -> 2;
81+
82+
next_key(weird, 3, up) -> 1;
83+
next_key(weird, 3, right) -> 4;
84+
next_key(weird, 3, down) -> 7;
85+
next_key(weird, 3, left) -> 2;
86+
87+
next_key(weird, 4, up) -> 4;
88+
next_key(weird, 4, right) -> 4;
89+
next_key(weird, 4, down) -> 8;
90+
next_key(weird, 4, left) -> 3;
91+
92+
next_key(weird, 5, up) -> 5;
93+
next_key(weird, 5, right) -> 6;
94+
next_key(weird, 5, down) -> 5;
95+
next_key(weird, 5, left) -> 5;
96+
97+
next_key(weird, 6, up) -> 2;
98+
next_key(weird, 6, right) -> 7;
99+
next_key(weird, 6, down) -> a;
100+
next_key(weird, 6, left) -> 5;
101+
102+
next_key(weird, 7, up) -> 3;
103+
next_key(weird, 7, right) -> 8;
104+
next_key(weird, 7, down) -> b;
105+
next_key(weird, 7, left) -> 6;
106+
107+
next_key(weird, 8, up) -> 4;
108+
next_key(weird, 8, right) -> 9;
109+
next_key(weird, 8, down) -> c;
110+
next_key(weird, 8, left) -> 7;
111+
112+
next_key(weird, 9, up) -> 9;
113+
next_key(weird, 9, right) -> 9;
114+
next_key(weird, 9, down) -> 9;
115+
next_key(weird, 9, left) -> 8;
116+
117+
next_key(weird, a, up) -> 6;
118+
next_key(weird, a, right) -> b;
119+
next_key(weird, a, down) -> a;
120+
next_key(weird, a, left) -> a;
121+
122+
next_key(weird, b, up) -> 7;
123+
next_key(weird, b, right) -> c;
124+
next_key(weird, b, down) -> d;
125+
next_key(weird, b, left) -> a;
126+
127+
next_key(weird, c, up) -> 8;
128+
next_key(weird, c, right) -> c;
129+
next_key(weird, c, down) -> c;
130+
next_key(weird, c, left) -> b;
131+
132+
next_key(weird, d, up) -> b;
133+
next_key(weird, d, right) -> d;
134+
next_key(weird, d, down) -> d;
135+
next_key(weird, d, left) -> d.

0 commit comments

Comments
 (0)