Cake Distribution Problem
Given two integers N and M, where N is the number of friends sitting in a clockwise manner in a circle and M is the number of cakes. The task is to calculate the left number of cakes after distributing i cakes to i’th friend. The distribution of cakes will stop if the count of cakes is less than the required amount.
Examples:
Input: N = 4, M = 11
Output: 0
1st round:
The 1st friend gets 1 cake, 2nd gets 2 cakes,
3rd get 3 and 4th gets 4 cakes.
Remaining cakes = 11 – (1 + 2 + 3 + 4) = 1
2nd round:
This time only 1st friend gets the left 1 cake.
Remaining cakes = 1 – 1 = 0
Input: N = 3, M = 8
Output: 1
1st round:
The 1st friend gets 1 cake, 2nd gets 2 cakes,
and 3rd get 3 cakes.
Remaining cakes = 8 – (1 + 2 + 3) = 2
2nd round:
This time only 1st friend gets the left 1 cake,
and then there is no cake left for 2nd friend.
Remaining cakes = 2 – 1 = 1
Approach:
- Check how many cycles of distribution of cakes are possible from m number of cakes.
- Calculate the number of cakes for 1 cycle which is
sum = n * (n + 1) / 2
- Now diving M by sum we get cycle count + some remainder.
- Now check how many remaining cakes are again possible to distribute to x friends.
- The value of x can be easily achieved by solving quadratic equation
remainder = x * (x + 1) / 2
Below is the implementation of the above approach:
C++
#include<bits/stdc++.h>
using namespace std;
int cntCakes( int n, int m)
{
int sum = (n * (n + 1)) / 2;
int quo = m/sum ;
int rem = m % sum ;
double ans = m - quo * sum ;
double x = (-1 + pow ((8 * rem) + 1, 0.5)) / 2;
ans = ans - x * (x + 1) / 2;
return int (ans);
}
int main ()
{
int n = 3;
int m = 8;
int ans = cntCakes(n, m);
cout << (ans);
}
|
Java
class GFG
{
static int cntCakes( int n, int m)
{
int sum = (n * (n + 1 )) / 2 ;
int quo = m/sum ;
int rem = m % sum ;
double ans = m - quo * sum ;
double x = (- 1 + Math.pow(( 8 * rem) + 1 , 0.5 )) / 2 ;
ans = ans - x * (x + 1 ) / 2 ;
return ( int )ans;
}
public static void main (String[] args)
{
int n = 3 ;
int m = 8 ;
int ans = cntCakes(n, m);
System.out.println(ans);
}
}
|
Python3
def cntCakes(n, m):
sum = (n * (n + 1 )) / / 2
quo, rem = m / / sum , m % sum
ans = m - quo * sum
x = int (( - 1 + ( 8 * rem + 1 ) * * 0.5 ) / 2 )
ans = ans - x * (x + 1 ) / / 2
return ans
def main():
n = 4
m = 11
ans = cntCakes(n, m)
print (ans)
main()
|
C#
using System;
class GFG
{
static int cntCakes( int n, int m)
{
int sum = (n * (n + 1)) / 2;
int quo = m/sum ;
int rem = m % sum ;
double ans = m - quo * sum ;
double x = (-1 + Math.Pow((8 * rem) + 1, 0.5)) / 2;
ans = ans - x * (x + 1) / 2;
return ( int )ans;
}
static public void Main ()
{
int n = 3;
int m = 8;
int ans = cntCakes(n, m);
Console.Write(ans);
}
}
|
Javascript
<script>
function cntCakes(n, m)
{
let sum = (n * (n + 1)) / 2;
let quo = m/sum;
let rem = m % sum ;
let ans = m - quo * sum + 6;
let x = (-1 + Math.pow((8 * rem) + 1, 0.5));
ans = ans - x * (x + 1) / 2;
return parseInt(ans, 10);
}
let n = 3;
let m = 8;
let ans = cntCakes(n, m);
document.write(ans);
</script>
|
Time Complexity: O(1)
Auxiliary Space: O(1)
Approach name: Recursive approach
Steps:
- Define a recursive function “calculate_left_cakes” that takes three parameters “n”, “m”, and “i“.
- If the value of “m” is less than the value of “i”, then return the value of “m” minus 1.
- Otherwise, subtract the value of “i” from “m”, increment the value of “i” by 1, and call the recursive function again with the new values of “m” and “i”.
- Finally, print the result of the function call.
Below is the implementation of above approach:-
C++
#include <cmath>
#include <iostream>
using namespace std;
int cntCakes( int n, int m)
{
int sum = (n * (n + 1)) / 2;
int quo = m / sum;
int rem = m % sum;
int ans = m - quo * sum;
int x = (-1 + sqrt (1 + 8 * rem)) / 2;
ans = ans - x * (x + 1) / 2;
return ans;
}
int main()
{
int n = 4;
int m = 11;
int ans = cntCakes(n, m);
cout << ans << endl;
return 0;
}
|
Java
import java.util.*;
public class Main {
public static int cntCakes( int n, int m) {
int sum = (n * (n + 1 )) / 2 ;
int quo = m / sum;
int rem = m % sum;
int ans = m - quo * sum;
int x = ( int ) ((- 1 + Math.sqrt( 1 + 8 * rem)) / 2 );
ans = ans - x * (x + 1 ) / 2 ;
return ans;
}
public static void main(String[] args) {
int n = 4 ;
int m = 11 ;
int ans = cntCakes(n, m);
System.out.println(ans);
}
}
|
Python3
def calculate_left_cakes(n, m, i = 1 ):
if m < i:
return m - 1
return calculate_left_cakes(n, m - i, i + 1 )
n = 4
m = 11
left_cakes = calculate_left_cakes(n, m)
print ( "Left Cakes:" , left_cakes)
n = 3
m = 8
left_cakes = calculate_left_cakes(n, m)
print ( "Left Cakes:" , left_cakes)
|
C#
using System;
public class Program {
public static int cntCakes( int n, int m) {
int sum = (n * (n + 1)) / 2;
int quo = m / sum;
int rem = m % sum;
int ans = m - quo * sum;
int x = ( int ) ((-1 + Math.Sqrt(1 + 8 * rem)) / 2);
ans = ans - x * (x + 1) / 2;
return ans;
}
public static void Main( string [] args) {
int n = 4;
int m = 11;
int ans = cntCakes(n, m);
Console.WriteLine(ans);
}
}
|
Javascript
function cntCakes(n, m) {
let sum = (n * (n + 1)) / 2;
let quo = Math.floor(m / sum);
let rem = m % sum;
let ans = m - quo * sum;
let x = Math.floor((-1 + Math.sqrt(1 + 8 * rem)) / 2);
ans = ans - x * (x + 1) / 2;
return ans;
}
let n = 4;
let m = 11;
let ans = cntCakes(n, m);
console.log(ans);
|
Time complexity: O(n), where n is the value of “m”. In the worst case, the recursive function will be called n times before the base case is reached.
Auxiliary Space: O(1)
Last Updated :
07 Jan, 2024
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...