質問

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
役に立ちましたか?

解決

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.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top