## [REBOL] Re: More on expressions

### From: joel:neely:fedex at: 2-Feb-2003 8:19

Many thanks to all who've participated in this thread. Anyone who wants to keep playing, skip reading this email until you've had your fun! For those who'd like a hint about another approach, keep reading this email below. . . . . . . . . . . . Joel Neely wrote:> Inspired by the discussions of ANY and ALL, I thought I'd share this > little puzzle, prefaced with a tad of background. >Gabriele took that hint in an interesting way I hadn't thought of. (Thanks, Gabriele, for the new food for thought!) Let me give a nudge in the direction I was thinking. We've discussed how ANY and ALL implicitly provide a way to implement chains of tests. I intended to reinforce that hint at the end of the email.> The trick, of course, is to find an expression that eliminates the > need for any explicit "decision" or "selection" activity. >Are there any other words that provide implicit tests? Stop here if you want to take some time for thought. For more along this line, keep reading. Gabriele got "dangerously" close to the strategy I was pondering, with his alternate suggestion:> a + b + c - (min a min b c) - max a max b c >and rightfully so, since I am the one who specified that the values would be numeric. Second nudge: suppose that A, B, and C were not numeric (so we can't use addition and subtraction). As before, stop reading unless you want more hints ( which will come faster as we get closer to the end ). Think about the relationship between decisions and sorting. What can can we say is accomplished by each iteration of something like the classic BubbleSort? We can "unwrap" BubbleSort for three values into the following sequence of operations: 1) compare A and B, swapping their values if out of order 2) compare B and C, swapping their values if out of order 3) compare A and B, swapping their values if out of order (and there are some combinations of values that require all three of these steps). We can diagram this using the notion of "sort networks", as presented by Knuth, in this way: A ---+-------+--- A' | | B ---+---+---+--- B' | C -------+------- C' where the diagram is read left-to-right, with each vertical bar as an instance of "compare and swap if out of order" using the two values at either end. At the right-hand-end, A', B', and C' contain the sorted values from A, B, and C. This is an ENORMOUS hint, if we think about how to implement the compare and swap if out of order without using IF. One last chance to play with these hints on your own before I spoil the secret. We could do the "compare and swap if out of order" with MIN and MAX, as follows: set [a b] reduce [a min b a max b] set [b c] reduce [b min c b max c] set [a b] reduce [a min b a max c] which provides a literal transcription of the sort network diagram if read from left to right. However, we didn't ask for the sorted list, but just the median, so let's skip the SET operations, and just use the expressions. Substituting the expression for the modified B into the second line above gives us set [b c] reduce [(a max b) min c (a max b) max c] Then we can substitute *that* expression for B (and the one for the new value of A) into the third line: set [a b] reduce [ (a min b) min ((a max b) min c) (a min b) max ((a max b) min c) ] and then we recall that we only wanted the median, which means we only wanted the ultimate value for B, giving us our final answer: (a min b) max ((a max b) min c) which will work for any datatype (number pair char money date time tuple series) that MIN and MAX handle. There's actually a practical (well, at least if you think "philosophy of programming" is practical ;-) point to this little puzzle. We programmers are biased to think operationally. It's very easy to approach a p[roblem by thinking, "If I were solving this, I'd first do blah, and then do blah-blah, and then if yadda-yadda I'd do ..." Most experienced programmers could see an expression in a problem specification such as a * b + a * c + a * d + ... + a * z and would almost instinctivly 1) know that it could be written as a * (b + c + c + ... + z) because we've been trained to know the properties of * and + as operators, and how they interact. 2) probably desire to rewrite it as shown above, becase we've been trained to think about saving compute time. However, we typically aren't trained to think of other parts of our language (such as MIN, MAX, or the inspiring ANY, ALL, EITHER, etc.) in the same way. It makes me wonder how often we miss opportunities to do simplifications just as valid as the above arithmetic example because don't think about our operators enough... Thanks for playing! -jn-