Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Apolgies if this has been asked and answered, but I'm not even sure what to search for. I have two functions defined as follows:

F[n_]:=Max[Select[Divisors[n],#<=Sqrt[n]&]];
P[n_] := Select[Range[1, 1000], F[#] == n &];

I have two questions:

  1. I have read the Mathematica help page on the # symbol, and I think I understand most of that. I do not, however, understand what # and & do in this specific context.

  2. How can I write P[n_ ] using a single line of code? It doesn't work if I simply copy and paste the definition for F into the definition of P:

    P[n_] := Select[ Range[1, 1000], Max[Select[Divisors[n],#<=Sqrt[n]&]] == n &]
    
share|improve this question

2 Answers 2

up vote 11 down vote accepted

Answering your second question - you don't maintain a proper nesting / variable localization. Here are two correct ways (there are more):

P[n_] := 
  Select[
     Range[1, 1000], 
     With[{m = #}, Max[Select[Divisors[m], # <= Sqrt[m] &]]] == n &
  ]

and

P[n_] := 
  Select[Range[1, 1000], 
     Function[m, Max[Select[Divisors[m], # <= Sqrt[m] &]] == n]]

The reason that we had to introduce an additional symbol m is that you have a function # <= Sqrt[m] & which mixes the two local variables at different levels. When this happens, you can't solve the problem using only slot-based functions, due to the apparent collision of essentially different variables.

Perhaps, the fact that you denote the argument for your original functions as n in both cases was what led to the conclusion. As a side note, avoid starting your function names with capital letters, this may lead to collisions with system symbols.

I believe that there is already an answer for the general slot-nesting question somewhere here on SE, so this answer likely has a temporary status.

share|improve this answer

In theory you can use only slot-based functions:

P1[n_] := Select[Range[1, 1000], Max@Select[Divisors[#], 
   Function @@ {Identity[Slot][] <= Sqrt[#]}] == n &];

P2[n_] := Select[Range[1, 1000], 
  Max@Select[Divisors[#3], #1[#2[] <= Sqrt[#3]]] == n &[Function, Slot, #] &];

You can even use the slot instead of n:

P3 = Select[Range[1, 1000], #1[Max@Select[
  Divisors[#3], #1[#2[] <= Sqrt[#3]]] == #4 &[#1, #2, #2[], #3]]] &[Function, Slot, #] &;

P[10] == P1[10] == P2[10] == P3[10]

True

Surely it is a very complicated approach, which is inappropriate for practical use. It is just an answer to Leonid's "you can't solve the problem using only slot-based functions".

share|improve this answer
    
Excellent answer, thank you. I tried about a thousand different ways of using only slot-based functions, but I would never have come up with anything close to this. –  Ashton Baker Nov 3 '13 at 22:57
    
+1. So, you solve the collision problem by delaying the binding, constructing the inner function at runtime. I haven't thought of that, pretty clever. OTOH, my statement was concerning the most straight-forward way. If you think of it, my first method (using With) is akin yours. –  Leonid Shifrin Nov 4 '13 at 0:08

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.