Given two points p (x1, y1) and q (x2, y2), Calculate the number of integral points lying on the line joining them.
Note:Â You are given the 4 points x1, y1, x2, y2 as Input.
Examples :
Input: x1 = 2, y1 = 2, x2 = 5, y2 = 2
Output: 2
Explanation: The strictly internal integral points on the horizontal line segment joining (2, 2) and (5, 2) are (3, 2) and (4, 2).Input: x1 = 1, y1 = 9, x2 = 8, y2 = 16
Output: 6
Explanation: There are 6 integral points on the line joining (1,9) and (8,16).
Table of Content
[Naive Approach] Step Division Check - O(max(dx, dy)) Time and O(1) Space
Divide segment into steps equal to max(dx, dy). Check each intermediate point (excluding endpoints) for integer coordinates.
- Compute dx = abs(x2 - x1), dy = abs(y2 - y1)
- steps = max(dx, dy)
- If steps == 0, return 0
- For i from 1 to steps -1, compute x and y using linear interpolation
- If both coordinates are integers, increment count
- Return count
#include <iostream>
#include <cmath>
using namespace std;
int countIntegralPoints(int x1, int y1, int x2, int y2) {
int dx = abs(x2 - x1);
int dy = abs(y2 - y1);
// Divide the segment into small equal parts
int steps = max(dx, dy);
if (steps == 0)
return 0;
int count = 0;
// Check all points between the two endpoints
for (int i = 1; i < steps; i++) {
long double x = x1 + (long double)(x2 - x1) * i / steps;
long double y = y1 + (long double)(y2 - y1) * i / steps;
// Count the point if both coordinates are integers
if (x == floor(x) && y == floor(y))
count++;
}
return count;
}
int main() {
int x1 = 2, y1 = 2;
int x2 = 5, y2 = 2;
cout << countIntegralPoints(x1, y1, x2, y2);
return 0;
}
class GFG {
static int countIntegralPoints(int x1, int y1, int x2, int y2) {
int dx = Math.abs(x2 - x1);
int dy = Math.abs(y2 - y1);
// Divide the segment into small equal parts
int steps = Math.max(dx, dy);
if (steps == 0)
return 0;
int count = 0;
// Check all points between the two endpoints
for (int i = 1; i < steps; i++) {
double x = x1 + (double)(x2 - x1) * i / steps;
double y = y1 + (double)(y2 - y1) * i / steps;
// Count the point if both coordinates are integers
if (x == Math.floor(x) && y == Math.floor(y))
count++;
}
return count;
}
public static void main(String[] args) {
int x1 = 2, y1 = 2;
int x2 = 5, y2 = 2;
System.out.println(countIntegralPoints(x1, y1, x2, y2));
}
}
import math
def countIntegralPoints(x1, y1, x2, y2):
dx = abs(x2 - x1)
dy = abs(y2 - y1)
# Divide the segment into small equal parts
steps = max(dx, dy)
if steps == 0:
return 0
count = 0
# Check all points between the two endpoints
for i in range(1, steps):
x = x1 + (x2 - x1) * i / steps
y = y1 + (y2 - y1) * i / steps
# Count the point if both coordinates are integers
if x == math.floor(x) and y == math.floor(y):
count += 1
return count
if __name__ == "__main__":
x1, y1 = 2, 2
x2, y2 = 5, 2
print(countIntegralPoints(x1, y1, x2, y2))
using System;
class GFG {
static int countIntegralPoints(int x1, int y1, int x2, int y2) {
int dx = Math.Abs(x2 - x1);
int dy = Math.Abs(y2 - y1);
// Divide the segment into small equal parts
int steps = Math.Max(dx, dy);
if (steps == 0)
return 0;
int count = 0;
// Check all points between the two endpoints
for (int i = 1; i < steps; i++) {
decimal x = x1 + (decimal)(x2 - x1) * i / steps;
decimal y = y1 + (decimal)(y2 - y1) * i / steps;
// Count the point if both coordinates are integers
if (x == Math.Floor(x) && y == Math.Floor(y))
count++;
}
return count;
}
static void Main(string[] args) {
int x1 = 2, y1 = 2;
int x2 = 5, y2 = 2;
Console.WriteLine(countIntegralPoints(x1, y1, x2, y2));
}
}
function countIntegralPoints(x1, y1, x2, y2)
{
let dx = Math.abs(x2 - x1);
let dy = Math.abs(y2 - y1);
// Divide the segment into small equal parts
let steps = Math.max(dx, dy);
if (steps === 0)
return 0;
let count = 0;
// Check all points between the two endpoints
for (let i = 1; i < steps; i++) {
let x = x1 + (x2 - x1) * i / steps;
let y = y1 + (y2 - y1) * i / steps;
// Count the point if both coordinates are integers
const EPS = 1e-9;
if (Math.abs(x % 1) < EPS && Math.abs(y % 1) < EPS)
count++;
}
return count;
}
// Driver code
const x1 = 2, y1 = 2;
const x2 = 5, y2 = 2;
console.log(countIntegralPoints(x1, y1, x2, y2));
Output
2
[Expected Approach] Mathematical Formula - O(log(min(dx, dy))) Time and O(1) Space
- If the edge formed by joining p and q is parallel to the Y-axis, then the number of integral points between the vertices is abs(p.y - q.y) - 1.
- If edge is parallel to the X-axis, then the number of integral points in between is abs(p.x - q.x) - 1.
- In general, we can find the integral points between the vertices using formula GCD(abs(p.x - q.x), abs(p.y - q.y)) - 1
How does the GCD formula work?Â
A clearer way to prove it is to focus on the size of the smallest possible step along the line.
Suppose the two points are:
P(x1, y1) and Q(x2, y2)
Let:
dx = |x2 - x1|
dy = |y2 - y1|
Now let:
g = GCD(dx, dy)
Since g divides both dx and dy, we can write:
dx = g × a
dy = g × b
where a and b are coprime.
So the movement from P to Q is:
(dx, dy) = g × (a, b)
This means we can move from P to Q in exactly g equal steps, where each step is:
(a, b) = (dx/g, dy/g)
Because a and b are integers, every step lands on an integer-coordinate point.
Therefore, the points on the line are:
P, P + (a,b), P + 2(a,b), ..., P + g(a,b) = Q
There are g + 1 points in total, including P and Q.
Since we want only the points strictly between P and Q, remove the two endpoints:
(g + 1) - 2 = g - 1
Since g = GCD(dx, dy):
Number of integer-coordinate points = GCD(dx, dy) - 1
Example:
P = (2, 3), Q = (8, 9)
dx = 6, dy = 6
GCD(6, 6) = 6
The smallest step is:
(6/6, 6/6) = (1, 1)
So we get:
(2,3) -> (3,4) -> (4,5) -> (5,6) -> (6,7) -> (7,8) -> (8,9)
There are 6 steps and therefore 5 points strictly between them.
Answer = 6 - 1 = 5.
#include <iostream>
#include <cmath>
using namespace std;
int gcd(int a, int b) {
a = abs(a);
b = abs(b);
while (b) {
int temp = a % b;
a = b;
b = temp;
}
return a;
}
int countIntegralPoints(int x1, int y1, int x2, int y2) {
// Same point, so nothing lies between them
if (x1 == x2 && y1 == y2)
return 0;
int dx = abs(x2 - x1);
int dy = abs(y2 - y1);
// Number of lattice points strictly between the endpoints
return gcd(dx, dy) - 1;
}
int main() {
int x1 = 2, y1 = 2;
int x2 = 5, y2 = 2;
cout << countIntegralPoints(x1, y1, x2, y2);
return 0;
}
class GFG {
static int gcd(int a, int b) {
a = Math.abs(a);
b = Math.abs(b);
while (b != 0) {
int temp = a % b;
a = b;
b = temp;
}
return a;
}
static int countIntegralPoints(int x1, int y1, int x2, int y2) {
// Same point, so nothing lies between them
if (x1 == x2 && y1 == y2)
return 0;
int dx = Math.abs(x2 - x1);
int dy = Math.abs(y2 - y1);
// Number of lattice points strictly between the endpoints
return gcd(dx, dy) - 1;
}
public static void main(String[] args) {
int x1 = 2, y1 = 2;
int x2 = 5, y2 = 2;
System.out.println(countIntegralPoints(x1, y1, x2, y2));
}
}
import math
def gcd(a, b):
a = abs(a)
b = abs(b)
while b:
a, b = b, a % b
return a
def countIntegralPoints(x1, y1, x2, y2):
# Same point, so nothing lies between them
if x1 == x2 and y1 == y2:
return 0
dx = abs(x2 - x1)
dy = abs(y2 - y1)
# Number of lattice points strictly between the endpoints
return gcd(dx, dy) - 1
if __name__ == "__main__":
x1, y1 = 2, 2
x2, y2 = 5, 2
print(countIntegralPoints(x1, y1, x2, y2))
using System;
class GFG {
static int gcd(int a, int b) {
a = Math.Abs(a);
b = Math.Abs(b);
while (b != 0) {
int temp = a % b;
a = b;
b = temp;
}
return a;
}
static int countIntegralPoints(int x1, int y1, int x2, int y2) {
// Same point, so nothing lies between them
if (x1 == x2 && y1 == y2)
return 0;
int dx = Math.Abs(x2 - x1);
int dy = Math.Abs(y2 - y1);
// Number of lattice points strictly between the endpoints
return gcd(dx, dy) - 1;
}
static void Main(string[] args) {
int x1 = 2, y1 = 2;
int x2 = 5, y2 = 2;
Console.WriteLine(countIntegralPoints(x1, y1, x2, y2));
}
}
function gcd(a, b) {
a = Math.abs(a);
b = Math.abs(b);
while (b !== 0) {
let temp = a % b;
a = b;
b = temp;
}
return a;
}
function countIntegralPoints(x1, y1, x2, y2) {
// Same point, so nothing lies between them
if (x1 === x2 && y1 === y2)
return 0;
let dx = Math.abs(x2 - x1);
let dy = Math.abs(y2 - y1);
// Number of lattice points strictly between the endpoints
return gcd(dx, dy) - 1;
}
// Driver code
const x1 = 2, y1 = 2;
const x2 = 5, y2 = 2;
console.log(countIntegralPoints(x1, y1, x2, y2));
Output
2
 Â
Â