# resolução spreadsheet challenge
## Ref: https://www.codingame.com/ide/puzzle/1d-spreadsheet
### Resolução
```java=
import java.util.*;
class Solution {
public static void main(String args[]) {
Scanner in = new Scanner(System.in);
int N = in.nextInt();
List<String> inputValuesList = new ArrayList<String>();
List<String> operatorList = new ArrayList<String>();
Integer[] results = new Integer[N+1];
for (int i = 0; i < N; i++) {
operatorList.add(in.next());
String firstInput = in.next();
String secondInput = in.next();
inputValuesList.add(firstInput);
inputValuesList.add(secondInput);
}
for (int i = 0, j=0; i < inputValuesList.size(); i = i + 2, j++) {
System.err.println("1");
if (results[j] == null) {
System.err.println("2");
int element = generateValue(results, inputValuesList.get(i), inputValuesList.get(i + 1), inputValuesList, operatorList, i / 2);
results[j] = element;
}
System.out.println(results[j]);
}
in.close();
}
private static int generateValue(Integer[] results, String firstValue, String secondValue, List<String> inputValuesList,
List<String> operators, int desiredCell) {
// logGenerateValue(desiredCell, firstValue, secondValue, operators.get(desiredCell));
int firstGeneratedValue;
int secondGeneratedValue;
int nextDesiredCell;
if (containsNullValueWithLeftValue(firstValue, secondValue)) {
firstGeneratedValue = Integer.valueOf(firstValue);
secondGeneratedValue = 0;
return operateValues(firstGeneratedValue, secondGeneratedValue, operators.get(desiredCell));
}
if (containsNullValueWithLeftRef(firstValue, secondValue)) {
nextDesiredCell = getDesiredCell(firstValue);
if (results[nextDesiredCell] == null){
firstGeneratedValue = generateValue(results, inputValuesList.get((nextDesiredCell * 2)),
inputValuesList.get((nextDesiredCell * 2) + 1), inputValuesList, operators, nextDesiredCell);
results[nextDesiredCell] = firstGeneratedValue;
} else {
firstGeneratedValue = results[nextDesiredCell];
}
secondGeneratedValue = 0;
return operateValues(firstGeneratedValue, secondGeneratedValue, operators.get(desiredCell));
}
if (containsDoubleRef(firstValue, secondValue)) {
nextDesiredCell = getDesiredCell(firstValue);
if (results[nextDesiredCell] == null){
firstGeneratedValue = generateValue(results, inputValuesList.get((nextDesiredCell * 2)),
inputValuesList.get((nextDesiredCell * 2) + 1), inputValuesList, operators, nextDesiredCell);
results[nextDesiredCell] = firstGeneratedValue;
} else {
firstGeneratedValue = results[nextDesiredCell];
}
nextDesiredCell = getDesiredCell(secondValue);
if (results[nextDesiredCell] == null){
secondGeneratedValue = generateValue(results, inputValuesList.get((nextDesiredCell * 2)),
inputValuesList.get((nextDesiredCell * 2) + 1), inputValuesList, operators, nextDesiredCell);
results[nextDesiredCell] = secondGeneratedValue;
} else {
secondGeneratedValue = results[nextDesiredCell];
}
return operateValues(firstGeneratedValue, secondGeneratedValue, operators.get(desiredCell));
}
if (containsRightRef(firstValue, secondValue)) {
firstGeneratedValue = Integer.valueOf(firstValue);
nextDesiredCell = getDesiredCell(secondValue);
if (results[nextDesiredCell] == null){
secondGeneratedValue = generateValue(results, inputValuesList.get((nextDesiredCell * 2)),
inputValuesList.get((nextDesiredCell * 2) + 1), inputValuesList, operators, nextDesiredCell);
results[nextDesiredCell] = secondGeneratedValue;
} else {
secondGeneratedValue = results[nextDesiredCell];
}
return operateValues(firstGeneratedValue, secondGeneratedValue, operators.get(desiredCell));
}
if (containsLeftRef(firstValue, secondValue)) {
nextDesiredCell = getDesiredCell(firstValue);
if (results[nextDesiredCell] == null){
firstGeneratedValue = generateValue(results, inputValuesList.get((nextDesiredCell * 2)),
inputValuesList.get((nextDesiredCell * 2) + 1), inputValuesList, operators, nextDesiredCell);
results[nextDesiredCell] = firstGeneratedValue;
} else {
firstGeneratedValue = results[nextDesiredCell];
}
secondGeneratedValue = Integer.valueOf(secondValue);
return operateValues(firstGeneratedValue, secondGeneratedValue, operators.get(desiredCell));
}
if (containsDoubleValues(firstValue, secondValue)) {
firstGeneratedValue = Integer.valueOf(firstValue);
secondGeneratedValue = Integer.valueOf(secondValue);
return operateValues(firstGeneratedValue, secondGeneratedValue, operators.get(desiredCell));
}
// No cenario ideal lançaria exceção avisando a falta de tratamento
return 0;
}
// validators
private static boolean containsNullValueWithLeftRef(String firstValue, String secondValue) {
return firstValue.contains("$") && secondValue.equals("_");
}
private static boolean containsNullValueWithLeftValue(String firstValue, String secondValue) {
return !firstValue.contains("$") && secondValue.equals("_");
}
private static boolean containsRightRef(String firstValue, String secondValue) {
return !firstValue.contains("$") && secondValue.contains("$");
}
private static boolean containsLeftRef(String firstValue, String secondValue) {
return firstValue.contains("$") && !secondValue.contains("$");
}
private static boolean containsDoubleRef(String firstValue, String secondValue) {
return firstValue.contains("$") && secondValue.contains("$");
}
private static boolean containsDoubleValues(String firstValue, String secondValue) {
return !firstValue.contains("$") && !secondValue.contains("$") && !secondValue.equals("_");
}
private static int getDesiredCell(String value) {
return Integer.valueOf(value.substring(1));
}
// operators
private static int operateValues(int firstValue, int secondValue, String operator) {
switch (operator) {
case "ADD":
return sum(firstValue, secondValue);
case "SUB":
return sub(firstValue, secondValue);
case "MULT":
return mult(firstValue, secondValue);
default:
return firstValue;
}
}
private static int sum(int firstValue, int secondValue) {
return (firstValue + secondValue);
}
private static int sub(int firstValue, int secondValue) {
return (firstValue - secondValue);
}
private static int mult(int firstValue, int secondValue) {
return (firstValue * secondValue);
}
// log
private static void logGenerateValue(int desiredCell, String firstValue, String secondValue, String operator) {
System.err.println("Cell: " + desiredCell
+ " | FirstValue = " + firstValue
+ " | SecondValue = " + secondValue
+ " | Operator = " + operator);
}
}
```