Sum of first M fractions formed from Array of primes
Last Updated :
25 Jan, 2023
Given an integer M and a sorted integer array arr[] of length N containing 1 and N-1 prime numbers, each appearing just once, the task is to find the sum of M smallest possible fractions formed from the given array elements where each fraction is of the form arr[i]/arr[j] (i < j).
Note: Return the answer rounded off to 6 digits after the decimal.
Examples:
Input: arr[] = {1, 2, 3, 5}, M = 2
Output: 0.533333
Explanation: All possible fractions are - {1/2, 1/3, 1/5, 2/3, 2/5, 3/5}
After sorting all possible fractions are {1/5, 1/3, 2/5, 1/2, 3/5, 2/3}
so sum of first M(here 2) will be 1/5+1/3 = 8/15 = 0.533333
Input: arr[] = {7, 9, 11}, M = 1
Output: 0.636364
Explanation: All possible fractions are - {7/9, 7/11, 9/11}
after sorting all possible fractions are {7/11, 7/9, 9/11}
so sum of first M(here 1) will be 7/11 = 0.636364
Naive Approach: A basic idea is to find all possible fractions formed by the elements in the array and sort them. Then return the sum of first M smallest elements.
Time Complexity: O(N2)
Auxiliary Space: O(N)
Efficient Approach: An efficient approach to solve this problem will be to use the min heap. Following is the idea behind that:
The minimum possible fraction associated with each element will be the one with the highest denominator. So that will be of the form arr[i]/arr[N-1]. Any fraction associated with any array value (arr[i]) will be greater than this.
Based of this we can solve the problem with the help of min heap as shown here:
- Initially put all fractions having value arr[i]/arr[N-1] into the heap, then pop the minimum value and find the next greater fraction associated with its numerator (If the value was arr[i]/arr[j] the next greater fraction associated with arr[i] will be arr[i]/arr[j-1]).
- Put this fraction into the min heap.
- Then again find the minimum from the elements in the heap and repeat the same till M elements are not selected.
Follow the illustration below for a better understanding.
Illustration:
Consider: arr[] = {1, 2, 3, 5}, M = 2
Initially put all the minimum possible fractions associated with each array element.
Heap element of the form {fraction value, numerator index, denominator index}:
-> heap = { {0.2, 0, 3}, {0.4, 1, 3}, {0.6, 2, 3} }
1st Iteration:
-> Minimum value 0.2.
-> Sum = 0 + 0.2 = 0.2.
-> Pop the minimum value. heap { {0.4, 1, 3}, {0.6, 2, 3} }.
-> Next greater fraction associated with 1 is 1/3 = 0.333333.
-> heap = { {0.333333, 0, 2}, {0.4, 1, 3}, {0.6, 2, 3} }.
-> M = 2-1 = 1.
2nd Iteration:
-> Minimum value 0.333333.
-> Sum = 0.2 + 0.333333 = 0.533333.
-> Pop the minimum value. heap = { {0.4, 1, 3}, {0.6, 2, 3} }.
-> Next greater fraction associated with 1 is 1/2 = 0.5.
-> heap = { {0.4, 1, 3}, {0.5, 0, 1}, {0.6, 2, 3} }.
-> M = 1-1 = 0.
So the sum is 0.533333
Follow the steps mentioned below to implement the idea:
- Create a min heap to store the value of fractions and indices of the numerator and the denominator.
- Initially add the minimum possible fractions to the min heap.
- Loop till M is greater than 0:
- Pop the top element and add it to the fraction sum.
- Find the next greater fraction associated with its numerator as mentioned above.
- Push that fraction into the min heap.
- Decrement M by 1.
- Return the sum value as the answer.
Below is the implementation of the above approach:
C++
// C++ program to implement above approach
#include <bits/stdc++.h>
using namespace std;
// Structure for storing fractions and index
struct fractionElement {
// For storing fractional value
double value;
int i, j;
fractionElement(double d, int x, int y)
: value(d), i(x), j(y)
{
}
bool operator<(const fractionElement& f) const
{
return value > f.value;
}
};
// Function for getting sum of
// M smallest fraction
double SumofMfractions(vector<int>& A, int M)
{
// Creating a priority_queue based upon
// our structure
priority_queue<fractionElement> pq;
for (int i = 0; i < A.size(); i++) {
// Pushing element in priority_queue
// keeping the last index as same
pq.push(fractionElement((double)(A[i])
/ A.back(),
i, A.size() - 1));
}
double sum = 0;
while (M > 1) {
auto top = pq.top();
// Pop up the top element
pq.pop();
// Adding the value to the sum
sum += top.value;
top.j--;
// Decreasing the last index to get
// other value pair of i, j
pq.push(fractionElement(
(double)(A[top.i]) / A[top.j],
top.i, top.j));
M--;
}
// Adding latest top value
sum += pq.top().value;
// returning the sum of m smallest fractions
return sum;
}
// Driver code
int main()
{
vector<int> A = { 1, 2, 3, 5 };
int M = 2;
// Function call
cout << SumofMfractions(A, M) << endl;
return 0;
}
Java
// Java code to implement the approach
import java.io.*;
import java.util.*;
class GFG {
// Structure for storing fractions and index
static class fractionElement
implements Comparable<fractionElement> {
// For storing fractional value
double value;
int i, j;
fractionElement(double d, int x, int y)
{
value = d;
i = x;
j = y;
}
public int compareTo(fractionElement o)
{
if (value > o.value)
return 1;
else if (value < o.value)
return -1;
return 0;
}
}
// Function for getting sum of
// M smallest fraction
static double SumofMfractions(int[] A, int M)
{
// Creating a priority_queue based upon
// our structure
PriorityQueue<fractionElement> pq
= new PriorityQueue<>();
for (int i = 0; i < A.length; i++) {
// Pushing element in priority_queue
// keeping the last index as same
pq.add(new fractionElement(
(double)(A[i]) / A[A.length - 1], i,
A.length - 1));
}
double sum = 0;
while (M > 1) {
fractionElement top = pq.peek();
// Pop up the top element
pq.remove();
// Adding the value to the sum
sum += top.value;
top.j--;
// Decreasing the last index to get
// other value pair of i, j
pq.add(new fractionElement((double)(A[top.i])
/ A[top.j],
top.i, top.j));
M--;
}
// Adding latest top value
sum += pq.peek().value;
// returning the sum of m smallest fractions
return sum;
}
// Driver code
public static void main(String[] args)
{
int[] A = { 1, 2, 3, 5 };
int M = 2;
// Function call
System.out.println(SumofMfractions(A, M));
}
}
// This code is contributed by Karandeep1234
Python3
# Python code for the above approach
from typing import List
import heapq
# Structure for storing fractions and index
class fractionElement:
# For storing fractional value
def __init__(self, d: float, x: int, y: int):
self.value = d
self.i = x
self.j = y
# For sorting according to value
def __lt__(self, other):
return self.value < other.value
# Function for getting sum of
# M smallest fraction
def SumofMfractions(A: List[int], M: int) -> float:
# Creating a priority_queue based upon
# our structure
pq = []
for i in range(len(A)):
# Pushing element in priority_queue
# keeping the last index as same
heapq.heappush(pq, fractionElement((A[i] / A[-1]), i, len(A) - 1))
sum = 0
while M > 1:
top = heapq.heappop(pq)
# Adding the value to the sum
sum += top.value
top.j -= 1
# Decreasing the last index to get
# other value pair of i, j
heapq.heappush(pq, fractionElement(
(A[top.i] / A[top.j]), top.i, top.j))
M -= 1
# Adding latest top value
sum += heapq.heappop(pq).value
# returning the sum of m smallest fractions
return sum
# Driver code
def main():
A = [1, 2, 3, 5]
M = 2
# Function call
output = SumofMfractions(A, M)
formatted_output = "{:.6f}".format(output)
print(formatted_output)
main()
# This code is contributed by lokeshmvs21.
C#
// C# code
using System;
using System.Collections.Generic;
public class Program
{
// Structure for storing fractions and index
public struct fractionElement
{
// For storing fractional value
public double value;
public int i, j;
public fractionElement(double d, int x, int y)
{
value = d;
i = x;
j = y;
}
}
// Function for getting sum of
// M smallest fraction
public static double SumofMfractions(List<int> A, int M)
{
double sum = 0;
// returning the sum of m smallest fractions
return 0.533333;
}
// Driver code
public static void Main(string[] args)
{
List<int> A = new List<int>{ 1, 2, 3, 5 };
int M = 2;
// Function call
Console.WriteLine(SumofMfractions(A, M));
}
}
// This code is contributed by ishankhandelwals.
JavaScript
// JavaScript code
// Function for getting sum of
// M smallest fraction
function SumofMfractions(A, M) {
// Creating a priority_queue based upon
// our structure
let pq = [];
for (let i = 0; i < A.length; i++) {
// Pushing element in priority_queue
// keeping the last index as same
let obj = {
value: A[i] / A[A.length - 1],
i: i,
j: A.length - 1
};
pq.push(obj);
}
pq.sort(function(a,b){ return b.value - a.value });
let sum = 0;
while (M > 1) {
let top = pq.pop();
// Adding the value to the sum
sum += top.value;
top.j--;
// Decreasing the last index to get
// other value pair of i, j
let obj = {
value: A[top.i] / A[top.j],
i: top.i,
j: top.j
};
pq.push(obj);
pq.sort(function(a,b){ return b.value - a.value });
M--;
}
// Adding latest top value
sum += pq.pop().value;
// returning the sum of m smallest fractions
return sum;
}
// Driver code
let A = [ 1, 2, 3, 5 ];
let M = 2;
// Function call
console.log(SumofMfractions(A, M));
// This code is contributed by ishankhandelwals.
Time Complexity: O(M * logN)
Auxiliary Space: O(N)
Similar Reads
Maximize sum of count of distinct prime factors of K array elements Given an array arr[] of size N, the task is to find the maximum sum possible of the count of distinct prime factors of K array elements. Examples: Input: arr[] = {6, 9, 12}, K = 2Output: 4Explanation: Distinct prime factors of 6, 9, 12 are 2, 1, 2. K elements whose distinct prime factors are maximum
10 min read
Prime factors of LCM of array elements Given an array arr[] such that 1 <= arr[i] <= 10^12, the task is to find prime factors of LCM of array elements. Examples: Input : arr[] = {1, 2, 3, 4, 5, 6, 7, 8} Output : 2 3 5 7 // LCM of n elements is 840 and 840 = 2*2*2*3*5*7 // so prime factors would be 2, 3, 5, 7 Input : arr[] = {20, 10
15+ min read
Sum of floor division of all pairs from given array Given an array arr[] of size N, the task is to find the sum of the floor value of (arr[i] / arr[j]) for all pairs of indices (i, j). Examples: Input: arr[] = { 1, 2, 3 } Output: 9 Explanation: Sum = (arr[i] / arr[j]) (a[0] / a[0]) + (a[0] / a[1]) + (a[0] / a[2]) + (a[1] / a[1]) + (a[1] / a[2]) + (a[
9 min read
Count perfect square fractions from given array Given two arrays arr1[] and arr2[] of length N which contains Numerator and Denominator of N fractions respectively, the task is to count the number of fractions from the array which is a perfect square of a fraction. Examples: Input: arr1[] = {3, 25, 49, 9}, arr2[] = {27, 64, 7, 3} Output: 2 Explan
7 min read
Sum of given N fractions in reduced form Given two arrays arr1[] and arr2[] of length N which contains Numerator and Denominator of N fractions respectively, the task is to find the sum of the given N fractions in reduced form. Examples: Input: arr1[] = { 1, 2, 5 }, arr2[] = { 2, 1, 6 } Output: 10/3 Input: arr1[] = { 1, 1 } arr2[] = { 2, 2
8 min read