Sunday puzzle - trying to improve my Erlang

View: New views
12 Messages — Rating Filter:   Alert me  

Sunday puzzle - trying to improve my Erlang

by Toby Thain-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi list,

I stumbled on this simple 'puzzle'[0] posted some years ago on  
comp.lang.tcl (originally to an Icon mailing list).

After solving it in Icon[1] and SQL[2] I decided to see what an  
Erlang solution would look like. I'm posting here firstly because  
other people's solutions would be interesting, and also I'd like to  
see how my own solution[3] could be improved.

Any takers over the weekend? :-)

--Toby

[0] http://groups.google.com/group/comp.lang.tcl/msg/8846d9f7491ba0ba
[1] http://telegraphics.com.au/svn/puzzles/trunk/vier-neun/vn.icn
[2] http://telegraphics.com.au/svn/puzzles/trunk/vier-neun/Makefile
[3] http://telegraphics.com.au/svn/puzzles/trunk/vier-neun/erlang/

_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: Sunday puzzle - trying to improve my Erlang

by Richard Carlsson-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Toby Thain wrote:

> Hi list,
>
> I stumbled on this simple 'puzzle'[0] posted some years ago on  
> comp.lang.tcl (originally to an Icon mailing list).
>
> After solving it in Icon[1] and SQL[2] I decided to see what an  
> Erlang solution would look like. I'm posting here firstly because  
> other people's solutions would be interesting, and also I'd like to  
> see how my own solution[3] could be improved.
>
> Any takers over the weekend? :-)
>
> --Toby
>
> [0] http://groups.google.com/group/comp.lang.tcl/msg/8846d9f7491ba0ba
> [1] http://telegraphics.com.au/svn/puzzles/trunk/vier-neun/vn.icn
> [2] http://telegraphics.com.au/svn/puzzles/trunk/vier-neun/Makefile
> [3] http://telegraphics.com.au/svn/puzzles/trunk/vier-neun/erlang/
Here's my version. Note that it's often better to think in terms of
stages of list processing (mapreduce etc.), instead of inserting and
looking up in dictionaries. I tag each generated pair with the E
element, just to make the list easier to work with later.

     /Richard

%% File: solve.erl
%% @author Richard Carlsson

-module(solve).
-export([it/0]).

%% Problem: VIER and NEUN are 4-digit squares; determine distinct V, I,
%% E, R, N, and U, such that there is a unique solution (VIER,NEUN) for
%% some particular E.

it() ->
    Qs = [integer_to_list(S) || S <- [X*X || X <- lists:seq(32,99)]],
    Ps = [{E,{Vr,Nn}} || [N,E,_U,N]=Nn <- Qs, [_V,_I,E1,_R]=Vr <- Qs,
                         E =:= E1,
                         length(ordsets:from_list(Nn++Vr)) =:= 6],
    D = lists:foldl(fun ({E,_}, D) -> dict:update_counter(E,1,D) end,
                    dict:new(), Ps),
    [P || {E,1} <- dict:to_list(D), {E1,P} <- Ps, E=:=E1].

_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: Sunday puzzle - trying to improve my Erlang

by Toby Thain-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On 6-Jul-08, at 9:17 AM, Richard Carlsson wrote:

> Toby Thain wrote:
>> Hi list,
>> I stumbled on this simple 'puzzle'[0] ...
>> [0] http://groups.google.com/group/comp.lang.tcl/msg/8846d9f7491ba0ba
...
> %% File: solve.erl
> %% @author Richard Carlsson

Wonderful, that's just the kind of brain-melting variation I was  
after. Those who can't get enough of this puzzle, there's another  
thread about it:

http://groups.google.ca/group/comp.lang.apl/browse_thread/thread/ 
8a1abe807d1eda3c/
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: Sunday puzzle - trying to improve my Erlang

by Edwin Fine :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Richard,

Lovely solution! It's stuff like this that helps newcomers to Erlang like myself to learn how to write better Erlang.

I'm curious, though; what is the reason for writing

Qs = [integer_to_list(S) || S <- [X*X || X <- lists:seq(32,99)]]

instead of

Qs = [integer_to_list(X*X) || X <- lists:seq(32,99)]

?

2008/7/6 Richard Carlsson <richardc@...>:
Toby Thain wrote:
Hi list,

