Open In App

Number of Triangles that can be formed given a set of lines in Euclidean Plane

Last Updated : 23 Jun, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given a set L = {l1, l2, ………, ln} of ‘n’ distinct lines on the Euclidean Plane. The ith line is given by an equation in the form aix + biy = ci. Find the number of triangles that can be formed using the lines in the set L. Note that no two pairs of lines intersect at the same point. 
Note: This problem doesn’t mention that the lines can’t be parallel which makes the problem difficult to solve.

Examples: 

Input: a[] = {1, 2, 3, 4}
       b[] = {2, 4, 5, 5}
       c[] = {5, 7, 8, 6}
Output: 2
The number of triangles that can be formed are: 2

Input: a[] = {1, 2, 3, 2, 4, 1, 2, 3, 4, 5}
       b[] = {2, 4, 6, 3, 6, 5, 10, 15, 20, 25}
       c[] = {3, 5, 11, 10, 9, 17, 13, 11, 7, 3}
Output: 30
The number of triangles that can be formed are: 30

Naive Algorithm

The naive algorithm can be described as: 

  1. Pick up 3 arbitrary lines from the set L.
  2. Now check if a triangle can be formed using the selected 3 lines. This can be done easily by checking that none of them is pairwise parallel.
  3. Increment the counter if the triangle can be formed. 
     

Time Complexity: There are nC3 triplets of lines. For each triplet, we have to do 3 comparisons to check that any 2 lines are not parallel which means the check can be done in O(1) time. This makes the naive algorithm O(n3).

Efficient Algorithm

This can also be achieved in O(n log n). The logic behind the efficient algorithm is described below.
We divide the set L in various subsets. The formation of subsets is based on slopes i.e. all the lines in a particular subset have the same slope i.e. they are parallel to each other.

Let us consider three sets (say A, B and C). For a particular set (say A) the lines belonging to this are all parallel to each other. If we have A, B, and C, we can pick one line from each set to get a triangle because none of these lines will be parallel. By making the subsets we have ensured that no two lines which are parallel are being picked together.

SubsetOfParallelLines

Now if we have only these 3 subsets

Number of triangles = (Number of ways to pick a line from A) * 
                      (Number of ways to pick a line from B) * 
                      (Number of ways to pick a line from C) 
                   = m1*m2*m3
Here m1 is count of elements with first slope (in Set A)
Here m2 is count of elements with first slope (in Set B)
Here m3 is count of elements with first slope (in Set C)

Similarly, if we have 4 subsets, we can extend this logic to get, 
Number of triangles = m1*m2*m3 + m1*m2*m4 + m1*m3*m4 + m2*m3*m4

For number of subsets greater than 3, If we have ‘k’ subsets, our task is to find the sum of number of elements of the subset taken 3 at a time. This can be done by maintaining a count array. We make a count array where counti denotes the count of the ith subset of parallel lines. 

We one by one compute following values.
sum1 = m1 + m2 + m3 .....
sum2 = m1*m2 + m1*m3 + ... + m2*m3 + m2*m4 + ...
sum3 = m1*m2*m3 + m1*m2*m4 + ...... m2*m3*m4 + ....
sum3 gives our final answer

C++




// C++ program to find the number of
// triangles that can be formed
// using a set of lines in Euclidean
// Plane
#include <bits/stdc++.h>
using namespace std;
 
#define EPSILON numeric_limits<double>::epsilon()
 
// double variables can't be checked precisely
// using '==' this function returns true if
// the double variables are equal
bool compareDoubles(double A, double B)
{
    double diff = A-B;
    return (diff<EPSILON) && (-diff<EPSILON);
}
 
