5 ms·
>We deal with maps a lot, and I usually ask this one: assume a matrix. Fill the matrix with numbers, so that the outer 'ring' of numbers has the value 1, one 'r
by Hupo 14y ago
>We deal with maps a lot, and I usually ask this one: assume a matrix. Fill the matrix with numbers, so that the outer 'ring' of numbers has the value 1, one 'ring' more to the center has the value 2, and so on. To visualize this, imagine that this matrix represents a height map, where each number represents a cell in a surface, and the value of the number is the elevation of the area of that cell. The result should be a height map of a pyramid. To make things easier, assume that the number of rows and columns in the matrix is equal, and that that number is uneven.
This sounded fun, so I thought about it for a couple minutes and came up with the following in JavaScript:
var pyramatrix = function(a) {
a += 1 - (a & 1); // increment a by one if even
var b = [], // pyramid y-axis
c = a-(a>>1), // get the "center" of the pyramid (eg. 7 -> 1234321 -> 4 is the center)
d = function(x) { return Math.abs((x+1)-c) }, // calculate offset from center
e, f, // values for storing current index offset
g = ''; // initialize string for pretty output
for(var i = 0; i < a; i++) {
b[i] = []; // pyramid "x-axis" (current row)
for (var j = 0; j < a; j++) {
e = d(i); // get y offset
f = d(j); // get x offset
b[i][j] = c - (e > f ? e : f); // set current index to center minus larger offset
g += '['+b[i][j]+']'; // add value to pretty output
}
g += '\n'; // add a line break after each row
}
console.log(g); // print pretty output
}
Example usage and output:
pyramatrix(7)
[1][1][1][1][1][1][1]
[1][2][2][2][2][2][1]
[1][2][3][3][3][2][1]
[1][2][3][4][3][2][1]
[1][2][3][3][3][2][1]
[1][2][2][2][2][2][1]
[1][1][1][1][1][1][1]
I was pretty satisfied when it worked exactly as intended on the first try!
EDIT: Now that I look at it, you could obviously move e = d(i); outside the second for loop, but for the sake of posterity I'm not going to change the solution from what I first came up with.
- roel_v 14y agoThat looks like a nice solution to me, some of the Javascript idioms I'm not familiar with, but after looking at it for a while it seems you're using what I'd consider the 'best' method of generating it - looping over each cell and calculating the height based on the distance to the 'top' (or 'center', depending on how you look at it). Personally I consider the 'naive' version (as in: the first, easy to manually verify version one would bang out as a prototype) to be one where a matrix is pre-allocated and each ring is filled in from the outside inwards (so first assign all 1's, then all 2's, and so on), but funnily enough nobody ever went that route, not even my colleagues who did it.
- Hupo 14y ago>Personally I consider the 'naive' version (as in: the first, easy to manually verify version one would bang out as a prototype) to be one where a matrix is pre-allocated and each ring is filled in from the outside inwards (so first assign all 1's, then all 2's, and so on) I'd consider the 'naive' version (and the first solution that popped to my mind pretty much instantly) to be where you first fill the grid with 1's, then then loop over the next level and add 1 and repeat until you're on the top. So like this for example: function(a) { a = a | 1; // add 1 to even numbers var b = new Array(a), i, y, x, s = 0; // initialize the array for(y = 0; y < a; y++) { b[y] = new Array(a); for(x = 0; x < a; x++) { b[y][x] = 0; } } // turn it into a pyramid heightmap for(i = a; i > 0; i--) { for(y = s; y < i; y++) { for(x = s; x < i; x++) { b[y][x]++; } } s++; } return b; } Though in JavaScript it's a bit more complex than it might otherwise be since you can't just declare a multi-dimensional int array in a single line. Anyway, I discarded this solution about as fast as I came up with it because I knew there'd be more clever ways to go about it, and came up with the offset calculation method a couple minutes after that. And amusingly enough I had to actually test and iterate this 'naive' version a bit before I got it running right, whereas my 'complex' solution worked on the first try. Funny how that goes.