Nested for-loops, there has to be a better way to do this

Yves S. Garret yoursurrogategod@REDACTED
Mon Aug 3 03:19:15 CEST 2009


Not quite.

For your input, this should be your output:
[4, 2, 1, 1, 1, 1, 1, 3, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2,
1, 1, 1, 1, 1]



On Jul 31, 9:34 am, Joe Armstrong <erl...@REDACTED> wrote:
> I still don't understand. Erlang (or any functional programming languages)
> is made from lots of small functions. Each function has inputs and outputs
> and there is some relationship between the inputs and the output.
>
> To specify a function we must state what the inputs are, state what
> the outputs are and state what the relationship between the inputs and
> outputs are.
>
> The fact that you print something is irrelevant. You could just as
> well say that the
> output of a function is a list and that you then print the items in the list one
> at a time.
>
> I have tried to write a program that *exactly* follows your spec.
> Following the rules in your spec I conclude that if the input to your program
> is the list [4,2,1,1] then the output should be [4,2,1,5,4,3,2,1,1,3,2,1]
>
> Is this correct?
>
> Here's the program - read the comments to see how the code relates to the spec.
>
> -module(process).
>
> -compile(export_all).
>
> test() ->
>     process([4,2,1,5]).
>
> process(In) ->
>     Out = f(In),
>     [io:format("~p~n", [I]) || I <- Out].
>
> %% Now we have to write f
> %% The spec says this:
>
> %% Takes first int, processes it (in this case, prints it out),
> %% decrements it, takes the second int, processes it (prints it out),
> %% decrements it and on.  When it gets to the very last item, it
> %% processes it until there are none left.  Then goes to the one above
> %% it, processes it, decrements it... wash, rinse, repeat :) .
>
> %% What this mean ... lets' take it bit by bit.
>
> %% The first two lines say
> %% Takes first int, processes it (in this case, prints it out),
> %% decrements it, takes the second int, processes it (prints it out),
>
> %% What happens after the first int has been decremented?
> %% Now we have to "take the second int" wheres the first Int gone?
> %% It seems like it is pushed onto a stack, so we can deal with it later.
> %% The idea of a stack is reinforced by saying later "goes to the one above"
>
> %% So here's what I think the first two lines of the spec mean:
>
> f(L) -> process(L, [], []).
>
> process([Int|T], Stack, Print) ->
>     %% Takes first int, processes it (in this case, prints it out),
>     %% decrements it, takes the second int, processes it (prints it out),
>     process(T, [Int-1|Stack], [Int|Print]);
>
> %% Now we get to the next major bit of the spec
> %%  .. When it gets to the very last item, it
> %%  .. processes it until there are none left.  Then goes to the one above
> %% .. it, processes it, decrements it... wash, rinse, repeat :) .
>
> %% This is very confusing. The word "it" is referred to many times
> %% What is "it".
> %% "when it gets to the very last item, it process it until there are non left"
>
> %% But if it has got to the very last item there there is nothing to process
> %% because it is the last item.
>
> %% To resolve this we look at the next lines of the spec
> %% " When it gets to the very last item, it
> %%   processes it until there are none left.  Then goes to the one above
> %%   it, processes it, decrements it... wash, rinse, repeat :) .
>
> %% I think this means this:
> process([], [H|Rest], Print) when H > 0->
>     process([], [H-1|Rest], [H|Print]);
>
> %% All this talk of decrementing things makes me wonder
> %% how the iteration will stop I assume it's when
> %% "it" reaches zero which is why I added the guard above.
> %% Let's add a base case
>
> process([], [0|Rest], Print) ->
>     process([], Rest, Print);
>
> %% Finally when "it" is zero and "there is nothing above"
>
> process([], [], Print) ->
>     lists:reverse(Print).
>
> %% end
>
> Incidentally if you had given a test case
> i.e that for the input  [4,2,1,1] then the output should be
> [4,2,1,5,4,3,2,1,1,3,2,1]
>
> Then I would have immediately translated this into a unit test:
>
>    test() ->
>         [4,2,1,5,4,3,2,1,1,3,2,1] = f([4,2,1,1]).
>
> *before* writing the code
>
> Cheers
>
> /Joe
>
> On Fri, Jul 31, 2009 at 3:59 AM, Yves S.
>
>
>
>
>
> Garret<yoursurrogate...@REDACTED> wrote:
> > Takes first int, processes it (in this case, prints it out),
> > decrements it, takes the second int, processes it (prints it out),
> > decrements it and on.  When it gets to the very last item, it
> > processes it until there are none left.  Then goes to the one above
> > it, processes it, decrements it... wash, rinse, repeat :) .
>
> > In retrospect, I could have made this clearer.
>
> > On Jul 29, 2:35 am, Joe Armstrong <erl...@REDACTED> wrote:
> >> I don't understand what you want.
>
> >> If the input to your program is: [5,5,10]
> >> the output should be: X
>
> >> What is X?
>
> >> /Joe
>
> >> On Wed, Jul 29, 2009 at 4:55 AM, Yves S.
>
> >> Garret<yoursurrogate...@REDACTED> wrote:
> >> > I was playing around with the idea of implementing a nested for-loop
> >> > like construct (I will concede, they are evil, but at rare times,
> >> > necessary.)  In non-functional programming languages, they are trivial
> >> > to do.  However, this has proved to be one of those simple things that
> >> > are a pain in the neck for me.  The idea was to be able to pass in a
> >> > list [5, 5, 10] (for example) and go through it all like 3 dimensional
> >> > array.  The below illustration is far from elegant (it's almost 23:00
> >> > where I live and need to go to work tomorrow early, so no time to come
> >> > up with something more sane :) ), but is there as an inquisitive
> >> > exercise.  Now, in my opinion, this implementation sucks (first time
> >> > I've ever gave such a problem a shot in Erlang.)
>
> >> > Is there a better way to do this?  Anyone would like to demonstrate
> >> > it?
>
> >> > Note: I've tested this code with the lists [2, 4] and [2, 4, 5].
>
> >> > Compiled with:
> >> > Erlang (SMP,ASYNC_THREADS,HIPE) (BEAM) emulator version 5.6.5
>
> >> > My code:
> >> > ======================================
> >> > -module(loopWrapper).
>
> >> > -export([runLoop/1]).
>
> >> > runLoop(List) ->
> >> >  [FirstVal | RestList] = List,
> >> >  NextVal = FirstVal - 1,
> >> >  if (length(RestList) > 0) and (FirstVal > 0) ->
> >> >    io:format("~B~n~n", [FirstVal]),
> >> >    runLoop(RestList),
> >> >    io:format("~n~n"),
> >> >    runLoop([NextVal | RestList]);
> >> >  FirstVal > 0 ->
> >> >    io:format("~B", [FirstVal]),
> >> >    runLoop([NextVal]);
> >> >  true ->
> >> >    null
> >> >  end.
>
> >> > ________________________________________________________________
> >> > erlang-questions mailing list. Seehttp://www.erlang.org/faq.html
> >> > erlang-questions (at) erlang.org
>
> >> ________________________________________________________________
> >> erlang-questions mailing list. Seehttp://www.erlang.org/faq.html
> >> erlang-questions (at) erlang.org
>
> > ________________________________________________________________
> > erlang-questions mailing list. Seehttp://www.erlang.org/faq.html
> > erlang-questions (at) erlang.org
>
> ________________________________________________________________
> erlang-questions mailing list. Seehttp://www.erlang.org/faq.html
> erlang-questions (at) erlang.org


More information about the erlang-questions mailing list