GFG App
Open App
Browser
Continue

# Number of triangles that can be formed with given N points

Given X and Y coordinates of N points on a Cartesian plane. The task is to find the number of possible triangles with the non-zero area that can be formed by joining each point to every other point.
Examples:

```Input: P[] = {{0, 0}, {2, 0}, {1, 1}, {2, 2}}
Output: 3
Possible triangles can be [(0, 0}, (2, 0), (1, 1)],
[(0, 0), (2, 0), (2, 2)] and [(1, 1), (2, 2), (2, 0)]

Input : P[] = {{0, 0}, {2, 0}, {1, 1}}
Output : 1```

A Naive approach has been already discussed in Number of possible Triangles in a Cartesian coordinate system
7Efficient Approach: Consider a point Z and find its slope with every other point. Now, if two points are having the same slope with point Z that means the 3 points are collinear and they cannot form a triangle. Hence, the number of triangles having Z as one of its points is the number of ways of choosing 2 points from the remaining points and then subtracting the number of ways of choosing 2 points from points having the same slope with Z. Since Z can be any point among N points, we have to iterate one more loop.

Steps to solve the problem:

• Initialize an empty map mp and a variable ans to 0.
•  Iterate from 0 to N-1.
• Clear the map mp.
• For each point i, calculate the slope of all other points with respect to the current point.
• calculate the greatest common divisor (GCD) of the difference in X and Y coordinate
• between point i and j. Divide the difference in X and Y coordinates by their GCD.
• Store the slope as a key-value pair in the map mp, where the key is a pair of integers representing the slope and the value is the frequency of that slope.
• Calculate the number of ways by the formula (N – (i + 1)) * (N – (i + 1) – 1) / 2. Add this value to the and.
• Iterate over the map mp, and for each key-value pair, calculate the number of ways by the formula j.second * (j.second – 1) /2.
• Subtract this value from the and.
• Return the final value of ans.

Below is the implementation of the above approach:

## C++

 `// C++ implementation of the above approach` `#include ` `using` `namespace` `std;`   `// This function returns the required number` `// of triangles` `int` `countTriangles(pair<``int``, ``int``> P[], ``int` `N)` `{` `    ``// Hash Map to store the frequency of` `    ``// slope corresponding to a point (X, Y)` `    ``map, ``int``> mp;` `    ``int` `ans = 0;`   `    ``// Iterate over all possible points` `    ``for` `(``int` `i = 0; i < N; i++) {` `        ``mp.clear();`   `        ``// Calculate slope of all elements` `        ``// with current element` `        ``for` `(``int` `j = i + 1; j < N; j++) {` `            ``int` `X = P[i].first - P[j].first;` `            ``int` `Y = P[i].second - P[j].second;`   `            ``// find the slope with reduced` `            ``// fraction` `            ``int` `g = __gcd(X, Y);` `            ``X /= g;` `            ``Y /= g;` `            ``mp[{ X, Y }]++;` `        ``}` `        ``int` `num = N - (i + 1);`   `        ``// Total number of ways to form a triangle` `        ``// having one point as current element` `        ``ans += (num * (num - 1)) / 2;`   `        ``// Subtracting the total number of ways to` `        ``// form a triangle having the same slope or are` `        ``// collinear` `        ``for` `(``auto` `j : mp)` `            ``ans -= (j.second * (j.second - 1)) / 2;` `    ``}` `    ``return` `ans;` `}`   `// Driver Code to test above function` `int` `main()` `{` `    ``pair<``int``, ``int``> P[] = { { 0, 0 }, { 2, 0 }, { 1, 1 }, { 2, 2 } };` `    ``int` `N = ``sizeof``(P) / ``sizeof``(P[0]);` `    ``cout << countTriangles(P, N) << endl;` `    ``return` `0;` `}`