// This function returns the number of triangles
// for a given set of lines
int numberOfTringles(int a[], int b[], int c[], int n)
{
    //slope array stores the slope of lines
    double slope[n];
    for (int i=0; i<n; i++)
        slope[i] = (a[i]*1.0)/b[i];
 
    // slope array is sorted so that all lines
    // with same slope come together
    sort(slope, slope+n);
 
    // After sorting slopes, count different
    // slopes. k is index in count[].
    int count[n], k = 0;
    int this_count = 1;   // Count of current slope
    for (int i=1; i<n; i++)
    {
        if (compareDoubles(slope[i], slope[i-1]))
            this_count++;
        else
        {
            count[k++] = this_count;
            this_count = 1;
        }
    }
    count[k++] = this_count;
 
    // calculating sum1 (Sum of all slopes)
    // sum1 = m1 + m2 + ...
    int sum1 = 0;
    for (int i=0; i<k; i++)
        sum1 += count[i];
 
    // calculating sum2. sum2 = m1*m2 + m2*m3 + ...
    int sum2 = 0;
    int temp[n];  // Needed for sum3
    for (int i=0; i<k; i++)
    {
        temp[i] = count[i]*(sum1-count[i]);
        sum2 += temp[i];
    }
    sum2 /= 2;
 
    // calculating sum3 which gives the final answer
    // m1 * m2 * m3 + m2 * m3 * m4 + ...
    int sum3 = 0;
    for (int i=0; i<k; i++)
        sum3 += count[i]*(sum2-temp[i]);
    sum3 /= 3;
 
    return sum3;
}
 
// Driver code
int main()
{
    // lines are stored as arrays of a, b
    // and c for 'ax+by=c'
    int a[] = {1, 2, 3, 4};
    int b[] = {2, 4, 5, 5};
    int c[] = {5, 7, 8, 6};
 
    // n is the number of lines
    int n = sizeof(a)/sizeof(a[0]);
 
    cout << "The number of triangles that"
            " can be formed are: "
         << numberOfTringles(a, b, c, n);
 
    return 0;
}


Java




// Java program to find the number of
// triangles that can be formed
// using a set of lines in Euclidean
// Plane
import java.util.*;
 
class GFG{
     
static double EPSILON = 1.0842e-19;
 
// Double variables can't be checked precisely
// using '==' this function returns true if
// the double variables are equal
static boolean compareDoubles(double A, double B)
{
    double diff = A - B;
    return (diff < EPSILON) &&
          (-diff < EPSILON);
}
 
// This function returns the number of
// triangles for a given set of lines
static int numberOfTringles(int []a, int []b,
                            int []c, int n)
{
     
    // Slope array stores the slope of lines
    Vector<Double> slope = new Vector<>();
    for(int i = 0; i < n; i++)
        slope.add((double)(a[i] * 1.0) / b[i]);
 
    // Slope array is sorted so that all lines
    // with same slope come together
    Collections.sort(slope);
 
    // After sorting slopes, count different
    // slopes. k is index in count[].
    int []count = new int [n];
    int k = 0;
     
    // Count of current slope
    int this_count = 1;
     
    for(int i = 1; i < n; i++)
    {
        if (compareDoubles((double)slope.get(i),
                           (double)slope.get(i - 1)))
            this_count++;
        else
        {
            count[k++] = this_count;
            this_count = 1;
        }
    }
    count[k++] = this_count;
 
    // Calculating sum1 (Sum of all slopes)
    // sum1 = m1 + m2 + ...
    int sum1 = 0;
    for(int i = 0; i < k; i++)
        sum1 += count[i];
 
    // Calculating sum2. sum2 = m1*m2 + m2*m3 + ...
    int sum2 = 0;
     
    // Needed for sum3
    int temp[] = new int [n];
     
    for(int i = 0; i < k; i++)
    {
        temp[i] = count[i] * (sum1 - count[i]);
        sum2 += temp[i];
    }
    sum2 /= 2;
 
    // Calculating sum3 which gives the
    // final answer
    // m1 * m2 * m3 + m2 * m3 * m4 + ...
    int sum3 = 0;
    for(int i = 0; i < k; i++)
        sum3 += count[i] * (sum2 - temp[i]);
         
    sum3 /= 3;
 
    return sum3;
}
 
// Driver code
public static void main(String[] args)
{
     
    // Lines are stored as arrays of a, b
    // and c for 'ax+by=c'
    int a[] = { 1, 2, 3, 4 };
    int b[] = { 2, 4, 5, 5 };
    int c[] = { 5, 7, 8, 6 };
 
    // n is the number of lines
    int n = a.length;
 
    System.out.println("The number of triangles " +
                       "that can be formed are: " +
                       numberOfTringles(a, b, c, n));
}
}
 
