<br><br><div class="gmail_quote">On Tue, Jul 8, 2008 at 3:47 AM, Richard A. O'Keefe <<a href="mailto:ok@cs.otago.ac.nz">ok@cs.otago.ac.nz</a>> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
An answer to the puzzle _could_ be something as simple as<br>
<br>
        io:format("VIER = 6241, NEUN = 9409\n")</blockquote><div> </div><div>> 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.<br>
Neun: 9409, Vier: 6241<br>ok<br><br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><br>
*Some* amount of human judgement will be needed to convert<br>
the problem specification to executable code.  For example,<br>
one way to find candidates is to enumerate integers in a<br>
certain range, square them, and check whether the squares<br>
have a suitable digit pattern.  But what range of integers?<br>
Looking at it, _we_ see that the range need not be any more<br>
than 32..99, but given that, the rest is pretty much<br>
trivial.  (sqrt(VIER) = 79, sqrt(NEUN) = 97, which is quite<br>
pretty.)  You can get a short list for NEUN thus:<br>
<br>
neun_candidates() -><br>
     [{N,E,U,NEUN} ||<br>
        X <- lists:seq(32, 99),<br>
        NEUN <- [X*X],<br>
        [N,E,U,N] <- [integer_to_list(NEUN)],<br>
        N /= E, N /= U, E /= U].<br>
which returns the list<br>
[{$1,$5,$2,1521}, {$1,$6,$8,1681}, {$4,$6,$2,4624},<br>
  {$5,$6,$2,5625}, {$9,$4,$0,9409}].<br>
The code for vier_candidates() is similar.<br>
Pasting them together is just<br>
<br>
vier_neun_candidates() -><br>
    A = vier_candidates(),<br>
    B = neun_candidates(),<br>
    [{VIER,NEUN} ||<br>
        {V,I,E,R,VIER} <- A,<br>
        {N,E,U,  NUEN} <- B,<br>
        % some testing goes here<br>
        ].<br>
<br>
Then it's simply a matter of checking the last condition<br>
<br>
answer() -><br>
     C <- vier_neun_candidates(),<br>
     [{VIER,NEUN} ||<br>
         {VIER,NEUN} <- C,<br>
         X <- [[OOPS || {VIER,OOPS} <- C, OOPS /= NEUN]],<br>
         X == [],<br>
         Y <- [[JUNK || {JUNK,NEUN} <- C, JUNK /= VIER]],<br>
        Y == []].<br>
<br>
Finishing the details left for anyone interested.<br>
One comment I _will_ make is that there is a rather pointless<br>
restriction in Erlang syntax: the generator of a list<br>
comprehension *may* include "X <- [expr]" but may *not*<br>
include "X = expr", which means exactly the same thing.<br>
<br>
neun_candidates() -><br>
     [{N,E,U,NEUN} ||<br>
        X <- lists:seq(32, 99),<br>
        NEUN = X*X,<br>
        [N,E,U,N] = integer_to_list(NEUN),<br>
        N /= E, N /= U, E /= U].<br>
<br>
would have been much clearer.<br>
<br>
More precisely, Erlang *does* allow these expressions<br>
BUT WITH THE WRONG MEANING!  A qualifier that is<br>
        <pattern> = <expression><br>
should SUCCEED or FAIL, and if it succeeds, the<br>
value it returns is quite irrelevant and should by NO<br>
means be restricted to 'true' or 'false'.<br>
<br>
Another way to hack around this is to rewrite<br>
        Pat = Expr<br>
as      (Pat = Expr, true)<br>
but that has the wrong semantics too, because when<br>
the value of Expr doesn't match Pat, we simply want<br>
that iteration of the list comprehension to fail,<br>
not to produce an exception in the whole thing.<br>
<br>
What could break if this part of Erlang syntax were fixed?<br>
Let us suppose that nobody writes list comprehensions<br>
containing<br>
        Nonvar = Expr<br>
because they could and should be rewritten to use == or<br>
=:=.  Would<br>
        _ = Expr<br>
make sense?  No, because it would be equivalent to<br>
        Expr.<br>
Would<br>
        X = Expr<br>
make sense?  No, because it would be equivalent to<br>
        Expr, X = true<br>
and what would be the point of that?<br>
<br>
It really is past time that something was done about this.<br>
If the current badly broken semantics cannot be changed,<br>
then at least a compile-time warning for any list<br>
comprehension containing Pat = Expr that it is almost<br>
certainly incorrect would be helpful.<br>
<div><div></div><div class="Wj3C7c"><br>
<br>
<br>
<br>
<br>
_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
<a href="http://www.erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://www.erlang.org/mailman/listinfo/erlang-questions</a><br>
</div></div></blockquote></div><br><br clear="all"><br>-- <br>--Hynek (Pichi) Vychodil