Robot Simulator -Erlang Track on Exercism

Hi,
I am following the Erlang Track on Exercism and I started to solve Robot Simulator.

I believe there is something wrong with their tests but I am not sure.
Could you take a look

The repo is here: erlang/exercises/practice/robot-simulator at main · exercism/erlang · GitHub

The first test is here. It seems to me that they are treating Robot as a variable whose content can be changed by robot_simulator:place/3. Do you think so? Am I missing something?

Regards,

Adolfo

4 Likes

Hello :slight_smile: Im a newb so this might be totally wrong, but the way I would do this is make robot a process, so create would spawn a process (or an actor). That actor can have its own state (as a record or something) and then the messages to it can create new versions of that state. This means you can have state, and it can change over time, but the functions in your robot process will be functionally pure, you wont actually be modifying the state.


% in robot as a gen_server
handle_call(advance, _From, S = #state{pos=P, dir=D}) ->
  NewPosition = handle_advance(P, D),
  {noreply, S#state{pos=NewPosition}}.  % here is a new state

handle_advance({X, Y}, north) -> {X, Y + 1 };
handle_advance({X, Y}, south) -> {X, Y - 1 };
...

Someone please jump in and batter me if this is wrong :smiley:

5 Likes

Without giving you too much information, @phsort is right.

Robot (the variable) is supposed to be a handle for a living Robot.

There is more than one way to implement that, but the typical one is to use a process for each robot and return its Pid on robot_simulator:create/0.

If you want to be more creative, you can try implementing the robot by storing its state in an ets table… But I would recommend you to try this approach only after you had learn how to solve the issue with processes :wink:

6 Likes

Hi :slight_smile:

Short answer: @phsort and @elbrujohalcon are right: you are supposed to do it with a process, be it a gen_server or gen_statem implementation or just a plain loop.

And @elbrujohalcon is also right that you could do it with an ets table (or the pdict even, if you want to get real dirty :face_with_raised_eyebrow:), but that is (IMO) really not the way it should be done. While Exercism has no requirements concerning how an exercise is to be solved, my advice is to not deliberately do things different than everybody else just for the sake of doing it different :wink:

That said, @adolfont, if you are stuck (or just want to cheat), there is always a reference/example solution in the exercises :wink: It is not always the best solution, mind you, it is just there to demonstrate that the exercise can be solved.

7 Likes

I had no clue about the example solutions :face_with_hand_over_mouth:

What…have…you…done!

5 Likes

I will admit to having uploaded a couple of non-working solutions to see how others have handled different problems when I’ve been completely stuck. And, of course, getting great advice on the Erlang Slack #learning channel.

5 Likes

That is correct :innocent: (Quite an addiction that was…)
I didn’t do Robot Simulator, though, that one was already there.

4 Likes

Just an update. As pointed out above, there was nothing wrong with the tests. If there is something wrong, it is that this exercise is intermediate for other languages but for Erlang, having to use gen_server, it is closer to hard. However it was very fun to solve and @elbrujohalcon (my mentor on Exercism) helped me a lot. Thanks!

5 Likes

Nice job! I also thought it was very tricky. It was a good learning experience to work through it.

3 Likes

Good job! “Have to” may be a bit of an exaggeration, I think this one is easier to solve without gen_servers using just ! and receive, but gen_servers are great and it’s a good thing if you already got to learn to use them.

gen_server is not necessarily the optimal way to solve all problems involving message passing though. It’s out of scope for the exercise, but consider for example if two robots could co-exist using your solution.

4 Likes