// This code is contributed by Stream_Cipher


Python3




#  Python program to find the number of
#  triangles that can be formed
#  using a set of lines in Euclidean
#  Plane
import math
EPSILON = 1.0842e-19
 
# double variables can't be checked precisely
# using '==' this function returns true if
# the double variables are equal
 
 
def compareDoubles(A, B):
    diff = A-B
    return (diff < EPSILON) and (-diff < EPSILON)
 
#  This function returns the number of triangles
#  for a given set of lines
 
 
def numberOfTringles(a, b, c, n):
    # slope array stores the slope of lines
    slope = []
 
    for i in range(0, n):
        slope.append((a[i]*1.0)/b[i])
 
    # slope array is sorted so that all lines
    # with same slope come together
    slope.sort()
 
    # After sorting slopes, count different
    # slopes. k is index in count[].
    k = 0
    count = []
    this_count = 1  # Count of current slope
 
    for i in range(1, n):
        if compareDoubles(slope[i], slope[i-1]):
            this_count = this_count + 1
        else:
            count.append(this_count)
            k = k + 1
            this_count = 1
 
    count.append(this_count)
    k = k + 1
 
    # calculating sum1 (Sum of all slopes)
    # sum1 = m1 + m2 + ...
    sum1 = 0
    for i in range(0, k):
        sum1 += count[i]
 
    # calculating sum2. sum2 = m1*m2 + m2*m3 + ...
    sum2 = 0
    temp = []  # Needed for sum3
    for i in range(0, k):
        temp.append(count[i]*(sum1-count[i]))
        sum2 += temp[i]
 
    sum2 = math.floor(sum2/2)
 
    # calculating sum3 which gives the final answer
    # m1 * m2 * m3 + m2 * m3 * m4 + ...
    sum3 = 0
    for i in range(0, k):
        sum3 += count[i]*(sum2-temp[i])
 
    sum3 = math.floor(sum3/3)
 
    return sum3
 
 
# Driver Code
# lines are stored as arrays of a, b
# and c for 'ax+by=c'
a = [1, 2, 3, 4]
b = [2, 4, 5, 5]
c = [5, 7, 8, 6]
 
# n is the number of lines
n = len(a)
 
print("The number of triangles that can be formed are: ",
      numberOfTringles(a, b, c, n))
 
# The code is contributed by Gautam goel (gautamgoel962)


C#




// C# program to find the number of
// triangles that can be formed
// using a set of lines in Euclidean
// Plane
using System.Collections.Generic;
using System; 
 