I stumbled on this simple 'puzzle'[0] posted some years ago on  comp.lang.tcl (originally to an Icon mailing list).

After solving it in Icon[1] and SQL[2] I decided to see what an  Erlang solution would look like. I'm posting here firstly because  other people's solutions would be interesting, and also I'd like to  see how my own solution[3] could be improved.

Any takers over the weekend? :-)

--Toby

[0] http://groups.google.com/group/comp.lang.tcl/msg/8846d9f7491ba0ba
[1] http://telegraphics.com.au/svn/puzzles/trunk/vier-neun/vn.icn
[2] http://telegraphics.com.au/svn/puzzles/trunk/vier-neun/Makefile
[3] http://telegraphics.com.au/svn/puzzles/trunk/vier-neun/erlang/

Here's my version. Note that it's often better to think in terms of
stages of list processing (mapreduce etc.), instead of inserting and
looking up in dictionaries. I tag each generated pair with the E
element, just to make the list easier to work with later.

   /Richard

%% File: solve.erl
%% @author Richard Carlsson

-module(solve).
-export([it/0]).

%% Problem: VIER and NEUN are 4-digit squares; determine distinct V, I,
%% E, R, N, and U, such that there is a unique solution (VIER,NEUN) for
%% some particular E.

it() ->
   Qs = [integer_to_list(S) || S <- [X*X || X <- lists:seq(32,99)]],
   Ps = [{E,{Vr,Nn}} || [N,E,_U,N]=Nn <- Qs, [_V,_I,E1,_R]=Vr <- Qs,
                        E =:= E1,
                        length(ordsets:from_list(Nn++Vr)) =:= 6],
   D = lists:foldl(fun ({E,_}, D) -> dict:update_counter(E,1,D) end,
                   dict:new(), Ps),
   [P || {E,1} <- dict:to_list(D), {E1,P} <- Ps, E=:=E1].

_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions



--
The great enemy of the truth is very often not the lie -- deliberate, contrived and dishonest, but the myth, persistent, persuasive, and unrealistic. Belief in myths allows the comfort of opinion without the discomfort of thought.
John F. Kennedy 35th president of US 1961-1963 (1917 - 1963)
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: Sunday puzzle - trying to improve my Erlang

by Richard Carlsson-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Edwin Fine wrote:

> Richard,
>
> Lovely solution! It's stuff like this that helps newcomers to Erlang
> like myself to learn how to write better Erlang.
>
> I'm curious, though; what is the reason for writing
>
> Qs = [integer_to_list(S) || S <- [X*X || X <- lists:seq(32,99)]]
>
> instead of
>
> Qs = [integer_to_list(X*X) || X <- lists:seq(32,99)]
None whatsoever. The person responsible should be keelhauled.
Oh, right... Sorry.

It's just a remnant of a refactoring. I started out working on
lists on the form [S div 1000, ..., S rem 10], but realized that
I could just use the lists of character codes instead. But I
didn't tidy up after changing to integer_to_list(S). Improved
version attached.

     /Richard

%% File: solve.erl
%% @author Richard Carlsson

-module(solve).
-export([it/0]).

%% Problem: VIER and NEUN are 4-digit squares; determine distinct V, I,
%% E, R, N, and U, such that (given the choice of E) there exists a
%% unique solution (VIER,NEUN).

it() ->
    Qs = [integer_to_list(X*X) || X <- lists:seq(32,99)],
    Ps = [{E,{Vr,Nn}} || [N,E,_U,N]=Nn <- Qs, [_V,_I,E1,_R]=Vr <- Qs,
                         E =:= E1,
                         length(ordsets:from_list(Nn++Vr)) =:= 6],
    D = lists:foldl(fun ({E,_}, D) -> dict:update_counter(E,1,D) end,
                    dict:new(), Ps),
    [P || {E,1} <- dict:to_list(D), {E1,P} <- Ps, E=:=E1].

_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: Sunday puzzle - trying to improve my Erlang

by Matthias Lang :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Saturday, July 05, Toby Thain wrote:

> I stumbled on this simple 'puzzle'[0] posted some years ago on  
> comp.lang.tcl (originally to an Icon mailing list).

