diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5ff6309
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,38 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store
\ No newline at end of file
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/checkstyle-idea.xml b/.idea/checkstyle-idea.xml
new file mode 100644
index 0000000..7f57652
--- /dev/null
+++ b/.idea/checkstyle-idea.xml
@@ -0,0 +1,15 @@
+
+
+
+ 10.15.0
+ JavaOnly
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000..919ce1f
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000..824b2cc
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..aa00ffa
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..ef964bb
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..2b63946
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..cadeb64
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,31 @@
+
+
+ 4.0.0
+
+ com.gatomalvado
+ MachineCoding
+ 1.0-SNAPSHOT
+
+
+ 21
+ 21
+ UTF-8
+
+
+
+ org.projectlombok
+ lombok
+ RELEASE
+ provided
+
+
+ org.projectlombok
+ lombok
+ 1.18.30
+ provided
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/gatomalvado/Main.java b/src/main/java/com/gatomalvado/Main.java
new file mode 100644
index 0000000..3af65b3
--- /dev/null
+++ b/src/main/java/com/gatomalvado/Main.java
@@ -0,0 +1,8 @@
+package com.gatomalvado;
+
+public class Main {
+
+ public static void main(String[] args) {
+ System.out.println("Hello world!");
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gatomalvado/splitwise/Main.java b/src/main/java/com/gatomalvado/splitwise/Main.java
new file mode 100644
index 0000000..21f5523
--- /dev/null
+++ b/src/main/java/com/gatomalvado/splitwise/Main.java
@@ -0,0 +1,104 @@
+package com.gatomalvado.splitwise;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Scanner;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import com.gatomalvado.splitwise.model.Expense;
+import com.gatomalvado.splitwise.model.ExpenseType;
+import com.gatomalvado.splitwise.model.User;
+import com.gatomalvado.splitwise.orchestrator.ExpenseManager;
+
+public class Main {
+
+ public static void main(String[] args) {
+ Scanner scanner = new Scanner(System.in);
+ ExpenseManager expenseManager = new ExpenseManager();
+
+ // create users
+ User user1 = User.builder().userId("User1").build();
+ User user2 = User.builder().userId("User2").build();
+ User user3 = User.builder().userId("User3").build();
+ User user4 = User.builder().userId("User4").build();
+
+ // add user to the expense manager
+ expenseManager.addUser(user1);
+ expenseManager.addUser(user2);
+ expenseManager.addUser(user3);
+ expenseManager.addUser(user4);
+
+ while(true){
+ String command = scanner.nextLine();
+ String[] commands = command.split(" ");
+ String commandType = commands[0];
+
+ switch(commandType){
+ case "SHOW":
+ if(commands.length == 2){
+ expenseManager.showBalanceForUser(commands[1]);
+ } else {
+ expenseManager.showBalance();
+ }
+ case "EXPENSE":
+ String userWhoPaid = commands[1];
+ int numberOfUsers = Integer.parseInt(commands[2]);
+ String expenseType = commands[3 + numberOfUsers];
+ List userInvolved = new ArrayList<>();
+ for(int i=3; i< 3+numberOfUsers; i++){
+ userInvolved.add(commands[i]);
+ }
+ Double amount = Double.parseDouble(commands[4+numberOfUsers]);
+ Expense expense = null;
+ switch(expenseType) {
+ case "EQUAL":
+ expense = Expense.builder()
+ .expenseType(ExpenseType.EQUAL)
+ .paidBy(userWhoPaid)
+ .paidFor(userInvolved)
+ .amount(amount)
+ .build();
+ expenseManager.addExpense(expense);
+ case "EXACT":
+ List amounts = new ArrayList<>();
+ for(int i=5+numberOfUsers; i percentages = new ArrayList<>();
+ for(int i=5+numberOfUsers; i paidFor;
+ private Double amount;
+ private List percentage;
+ private List exactAmount;
+}
diff --git a/src/main/java/com/gatomalvado/splitwise/model/ExpenseType.java b/src/main/java/com/gatomalvado/splitwise/model/ExpenseType.java
new file mode 100644
index 0000000..9422257
--- /dev/null
+++ b/src/main/java/com/gatomalvado/splitwise/model/ExpenseType.java
@@ -0,0 +1,13 @@
+package com.gatomalvado.splitwise.model;
+
+public enum ExpenseType {
+ EQUAL("equal"),
+ EXACT("exact"),
+ PERCENT("percent");
+
+ private String name;
+
+ ExpenseType(String name) {
+ this.name = name;
+ }
+}
diff --git a/src/main/java/com/gatomalvado/splitwise/model/User.java b/src/main/java/com/gatomalvado/splitwise/model/User.java
new file mode 100644
index 0000000..8e405d1
--- /dev/null
+++ b/src/main/java/com/gatomalvado/splitwise/model/User.java
@@ -0,0 +1,15 @@
+package com.gatomalvado.splitwise.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+
+@Data
+@AllArgsConstructor
+@Builder
+public class User {
+ private String userId;
+ private String name;
+ private String email;
+ private String mobile;
+}
diff --git a/src/main/java/com/gatomalvado/splitwise/model/UserBalance.java b/src/main/java/com/gatomalvado/splitwise/model/UserBalance.java
new file mode 100644
index 0000000..1fdff03
--- /dev/null
+++ b/src/main/java/com/gatomalvado/splitwise/model/UserBalance.java
@@ -0,0 +1,16 @@
+package com.gatomalvado.splitwise.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class UserBalance {
+ private String owedTo;
+ private String userId;
+ private Double amount;
+}
diff --git a/src/main/java/com/gatomalvado/splitwise/orchestrator/ExpenseManager.java b/src/main/java/com/gatomalvado/splitwise/orchestrator/ExpenseManager.java
new file mode 100644
index 0000000..44e9f5d
--- /dev/null
+++ b/src/main/java/com/gatomalvado/splitwise/orchestrator/ExpenseManager.java
@@ -0,0 +1,73 @@
+package com.gatomalvado.splitwise.orchestrator;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.ServiceLoader;
+import java.util.stream.Collectors;
+
+import com.gatomalvado.splitwise.model.Expense;
+import com.gatomalvado.splitwise.model.ExpenseType;
+import com.gatomalvado.splitwise.model.User;
+import com.gatomalvado.splitwise.model.UserBalance;
+import com.gatomalvado.splitwise.service.UserBalanceGenerator;
+
+public class ExpenseManager {
+
+ private Map userStore;
+
+ private List userBalances;
+
+ private Map userBalanceGeneratorMap;
+
+ public ExpenseManager(){
+ this.userStore = new HashMap<>();
+ this.userBalances = new ArrayList<>();
+ initMap();
+ }
+
+ public void addExpense(Expense expense) {
+ List userBalanceList = userBalanceGeneratorMap.get(expense.getExpenseType()).generateUserBalance(expense);
+ userBalances.addAll(userBalanceList);
+ }
+
+ public void addUser(User user){
+ userStore.put(user.getUserId(), user);
+ }
+
+ public void showBalance() {
+ Collection userCollection = userStore.values();
+ userCollection.stream().forEach((usr) -> {
+ List userBalanceList = userBalances.stream().filter((usb) -> usb.getUserId().equals(usr.getUserId())).toList();
+ Map oweToMap = new HashMap<>();
+ userBalanceList.forEach((usb) -> {
+ oweToMap.put(usb.getOwedTo(), oweToMap.getOrDefault(usb.getOwedTo(), 0.0) + usb.getAmount());
+ });
+ oweToMap.keySet().forEach((otm) -> {
+ System.out.println(usr.getUserId() + " owes to " + otm + " " + oweToMap.get(otm));
+ });
+ });
+ }
+
+ public void showBalanceForUser(String userId) {
+ List userBalanceList = userBalances.stream().filter((usb) -> usb.getUserId().equals(userId)).toList();
+ Map oweToMap = new HashMap<>();
+ userBalanceList.forEach((usb) -> {
+ oweToMap.put(usb.getOwedTo(), oweToMap.getOrDefault(usb.getOwedTo(), 0.0) + usb.getAmount());
+ });
+ oweToMap.keySet().forEach((otm) -> {
+ System.out.println(userId + " owes to " + otm + " " + oweToMap.get(otm));
+ });
+ }
+
+ private void initMap(){
+ userBalanceGeneratorMap = new HashMap<>();
+ ServiceLoader serviceLoader = ServiceLoader.load(UserBalanceGenerator.class);
+ for(UserBalanceGenerator userBalanceGenerator : serviceLoader) {
+ userBalanceGeneratorMap.put(userBalanceGenerator.getType(), userBalanceGenerator);
+ }
+ }
+
+}
diff --git a/src/main/java/com/gatomalvado/splitwise/service/UserBalanceGenerator.java b/src/main/java/com/gatomalvado/splitwise/service/UserBalanceGenerator.java
new file mode 100644
index 0000000..e5b72a2
--- /dev/null
+++ b/src/main/java/com/gatomalvado/splitwise/service/UserBalanceGenerator.java
@@ -0,0 +1,13 @@
+package com.gatomalvado.splitwise.service;
+
+import java.util.List;
+
+import com.gatomalvado.splitwise.model.Expense;
+import com.gatomalvado.splitwise.model.ExpenseType;
+import com.gatomalvado.splitwise.model.UserBalance;
+
+public interface UserBalanceGenerator {
+ List generateUserBalance(Expense expense);
+
+ ExpenseType getType();
+}
diff --git a/src/main/java/com/gatomalvado/splitwise/service/impl/EqualUserBalanceGenerator.java b/src/main/java/com/gatomalvado/splitwise/service/impl/EqualUserBalanceGenerator.java
new file mode 100644
index 0000000..696987f
--- /dev/null
+++ b/src/main/java/com/gatomalvado/splitwise/service/impl/EqualUserBalanceGenerator.java
@@ -0,0 +1,32 @@
+package com.gatomalvado.splitwise.service.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.gatomalvado.splitwise.model.Expense;
+import com.gatomalvado.splitwise.model.ExpenseType;
+import com.gatomalvado.splitwise.model.UserBalance;
+import com.gatomalvado.splitwise.service.UserBalanceGenerator;
+
+public class EqualUserBalanceGenerator implements UserBalanceGenerator {
+
+ @Override
+ public List generateUserBalance(Expense expense) {
+ List userBalances = new ArrayList<>();
+ Double amount = expense.getAmount();
+ int usersLength = expense.getPaidFor().size();
+ double amountToDistribute = amount/usersLength;
+ for(String userId: expense.getPaidFor()) {
+ if(!userId.equals(expense.getPaidBy())){
+ userBalances.add(UserBalance.builder().amount(amountToDistribute).owedTo(expense.getPaidBy()).userId(userId).build());
+ }
+ }
+ return userBalances;
+ }
+
+ @Override
+ public ExpenseType getType() {
+ return ExpenseType.EQUAL;
+ }
+
+}
diff --git a/src/main/java/com/gatomalvado/splitwise/service/impl/ExactUserBalanceGenerator.java b/src/main/java/com/gatomalvado/splitwise/service/impl/ExactUserBalanceGenerator.java
new file mode 100644
index 0000000..94af301
--- /dev/null
+++ b/src/main/java/com/gatomalvado/splitwise/service/impl/ExactUserBalanceGenerator.java
@@ -0,0 +1,46 @@
+package com.gatomalvado.splitwise.service.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
+import com.gatomalvado.splitwise.model.Expense;
+import com.gatomalvado.splitwise.model.ExpenseType;
+import com.gatomalvado.splitwise.model.UserBalance;
+import com.gatomalvado.splitwise.service.UserBalanceGenerator;
+
+public class ExactUserBalanceGenerator implements UserBalanceGenerator {
+
+ @Override
+ public List generateUserBalance(Expense expense) {
+ if(!validateShare(expense)) {
+ // throw exception here
+ }
+ List userBalances = new ArrayList<>();
+ int usersLength = expense.getPaidFor().size();
+ List amounts = expense.getExactAmount();
+ for(int i=0; i amounts = expense.getExactAmount();
+ Double amount = expense.getAmount();
+ double total = 0.0;
+ for(int i=0; i generateUserBalance(Expense expense) {
+ if(!validateShare(expense)) {
+ // throw exception here
+ }
+ List userBalances = new ArrayList<>();
+ Double amount = expense.getAmount();
+ int usersLength = expense.getPaidFor().size();
+ for(int i=0; i percentage = expense.getPercentage();
+ AtomicReference ans = new AtomicReference<>(0.0);
+ percentage.stream().forEach((pc) ->{
+ ans.set(ans.get() + pc);
+ });
+ Double finalValue = ans.get();
+ return finalValue == 100.0;
+ }
+
+}