diff --git a/training/equivalent_resistor.go b/training/equivalent_resistor.go new file mode 100644 index 0000000..8c9e3cf --- /dev/null +++ b/training/equivalent_resistor.go @@ -0,0 +1,92 @@ +package main + +import "fmt" +import "os" +import "bufio" +import "strings" + +const VALUE = "value" +const SERIES = "series" +const PARALLEL = "parallel" + +type Operation struct { + operator string + value int + operands []*Operation + parent *Operation +} + +func (op *Operation) addOperand(other *Operation) { + op.operands = append(op.operands, other) +} + +func (op *Operation) setOperator(diagramItem string) { + if diagramItem == "[" { + op.operator = PARALLEL + } else if diagramItem == "(" { + op.operator = SERIES + } +} + +func (op *Operation) compute() float64 { + if op.operator == VALUE { + return float64(op.value) + } + var operandValues []float64 + for _, operation := range op.operands { + operandValues = append(operandValues, operation.compute()) + } + sum := 0.0 + if op.operator == SERIES { + for _, value := range operandValues { + sum += value + } + } else { + for _, value := range operandValues { + sum += 1 / value + } + sum = 1 / sum + } + return sum +} + +func main() { + scanner := bufio.NewScanner(os.Stdin) + scanner.Buffer(make([]byte, 1000000), 1000000) + + var N int + scanner.Scan() + fmt.Sscan(scanner.Text(), &N) + + resistors := make(map[string]int) + for i := 0; i < N; i++ { + var name string + var R int + scanner.Scan() + fmt.Sscan(scanner.Text(), &name, &R) + resistors[name] = R + } + scanner.Scan() + circuit := strings.Split(scanner.Text(), " ") + mainOperation := &Operation{} + mainOperation.setOperator(circuit[0]) + currentOperation := mainOperation + for _, item := range circuit[1:] { + if item == "[" || item == "(" { + newOp := &Operation{parent: currentOperation} + currentOperation = newOp + currentOperation.setOperator(item) + } else if item == "]" || item == ")" { + if currentOperation != mainOperation { + currentOperation.parent.addOperand(currentOperation) + currentOperation = currentOperation.parent + } + } else { + value := resistors[item] + valueOp := &Operation{operator: VALUE, value: value, parent: currentOperation} + currentOperation.addOperand(valueOp) + } + } + + fmt.Printf("%.1f\n", mainOperation.compute()) +}