After reading the description four times, I still wasn't completely
sure what 'uniquely determines' means, but ploughed ahead, assuming
it'd become obvious when I saw the solutions, which it did.

I wrote the solution below before looking at the other solutions, but
was coward enough to peek at Richard's much shorter one before posting.
The obvious advantage of my solution is that I understand it ;-)

Matt

--------------------

-module(sq).
-export([go/0]).

go() ->
    All = all_answers(),
    Unique_viers = [ Vier || {Vier, _} <- All,
                             length([X || {X, _} <- All, X == Vier]) == 1],
    Unique_neuns = [ Neun || {_, Neun} <- All,
                             length([X || {_, X} <- All, X == Neun]) == 1],
    [ {Vier, Neun} || {Vier, Neun} <- All,
                      lists:member(Vier, Unique_viers),
                      lists:member(Neun, Unique_neuns)].

all_answers() ->
    [ {{V,I,E1,R}, {N,E2,U,N}} ||
        {V,I,E1,R} <- possible_viers(),
        {N,E2,U,N} <- possible_neuns(),
        E1 == E2, all_unique([V,I,R,N,U])].

square_digits() ->
    Squares = [ X * X || X <- lists:seq(30, 100)],
    [ {X div 1000, (X div 100) rem 10, (X div 10) rem 10, X rem 10} || X <- Squares].

possible_neuns() ->
    [ X || X = {N,E,U,N} <- square_digits(), all_unique([N,E,U])].

possible_viers() ->
    [ X || X = {V,I,E,R} <- square_digits(), all_unique([V,I,E,R])].

all_unique([]) -> true;
all_unique([H|T]) -> not lists:member(H, T) andalso all_unique(T).
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: Sunday puzzle - trying to improve my Erlang

by Toby Thain-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On 6-Jul-08, at 7:25 PM, Matthias Lang wrote:

> On Saturday, July 05, Toby Thain wrote:
>
>> I stumbled on this simple 'puzzle'[0] posted some years ago on
>> comp.lang.tcl (originally to an Icon mailing list).
>
> After reading the description four times, I still wasn't completely
> sure what 'uniquely determines' means, but ploughed ahead, assuming
> it'd become obvious when I saw the solutions, which it did.

I didn't find the wording very clear either :) Tried to reword it but  
abandoned the effort. I notice Richard restated it in comments.

--Toby
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: Sunday puzzle - trying to improve my Erlang

by Edwin Fine :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message



On Sun, Jul 6, 2008 at 5:39 PM, Richard Carlsson <richardc@...> wrote:
Edwin Fine wrote:
Richard,

Lovely solution! It's stuff like this that helps newcomers to Erlang like myself to learn how to write better Erlang.

I'm curious, though; what is the reason for writing

Qs = [integer_to_list(S) || S <- [X*X || X <- lists:seq(32,99)]]

instead of

Qs = [integer_to_list(X*X) || X <- lists:seq(32,99)]

None whatsoever. The person responsible should be keelhauled.
Oh, right... Sorry.

It's just a remnant of a refactoring. I started out working on
lists on the form [S div 1000, ..., S rem 10], but realized that
I could just use the lists of character codes instead. But I
didn't tidy up after changing to integer_to_list(S). Improved
version attached.
 
Oh, thank goodness!!  I thought it was some expert optimization or technique that I just couldn't understand :)


   /Richard

%% File: solve.erl
%% @author Richard Carlsson

-module(solve).
-export([it/0]).

%% Problem: VIER and NEUN are 4-digit squares; determine distinct V, I,
%% E, R, N, and U, such that (given the choice of E) there exists a
%% unique solution (VIER,NEUN).

it() ->
   Qs = [integer_to_list(X*X) || X <- lists:seq(32,99)],
   Ps = [{E,{Vr,Nn}} || [N,E,_U,N]=Nn <- Qs, [_V,_I,E1,_R]=Vr <- Qs,
                        E =:= E1,
                        length(ordsets:from_list(Nn++Vr)) =:= 6],
   D = lists:foldl(fun ({E,_}, D) -> dict:update_counter(E,1,D) end,
                   dict:new(), Ps),
   [P || {E,1} <- dict:to_list(D), {E1,P} <- Ps, E=:=E1].




