Skip to content

Instantly share code, notes, and snippets.

@zkessin
Last active February 14, 2019 15:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save zkessin/cecb73cc9a14db96b4da611ba0f2c341 to your computer and use it in GitHub Desktop.
Save zkessin/cecb73cc9a14db96b4da611ba0f2c341 to your computer and use it in GitHub Desktop.
Charlie on the MTA in Elixir
-module(loop).
% If you are not from greater Boston watch this video of the Song "Charlie on the MTA" by the Kingston Trio
% And this will make more sense https://www.youtube.com/watch?v=MbtkL5_f6-4
-export([charlie/1, init/0, run/0]).
-type line() :: 'red'|'green_e'|'blue'|'orange'.
-type station() :: 'kendal'|'charles/mgh'|'park_st'|'government_center'|'heath'.
-type events() :: {'board', station(), line(), 10} |
{'change', 'red','green_e', 'park_st'} |
{'travel', station(), station()} |
{'exit', station(), 5} |
{'sandwich', station()}.
-record(state, {
station :: station(),
money :: integer(),
line :: line()
}).
-spec(charlie(#state{}) -> no_return()).
charlie(State = #state{money = Money, station = none}) ->
io:format("Charlie ~p~n", [State]),
receive
{board, Station, Line, Fare}->
charlie(#state{station = Station,
money = Money - Fare,
line = Line}
)
end;
charlie(State = #state{station = Station, line = Line, money = Money}) ->
io:format("Charlie ~p~n", [State]),
receive
{travel, Station, NewStation} ->
charlie(State#state{station = NewStation});
{change, Line, NewLine, Station} ->
charlie(State#state{line = NewLine});
{sandwich , Station} ->
charlie(State);
{exit, Station, Fare} when Money - Fare > 0 ->
charlie(State#state{station=none, line=none})
end.
init() ->
charlie(#state{station = none,
money = 10,
line = none
}).
run() ->
Pid = spawn(?MODULE, init, []),
Events = [{'board', 'kendal','red', 10},
{'travel', 'kendal','charles/mgh'},
{'travel', 'charles/mgh', 'park_st'},
{'change', 'red','green_e', 'park_st'},
{'travel', 'park_st', 'heath'},
{'exit', 'heath', 5},
{'travel', 'heath', 'government_center'},
{'sandwich', 'government_center'}],
[Pid ! Event || Event <- Events],
Pid.
defmodule Loop do
# If you are not from greater Boston watch this video of the Song "Charlie on the MTA" by the Kingston Trio
# And this will make more sense https://www.youtube.com/watch?v=MbtkL5_f6-4
defstruct station: :none, money: 0, line: :none
@type line() :: :red | :green_e | :blue | :orange
@type station() :: :kendal | :"charles/mgh" | :park_st | :government_center | :heath
@type event() ::
{:board, station(), line(), 10}
| {:change, :red, :green_e, :park_st}
| {:travel, station(), station()}
| {:exit, station(), 5}
| {:sandwich, station()}
@spec loop(%Loop{}) :: no_return()
def loop(state = %Loop{money: money, station: :none, line: :none}) do
IO.puts("State #{inspect(state)}")
receive do
{:board, station, line, fare} ->
loop(%Loop{state | money: money - fare, station: station, line: line})
end
end
def loop(state = %Loop{station: station, money: money, line: line}) do
IO.puts("State #{inspect(state)}")
receive do
{:travel, ^station, newstation} ->
loop(%Loop{state | station: newstation})
{:change, ^line, newline, ^station} ->
loop(%Loop{state | line: newline})
{:sandwhich, ^station} ->
loop(state)
{:exit, ^station, fare} when money - fare > 0 ->
loop(%Loop{state | station: :none, line: :none})
end
end
def init() do
loop(%Loop{station: :none, money: 10, line: :none})
end
@spec run() :: pid()
def run() do
pid = spawn(Loop, :init, [])
events = [
{:board, :kendal, :red, 10},
{:travel, :kendal, :"charles/mgh"},
{:travel, :"charles/mgh", :park_st},
{:change, :red, :green_e, :park_st},
{:travel, :park_st, :heath},
{:exit, :heath, 5},
{:travel, :heath, :government_center},
{:sandwich, :government_center}
]
for evt <- events, do: send(pid, evt)
pid
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment