Fitting Elements into a Square Array#
In this article, we explore how to fit a list of elements into a square array, even when the number of elements may not perfectly match a square number. When the number of elements does not fill the array completely, we will need to implement padding.
Example Scenario#
Let’s start with a simple example using the numbers 1, 2, 3, 4,
and 5
.
These numbers can fit into a
3x3
matrix, which would look like this:
1 2 3
4 5 0
0 0 0
Notice here that we pad with zeros.
However, these numbers cannot fit into a 2x2
square, as that would leave the 5
out.
Finding the Appropriate Size#
To determine the suitable size for our square, we need to base our logic on the number of elements. We can utilize a function to facilitate this.
Using a lambda function, we introduce the variable Ω
, which represents the count of elements. In our example, we have 5
elements:
{≢⍵} 1 2 3 4 5
This results in:
5
We need to find the nearest square number that can accommodate these elements.
To achieve this, we calculate the square root of the count of elements:
{(≢⍵) * ÷ 2} 1 2 3 4 5
This results in:
2.236067977
Since √5
is not a whole number, we must round it up to ensure the square is sufficiently large. The next integer is 3
. Therefore, we can define s
to represent this value, which squared gives us:
{⌈(≢⍵) * ÷ 2} 1 2 3 4 5
This results in:
3
We derive the square number of elements which, in our case, is:
{s × s ← ⌈(≢⍵) * ÷ 2} 1 2 3 4 5
This yields:
9
This implies the final array will need 9
elements.
Padding the Array#
To pad the original list to fit the new size, we can utilize the take
function. However, the take
function requires us to provide the number of elements first, followed by the data. Consequently, we must swap the order of arguments.
We can get the padded array using:
{⍵ ↑ ⍨ s × s ← ⌈(≢⍵) * ÷ 2} 1 2 3 4 5
This results in:
1 2 3 4 5 0 0 0 0
Now we have 9
elements, and the next step is to reshape the final array into s
rows and s
columns.
Refining the Definition#
We can refine our function slightly. We visualize the whole expression in terms of s
, the outcome from the previous expression on the right.
By utilizing a tested function, we can perform self-multiplication:
{s * s} 1 2 3 4 5
This gives:
9
This means we need to pad our original argument from the outside, ultimately reshaping the array to align with our specifications.
Self-Concatenation#
Instead of using s
explicitly, we can explore another approach. By replacing the explicit naming of s
with a functional notation, we can express the operation more concisely.
Using a function that applies the same argument on both sides:
{(,⍨⍴ × ⍨ ↑⍵⍨) ⌈ (≢⍵) * ÷ 2} 1 2 3 4 5
This notation offers a neat and compact way to implement our logic without cluttering it with variable declarations.
Conclusion#
This concise method is an effective way to arrange elements into a square array while managing padding gracefully. Thank you for following along in this exploration of square array fitting.