Sort three variables: Difference between revisions
Content added Content deleted
SqrtNegInf (talk | contribs) m (→{{header|Ruby}}: 'Perl 6' to 'Raku') |
(→{{header|TXR}}: New entry.) |
||
Line 3,338: | Line 3,338: | ||
z: 77444 |
z: 77444 |
||
</pre> |
</pre> |
||
=={{header|TXR}}== |
|||
The following is a comprehensive solution to the general problem of sorting any number of mutable places. We develop a macro operator called <code>sort-places</code> which is called with zero or more argument expressions that denote assignable places. The places are sorted in order according to the <code>greater</code> function. |
|||
The zero and one argument cases are handled as no-ops; the arguments are not evaluated at all, even for their side effects if they have any. The two argument case is handled by generating a conditional which controls a single swap. The three-argument case performs up to three swaps. |
|||
For four or more arguments, a hidden vector object is generated. The values of the places are stuffed into the vector, which is then sorted, after which the values are retrieved and stored in the places. |
|||
'''All cases work in such a way that the place expressions are evaluated at most once,''' which is achieved by leveraging the simple-to-use <code>placelet</code> macro. |
|||
<syntaxhighlight lang="txrlisp">(defmacro sort-places (. places) |
|||
(caseql (len places) |
|||
((0 1) nil) |
|||
(2 (with-gensyms (p0 p1) |
|||
^(placelet ((p0 (read-once ,[places 0])) |
|||
(p1 (read-once ,[places 1]))) |
|||
(if (greater p0 p1) |
|||
(swap p0 p1))))) |
|||
(3 (with-gensyms (p0 p1 p2) |
|||
^(placelet ((p0 (read-once ,[places 0])) |
|||
(p1 (read-once ,[places 1])) |
|||
(p2 (read-once ,[places 2]))) |
|||
(if (greater p0 p1) |
|||
(swap p0 p1)) |
|||
(if (greater p1 p2) |
|||
(swap p1 p2)) |
|||
(if (greater p0 p1) |
|||
(swap p0 p1))))) |
|||
(t (let ((gens [mapcar (ret (gensym)) places])) |
|||
(with-gensyms (vec) |
|||
^(placelet ,(zip gens places) |
|||
(let ((,vec (vec ,*gens))) |
|||
(nsort ,vec) |
|||
(set ,*(append-each ((g gens) |
|||
(i 0)) |
|||
^(,g [,vec ,i])))))))))) |
|||
(prinl (sort-places)) |
|||
(let ((x 1)) |
|||
(sort-places x) |
|||
(prinl x)) |
|||
(let ((x 2) |
|||
(y 1)) |
|||
(sort-places x y) |
|||
(prinl (list x y))) |
|||
(let ((a 3) |
|||
(b 2) |
|||
(c 1)) |
|||
(sort-places a b c) |
|||
(prinl (list a b c))) |
|||
(let ((a 4) |
|||
(b 3) |
|||
(c 2) |
|||
(d 1)) |
|||
(sort-places a b c d) |
|||
(prinl (list a b c d)))</syntaxhighlight> |
|||
{{out}} |
|||
<pre>nil |
|||
1 |
|||
(1 2) |
|||
(1 2 3) |
|||
(1 2 3 4)</pre> |
|||
=={{header|Visual Basic .NET}}== |
=={{header|Visual Basic .NET}}== |