# Triangular numbers boolean function

I read the new book by Paul Wellin Programming in Mathematica. There is an exercise about triangular numbers. (The n-th triangular number is defined as the sum of the integers 1 through n.
They are so named because they can be represented visually by arranging rows of dots in a triangular manner. The first ten triangular numbers are: 1, 3, 6, 10, 15, 21, 28, 36, 45.)

In the solution there are given functions which will give the nth triangular number.

For instance:

f1[n_] := Total[Range[n]]

f2[n_] := Fold[#1 + #2 &, 0, Range[n]]

f3[n_] := Binomial[n + 1, 2]


Regarding the timings, we have f3 > f1 > f2 (using the number 50000005000000 from Wellin's book) (in my laptop t3 = 0.01 sec, t1 = 0.18 sec, t3 = 3.8 sec).

I was thinking about a boolean function that will return true or false, whether the number is triangular or not.

My procedural style approach is:

triangularQ[n_] :=
Module[{y, dy}, For[y = 0; dy = 1, y < n, y += dy++];
If[y == n, Print[True], Print[False]]]


But it does not look so efficient.

Are there other approaches that use functional programming?

It seems good to compare the various solutions (the number 50000005000000 is from Wellin's book).

First the procedural:

In:= triangularQ // Timing

During evaluation of In:= True

Out= {41.562500, Null}


Aky's

In:= f[x_, n_] := f[x - n, n + 1]; f[0, n_] := True;
f[x_ /; x < 0, n_] := False

In:=
Block[{$IterationLimit = ∞}, f[50000005000000, 1]] // Timing Out= {114.703125, True}  Eldo's I coud not get true for MemberQ[ f2 /@ Range@(10^7), 50000005000000]  in reasonable time (less than$2$minutes). Nasser's In:= triangularQ // Timing During evaluation of In:= True Out= {41.421875, Null}  So the procedural style is not deficient at all :-)! • Here's a functional approach: define f[x_, n_] := f[x - n, n + 1]; f[0, n_] := True; f[x_ /; x < 0, n_] := False and evaluate f[testNumber, 1], if True it is a triangular number, if False then not. Of course, there's an explicit formula for triangular numbers (try Sum[k, {k, 1, n}]) so using that formula you could simply check whether the number being tested has a positive integral solution in n. But that's no longer a functional programming solution. – Aky Jul 12 '14 at 10:58 • Aky I know that formula Sum[k, {k, 1, n}] will return the nth triangular number but I cannot understand what do you mean by "...you could simply check whether the number being tested has a positive integral solution in n..." – Dimitris Jul 12 '14 at 11:28 • If m is a triangular number then m == n(n+1)/2 will be satisfied by some positive integer n, otherwise it won't. – Aky Jul 12 '14 at 12:14 • I obtain much quicker times (<1ms) than you cite for @Nasser Binomial approach - you may want to Clear formulae and variables and retest? – PlaysDice Jul 12 '14 at 15:34 • You are right! My apologies to Nasser! – Dimitris Jul 12 '14 at 22:45 ## 6 Answers Here is another approach (based on$t_n=\frac{n(n+1)}{2}$): fn[x_] := Mod[Sqrt[1 + 8 x], 2] == 1  For the test example fn is true: Just for fun (but factoring extremely large numbers an issue): an[x_?(# > 0 &)] := Abs[# - 2 x/#] & @@ Nearest[Divisors[ 2 x], Sqrt[2 x]] == 1 an := True  Just for illustration (and not proof but are straightforward to show): this is picking from 0,1,...,100 the triangular numbers. fnf = Pick[Range[0, 100], fn[#] & /@ Range[0, 100]] anf = Pick[Range[0, 100], an[#] & /@ Range[0, 100]] tn = Table[j (j + 1)/2, {j, 0, Length[anf] - 1}] Grid[Prepend[ Transpose[ {tn, fnf, anf}], {"Triangular number", "fn", "an"}], Frame -> All] UPDATE Testing the case in edited question (and using Mr Wizard timeAvg function): timeAvg[func_] := Do[If[# > 0.3, Return[#/5^i]] & @@ Timing@Do[func, {5^i}], {i, 0, 15}] {timeAvg[#], #} &@fn  yields:{1.47200*10^-8, True} • What is this timeAvg function? – Dimitris Jul 12 '14 at 12:11 • Definetely, very quick! – Dimitris Jul 12 '14 at 12:13 • @dimitris Mr. Wizard provided this code as a way to get the average timing of a function/procedure by doing it over and over again. You can search the site for more insights. – ubpdqn Jul 12 '14 at 12:14 • @ubqdqn +1 how would you code (f.e. with a Manipulate) images like here: link? I tried but ended up with extremely ugly code. – eldo Jul 12 '14 at 23:16 • @eldo sorry for the delay in replying...this is related and in the post there is a link to a notebook...I have not looked at this since the time...my code may be ugly: mathematica.stackexchange.com/a/39347/1997 – ubpdqn Jul 14 '14 at 3:43 The$n^{th}$triangle number satisfies Binomial[n+1,2], therefore, solving for m=Binomial[n+1,2] and checking if the solution is an integer gives the answer directly. triangularQ[m_] := IntegerQ@(n /. First@Solve[Binomial[n + 1, 2] == m, n]) {#, triangularQ[#]} & /@ Range[2, 28] // TableForm There is an especially useful function HarmonicNumber appearing most likely the best approach in similar tasks since its implementation is optimized and it has close relations to number theoretic functions like the Riemann zeta function ζ represented in Mathematica by Zeta, basically HarmonicNumber tends to Zeta for Re[z] > 1 : Limit[ HarmonicNumber[n, z], n -> Infinity, Assumptions -> Re[z] > 1]  Zeta[z]  where z can be an arbitrary complex number with the real part greater than$1\$.

We ask if a given integer k is triangular, i.e. if there exist another integer n such that $$1 + 2 + \ldots + n = k$$ Here is a straightforward implementation of natural (direct) approach:

tri[k_Integer] := Resolve @ Exists[ n, n ∈ Integers && n > 0,
k == HarmonicNumber[n, -1]]


It works this way:

tri /@ Range[3, 10]

{True, False, False, True, False, False, False, True}


It can be generalized to a more universal solution, namely when we are looking for higher order triangular numbers, e.g. HarmonicNumber[n, -p] yields the following sum $$1^p + 2^p + \ldots + n^p = k(n,p)$$

tri[k_Integer, p_Integer] := Resolve @ Exists[ n, n ∈ Integers && n > 0,
k == HarmonicNumber[n, -p]]


e.g. this gives a few first order triangular numbers

{#, HarmonicNumber [n, -#]} & /@ Range // TableForm // TraditionalForm and of course

HarmonicNumber[n, -p] == Sum[k^p, {k, n}]

True


To conclude we underline that the solution based on HarmonicNuber is the fastest, the most general and sheds light on crucial number theoretic objects.

• always learning something...thank you for nice answer – ubpdqn Jul 12 '14 at 11:55

Well, not to beat a dead horse, but there is a way to do this using simple arithmetic, the pieces of which are in some of the responses given so far. Since any triangular number T is equal to n(n+1)/2 for some n, a bit of algebraic manipulation gives:

2T = n^2 + n
8T = 4n^2 + 4n


Completing the square:

8T + 1 = 4n^2 + 4n + 1
= (2n+1)^2


So, T is triangular if 8T+1 is an odd perfect-square. Here then is the test:

SquareNumberQ[n_]:= IntegerQ[Sqrt[n]];
TriangularNumberQ[t_]:= OddQ[Sqrt[8t+1]] && SquareNumberQ[8t+1]

TriangularNumberQ//Timing
{0.000045, True}


Finding all triangular numbers less than 10^6 takes about 8 seconds on my computer using

Select[Range[10^6], TriangularNumberQ]

• I just saw the reply from Mr. Wellin. Thank you very much! – Dimitris Apr 23 '15 at 16:44
MemberQ[f2 /@ Range@1000, 3003]


True

With[{r = Range@10, tri = f2 /@ Range@1000}, Transpose[{r, MemberQ[tri, #] & /@ r}]] // TableForm Take[CoefficientList[Series[x/(1 - x)^3, {x, 0, 100}], x], -10]


{4186, 4278, 4371, 4465, 4560, 4656, 4753, 4851, 4950, 5050}

This is not a computationally efficient solution, but it works also in a spreadsheet:

nn = 12;
a = Table[Sum[If[n == k*(k + 1)/2, 1, 0], {k, 1, nn}], {n, 1, nn}];
b = Table[If[a[[i]] == 1, True, False], {i, 1, nn}]


Output:

{True, False, True, False, False, True, False, False, False, True, False, False}