Once I faced with such a task. You have a list of elements. Each element representsa relative pointer to another element. For example, +3 means, that you have to move to the 3 elements to the right from current, and -1 means, that you have to move 1 element to the left from current.

You start from the first element. You have to calculate the number of steps to get outfrom a list or say 'never' if it's impossible to get out.

And, you have to solve it with O(N) limitations for time and space(yeah, both!) and inErlang(of course. You're reading an artiсle about Erlang, aren't you?)

2. You have to bear in mind, that there are 3 border cases, when you're getting out, when you're getting into a forever cycle and when you're running into 0.(you can't move neither to the left nor to the right)

Here's the picture:

3. To deal with cycles you have to use 2 pointers - fast & slow. When fast == slow, there's a loop and you can't get out. But here's a caveat: you have to compareNOT current pointers(slow and fast), but you have to keep tracking positions in arrayand check if slow pointer points to the same position as the fast one does!

Once I had an interview into a big international & well known software company.Everything was rather good than bad, but at the end of my interview I asked an interviewer: "I know that I haven't done perfect. What can I do to impress you? Give me a task". And he gave.

Write the tac utility from scratch.I told him, that I could give him an algorithm, but would it be enough? He told that it wouldn't be enough. And that I had to a complete industrial-grade application. In Python or Bash. And that I have only 15 minutes for this. And the brute-force solution when you read all the file line-by-line, then reverse line list & print it - doesn't count, because it's inefficient(if file is big, for example).

I should suspect that something was wrong. I knew that it's possible to write less or more precise algorithm, but it's impossible to write a complete utility(in given 15 minutes).

I had to bare in mind, that I was interviewing for a dev-OPS position. And probably I should have explained him why the industrial-grade application couldn't be written in 15 minutes. And probably that was a solution.

But instead of this I started to code. I was doomed for fail :)

But I didn't give up. Of course I haven't passed the interview. But I solved this task after the interview. Eventually.

Algorithm. Read constant size chunks of file from end. Chunk by chunk. When current chunk have been read successfully - try to display all it's full lines in reverse order. And we have to attach the remainder from the previous read/display block to the end of the first string to be displayed of current read/display block. If we got an error during positioning/reading of some chunk - we just read from the beginning all that is left to be read & display it.

There are a lot of debug howtos for erlang. Sometimes they're not obvious. Even official.Maybe that's why many programmers say: "There is no good debugger for erlang. It's ugly. It's unusable. It's awkward. I won't use it."

I would argue. So I wrote this article to prove, that you can debug in Erlang.

Here's my own. It's for dummies :) Just do as it's written here and it will work. I promise.

And enter there a line number where you want place your breakpoint to: (in my case it's 38) A debugger will substitute the line number where are you at the moment. If the "Ok" button is not active, like here:

don't panic! Just press "space" then backspace/delete or just enter the line number manually. And the "Ok" button will become active:

It's a victory! You've just set up your first breakpoint in Erlang! Condratulations! (of course if you see the following):

7. You're on your way. It's left just to debug this evil program. To do this, return back to your erlang shell and call any function which is being exported by your module and which calls the code where your breakpoint is located. In my case I call "do/1" function:

2>tac:do("cat.txt").

If you done everything as I'd described, a debugger automatically would attach to the process which you interpreted first and then started from the shell:

This is kind a interview-task.The main idea is - to make a tree, we get a middle of an array as a node, then left subtree will be built from left array and right - from right. Recursively.It's body-recursive solution.

Both fifty & hundred series experiment showed, that the greater list length is,the less difference between standard lists:split & custom algorithm which saves O(n/2) time.For a 10-element list custom algorithm is faster more than 2 times, but for a million-element list this difference shrinks slightly.

Recently I had an interview. Kidding. I've been doing interviews a lot(in Ukraine). But I just started tasting them in EU/US.

Here's one of mine.

I = InterviewerM = Me

I: "We give you a task. You have to finish it as soon as possible, but there is no time limit. Also, there are restrictions in big-O which you have to bare them in mind. Also, there is a restriction - finish this task in plain Erlang."

M: "Okay."

I finished this task as soon as possible, the program was working & tested, fully documented in comments.

Everything would be ok, you'd thought, right, ha?NO!

I was waiting for results and thinking: "I'm so cool guy, really. I've done everything as they wanted".

And during that, skype beeped and recruiter told me: "Everything is OK, but they told, that your code is dirty". So, "the client isn't happy & blah-blah-blah".

M:(not at loud) "F*ck. Are you kidding me? There WAS NO SUCH A RESTRICTION AS CODE CLEANLINESS".

If there was such, I would spend some time to make it, heck, CLEAN. In that case, I would maximize these parameters together. So, it turned for me, like I saved time for task completion(the condition which had been explicitly given to me) and maximized my(PROFIT :) ), but, there was some condition which wasn't even GIVEN to me, and it completely knocked me out.

The point is:

1. For guys who hire. If you're so smart, please, specify ALL of your restrictions when you're giving a task to a candidate. Sometimes technical guys accept your task literally.

If you do so, a candidate considers you as a future colleague and a mr. good guy.If you don't, you'll be an asshole in candidate's(and probably in your future colleague's) eyes.

2. For candidates.

Don't be so stupid, like I was. Don't trust interviewer. Be paranoid. Do your best in all senses, and don't expect, that you'll be hired at a place where you're being interviewed.Only statistics. The more you try, the greater you chance is.

The goal is: make a nested list flatten using tail recursion. To achieve this goal, you have to shift your mind a bit: you can remake/change not only accumulator, but several params simultanеously. In any way: not only cut, but construct also!

fl_tr(L) whenis_list(L)-> fl_tr(L, []). %helper wrapperfl_tr([], R) ->lists:reverse(R); %final clause/terminal conditionfl_tr([[]|T], R) -> fl_tr(T, R); %the first element is an empty list, just skip itfl_tr([[H|T1]|T2], R) -> fl_tr([H|[T1|T2]], R); %the first element is a non-empty list(first clause rip off empty ones),%move its head to the outer list head(for further processing),%and move its tail to the head of general tailfl_tr([H|T], R) -> fl_tr(T, [H|R]). %the first element is just an element - add to result(gotcha!)