Algorithm to generate positive rational numbers
Last Updated :
01 Aug, 2024
A rational number is of the form p/q where p and q are integers. The problem statement is to generate rational number such that any particular number is generated in a finite time. For a given n, we generate all rational numbers where 1 <= p <= n and 1 <= q <= n Examples:
Input : 5
Output : 1, 1/2, 2, 1/3, 2/3, 3/2, 3, 1/4,
3/4, 4/3, 4, 1/5, 2/5, 3/5, 4/5,
5/4, 5/3, 5/2, 5
Input : 7
Output :1, 1/2, 2, 1/3, 2/3, 3/2, 3, 1/4, 3/4,
4/3, 4, 1/5, 2/5, 3/5, 4/5, 5/4, 5/3,
5/2, 5, 1/6, 5/6, 6/5, 6, 1/7, 2/7, 3/7,
4/7, 5/7, 6/7, 7/6, 7/5, 7/4, 7/3, 7/2, 7
In mathematical terms a set is countably infinite if its elements can be mapped on a one to one basis with the set of natural numbers. The problem statement here is to generate combinations of p/q where both p and q are integers and any particular combination of p and q will be reached in a finite no. of steps. If p is incremented 1, 2, 3... etc keeping q constant or vice versa all combinations cannot be reached in finite time. The way to handle this is to imagine the natural numbers arranged as a row, col of a matrix (1, 1) (1, 2) (1, 3) (1, 4) (2, 1) (2, 2) (2, 3) (2, 4) (3, 1) (3, 2) (3, 3) (3, 4) (4, 1) (4, 2) (4, 3) (4, 4) These elements are traversed in an inverted L shape in each iteration (1, 1) (1, 2), (2, 2) (2, 1) (1, 3), (2, 3), (3, 3), (3, 2), (3, 1) yielding 1/1 1/2, 2/2, 2/1 1/3, 2/3, 3/3, 3/2, 3/1 Obviously this will yield duplicates as 2/1 and 4/2 etc, but these can be weeded out by using the Greatest common divisor constraint.
C++
// C++ program to implement the approach
#include <bits/stdc++.h>
using namespace std;
class RationalNumber {
int numerator, denominator;
public:
RationalNumber(int n, int d)
{
numerator = n;
denominator = d;
}
string toString()
{
if (denominator == 1) {
return to_string(numerator);
}
else {
return to_string(numerator) + "/"
+ to_string(denominator);
}
}
};
vector<RationalNumber> generate(int n)
{
vector<RationalNumber> list ;
if (n > 1) {
RationalNumber rational (1, 1);
list.push_back(rational);
}
for (int loop = 1; loop <= n; loop++) {
int jump = 1;
// Handle even case
if (loop % 2 == 0)
jump = 2;
else
jump = 1;
for (int row = 1; row <= loop - 1; row += jump) {
// Add only if there are no common divisors
// other than 1
if (__gcd(row, loop) == 1) {
RationalNumber rational(row, loop);
list.push_back(rational);
}
}
for (int col = loop - 1; col >= 1; col -= jump) {
// Add only if there are no common divisors
// other than 1
if (__gcd(col, loop) == 1) {
RationalNumber rational (loop, col);
list.push_back(rational);
}
}
}
return list;
}
// Driver Code
int main()
{
vector<RationalNumber> rationals = generate(7);
for (RationalNumber rational : rationals)
cout << rational.toString() + ", ";
}
// This code is contributed by phasing17
Java
// Java program
import java.util.ArrayList;
import java.util.List;
class Rational {
private static class RationalNumber {
private int numerator;
private int denominator;
public RationalNumber(int numerator, int denominator)
{
this.numerator = numerator;
this.denominator = denominator;
}
@Override
public String toString()
{
if (denominator == 1) {
return Integer.toString(numerator);
}
else {
return Integer.toString(numerator) + '/' +
Integer.toString(denominator);
}
}
}
/**
* Greatest common divisor
* @param num1
* @param num2
* @return
*/
private static int gcd(int num1, int num2)
{
int n1 = num1;
int n2 = num2;
while (n1 != n2) {
if (n1 > n2)
n1 -= n2;
else
n2 -= n1;
}
return n1;
}
private static List<RationalNumber> generate(int n)
{
List<RationalNumber> list = new ArrayList<>();
if (n > 1) {
RationalNumber rational = new RationalNumber(1, 1);
list.add(rational);
}
for (int loop = 1; loop <= n; loop++) {
int jump = 1;
// Handle even case
if (loop % 2 == 0)
jump = 2;
else
jump = 1;
for (int row = 1; row <= loop - 1; row += jump) {
// Add only if there are no common divisors other than 1
if (gcd(row, loop) == 1) {
RationalNumber rational = new RationalNumber(row, loop);
list.add(rational);
}
}
for (int col = loop - 1; col >= 1; col -= jump) {
// Add only if there are no common divisors other than 1
if (gcd(col, loop) == 1) {
RationalNumber rational = new RationalNumber(loop, col);
list.add(rational);
}
}
}
return list;
}
public static void main(String[] args)
{
List<RationalNumber> rationals = generate(7);
System.out.println(rationals.stream().
map(RationalNumber::toString).
reduce((x, y) -> x + ", " + y).get());
}
}
Python
# Python3 program to implement the approach
from math import gcd
class RationalNumber:
def __init__(self, numerator, denominator):
self.numerator = numerator;
self.denominator = denominator;
def __repr__(self):
if (self.denominator == 1):
return str(self.numerator)
else:
return str(self.numerator)+ '/' + str(self.denominator);
def generate(n):
list1 = [];
if (n > 1):
rational = RationalNumber(1, 1);
list1.append(rational);
for loop in range (1, n + 1):
jump = 1;
# Handle even case
if (loop % 2 == 0):
jump = 2;
else:
jump = 1;
for row in range(1, loop, jump):
# Add only if there are no common divisors
# other than 1
if (gcd(row, loop) == 1):
rational = RationalNumber(row, loop);
list1.append(rational);
for col in range(loop - 1, 0, -jump):
# Add only if there are no common divisors
# other than 1
if (gcd(col, loop) == 1):
rational = RationalNumber(loop, col);
list1.append(rational);
return list1;
# Driver Code
rationals = generate(7);
print(", ".join(repr(rational) for rational in rationals))
# This code is contributed by phasing17
C#
// C# program to implement the approach
using System;
using System.Linq;
using System.Collections.Generic;
public class RationalNumber {
private int numerator;
private int denominator;
public RationalNumber(int numerator, int denominator)
{
this.numerator = numerator;
this.denominator = denominator;
}
public string toString()
{
if (denominator == 1) {
return Convert.ToString(numerator);
}
else {
return Convert.ToString(numerator) + '/'
+ Convert.ToString(denominator);
}
}
}
class Rational {
/**
* Greatest common divisor
* @param num1
* @param num2
* @return
*/
private static int gcd(int num1, int num2)
{
int n1 = num1;
int n2 = num2;
while (n1 != n2) {
if (n1 > n2)
n1 -= n2;
else
n2 -= n1;
}
return n1;
}
private static List<RationalNumber> generate(int n)
{
List<RationalNumber> list
= new List<RationalNumber>();
if (n > 1) {
RationalNumber rational
= new RationalNumber(1, 1);
list.Add(rational);
}
for (int loop = 1; loop <= n; loop++) {
int jump = 1;
// Handle even case
if (loop % 2 == 0)
jump = 2;
else
jump = 1;
for (int row = 1; row <= loop - 1;
row += jump) {
// Add only if there are no common divisors
// other than 1
if (gcd(row, loop) == 1) {
RationalNumber rational
= new RationalNumber(row, loop);
list.Add(rational);
}
}
for (int col = loop - 1; col >= 1;
col -= jump) {
// Add only if there are no common divisors
// other than 1
if (gcd(col, loop) == 1) {
RationalNumber rational
= new RationalNumber(loop, col);
list.Add(rational);
}
}
}
return list;
}
// Driver Code
public static void Main(string[] args)
{
List<RationalNumber> rationals = generate(7);
foreach(var rational in rationals)
Console.Write(rational.toString() + ", ");
}
}
// This code is contributed by phasing17
JavaScript
// JavaScript program to implement the approach
class RationalNumber {
constructor(numerator, denominator)
{
this.numerator = numerator;
this.denominator = denominator;
}
toString()
{
if (this.denominator == 1) {
return (this.numerator).toString();
}
else {
return (this.numerator).toString() + '/'
+ (this.denominator).toString();
}
}
}
function gcd(num1, num2)
{
let n1 = num1;
let n2 = num2;
while (n1 != n2) {
if (n1 > n2)
n1 -= n2;
else
n2 -= n1;
}
return n1;
}
function generate(n)
{
let list = [];
if (n > 1) {
let rational = new RationalNumber(1, 1);
list.push(rational);
}
for (var loop = 1; loop <= n; loop++) {
var jump = 1;
// Handle even case
if (loop % 2 == 0)
jump = 2;
else
jump = 1;
for (var row = 1; row <= loop - 1; row += jump) {
// Add only if there are no common divisors
// other than 1
if (gcd(row, loop) == 1) {
let rational
= new RationalNumber(row, loop);
list.push(rational);
}
}
for (var col = loop - 1; col >= 1; col -= jump) {
// Add only if there are no common divisors
// other than 1
if (gcd(col, loop) == 1) {
let rational
= new RationalNumber(loop, col);
list.push(rational);
}
}
}
return list;
}
// Driver Code
let rationals = generate(7);
for (var rational of rationals)
process.stdout.write(rational.toString() + ", ");
// This code is contributed by phasing17
Output1, 1/2, 2, 1/3, 2/3, 3/2, 3, 1/4, 3/4, 4/3, 4, 1/5, 2/5, 3/5, 4/5, 5/4, 5/3, 5/2, 5, 1/6, 5/6, 6/5, 6, 1/7, 2/7, 3/7, 4/7, 5/7, 6/7, 7/6, 7/5, 7/4, 7/3, 7/2, 7
Time Complexity: O(n2)
Space Complexity: O(n2)
Similar Reads
Generating numbers that are divisor of their right-rotations Given a number m, find all numbers which have m digits and are a divisor of their right rotation. Right-rotation of a number N is the result of rotating the digits of N one place to the right and wrapping the least significant digit around so that it becomes the most significant digit. For example,
10 min read
N-th term of George Cantor set of rational numbers George cantor named mathematician gave a proof that set of rational numbers is enumerable. We don't have to proof it over here rather we have to determine the Nth term in the set of rational numbers. Examples : Input : N = 8 Output : 2/3 Input : N = 15 Output : 1/5 See image for reference of countin
7 min read
Search in an Array of Rational Numbers without floating point arithmetic Given a sorted array of rational numbers, where each rational number is represented in the form p/q (where p is the numerator and q is the denominator), the task is to find the index of a given rational number x in the array. If the number does not exist in the array, return -1.Examples: Input: arr[
9 min read
Find ratio of zeroes, positive numbers and negative numbers in the Array Given an array a of integers of size N integers, the task is to find the ratio of positive numbers, negative numbers and zeros in the array up to four decimal places. Examples: Input: a[] = {2, -1, 5, 6, 0, -3} Output: 0.5000 0.3333 0.1667 There are 3 positive, 2 negative, and 1 zero. Their ratio wo
7 min read
Generate all the binary number from 0 to n Given a positive integer number n generate all the binary number from 0 to n. Examples: Input : 5 Output : 0 1 10 11 100 101 Binary numbers are 0(0), 1(1), 2(10), 3(11), 4(100) and 5(101). Input : 10 Output : 0 1 10 11 100 101 110 111 1000 1001 1010 This program simple use predefined function (itoa(
6 min read