class GFG{
     
static double EPSILON = 1.0842e-19;
 
// Double variables can't be checked precisely
// using '==' this function returns true if
// the double variables are equal
static bool compareDoubles(double A, double B)
{
    double diff = A - B;
    return (diff < EPSILON) &&
          (-diff < EPSILON);
}
 
// This function returns the number of
// triangles for a given set of lines
static int numberOfTringles(int []a, int []b,
                            int []c, int n)
{
     
    // Slope array stores the slope of lines
    List<double> slope = new List<double>();
    for(int i = 0; i < n; i++)
        slope.Add((double)(a[i] * 1.0) / b[i]);
 
    // Slope array is sorted so that all lines
    // with same slope come together
    slope.Sort();
 
    // After sorting slopes, count different
    // slopes. k is index in count[].
    int []count = new int [n];
    int k = 0;
     
    // Count of current slope
    int this_count = 1;
     
    for(int i = 1; i < n; i++)
    {
        if (compareDoubles((double)slope[i],
                           (double)slope[i - 1]))
            this_count++;
        else
        {
            count[k++] = this_count;
            this_count = 1;
        }
    }
    count[k++] = this_count;
 
    // Calculating sum1 (Sum of all slopes)
    // sum1 = m1 + m2 + ...
    int sum1 = 0;
    for(int i = 0; i < k; i++)
        sum1 += count[i];
 
    // Calculating sum2. sum2 = m1*m2 + m2*m3 + ...
    int sum2 = 0;
     
    // Needed for sum3
    int []temp = new int [n];
    for(int i = 0; i < k; i++)
    {
        temp[i] = count[i] * (sum1 - count[i]);
        sum2 += temp[i];
    }
    sum2 /= 2;
 
    // Calculating sum3 which gives
    // the final answer
    // m1 * m2 * m3 + m2 * m3 * m4 + ...
    int sum3 = 0;
     
    for(int i = 0; i < k; i++)
        sum3 += count[i] * (sum2 - temp[i]);
         
    sum3 /= 3;
 
    return sum3;
}
 
// Driver code
public static void Main()
{
     
    // lines are stored as arrays of a, b
    // and c for 'ax+by=c'
    int []a = { 1, 2, 3, 4 };
    int []b = { 2, 4, 5, 5 };
    int []c = { 5, 7, 8, 6 };
 
    // n is the number of lines
    int n = a.Length;
 
     Console.WriteLine("The number of triangles " +
                       "that can be formed are: " +
                       numberOfTringles(a, b, c, n));
}
}
 
// This code is contributed by Stream_Cipher


Javascript




<script>
      // JavaScript program to find the number of
      // triangles that can be formed
      // using a set of lines in Euclidean
      // Plane
      const EPSILON = 1.0842e-19;
 
      // Double variables can't be checked precisely
      // using '==' this function returns true if
      // the double variables are equal
      function compareDoubles(A, B) {
        var diff = A - B;
        return diff < EPSILON && -diff < EPSILON;
      }
 
      // This function returns the number of
      // triangles for a given set of lines
      function numberOfTringles(a, b, c, n) {
        // Slope array stores the slope of lines
        var slope = [];
        for (var i = 0; i < n; i++) slope.push(parseFloat(a[i] * 1.0) / b[i]);
 
        // Slope array is sorted so that all lines
        // with same slope come together
        slope.sort();
 
        // After sorting slopes, count different
        // slopes. k is index in count[].
        var count = new Array(n).fill(0);
        var k = 0;
 
        // Count of current slope
        var this_count = 1;
 
        for (var i = 1; i < n; i++) {
          if (compareDoubles(parseFloat(slope[i]), parseFloat(slope[i - 1])))
            this_count++;
          else {
            count[k++] = this_count;
            this_count = 1;
          }
        }
        count[k++] = this_count;
 
        // Calculating sum1 (Sum of all slopes)
        // sum1 = m1 + m2 + ...
        var sum1 = 0;
        for (var i = 0; i < k; i++) sum1 += count[i];
 
        // Calculating sum2. sum2 = m1*m2 + m2*m3 + ...
        var sum2 = 0;
 
        // Needed for sum3
        var temp = new Array(n).fill(0);
        for (var i = 0; i < k; i++) {
          temp[i] = count[i] * (sum1 - count[i]);
          sum2 += temp[i];
        }
        sum2 /= 2;
 
        // Calculating sum3 which gives
        // the final answer
        // m1 * m2 * m3 + m2 * m3 * m4 + ...
        var sum3 = 0;
        for (var i = 0; i < k; i++) sum3 += count[i] * (sum2 - temp[i]);
        sum3 /= 3;
        return sum3;
      }
 
      // Driver code
      // lines are stored as arrays of a, b
      // and c for 'ax+by=c'
      var a = [1, 2, 3, 4];
      var b = [2, 4, 5, 5];
      var c = [5, 7, 8, 6];
 
      // n is the number of lines
      var n = a.length;
 
      document.write(
        "The number of triangles " +
          "that can be formed are: " +
          numberOfTringles(a, b, c, n)
      );
       
      // This code is contributed by rdtank.
    </script>