--
The great enemy of the truth is very often not the lie -- deliberate, contrived and dishonest, but the myth, persistent, persuasive, and unrealistic. Belief in myths allows the comfort of opinion without the discomfort of thought.
John F. Kennedy 35th president of US 1961-1963 (1917 - 1963)
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: Sunday puzzle - trying to improve my Erlang

by Richard Carlsson-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Toby Thain wrote:
> On 6-Jul-08, at 7:25 PM, Matthias Lang wrote:
>> After reading the description four times, I still wasn't completely
>> sure what 'uniquely determines' means, but ploughed ahead, assuming
>> it'd become obvious when I saw the solutions, which it did.
>
> I didn't find the wording very clear either :) Tried to reword it but  
> abandoned the effort. I notice Richard restated it in comments.

I also found that the greatest snag was understanding the exact
specification of the problem. I eventually had to peek at the Icon
solution to see what it was generating.

     /Richard
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: Sunday puzzle - trying to improve my Erlang

by Richard O'Keefe :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

An answer to the puzzle _could_ be something as simple as

        io:format("VIER = 6241, NEUN = 9409\n")

*Some* amount of human judgement will be needed to convert
the problem specification to executable code.  For example,
one way to find candidates is to enumerate integers in a
certain range, square them, and check whether the squares
have a suitable digit pattern.  But what range of integers?
Looking at it, _we_ see that the range need not be any more
than 32..99, but given that, the rest is pretty much
trivial.  (sqrt(VIER) = 79, sqrt(NEUN) = 97, which is quite
pretty.)  You can get a short list for NEUN thus:

neun_candidates() ->
     [{N,E,U,NEUN} ||
        X <- lists:seq(32, 99),
        NEUN <- [X*X],
        [N,E,U,N] <- [integer_to_list(NEUN)],
        N /= E, N /= U, E /= U].
which returns the list
[{$1,$5,$2,1521}, {$1,$6,$8,1681}, {$4,$6,$2,4624},
  {$5,$6,$2,5625}, {$9,$4,$0,9409}].
The code for vier_candidates() is similar.
Pasting them together is just

vier_neun_candidates() ->
    A = vier_candidates(),
    B = neun_candidates(),
    [{VIER,NEUN} ||
        {V,I,E,R,VIER} <- A,
        {N,E,U,  NUEN} <- B,
        % some testing goes here
        ].

Then it's simply a matter of checking the last condition

answer() ->
     C <- vier_neun_candidates(),
     [{VIER,NEUN} ||
         {VIER,NEUN} <- C,
         X <- [[OOPS || {VIER,OOPS} <- C, OOPS /= NEUN]],
         X == [],
         Y <- [[JUNK || {JUNK,NEUN} <- C, JUNK /= VIER]],
        Y == []].

Finishing the details left for anyone interested.
One comment I _will_ make is that there is a rather pointless
restriction in Erlang syntax: the generator of a list
comprehension *may* include "X <- [expr]" but may *not*
include "X = expr", which means exactly the same thing.

neun_candidates() ->
     [{N,E,U,NEUN} ||
        X <- lists:seq(32, 99),
        NEUN = X*X,
        [N,E,U,N] = integer_to_list(NEUN),
        N /= E, N /= U, E /= U].

would have been much clearer.

More precisely, Erlang *does* allow these expressions
BUT WITH THE WRONG MEANING!  A qualifier that is
        <pattern> = <expression>
should SUCCEED or FAIL, and if it succeeds, the
value it returns is quite irrelevant and should by NO
means be restricted to 'true' or 'false'.

Another way to hack around this is to rewrite
        Pat = Expr
as (Pat = Expr, true)
but that has the wrong semantics too, because when
the value of Expr doesn't match Pat, we simply want
that iteration of the list comprehension to fail,
not to produce an exception in the whole thing.

What could break if this part of Erlang syntax were fixed?
Let us suppose that nobody writes list comprehensions
containing
        Nonvar = Expr
because they could and should be rewritten to use == or
=:=.  Would
        _ = Expr
make sense?  No, because it would be equivalent to
        Expr.
Would
        X = Expr
make sense?  No, because it would be equivalent to
        Expr, X = true
and what would be the point of that?

It really is past time that something was done about this.
If the current badly broken semantics cannot be changed,
then at least a compile-time warning for any list
comprehension containing Pat = Expr that it is almost
certainly incorrect would be helpful.





