Order by pair comparisons: Difference between revisions
m
→{{header|Wren}}: Minor tidy
m (→{{header|J}}: make quicksort implementation be general (taking comparison function as an argument)) |
m (→{{header|Wren}}: Minor tidy) |
||
(3 intermediate revisions by 3 users not shown) | |||
Line 32:
{{trans|Python: Sort with custom comparator}}
<
R Int(input(‘IS #6 <, ==, or > #6 answer -1, 0 or 1:’.format(a, b)))
V items = ‘violet red green indigo blue yellow orange’.split(‘ ’)
V ans = sorted(items, key' cmp_to_key(user_cmp))
print("\n"ans.join(‘ ’))</
{{out}}
Line 70:
=={{header|Action!}}==
<
PROC PrintArray(PTR ARRAY a BYTE size)
Line 137:
PutE() Print("Sorted array: ")
PrintArray(arr,COUNT)
RETURN</
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Order_by_pair_comparisons.png Screenshot from Atari 8-bit computer]
Line 168:
=={{header|Arturo}}==
<
count: 0
Line 187:
print ""
print ["sorted =>" sortedLst]</
{{out}}
Line 205:
=={{header|AutoHotkey}}==
<
result := [], num := 0, Questions :=""
Line 234:
output .= color ", "
MsgBox % Questions "`nSorted Output :`n" Trim(output, ", ")
return</
{{out}}
Line 256:
=={{header|C}}==
Using qsort; not very efficient
<
#include <string.h>
#include <stdlib.h>
Line 288:
printOrder(items, sizeof(items)/sizeof(*items));
return 0;
}</
{{out}}
<pre>
Line 315:
=={{header|C++}}==
===C++: Binary search insertion sort===
<
#include <iostream>
#include <vector>
Line 361:
PrintOrder(sortedItems);
return 0;
}</
{{out}}
<pre>
Line 388:
===C++: STL sort with custom comparator===
<
#include <iostream>
#include <vector>
Line 421:
PrintOrder(items);
return 0;
}</
{{out}}
<pre>
Line 442:
=={{header|Commodore BASIC}}==
<
110 DIM IN$(6), OU$(6)
120 FOR I=0 TO 6:READ IN$(I): NEXT I
Line 474:
410 FOR Q=0 TO N-2:PRINT OU$(Q)",";:NEXT Q
420 PRINT OU$(N-1)")"
430 RETURN</
{{Out}}
<pre>
Line 494:
=={{header|F_Sharp|F#}}==
This task uses [https://rosettacode.org/wiki/Factorial_base_numbers_indexing_permutations_of_a_collection#F.23 Factorial base numbers indexing permutations of a collection (F#)]
<
// Order by pair comparisons. Nigel Galloway: April 23rd., 2021
let clrs=let n=System.Random() in lN2p [|for g in 7..-1..2->n.Next(g)|] [|"Red";"Orange";"Yellow";"Green";"Blue";"Indigo";"Violet"|]
let rec fG n g=printfn "Is %s less than %s" n g; match System.Console.ReadLine() with "Yes"-> -1|"No"->1 |_->printfn "Enter Yes or No"; fG n g
let mutable z=0 in printfn "%A sorted to %A using %d questions" clrs (clrs|>Array.sortWith(fun n g->z<-z+1; fG n g)) z
</syntaxhighlight>
</lang>▼
{{out}}
Possible interaction:
Line 549:
Asking the user for an ordering specifier inside a custom comparator:
{{works with|Factor|0.99 2021-02-05}}
<
qw{ violet red green indigo blue yellow orange }
[ "Is %s > %s? (y/n) " printf readln "y" = +gt+ +lt+ ? ] sort .</
{{out}}
<pre>
Line 573:
=={{header|FreeBASIC}}==
{{trans|Commodore BASIC}}
<
Dim Shared As Byte r, n = 1
Dim Shared As String IN1, OU1
Line 618:
PrintOrder
Sleep
</syntaxhighlight>
</lang>▼
=={{header|Go}}==
===Go: Binary search insertion sort===
<
import (
Line 659:
}
fmt.Println(sortedItems)
}</
{{out}}
<pre>
Line 686:
===Go: Standard sort with custom comparator===
<
import (
Line 712:
sort.Sort(items)
fmt.Println(items)
}</
{{out}}
<pre>
Line 733:
Injection of interaction with user is not straight-forward in pure functional language. In Haskell we use monads in order to abstract the computation flow and side effects. Fortunately the monadlist library [[https://hackage.haskell.org/package/monadlist]] contains monadic variants of most popular list operations so that it becomes easy to implement our favorite sorting algorithms.
<
import Control.Monad.ListM (sortByM, insertByM, partitionM, minimumByM)
import Data.Bool (bool)
Line 754:
go (h:t) = do (l, g) <- partitionM (fmap (LT /=) . cmp h) t
go l <+> pure [h] <+> go g
(<+>) = liftM2 (++)</
Now we can sort lists with effects. For example, we may count number of comparisons, using writer monad:
Line 780:
We are ready to ask user to compare entries for us:
<
putStr $ show a ++ " ≤ " ++ show b ++ " ? [y/n] "
bool GT LT . ("y" ==) <$> getLine
colors = ["Violet", "Red", "Green", "Indigo", "Blue", "Yellow", "Orange"]</
<pre>*Main> isortM ask colors
Line 841:
It seems that insertion sort with 13 comparisons is the best one, and tree sort which needed 17 questions is the worst. But efficiency of sorting depends on the order of given list. Simple statistics could be made to compare these three methods for all possible permutations of seven elements.
<
mapM_ showHist $ hist res
putStrLn $ "Median number of comparisons: " ++ show (median res)
Line 855:
line = show n ++ "\t" ++ bar ++ " " ++ show perc ++ "%"
bar = replicate (max perc 1) '*'
perc = (100 * l) `div` product [1..7]</
Comparing these three methods gives that for random inputs tree sort is the best choice.
Line 911:
=={{header|J}}==
Implementation (here we assume that ordering is transitive):<
sel=: {{ u#[ }}
Line 941:
LT=: <:%=i.#items
askless quicksort y
}}</
Task example:<
Is indigo less than violet? yes
Is indigo less than red? no
Line 956:
Is green less than blue? yes
Is red less than orange? yes
red orange yellow green blue indigo violet</
=={{header|Java}}==
===Java: Binary search insertion sort===
<
public class SortComp1 {
Line 984:
System.out.println(sortedItems);
}
}</
{{out}}
<pre>
Line 1,011:
===Java: Standard sort with custom comparator===
<
public class OrderByPair {
Line 1,026:
System.out.println(items);
}
}</
{{out}}
<pre>
Line 1,053:
In order for a jq program to interact with a user, prompts must be directed to stderr,
which currently means that the prompt string will be printed with quotation marks.
<
def r:
$prompt | stderr
Line 1,085:
| order as $ordered
| ("\nThe colors of the rainbow, in sorted order, are:",
$ordered )</
'''Recommended Invocation Options''': -nRrc
Line 1,124:
=={{header|Julia}}==
<
const ordering = Dict("violet" => 7, "red" => 1, "green" => 4, "indigo" => 6, "blue" => 5,
"yellow" => 3, "orange" => 2)
Line 1,164:
println("Unsorted: $words")
println("Sorted: $(orderbypair!(words)). Total requests: $(nrequests[1]).")
</
<pre>
Is violet greater than indigo? (Y/N) => y
Line 1,184:
=={{header|Lua}}==
<
print("unsorted: " .. table.concat(colors," "))
known, notyn, nc, nq = {}, {n="y",y="n"}, 0, 0
Line 1,199:
end)
print("sorted: " .. table.concat(colors," "))
print("(" .. nq .. " questions needed to resolve " .. nc .. " comparisons)")</
{{out}}
<pre>unsorted: violet red green indigo blue yellow orange
Line 1,220:
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<
HumanOrderCheck[opt1_,opt2_]:=ChoiceDialog[Row@{"Is {",opt1,", ", opt2, "} ordered?"},{"Yes"->True,"No"->False}]
Sort[{"violet","red","green","indigo","blue","yellow","orange"},HumanOrderCheck]</
{{out}}
After some Yes/No clicks you should get:
<pre>{"red", "orange", "yellow", "green", "blue", "indigo", "violet"}</pre>
=={{header|MiniScript}}==
<syntaxhighlight lang="miniscript">
insertSort = function(arr, item)
lo = 0
hi = arr.len
while lo < hi
mid = floor((lo + hi) / 2)
ans = input("Is " + item + " less than " + arr[mid] + "? y/n: ")
ans = ans[0].lower
if ans == "y" then
hi = mid
else
lo = mid + 1
end if
end while
arr.insert(lo, item)
end function
items = "violet red green indigo blue yellow orange".split
ordered = []
for item in items
insertSort(ordered, item)
end for
print ordered
</syntaxhighlight>
{{out}}
<pre>
Is red less than violet? y/n: y
Is green less than violet? y/n: y
Is green less than red? y/n: n
Is indigo less than green? y/n: n
Is indigo less than violet? y/n: y
Is blue less than indigo? y/n: y
Is blue less than green? y/n: n
Is yellow less than blue? y/n: y
Is yellow less than green? y/n: y
Is yellow less than red? y/n: n
Is orange less than blue? y/n: y
Is orange less than yellow? y/n: y
Is orange less than red? y/n: n
["red", "orange", "yellow", "green", "blue", "indigo", "violet"]
=={{header|Nim}}==
Using a list filled by binary insertion and a custom comparison function.
<
let list = ["violet", "red", "green", "indigo", "blue", "yellow", "orange"]
Line 1,251 ⟶ 1,294:
sortedList.insert(elem, sortedList.upperBound(elem, comp))
echo "Sorted list: ", sortedList.join(", ")</
{{out}}
Line 1,273 ⟶ 1,316:
List:
<
let count = ref 0 in
let mycmp s1 s2 = (
Line 1,283 ⟶ 1,326:
let sorted = List.sort mycmp items in
List.iter (Printf.printf "%s ") sorted;
print_newline ()</
{{out}}
<pre>
Line 1,303 ⟶ 1,346:
Array:
<
let count = ref 0 in
let mycmp s1 s2 = (
Line 1,313 ⟶ 1,356:
Array.sort mycmp items;
Array.iter (Printf.printf "%s ") items;
print_newline ()</
{{out}}
<pre>
Line 1,339 ⟶ 1,382:
=={{header|Perl}}==
<
use strict; # https://rosettacode.org/wiki/Order_by_pair_comparisons
Line 1,354 ⟶ 1,397:
my @sorted = sort ask qw( violet red green indigo blue yellow orange );
print "sorted: @sorted\n";</
{{out}}
<pre>
Line 1,379 ⟶ 1,422:
I picked an initial ordering that requires a fairly easy to remember set of answers: 4Y then alternate.<br>
The builtin sort(s) use an initial gap of 10%, ultimately balancing #comparisons against cache hits, which leads to a wider range of #questions, as said best case 6, worst case 21. A better match to the narrower range of Python (I think 10..14) could probably be made using a copy of custom_sort (it is only 52 lines) with an initial 50% gap.
<!--<
<span style="color: #004080;">integer</span> <span style="color: #000000;">qn</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">ask</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
Line 1,390 ⟶ 1,433:
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">custom_sort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ask</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"violet orange red yellow green blue indigo"</span><span style="color: #0000FF;">))</span>
<!--</
{{out}}
<pre>
Line 1,411 ⟶ 1,454:
Uses binary search to insert successive items into a growing ordered list. Comparisons are asked for.
<
"""
Insert item x in list a, and keep it sorted assuming a is sorted.
Line 1,436 ⟶ 1,479:
items = 'violet red green indigo blue yellow orange'.split()
ans, questions = order(items)
print('\n' + ' '.join(ans))</
{{out}}
Line 1,470 ⟶ 1,513:
This uses a custom comparator together with [https://docs.python.org/3/library/functools.html?highlight=cmp_to_key#functools.cmp_to_key functools.cmp_to_key] to sort the previous order in fourteen questions.
<
def user_cmp(a, b):
Line 1,478 ⟶ 1,521:
items = 'violet red green indigo blue yellow orange'.split()
ans = sorted(items, key=cmp_to_key(user_cmp))
print('\n' + ' '.join(ans))</
{{out}}
Line 1,515 ⟶ 1,558:
<code>sortwith</code> sorts by insertion sort by default, of by merge sort falling back to insertion sort for nests of fewer than 16 items if the Quackery extensions are loaded. In either instance, as this is sorting a nest of seven items, it will be by insertion sort.
<
$ " before " join
swap join
Line 1,527 ⟶ 1,570:
dup witheach [ echo$ sp ] cr cr
sortwith askuser cr
witheach [ echo$ sp ] cr</
{{out}}
Line 1,556 ⟶ 1,599:
Since the calls to the comparator are minimized, and the info that the user provides is analogous to the required return values of the comparator, we just need to embed the prompt directly in the comparator.
<syntaxhighlight lang="raku"
sub by_asking ( $a, $b ) {
$ask_count++;
Line 1,577 ⟶ 1,620:
die if @sorted».substr(0,1).join ne 'roygbiv';
my $expected_ask_count = @colors.elems * log(@colors.elems);
warn "Too many questions? ({:$ask_count} > {:$expected_ask_count})" if $ask_count > $expected_ask_count;</
{{out}}
<pre>
Line 1,602 ⟶ 1,645:
Also note that lists in REXX start with unity, not zero.
<
colors= 'violet red green indigo blue yellow orange'
q= 0; #= 0; $=
Line 1,626 ⟶ 1,669:
else lo= mid + 1
end /*q*/
$= subword($, 1, lo) x subword($, lo+1); return q</
{{out|output|text= (only showing the results and eliding the querying/answering):}}
<pre>
Line 1,648 ⟶ 1,691:
=={{header|Ruby}}==
===Ruby: Binary search insertion sort===
<
count = 0
sortedItems = []
Line 1,660 ⟶ 1,703:
sortedItems.insert(spotToInsert, item)
}
p sortedItems</
{{out}}
<pre>
Line 1,687 ⟶ 1,730:
===Ruby: Standard sort with custom comparator===
<
count = 0
p items.sort {|a, b|
Line 1,693 ⟶ 1,736:
print "(#{count}) Is #{a} <, =, or > #{b}. Answer -1, 0, or 1: "
gets.to_i
}</
{{out}}
<pre>
Line 1,722 ⟶ 1,765:
{{libheader|Wren-ioutil}}
{{libheader|Wren-fmt}}
<
import "./fmt" for Fmt
// Inserts item x in list a, and keeps it sorted assuming a is already sorted.
Line 1,757 ⟶ 1,800:
var ordered = order.call(items)
System.print("\nThe colors of the rainbow, in sorted order, are:")
System.print(ordered)</
{{out}}
Line 1,777 ⟶ 1,820:
The colors of the rainbow, in sorted order, are:
[red, orange, yellow, green, blue, indigo, violet]
=={{header|XPL0}}==
<syntaxhighlight lang "XPL0">include xpllib; \for Print
int Items, Size, I, J, Gap, JG, T, C, Count;
[Items:= ["violet", "red", "green", "indigo", "blue", "yellow", "orange"];
Size:= 7;
Count:= 0;
Gap:= Size>>1;
while Gap > 0 do
[for I:= Gap to Size-1 do
[J:= I - Gap;
loop [JG:= J + Gap;
Count:= Count+1;
Print("%2d: Is %6s less than %6s (y/n)? ",
Count, Items(J), Items(JG));
repeat OpenI(1);
C:= ChIn(1);
until C=^y or C=^n;
ChOut(0, C); CrLf(0);
if C = ^y then quit;
T:= Items(J); Items(J):= Items(JG); Items(JG):= T;
J:= J - Gap;
if J < 0 then quit;
];
];
Gap:= Gap>>1;
];
Print("The colors of the rainbow, in sorted order, are:\n");
for I:= 0 to Size-2 do Print("%s, ", Items(I));
Print("%s\n", Items(I));
]</syntaxhighlight>
{{out}}
<pre>
1: Is violet less than indigo (y/n)? n
2: Is red less than blue (y/n)? y
3: Is green less than yellow (y/n)? n
4: Is violet less than orange (y/n)? n
5: Is indigo less than orange (y/n)? n
6: Is orange less than red (y/n)? n
7: Is orange less than yellow (y/n)? y
8: Is yellow less than indigo (y/n)? y
9: Is indigo less than blue (y/n)? n
10: Is yellow less than blue (y/n)? y
11: Is indigo less than green (y/n)? n
12: Is blue less than green (y/n)? n
13: Is yellow less than green (y/n)? y
14: Is indigo less than violet (y/n)? y
The colors of the rainbow, in sorted order, are:
red, orange, yellow, green, blue, indigo, violet
</pre>
|