Joe Riel

9660 Reputation

23 Badges

20 years, 6 days

MaplePrimes Activity


These are answers submitted by Joe Riel

There are several problems with this

  1. L is reassigned to an empty array in place
  2. L is local to queens, so even if the above were corrected there is an issue.
  3. The inner while loop in queens should negate the result of place.

Here is a modified version.  I made L a parameter to place.

place := proc(k,L)
local i;
    for i to k-1 do
        if L(i)=L(k) # two in the same column
        or abs(L(i)-L(k)) = abs(i-k) # in the same diagonal
        then
            return false;
        fi:
    end do;
    return true;
end proc:

queens := proc(n)
local k,L;
    L := Array(1..n);
    k := 1; # k is the current row
    while k > 0 do
        L(k) := L(k)+1; # move to the next column
        while L(k) <= n and not place(k,L) do # can this queen be placed
            L(k) := L(k) + 1;
        end do;
        if L(k)<=n # a position is found
        then if k = n # the solution has been found
             then print(L);
             else
                 k := k+1;
                 L(k) := 0;
             fi:
        else
            k := k-1; # backtrack
        end if;
    end do;
    return NULL;
end proc:

Why not use ?ListTools:-MakeUnique, as John suggested?  Of course, learning to roll your own solution is a useful exercise.  Here's an interesting approach described by Roman Pearce.

Once you have created the procedure f, as Georgios described, you can plot it with

plot(f, 0..1);

where the 0..1 specifies the domain over which to evaluate f.

An alternative is to forego creating a procedure and instead use an expression.  In that case you have to tell Maple what variable to vary:

ex := x^2+1:
plot(ex, x = 0..1);

It's not the only way, but it is probably the simplest. An alternative, which can be useful in some situations, is to use the `[]` procedure:

`[]`(a,b,c);
                         [a,b,c]

 

Maybe this will help:

plots[odeplot](sol1, [z, denom(rhs(eqn3))], 0 .. 1);

It might be more natural to swap the polarity, but here is a routine you can use to rotate left/right.

Rotate := proc(L, i::integer) 
local k;
    k := modp(i,nops(L)); 
   [L[k+1..][], L[..k][]]; 
end proc:
L := [1,2,3,4,5]:
Rotate(L, 2);
                                [3, 4, 5, 1, 2]
Rotate(L, -2);
                                [4, 5, 1, 2, 3]



That helps, but I'm still not sure I understand.  That is, if E is an nxn matrix, why are you accessing it with one index (E[i])?

I'm going to assume that E is actually a list.  Here are two implementation, which may or may not do what you want.  The first is a straightforward implementation of your original idea (as I understand it), but using seqs.  The algorithm is not particularly efficient.  The second procedure uses a method I described here to first create a permutation list that is used to sort the list.  That permits looking at adjacent values to find the minimum, which significantly improves the speed.  After computing the values, it applies the inverse permutation to return the final list in the desired order.

slow := proc(E :: list)
local i,j,n;
    n := nops(E);
    [seq(min(seq(abs(E[i]-E[j]),j=1..i-1),
             seq(abs(E[i]-E[j]),j=i+i..n)
            )
         , i = 1..n)
    ];
end proc:

fast := proc(E :: list(numeric))
local i, n, P, L, A;
    n := nops(E);
    # compute permutation that sorts E
    P := map(attributes, sort([seq(setattribute(SFloat(E[i]),i), i=1..n)]));
    # apply permutation to sort E
    L := [seq(E[i], i in P)];
    # compute adjacent differences
    L := L[2..] - L[..-2];
    # compute minimum adjacencies
    L := [L[1], seq(min(L[i],L[i+1]), i=1..n-2), L[n-1]];
    # apply inverse permutation to restore order
    A := Array(1..n);
    for i to n do
        A[P[i]] := L[i];
    end do;
    [seq(A[i], i=1..n)];
end proc:

n := 1000:
L := RandomTools:-Generate(list(integer(range=0..5),n)):
time(slow(L));
                                     0.504

time(fast(L));
                                     0.008

You can reassign the index variable in the loop, however, to get it to restart from the beginning you have assign it the initial value minus the step value because the index is incremented by each time at the top of the loop, except for the first time. I generally don't reassign a loop counter and instead would follow Roman's advice to use a while loop.

What is t?  What is a? With a unassigned (which it is here) you cannot do

a[t] := a[t],a[0]

Technically, you can make the assignment, in a procedure, however, when later you try to reference a[t] it you get an infinite recursion.

 

What are a and s doing?  The assignment a[s] := a[s],a[0] will almost certainly give an error.  That is, it is similar to

restart;
x := x+1;
Error, recursive assignment

If the elements are real, a more efficient technique is to first sort them, then select the minimum adjacent difference:

smallestRealDiff := proc(L :: list)
local sL;
    sL := sort(L);
    min(sL[2..] - sL[..-2])
end proc:

 

It is not clear what you want.  What do mean by "assigning an equation"?  If you want to assign each equation to an indexed variable, then why not do so directly in a do loop:

for i to 3 do
  eq[i] := a[i] = b[i];
end do:

 

Here's two alternatives.

eqs := {diff(y(x),x,x)+y(x)^2*x^2=x^2}:
ics := {y(0)=y0, D(y)(0)=dy0}:
integ := dsolve(eqs union ics, numeric, 'parameters'=[y0,dy0]):

Various phase-space plots
integ('parameters' = [0,0]):
plots:-odeplot(integ, [y(x),D(y)(x)], 0..10, 'numpoints'=1000);

integ('parameters' = [0,1]):
plots:-odeplot(integ, [y(x),D(y)(x)], 0..10, 'numpoints'=1000);

Alternative that uses 'initial' to reinitialize the integrator

ics := {y(0)=0, D(y)(0)=0}:
integ := dsolve(eqs union ics, numeric):

plots:-odeplot(integ, [y(x),D(y)(x)], 0..10, 'numpoints'=1000);

integ('initial'); # this will tell you list order
integ('initial' = [0,0,1]):
plots:-odeplot(integ, [y(x),D(y)(x)], 0..10, 'numpoints'=1000);

 

You need to define what you mean by the difference of two lists. Giving the expected output for the following may suffice,

listdiff( [1,2,2,3,3], [2,1] );

Possible answers are 
 1. error (lists must be the same size)
 2. [-1,1,2,3,3] (difference of corresponding elements, augmented with zero)
 3. [2,3,3] (multiset difference)
 4. [3,3]   (erasure?)

Consider doing what I did when you first posted this.  That is, wrap your code into a Maple procedure, then use the Maple debugger to step through the code.  That is, do

myproc := proc()
  (* all your code *)
end proc:
stopat(myproc):
myproc();

That will bring up the Maple debugger.  You can execute each line one at a time, using the next, into, step, etc commands (read the ?debugger help page).

First 72 73 74 75 76 77 78 Last Page 74 of 114