Saturday, October 21, 2023

Problem Solving: Allotment calculator

 Problem Statement:

Suppose the Government plans to issue up to $10,000 of Savings Bonds. Four individuals applied for a total of $18,000 of Savings Bonds: A ($2,000), B ($4,000) C ($5,500) and D ($6,500).

The available bonds will be spread out among as many investors as possible in the following manner:

  • Applications are filled in denominations of $500 upwards.
  • After Round 4, $8,000 of Savings Bonds have been allotted, and Investor A's application has been fully met. $2,000 of Savings Bonds are left.
  • In Round 5, $1,500 of Savings Bonds are allotted.
  • In Round 6, the remaining $500 is insufficient to fill all applications.
  • One person among Investor B, Investor C and Investor D is randomly allotted the remaining $500. In this case, Investor C gets it.

The cutoff amount in this case is $2,500. In the final allotment:

  • Investor A is allotted $2,000.
  • Investor B and Investor D get $2,500 each.
  • Investor C gets $3,000.
limitations:

1. The minimum individual investment amount is $500
2. The maximum individual investment amount is $200000
3. The individual investment amount always should be multiplies of $500

Find out the allotment amount issued to each individual investor.

The Solution:

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
public class SbPlanningCalculator {

private final static Integer MIN = 500;
private final static Integer MAX = 2_00_000;

private final static Predicate<List<User>> isAllValid = users -> {
int allCount = users.size();
int validCount = (int)users.stream().
map(User::getValue).
filter(value -> value >= MIN && value <= MAX && value % MIN == 0).
count();
return allCount == validCount;
};

public static Map<String, Integer> calculateMyPotential(List<User> users, Integer issuedAmount){

if(!isAllValid.test(users)){
System.err.print("Found Invalid Amounts among the users. ");
return null;
}

int total = 0;
Map<String, Integer> allotments = new HashMap<>(0);

int rounds = Math.divideExact(issuedAmount, users.size() * MIN);

int i = 0;
while(i <= rounds) {
for (User user : users) {
int issuedBalanceTotal = issuedAmount - total;

if (issuedBalanceTotal == 0) {
break;
}

if (user.getValue() >= MIN) {
total = total + MIN;
user.setValue(user.getValue() - MIN);

if (allotments.containsKey(user.getName())) {
int userAllotment = allotments.get(user.getName());
allotments.put(user.getName(), userAllotment + MIN);
} else {
allotments.put(user.getName(), MIN);
}
}

}
i++;
}
return allotments;
}
}

Test Cases:

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

class SbPlanningCalculatorTest {

@Test
void testCalculateMyPotentialCase1(){
List<User> users = new ArrayList<>(0);
users.add(new User("A", 2000));
users.add(new User("B", 4000));
users.add(new User("C", 5500));
users.add(new User("D", 6500));

Map<String, Integer> allotments = SbPlanningCalculator.calculateMyPotential(users, 10000);
System.out.println(allotments);
assert allotments != null;
var x = allotments.entrySet().stream().collect(Collectors.groupingBy(Map.Entry::getValue, Collectors.counting()));
long sum = x.entrySet().stream().map(e -> e.getKey() * e.getValue()).mapToLong(l -> l).sum();
Assertions.assertEquals(10000, sum);
}

@Test
void testCalculateMyPotentialCase2(){
List<User> users = new ArrayList<>(0);
users.add(new User("A", 2000));
users.add(new User("B", 4000));
users.add(new User("C", 5500));
users.add(new User("D", 26000));

Map<String, Integer> allotments = SbPlanningCalculator.calculateMyPotential(users, 1_000_000_000);
System.out.println(allotments);
assert allotments != null;
var x = allotments.entrySet().stream().collect(Collectors.groupingBy(Map.Entry::getValue, Collectors.counting()));
long sum = x.entrySet().stream().map(e -> e.getKey() * e.getValue()).mapToLong(l -> l).sum();
Assertions.assertEquals(37500, sum);
}

@Test
void testCalculateMyPotentialCase3(){
List<User> users = new ArrayList<>(0);
users.add(new User("A", 500));
users.add(new User("B", 2_00_000));
users.add(new User("C", 14000));
users.add(new User("D", 26000));

Map<String, Integer> allotments = SbPlanningCalculator.calculateMyPotential(users, 1_000_000_000);
System.out.println(allotments);
assert allotments != null;
var x = allotments.entrySet().stream().collect(Collectors.groupingBy(Map.Entry::getValue, Collectors.counting()));
long sum = x.entrySet().stream().map(e -> e.getKey() * e.getValue()).mapToLong(l -> l).sum();
Assertions.assertEquals(2_40_500, sum);
}

@Test
void testCalculateMyPotentialCase4(){
List<User> users = new ArrayList<>(0);
users.add(new User("A", 1_000_000));
users.add(new User("B", 2_00_000));
users.add(new User("C", 250));
users.add(new User("D", 26000));

Map<String, Integer> allotments = SbPlanningCalculator.calculateMyPotential(users, 1_000_000_000);
System.out.println(allotments);
Assertions.assertNull(allotments);
}

@Test
void testCalculateMyPotentialCase5(){
List<User> users = new ArrayList<>(0);
users.add(new User("A", 2_00_000));
users.add(new User("B", 2_00_000));
users.add(new User("C", 2_00_000));
users.add(new User("D", 26000));

for(int x = 0; x < 5500; x++){
users.add(new User("X" + x, 2_00_000));
}

Map<String, Integer> allotments = SbPlanningCalculator.calculateMyPotential(users, 1_000_000_000);

assert allotments != null;
var x = allotments.entrySet().stream().collect(Collectors.groupingBy(Map.Entry::getValue, Collectors.counting()));
System.out.println(x);
long sum = x.entrySet().stream().map(e -> e.getKey() * e.getValue()).mapToLong(l -> l).sum();
Assertions.assertEquals(1_000_000_000, sum);
}
}

No comments:

Post a Comment

Let's try to build scrum masters/project managers/software architects/even a company with training AI models

The concept: The basic concept is to build trained AI model for each role separately in scalable fashion within a private cloud. As an examp...