0

I would like to define a function that takes an integer n and returns an integer n* such that n and n* are in the same set of integers from 1 to n,and the function must be bijective.

I tried the following

fun bij(n) =
      let 
        val ls = zip(upto (1, n), List.rev(upto (1, n))) 
        val Tw_2 = fn(a, b) => b
      in Tw_2(List.last(ls, n-1)) end;

but unfortunately, it returns 1 for all my values of n. I am really stuck here. Can anyone give me some ideas on how to implement this?

The behavior of bij must look something like

bij(1) = 3
bij(2) = 2
bij(3) = 1
chris
  • 4,988
  • 20
  • 36
Emma
  • 323
  • 3
  • 16
  • Do you possibly want to define a function that takes an integer n and returns a function that takes an integer m and returns an integer m* such that m and m* are in the same set of integers from 1 to n? – qaphla Nov 02 '13 at 23:57
  • I don't get it, in your first example n=1, and n*=3. So how is it that n and n* are in the same set of integers from 1 to n? For sure n* should be an integer between 1 and n. Could you please elaborare? – Edwin Dalorzo Nov 03 '13 at 13:44
  • well maybe i failed to explain what i really want,the big picture is like this:I have a list '[2,1,3]',i would want a function that permutes this list back to '[1,2,3]' for example. – Emma Nov 03 '13 at 21:46
  • Something's missing there... You want `bij(1)` to return a value between `1` and `n`, but you haven't told it what `n` is. It needs another parameter. – Nick Barnes Nov 04 '13 at 12:01
  • In the code above is `zip` actually `ListPair.zip`? And what is the definition of `upto`? Furthermore, `List.last` only takes a single argument, which function did you actually mean? Do you just need an arbitrary function that satisfies your specification (the simplest one that comes to mind is `fn x => x` ;)) or a specific one? In your example it looks as if for given `n`, `bij(n, i)` should map the numbers `1 2 3 ... n` (in this order) to `n n-1 n-2 ... 1` (in this order)? Could you clarify? – chris Nov 05 '13 at 05:57

1 Answers1

1

If I understand your question correctly, an easy solution would be:

fun bij(n, i) = n + 1 - i;

Which can be represented by the following table

i         | 1    2    3  ... n-2  n-1  n
bij(n, i) | n  n-1  n-2  ...   3    2  1

and which works as expected for numbers between 1 and n. Intuitively a (positive) number i is i steps "to the right of 0" and we map this to a number that is i (actually i - 1) steps "to the left of n".

Maybe you wanted to construct the above table explicitly via lists?

fun upto(m, n) = if n < m then [] else m :: upto(m+1, n);

fun table n = ListPair.zip (upto(1, n), List.rev (upto(1, n)));

Example:

> table 5;
val it = [(1, 5), (2, 4), (3, 3), (4, 2), (5, 1)]: (int * int) list

Then to get the i-th pair of a list xs you could use

List.nth (xs, i-1)

Putting all together

fun bij(n, i) =
      let
        val table = ListPair.zip (upto(1, n), List.rev (upto(1, n)));
        fun snd(x, y) = y;
      in snd(List.nth (table, i-1)) end;

Which does the same as the initial function, except in a more complicated way.

chris
  • 4,988
  • 20
  • 36