Output: 

The number of triangles that can be formed are: 2

Time Complexity: All the loops in the code are O(n). The time complexity in this implementation is thus driven by the sort function used to sort the slope array. This makes the algorithm O(nlogn).
Auxiliary Space: O(n)

 



Previous Article
Next Article

Similar Reads

Number of triangles formed from a set of points on three lines
Given three integers m, n, and k that store the number of points on lines l1, l2, and l3 respectively that do not intersect. The task is to find the number of triangles that can possibly be formed from these set of points. Examples: Input: m = 3, n = 4, k = 5 Output: 205Input: m = 2, n = 2, k = 1 Output: 10 Approach: The total number of points are
5 min read
Total number of triangles formed when there are H horizontal and V vertical lines
Given a triangle ABC. H horizontal lines from side AB to AC (as shown in fig.) and V vertical lines from vertex A to side BC are drawn, the task is to find the total no. of triangles formed.Examples: Input: H = 2, V = 2 Output: 18 As we see in the image above, total triangles formed are 18.Input: H = 3, V = 4 Output: 60 Approach: As we see in the i
5 min read
Maximum number of region in which N non-parallel lines can divide a plane
Given N', the number of non-parallel lines. The task is to find the maximum number of regions in which these lines can divide a plane.Examples: Input : N = 3 Output : 7Input : N = 2 Output : 4 [caption width="800"]Maximum number of regions on a plane formed due to non-parallel lines[/caption] Approach: The above image shows the maximum number of re
4 min read
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,
9 min read
Find number of unique triangles among given N triangles
Given three arrays a[], b[], and c[] of N elements representing the three sides of N triangles. The task is to find the number of triangles that are unique out of given triangles. A triangle is non-unique if all of its sides match with all the sides of some other triangle in length.Examples: Input: a[] = {1, 2}, b[] = {2, 3}, c[] = {3, 5} Output: 2
6 min read
Number of triangles in a plane if no more than two points are collinear
Given n points in a plane and no more than two points are collinear, the task is to count the number of triangles in a given plane. Examples: Input : n = 3 Output : 1 Input : n = 4 Output : 4 Let there are n points in a plane and no three or more points are collinear then number of triangles in the given plane is given by [Tex]^{n}\textrm{C}_{3} =
4 min read
Maximum count of Equilateral Triangles that can be formed within given Equilateral Triangle
Given two integers N and K where N denotes the unit size of a bigger Equilateral Triangle, the task is to find the number of an equilateral triangle of size K that are present in the bigger triangle of side N. Examples: Input: N = 4, K = 3 Output: 3Explanation:There are 3 equilateral triangles of 3 unit size which are present in the Bigger equilate
5 min read
Check if N given lines can be intersected by K vertical lines
Given N horizontal lines represented by an array position[][] of size N, where position[i] represents the ith horizontal line which has x-coordinates from position[i][0] to position[i][1] and an integer K, which represents the maximum number of vertical lines that can be drawn, the task is to check if N given lines can be intersected by at most K v
6 min read
Python - Find the maximum number of triangles with given points on three lines
Given three parallel straight lines l1, l2 and l3 lying in the same plane. Total numbers of m, n and k points lie on the line l1, l2, l3 respectively. This article aims to find the maximum number of triangles formed with vertices at these points. Examples: Input : m = 14, n = 34, k = 114 Output : 448708.0 Input : m = 95, n = 77, k = 94 Output : 275
3 min read
Maximize count of unique Squares that can be formed with N arbitrary points in coordinate plane
Given a positive integer N, the task is to find the maximum number of unique squares that can be formed with N arbitrary points in the coordinate plane. Note: Any two squares that are not overlapping are considered unique. Examples: Input: N = 9Output: 5Explanation:Consider the below square consisting of N points: The squares ABEF, BCFE, DEHG, EFIH
7 min read
Practice Tags :