Matrix from permutations

hey i have been trying to write a function which should take an initial integer series and outputs a matrix with different unique permutations according to a specific idea.

I have made a first sketch here:

(
~getMatrix = { |series|
	var matrixSize = series.size;
	var matrix = Array.fill(matrixSize, {
		Array.fill(matrixSize, { 0 } );
	});

	// Fill first row and column with initial series
	matrix.put(0, series);

	matrix.do { |row, i|
		row.put(0, series[i]);
	};

	// Calculate differences and update matrix
	(1..matrixSize - 1).do { |i|
		(1..matrixSize - 1).do { |j|
			var rowDif = (matrix[i-1][0] - matrix[i][0]).abs;
			matrix[i][j] = (matrix[i-1][j] + rowDif) % matrixSize;
		};
	};

	matrix;
};

~series = [3, 7, 1, 6, 5, 2, 4];

~getMatrix.(~series);
)

The desired output for the input data [3, 7, 1, 6, 5, 2, 4] should be:

// desired output:
[
	[3,  7,  1,  6,  5,  2,  4],
	[7,  4,  5,  3,  2,  6,  1],
	[1,  5,  6,  4,  3,  7,  2],
	[6,  3,  4,  2,  1,  5,  7],
	[5,  2,  3,  1,  7,  4,  6],
	[2,  6,  7,  5,  4,  1,  3],
	[4,  1,  2,  7,  6,  3,  5]
];

I have thought it through already, this is what should happen:

After filling the first row and the first column with the initial series, calculate the absolute differece between [0][0] and [1][0]

(3 - 7).abs; // -> 4

or in other terms:

([0][0] - [1][0]).abs

use this absolute difference and add it to item:

[0][1] % matrixSize and put it into [1][1]
[0][2] % matrixSize and put it into [1][2]
[0][n] % matrixSize and put it into [1][n]

(7 + 4).mod(7) // [1][1]
(1 + 4).mod(7) // [1][2]
(6 + 4).mod(7) // [1][3]
(5 + 4).mod(7) // [1][4]
(2 + 4).mod(7) // [1][5]
(4 + 4).mod(7) // [1][6]

or in other terms:

([0][1] + rowDif) % matrixSize // [1][1]
([0][2] + rowDif) % matrixSize // [1][2]
([0][n] + rowDif) % matrixSize // [1][n]

then calcute the next absolute difference between [1][0] and [2][0] and use this absolute difference and add it to item [1][1] mod(matrixSize) and put it into [2][1]

and so on until all remaining items of the matrix are filled.

Could someone help me to calculate the absolute differences and the updating of the matrix correctly? many thanks

EDIT: i have updated the code, i think the absolute differences are calculated correctly now. but the addition does not work. in general i think there is also a way more elegant way to do this.

Your code looks correct to me, although I would move the rowDif calculation into the outer loop since it only needs to be calculated once per row.

The problem is that the desired output does not match your specification. For example, you specify that matrix[2][1] = (matrix[1][0] - matrix[2][0]).abs + matrix[1][1] % 7. This would be (1 - 7).abs + 4 % 7 = 3, which is what your code correctly outputs, but this does not match your desired output of 5.

Also notice that your desired output contains numbers ranging from 1 to 7. If your algorithm ends with something % 7, the output will range from 0 to 6, so you will probably need to add 1 at the end, although it is still not clear to me what algorithm you can apply to get your desired output.

thanks for your suggestion i have moved it to the outer loop.


(
~getMatrix = { |series|
	var matrixSize = series.size;
	var matrix = Array.fill(matrixSize, {
		Array.fill(matrixSize, { 0 } );
	});

	// Fill first row and column with initial series
	matrix.put(0, series);

	matrix.do { |row, i|
		row.put(0, series[i]);
	};

	// Calculate differences and update matrix
	(1..matrixSize - 1).do { |i|
		var rowDif = (matrix[i-1][0] - matrix[i][0]).abs;
		(1..matrixSize - 1).do { |j|
			matrix[i][j] = (matrix[i-1][j] + rowDif) % matrixSize;
		};
	};

	matrix;
};

~series = [3, 7, 1, 6, 5, 2, 4];

~getMatrix.(~series);
)

running this updated code does give me the correct second row:

[7, 4, 5, 3, 2, 6, 1]

from the third row on the calculation is not correct due to a mistake i made, sorry.
it should not calculate the absolute difference but also the addition between the values mod(7), i guess. let me rethink this. filled out a table last night and was sure to have found the correct formula…

okay what i initially did in my head to calculate the differences was this, for every pair of items. finding x to satisfy the condition.

f = { |x| (3 + x).wrap(1, 7) == 7 };
f.(4);

f = { |x| (7 + x).wrap(1, 7) == 1 };
f.(1);

f = { |x| (1 + x).wrap(1, 7) == 6 };
f.(5);

f = { |x| (6 + x).wrap(1, 7) == 5 };
f.(6);

f = { |x| (5 + x).wrap(1, 7) == 2 };
f.(4);

f = { |x| (2 + x).wrap(1, 7) == 4 };
f.(2);

lets see if this fits with the the other calculations to make it consistent. i think ive used wrap.(1, 7) in my head instead of modulus also for the other items…

okay i i think i got it, i have exchanged the modulus with .wrap(1, matrixSize) and reversed the order for the substraction to calculate the “difference”

(
~getMatrix = { |series|
	var matrixSize = series.size;
	var matrix = Array.fill(matrixSize, {
		Array.fill(matrixSize, { 0 } );
	});

	// Fill first row and column with initial series
	matrix.put(0, series);

	matrix.do { |row, i|
		row.put(0, series[i]);
	};

	// Calculate differences and update matrix
	(1..matrixSize - 1).do { |i|
		var rowDif = (matrix[i][0] - matrix[i-1][0]).wrap(1, matrixSize);
		(1..matrixSize - 1).do { |j|
			matrix[i][j] = (matrix[i-1][j] + rowDif).wrap(1, matrixSize);
		};
	};

	matrix;
};

~series = [3, 7, 1, 6, 5, 2, 4];

~getMatrix.(~series);
)

~getMatrix.(Array.series(7, 1).scramble);

if you have any tips on writing this more elegantly let me know :slight_smile:
thanks alot @PitchTrebler and sorry for the confusion!