_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: Sunday puzzle - trying to improve my Erlang

by Hynek Vychodil :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message



On Tue, Jul 8, 2008 at 3:47 AM, Richard A. O'Keefe <ok@...> wrote:
An answer to the puzzle _could_ be something as simple as

       io:format("VIER = 6241, NEUN = 9409\n")

*Some* amount of human judgement will be needed to convert
the problem specification to executable code.  For example,
one way to find candidates is to enumerate integers in a
certain range, square them, and check whether the squares
have a suitable digit pattern.  But what range of integers?
Looking at it, _we_ see that the range need not be any more
than 32..99, but given that, the rest is pretty much
trivial.  (sqrt(VIER) = 79, sqrt(NEUN) = 97, which is quite
pretty.)  You can get a short list for NEUN thus:

neun_candidates() ->
    [{N,E,U,NEUN} ||
       X <- lists:seq(32, 99),
       NEUN <- [X*X],
       [N,E,U,N] <- [integer_to_list(NEUN)],
       N /= E, N /= U, E /= U].
which returns the list
[{$1,$5,$2,1521}, {$1,$6,$8,1681}, {$4,$6,$2,4624},
 {$5,$6,$2,5625}, {$9,$4,$0,9409}].
The code for vier_candidates() is similar.
Pasting them together is just

vier_neun_candidates() ->
   A = vier_candidates(),
   B = neun_candidates(),
   [{VIER,NEUN} ||
       {V,I,E,R,VIER} <- A,
       {N,E,U,  NUEN} <- B,
       % some testing goes here
       ].

Then it's simply a matter of checking the last condition

answer() ->
    C <- vier_neun_candidates(),
    [{VIER,NEUN} ||
        {VIER,NEUN} <- C,
        X <- [[OOPS || {VIER,OOPS} <- C, OOPS /= NEUN]],
        X == [],
        Y <- [[JUNK || {JUNK,NEUN} <- C, JUNK /= VIER]],
       Y == []].

Finishing the details left for anyone interested.
One comment I _will_ make is that there is a rather pointless
restriction in Erlang syntax: the generator of a list
comprehension *may* include "X <- [expr]" but may *not*
include "X = expr", which means exactly the same thing.

neun_candidates() ->
    [{N,E,U,NEUN} ||
       X <- lists:seq(32, 99),
       NEUN = X*X,
       [N,E,U,N] = integer_to_list(NEUN),
       N /= E, N /= U, E /= U].

  neun_candidates() ->
    [{N,E,U,NEUN} ||
       X <- lists:seq(32, 99),
       begin
          NEUN = X*X,
          [N,E,U,N1] = integer_to_list(NEUN),
          N =:= N1 andalso N /= E andalso N /= U andalso E /= U
      end].




would have been much clearer.

More precisely, Erlang *does* allow these expressions
BUT WITH THE WRONG MEANING!  A qualifier that is
       <pattern> = <expression>
should SUCCEED or FAIL, and if it succeeds, the
value it returns is quite irrelevant and should by NO
means be restricted to 'true' or 'false'.

Another way to hack around this is to rewrite
       Pat = Expr
as      (Pat = Expr, true)
but that has the wrong semantics too, because when
the value of Expr doesn't match Pat, we simply want
that iteration of the list comprehension to fail,
not to produce an exception in the whole thing.

What could break if this part of Erlang syntax were fixed?
Let us suppose that nobody writes list comprehensions
containing
       Nonvar = Expr
because they could and should be rewritten to use == or
=:=.  Would
       _ = Expr
make sense?  No, because it would be equivalent to
       Expr.
Would
       X = Expr
make sense?  No, because it would be equivalent to
       Expr, X = true
and what would be the point of that?

It really is past time that something was done about this.
If the current badly broken semantics cannot be changed,
then at least a compile-time warning for any list
comprehension containing Pat = Expr that it is almost
certainly incorrect would be helpful.





_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions



--
--Hynek (Pichi) Vychodil
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: Sunday puzzle - trying to improve my Erlang

by Hynek Vychodil :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message



