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
Number of integral points strictly between two endpoints equals gcd(|x2 - x1|, |y2 - y1|) - 1. This excludes both endpoints.
- If both points are same, return 0
- Compute dx = abs(x2 - x1), dy = abs(y2 - y1)
- Calculate gcd of dx and dy
- Return gcd(dx, dy) - 1
#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