I'm kind of new to using Mathematica, so any help is great. I'm trying to write a program that will create a list or matrix that will give each small triangle's point numbers. For example if given an isosceles right triangle, the example below gives the sides as 4 and the numbering of the points is just like below, then it should give a list or table such as
dat= {{1,2,6},{2,3,7},{3,4,8},{4,5,9},{6,7,10},{7,8,11},{8,9,12},{10,11,13},
{11,12,14},{13,14,15},{2,6,7},{3,7,8},{4,8,9},{7,10,11},{8,11,12},{11,13,14}}.
I've tried writing a few loops, but am not getting anywhere. I know that the starting number on the diagonal of the big triangle will add whatever the side is and start decreasing that value as u go up. For example, the first point always starts at 1, and as u move up the rows of triangle, you add 1+(x+1)
to get 6. Then going up the next row of triangles, it is 6+(x)
, to get 10. And so on. So I see two iterators? once increasing? one decreasing? Any help or ideas will be helpful. Thanks!
Answer
A revision of my earlier, hurried function:
fn[_, 0] := {}
fn[s_:1, n_] := Join[
Rest @ Array[Thread @ {#, # + {n, 1}, # + n + 1} &, n, s, Join],
fn[s + n + 1, n - 1]
]
Test:
fn[4]
{{1, 2, 6}, {2, 6, 7}, {2, 3, 7}, {3, 7, 8}, {3, 4, 8}, {4, 8, 9}, {4, 5, 9},
{6, 7, 10}, {7, 10, 11}, {7, 8, 11}, {8, 11, 12}, {8, 9, 12}, {10, 11, 13},
{11, 13, 14}, {11, 12, 14}, {13, 14, 15}}
It is a recursive function that calls itself. It operates line by line; it keeps track of two values: s
which is the starting number (defaulting to one), and n
which is the number of lines left to go (your input value to begin with). I shall try to add a full breakdown of the code later.
Breakdown
Starting from the innermost part I wrote a Function
that takes a single number and returns the corresponding triangle points, given the correct value for n
. For point 3
in the bottom line of your diagram:
n = 4; (* there are four lines above point 3 *)
{#, # + {n, 1}, # + n + 1} &[3]
{3, {7, 4}, 8}
This represents two paths, either 3, 7, 8 or 3, 4, 8; I expand it using Thread
:
Thread @ {3, {7, 4}, 8}
{{3, 7, 8}, {3, 4, 8}}
I use this function in Array
, with the additional parameter s
which is the starting number for that line. For the first line in the diagram it is 1
, for the second 6
, the third 10
, etc. Using the second line as an example:
n = 3;
s = 6;
Array[Thread @ {#, # + {n, 1}, # + n + 1} &, n, s, Join]
{{6, 9, 10}, {6, 7, 10}, {7, 10, 11}, {7, 8, 11}, {8, 11, 12}, {8, 9, 12}}
Note that we have an incorrect triplet: {6, 9, 10}. This occurs at the start of each line because the line above is one element shorter; I get rid of it using Rest
.
We now have a function to generate triplets for each line. To find all lines I have the function call itself with the parameters for the line above it and Join
the results. When the outer function (fn
) is called with 0
for parameter n
meaning "zero lines above" it returns an empty set ({}
) and the recursion terminates.
Comments
Post a Comment