## Java

 `// Java implementation of the above approach`   `import` `java.util.*;`   `class` `GFG {` `    ``// A recursive function to find gcd of two numbers.` `    ``static` `int` `__gcd(``int` `x, ``int` `y)` `    ``{` `        ``x = Math.abs(x);` `        ``y = Math.abs(y);` `        ``while` `(y > ``0``) {` `            ``int` `t = y;` `            ``y = x % y;` `            ``x = t;` `        ``}` `        ``return` `x;` `    ``}`   `    ``// This function returns the required number` `    ``// of triangles` `    ``static` `int` `countTriangles(``int``[][] P, ``int` `N)` `    ``{` `        ``// Hash Map to store the frequency of` `        ``// slope corresponding to a point (X, Y)` `        ``// map, int> mp;` `        ``HashMap mp` `            ``= ``new` `HashMap();`   `        ``int` `ans = ``0``;`   `        ``// Iterate over all possible points` `        ``for` `(``int` `i = ``0``; i < N; i++) {` `            ``mp.clear();`   `            ``// Calculate slope of all elements` `            ``// with current element` `            ``for` `(``int` `j = i + ``1``; j < N; j++) {` `                ``int` `X = P[i][``0``] - P[j][``0``];` `                ``int` `Y = P[i][``1``] - P[j][``1``];`   `                ``// find the slope with reduced` `                ``// fraction` `                ``int` `g = __gcd(X, Y);` `                ``X = (``int``)(X / g);` `                ``Y = (``int``)(Y / g);`   `                ``String key = String.valueOf(X) + ``","` `                             ``+ String.valueOf(Y);`   `                ``if` `(!mp.containsKey(key))` `                    ``mp.put(key, ``0``);` `                ``mp.put(key, mp.get(key) + ``1``);` `            ``}`   `            ``int` `num = N - (i + ``1``);`   `            ``// Total number of ways to form a triangle` `            ``// having one point as current element` `            ``ans += (``int``)((num * (num - ``1``)) / ``2``);`   `            ``// Subtracting the total number of ways to` `            ``// form a triangle having the same slope or are` `            ``// collinear` `            ``for` `(Map.Entry entry :` `                 ``mp.entrySet())` `                ``ans -= (entry.getValue()` `                        ``* (entry.getValue() - ``1``))` `                       ``/ ``2``;` `        ``}` `        ``return` `ans;` `    ``}`   `    ``// Driver Code to test above function` `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``int``[][] P` `            ``= { { ``0``, ``0` `}, { ``2``, ``0` `}, { ``1``, ``1` `}, { ``2``, ``2` `} };` `        ``int` `N = P.length;` `        ``System.out.println(countTriangles(P, N));` `    ``}` `}`   `// The code is contributed by phasing17`

## Python3

 `# Python3 implementation of the above approach ` `from` `collections ``import` `defaultdict` `from` `math ``import` `gcd`   `# This function returns the ` `# required number of triangles ` `def` `countTriangles(P, N): `   `    ``# Hash Map to store the frequency of ` `    ``# slope corresponding to a point (X, Y) ` `    ``mp ``=` `defaultdict(``lambda``:``0``) ` `    ``ans ``=` `0`   `    ``# Iterate over all possible points ` `    ``for` `i ``in` `range``(``0``, N): ` `        ``mp.clear() `   `        ``# Calculate slope of all elements ` `        ``# with current element ` `        ``for` `j ``in` `range``(i ``+` `1``, N): ` `            ``X ``=` `P[i][``0``] ``-` `P[j][``0``] ` `            ``Y ``=` `P[i][``1``] ``-` `P[j][``1``] `   `            ``# find the slope with reduced ` `            ``# fraction ` `            ``g ``=` `gcd(X, Y) ` `            ``X ``/``/``=` `g ` `            ``Y ``/``/``=` `g ` `            ``mp[(X, Y)] ``+``=` `1` `        `  `        ``num ``=` `N ``-` `(i ``+` `1``) `   `        ``# Total number of ways to form a triangle ` `        ``# having one point as current element ` `        ``ans ``+``=` `(num ``*` `(num ``-` `1``)) ``/``/` `2`   `        ``# Subtracting the total number of ` `        ``# ways to form a triangle having ` `        ``# the same slope or are collinear ` `        ``for` `j ``in` `mp: ` `            ``ans ``-``=` `(mp[j] ``*` `(mp[j] ``-` `1``)) ``/``/` `2` `    `  `    ``return` `ans `   `# Driver Code` `if` `__name__ ``=``=` `"__main__"``: `   `    ``P ``=` `[[``0``, ``0``], [``2``, ``0``], [``1``, ``1``], [``2``, ``2``]] ` `    ``N ``=` `len``(P) ` `    ``print``(countTriangles(P, N))` `    `  `# This code is contributed by Rituraj Jain`