On Tue, Jul 8, 2008 at 3:47 AM, Richard A. O'Keefe <ok@...> wrote:
An answer to the puzzle _could_ be something as simple as

       io:format("VIER = 6241, NEUN = 9409\n")
 
> begin Qs = [integer_to_list(S) || S <- [X*X || X <- lists:seq(32,99)]], Ps = [{E,{Vr,Nn}} || [N,E,_U,N]=Nn <- Qs, [_V,_I, E1, _R] = Vr <-Qs, E=:=E1, length(ordsets:from_list(Nn++Vr)) =:= 6], D = lists:foldl(fun ({E,_}, D) -> dict:update_counter(E,1,D) end, dict:new(), Ps), [{VIER, NEUN}] = [P || {E,1} <- dict:to_list(D), {E1,P} <- Ps, E=:=E1], io:format("Neun: ~s, Vier: ~s~n", [NEUN, VIER]) end.
Neun: 9409, Vier: 6241
ok


*Some* amount of human judgement will be needed to convert
the problem specification to executable code.  For example,
one way to find candidates is to enumerate integers in a
certain range, square them, and check whether the squares
have a suitable digit pattern.  But what range of integers?
Looking at it, _we_ see that the range need not be any more
than 32..99, but given that, the rest is pretty much
trivial.  (sqrt(VIER) = 79, sqrt(NEUN) = 97, which is quite
pretty.)  You can get a short list for NEUN thus:

neun_candidates() ->
    [{N,E,U,NEUN} ||
       X <- lists:seq(32, 99),
       NEUN <- [X*X],
       [N,E,U,N] <- [integer_to_list(NEUN)],
       N /= E, N /= U, E /= U].
which returns the list
[{$1,$5,$2,1521}, {$1,$6,$8,1681}, {$4,$6,$2,4624},
 {$5,$6,$2,5625}, {$9,$4,$0,9409}].
The code for vier_candidates() is similar.
Pasting them together is just

vier_neun_candidates() ->
   A = vier_candidates(),
   B = neun_candidates(),
   [{VIER,NEUN} ||
       {V,I,E,R,VIER} <- A,
       {N,E,U,  NUEN} <- B,
       % some testing goes here
       ].

Then it's simply a matter of checking the last condition

answer() ->
    C <- vier_neun_candidates(),
    [{VIER,NEUN} ||
        {VIER,NEUN} <- C,
        X <- [[OOPS || {VIER,OOPS} <- C, OOPS /= NEUN]],
        X == [],
        Y <- [[JUNK || {JUNK,NEUN} <- C, JUNK /= VIER]],
       Y == []].

Finishing the details left for anyone interested.
One comment I _will_ make is that there is a rather pointless
restriction in Erlang syntax: the generator of a list
comprehension *may* include "X <- [expr]" but may *not*
include "X = expr", which means exactly the same thing.

neun_candidates() ->
    [{N,E,U,NEUN} ||
       X <- lists:seq(32, 99),
       NEUN = X*X,
       [N,E,U,N] = integer_to_list(NEUN),
       N /= E, N /= U, E /= U].

would have been much clearer.

More precisely, Erlang *does* allow these expressions
BUT WITH THE WRONG MEANING!  A qualifier that is
       <pattern> = <expression>
should SUCCEED or FAIL, and if it succeeds, the
value it returns is quite irrelevant and should by NO
means be restricted to 'true' or 'false'.

Another way to hack around this is to rewrite
       Pat = Expr
as      (Pat = Expr, true)
but that has the wrong semantics too, because when
the value of Expr doesn't match Pat, we simply want
that iteration of the list comprehension to fail,
not to produce an exception in the whole thing.

What could break if this part of Erlang syntax were fixed?
Let us suppose that nobody writes list comprehensions
containing
       Nonvar = Expr
because they could and should be rewritten to use == or
=:=.  Would
       _ = Expr
make sense?  No, because it would be equivalent to
       Expr.
Would
       X = Expr
make sense?  No, because it would be equivalent to
       Expr, X = true
and what would be the point of that?

It really is past time that something was done about this.
If the current badly broken semantics cannot be changed,
then at least a compile-time warning for any list
comprehension containing Pat = Expr that it is almost
certainly incorrect would be helpful.





_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions



--
--Hynek (Pichi) Vychodil
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions
LightInTheBox - Buy quality products at wholesale price!