How do you sort a list from least to greatest in Standard ML?

203 Views Asked by At

I'm new to ML, and a bit of my code isn't working. I'm creating a function in ML where it's supposed to sort reals and then compile them into a single list. I created a large if-then statement, but it keeps failing at one particular point and I can't figure out why.

Here's my code:

fun sort3(c: real, g: real, j: real) =
  if c < g andalso g < j then [c, g, j] 
  else if c < g andalso g > j then [c, j, g] 
  else if c > g andalso c < j then [g, c, j]
  else if c > g andalso c > j then [g, j, c]
  else if c > g andalso g > j then [j, g, c] 
  else [j, c, g];

When I submit 3 real numbers into them, I expect to get them sorted from least to greatest. Most of the time, this is true, with two major exceptions. I'll write my results down below (all of them are real, not int).

  1. (1,2,3) = (1,2,3)
  2. (3,2,1) = (2,1,3) X
  3. (2,1,3) = (1,2,3)
  4. (3,1,2) = (1,2,3)
  5. (2,3,1) = (2,1,3) X
  6. (1,3,2) = (1,2,3)

Is there something wrong with my code? Is ML particular about using too many if-then statements? Thank you in advance!

1

There are 1 best solutions below

0
Chris On

Looking at your code, you've made some bad assumptions:

fun sort3(c: real, g: real, j: real) =
  if c < g andalso g < j then [c, g, j]     
  else if c < g andalso g > j then [c, j, g] 
  else if c > g andalso c < j then [g, c, j]
  else if c > g andalso c > j then [g, j, c]
  else if c > g andalso g > j then [j, g, c] 
  else [j, c, g];
if c < g andalso g < j then [c, g, j]  

This holds up.

else if c < g andalso g > j then [c, j, g]

This one not so much. We know from your conditional expression that c is less than g, and that j is less than g, but this does not tell us anything about the relationship between c and j.

else if c > g andalso c < j then [g, c, j]

This logic holds up.

else if c > g andalso c > j then [g, j, c]

We know from this that both g and j are less than c, but not how g and j relate to each other.

else if c > g andalso g > j then [j, g, c] 

This logic works.

A different way to approach this might be with nested conditionals, establish first which is the smallest, at which point there are only two values to compare.

let sort(a: real, b: real, c: real) =
  if a < b andalso a < c then
    (* 'a' must be the smallest *)
    if b < c then [a, b, c]
    else [a, c, b]
  else if b < a andalso b < c then
    (* 'b' must be the smallest *)
    if a < c then [b, a, c]
    else [b, c, a]
  else 
    (* 'c' is the smallest *)
    if a < b then [c, a, b]
    else [c, b, a]