## C#

 `// C# implementation of the above approach`   `using` `System;` `using` `System.Collections.Generic;`   `class` `GFG {` `    ``// A recursive function to find gcd of two numbers.` `    ``static` `int` `__gcd(``int` `x, ``int` `y)` `    ``{` `        ``x = Math.Abs(x);` `        ``y = Math.Abs(y);` `        ``while` `(y > 0) {` `            ``int` `t = y;` `            ``y = x % y;` `            ``x = t;` `        ``}` `        ``return` `x;` `    ``}`   `    ``// This function returns the required number` `    ``// of triangles` `    ``static` `int` `countTriangles(``int``[, ] P, ``int` `N)` `    ``{` `        ``// Hash Map to store the frequency of` `        ``// slope corresponding to a point (X, Y)` `        ``// map, int> mp;` `        ``Dictionary<``string``, ``int``> mp` `            ``= ``new` `Dictionary<``string``, ``int``>();`   `        ``int` `ans = 0;`   `        ``// Iterate over all possible points` `        ``for` `(``int` `i = 0; i < N; i++) {` `            ``mp.Clear();`   `            ``// Calculate slope of all elements` `            ``// with current element` `            ``for` `(``int` `j = i + 1; j < N; j++) {` `                ``int` `X = P[i, 0] - P[j, 0];` `                ``int` `Y = P[i, 1] - P[j, 1];`   `                ``// find the slope with reduced` `                ``// fraction` `                ``int` `g = __gcd(X, Y);` `                ``X = (``int``)(X / g);` `                ``Y = (``int``)(Y / g);`   `                ``int``[] l1 = { X, Y };` `                ``string` `key = ``string``.Join(``", "``, l1);`   `                ``if` `(!mp.ContainsKey(key))` `                    ``mp[key] = 0;` `                ``mp[key]++;` `            ``}`   `            ``int` `num = N - (i + 1);`   `            ``// Total number of ways to form a triangle` `            ``// having one point as current element` `            ``ans += (``int``)((num * (num - 1)) / 2);`   `            ``// Subtracting the total number of ways to` `            ``// form a triangle having the same slope or are` `            ``// collinear` `            ``foreach``(``var` `entry ``in` `mp) ans` `                ``-= (entry.Value * (entry.Value - 1)) / 2;` `        ``}` `        ``return` `ans;` `    ``}`   `    ``// Driver Code to test above function` `    ``public` `static` `void` `Main(``string``[] args)` `    ``{` `        ``int``[, ] P` `            ``= { { 0, 0 }, { 2, 0 }, { 1, 1 }, { 2, 2 } };` `        ``int` `N = P.GetLength(0);` `        ``Console.WriteLine(countTriangles(P, N));` `    ``}` `}`   `// The code is contributed by Nidhi goel`

## Javascript

 `// JavaScript implementation of the above approach`   `// A recursive function to find gcd of two numbers. ` `function` `__gcd(x, y) {` `  ``if` `((``typeof` `x !== ``'number'``) || (``typeof` `y !== ``'number'``)) ` `    ``return` `false``;` `  ``x = Math.abs(x);` `  ``y = Math.abs(y);` `  ``while``(y) {` `    ``var` `t = y;` `    ``y = x % y;` `    ``x = t;` `  ``}` `  ``return` `x;` `}`   `// This function returns the required number` `// of triangles` `function` `countTriangles(P, N)` `{` `    ``// Hash Map to store the frequency of` `    ``// slope corresponding to a point (X, Y)` `    ``// map, int> mp;` `    ``let mp = ``new` `Map();` `    `  `    ``let ans = 0;`   `    ``// Iterate over all possible points` `    ``for` `(let i = 0; i < N; i++) {` `        ``mp.clear();`   `        ``// Calculate slope of all elements` `        ``// with current element` `        ``for` `(let j = i + 1; j < N; j++) {` `            ``let X = P[i][0] - P[j][0];` `            ``let Y = P[i][1] - P[j][1];`   `            ``// find the slope with reduced` `            ``// fraction` `            ``let g = __gcd(X, Y);` `            ``X = Math.floor(X/g);` `            ``Y = Math.floor(Y/g);` `            `  `            ``if``(mp.has([X, Y].join())){` `                ``mp.set([X, Y].join(), mp.get([X, Y].join()) + 1);` `            ``}` `            ``else``{` `                ``mp.set([X, Y].join(), 1);` `            ``}` `            `  `        ``}` `        ``let num = N - (i + 1);`   `        ``// Total number of ways to form a triangle` `        ``// having one point as current element` `        ``ans += Math.floor((num * (num - 1)) / 2);`   `        ``// Subtracting the total number of ways to` `        ``// form a triangle having the same slope or are` `        ``// collinear` `        ``for` `(const [key, value] of mp.entries())` `            ``ans -= (value * (value - 1)) / 2;` `    ``}` `    ``return` `ans;` `}`   `// Driver Code to test above function` `let P = [[0, 0], [2, 0], [1, 1 ], [2, 2 ]];` `let N = P.length;` `console.log(countTriangles(P, N));`   `// The code is contributed by Nidhi goel`

Output:

`3`

Time Complexity: O(N2logN)
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up