Created
March 31, 2025 17:14
-
-
Save shortthirdman/32345bf9d82b49539fa2156e881910bb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.*; | |
import java.util.stream.Collectors; | |
/** | |
* TransactionType enum as an example. | |
* In your challenge environment, this might be pre-defined. | |
*/ | |
enum TransactionType { | |
P2P, | |
P2M, | |
P2MERC // or any other types you need | |
} | |
/** | |
* TransactionSummary as an example. | |
* In your challenge environment, this might be pre-defined. | |
*/ | |
class TransactionSummary { | |
private final int transactionId; | |
private final boolean isSenderEligibleForReward; | |
private final boolean isRewarded; | |
public TransactionSummary(int transactionId, boolean isSenderEligibleForReward, boolean isRewarded) { | |
this.transactionId = transactionId; | |
this.isSenderEligibleForReward = isSenderEligibleForReward; | |
this.isRewarded = isRewarded; | |
} | |
public int getTransactionId() { | |
return transactionId; | |
} | |
public boolean isSenderEligibleForReward() { | |
return isSenderEligibleForReward; | |
} | |
public boolean isRewarded() { | |
return isRewarded; | |
} | |
} | |
/** | |
* Payment class that you need to implement. | |
* It keeps track of transactions, determines if the sender is in the top X | |
* for P2M transaction amounts, and returns a TransactionSummary. | |
*/ | |
public class Payment { | |
// Map of senderId -> (TransactionType -> count of transactions) | |
private final Map<Integer, Map<TransactionType, Integer>> userTransactionCounts; | |
// Map of senderId -> total amount of P2M transactions | |
private final Map<Integer, Integer> userP2MTotalAmounts; | |
// The threshold rank (top X) for reward eligibility | |
private final int topX; | |
public Payment(int topX) { | |
this.topX = topX; | |
this.userTransactionCounts = new HashMap<>(); | |
this.userP2MTotalAmounts = new HashMap<>(); | |
} | |
/** | |
* Records a payment and returns a TransactionSummary. | |
* | |
* @param transactionId unique identifier for the transaction | |
* @param senderId user who initiates the transaction | |
* @param amount transaction amount | |
* @param transactionType type of the transaction (P2P, P2M, etc.) | |
* @return TransactionSummary indicating reward status | |
*/ | |
public TransactionSummary makePayment(int transactionId, int senderId, int amount, TransactionType transactionType) { | |
// 1. Increment transaction count for the sender and transaction type | |
userTransactionCounts | |
.computeIfAbsent(senderId, k -> new HashMap<>()) | |
.merge(transactionType, 1, Integer::sum); | |
boolean isSenderEligibleForReward = false; | |
boolean isRewarded = false; | |
// 2. If P2M, update total amounts and check if user is in the top X | |
if (transactionType == TransactionType.P2M) { | |
// Update total P2M amount for this sender | |
userP2MTotalAmounts.merge(senderId, amount, Integer::sum); | |
// Sort users by their total P2M amounts in descending order | |
List<Map.Entry<Integer, Integer>> sortedByP2MDesc = userP2MTotalAmounts.entrySet() | |
.stream() | |
.sorted((e1, e2) -> e2.getValue().compareTo(e1.getValue())) | |
.collect(Collectors.toList()); | |
// Determine if the sender is within the top X | |
int rank = 1; | |
for (Map.Entry<Integer, Integer> entry : sortedByP2MDesc) { | |
if (entry.getKey() == senderId) { | |
// The user definitely has some P2M total | |
isSenderEligibleForReward = true; | |
// If within top X, they get rewarded | |
if (rank <= topX) { | |
isRewarded = true; | |
} | |
break; | |
} | |
rank++; | |
} | |
} | |
// 3. Return the transaction summary | |
return new TransactionSummary(transactionId, isSenderEligibleForReward, isRewarded); | |
} | |
/** | |
* Given a senderId, returns how many transactions of a certain type they have made. | |
* | |
* @param senderId user whose transactions we are counting | |
* @param transactionType type of transaction to filter | |
* @return number of transactions of the given type made by the user | |
*/ | |
public int getNumberOfTransactions(int senderId, TransactionType transactionType) { | |
return userTransactionCounts | |
.getOrDefault(senderId, Collections.emptyMap()) | |
.getOrDefault(transactionType, 0); | |
} | |
// Main method for quick demo (optional) | |
public static void main(String[] args) { | |
Payment payment = new Payment(2); // topX = 2, meaning top 2 P2M spenders get rewarded | |
TransactionSummary ts1 = payment.makePayment(101, 10, 500, TransactionType.P2M); | |
TransactionSummary ts2 = payment.makePayment(102, 11, 300, TransactionType.P2M); | |
TransactionSummary ts3 = payment.makePayment(103, 10, 200, TransactionType.P2M); | |
TransactionSummary ts4 = payment.makePayment(104, 12, 1000, TransactionType.P2M); | |
System.out.println("User 10 total P2M transactions: " | |
+ payment.getNumberOfTransactions(10, TransactionType.P2M)); | |
System.out.println("User 11 total P2M transactions: " | |
+ payment.getNumberOfTransactions(11, TransactionType.P2M)); | |
System.out.println("Transaction 101 -> isRewarded? " + ts1.isRewarded()); | |
System.out.println("Transaction 102 -> isRewarded? " + ts2.isRewarded()); | |
System.out.println("Transaction 103 -> isRewarded? " + ts3.isRewarded()); | |
System.out.println("Transaction 104 -> isRewarded? " + ts4.isRewarded()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment