Resistance calculator: Difference between revisions

From Rosetta Code
Content added Content deleted
(Converted to draft task. Added headers and rearranged existing language entries into alphabetical order.)
 
(39 intermediate revisions by 12 users not shown)
Line 15:
 
;Input
[https://photos.app.goo.gl/58heQVm8UJYf8Ra29 Parallel ResistorResistance Calculator]
 
* Infix: ((((R810 + R102) * R96 + R78) * R66 + R54) * R48 + R34) * R28 + R16
* RPN: 10 2 + 6 * 8 + 6 * 4 + 8 * 4 + 8 * 6 +
* Voltage = 18.0 V
Line 44:
8.000 7.200 0.900 6.480 | | r
6.000 10.800 1.800 19.440 | r
 
=={{header|11l}}==
{{trans|Python}}
===RPN===
<syntaxhighlight lang="11l">T Resistor
Float resistance
voltage = 0.0
Resistor? a, b
Char symbol
 
F (resistance = 0.0, Resistor? a = N, b = N; symbol = Char(‘r’))
.resistance = resistance
.a = a
.b = b
.symbol = symbol
 
F.virtual.new res() -> Float
R .resistance
F.virtual.new setVoltage(Float voltage) -> Void
.voltage = voltage
F current()
R .voltage / .res()
F effect()
R .current() * .voltage
F report(level = ‘’) -> Void
print(‘#4.3 #4.3 #4.3 #4.3 #.#.’.format(.res(), .voltage, .current(), .effect(), level, .symbol))
I .a != N {.a.report(level‘| ’)}
I .b != N {.b.report(level‘| ’)}
 
T Serial(Resistor)
F (Resistor a, b)
.a = move(b)
.b = a
.symbol = Char(‘+’)
 
F.virtual.override res() -> Float
R .a.res() + .b.res()
 
F.virtual.override setVoltage(Float voltage) -> Void
V ra = .a.res()
V rb = .b.res()
.a.setVoltage(ra / (ra + rb) * voltage)
.b.setVoltage(rb / (ra + rb) * voltage)
.voltage = voltage
 
T Parallel(Resistor)
F (Resistor a, b)
.a = move(b)
.b = a
.symbol = Char(‘*’)
 
F.virtual.override res() -> Float
R 1 / (1 / .a.res() + 1 / .b.res())
 
F.virtual.override setVoltage(Float voltage) -> Void
.a.setVoltage(voltage)
.b.setVoltage(voltage)
.voltage = voltage
 
F build(s)
[Resistor] stack
L(word) s.split(‘ ’)
I word == ‘+’
Resistor p = stack.pop()
stack.append(Serial(p, stack.pop()))
E I word == ‘*’
Resistor p = stack.pop()
stack.append(Parallel(p, stack.pop()))
E
stack.append(Resistor(Float(word)))
R stack.pop()
 
Resistor node = build(‘10 2 + 6 * 8 + 6 * 4 + 8 * 4 + 8 * 6 +’)
print(‘ Ohm Volt Ampere Watt Network tree’)
node.setVoltage(18.0)
node.report()</syntaxhighlight>
 
=={{header|CoffeeScript}}==
===RPN===
<langsyntaxhighlight lang="coffeescript">nd = (num) -> num.toFixed(3).padStart 8
 
class Resistor
Line 87 ⟶ 163:
node.setVoltage 18.0
print " Ohm Volt Ampere Watt Network tree"
node.report ""</langsyntaxhighlight>
 
=={{header|FreeBASIC}}==
===Infix===
{{trans|Go}}
<syntaxhighlight lang="vbnet">Const NULL As Any Ptr = 0
 
Type Resistor
symbol As String
resistance As Double
voltage As Double
a As Resistor Ptr
b As Resistor Ptr
End Type
 
Function res(r As Resistor Ptr) As Double
Select Case r->symbol
Case "+"
Return res(r->a) + res(r->b)
Case "*"
Return 1 / (1 / res(r->a) + 1 / res(r->b))
Case Else
Return r->resistance
End Select
End Function
 
Sub setVoltage(r As Resistor Ptr, voltage As Double)
Select Case r->symbol
Case "+"
Dim ra As Double = res(r->a)
Dim rb As Double = res(r->b)
setVoltage(r->a, ra / (ra + rb) * voltage)
setVoltage(r->b, rb / (ra + rb) * voltage)
Case "*"
setVoltage(r->a, voltage)
setVoltage(r->b, voltage)
End Select
r->voltage = voltage
End Sub
 
Function current(r As Resistor Ptr) As Double
Return r->voltage / res(r)
End Function
 
Function effect(r As Resistor Ptr) As Double
Return current(r) * r->voltage
End Function
 
Sub report(r As Resistor Ptr, level As String)
Print Using "###.### ###.### ###.### ###.### & &"; res(r); r->voltage; current(r); effect(r); level; r->symbol
If r->a <> NULL Then report(r->a, level + " |")
If r->b <> NULL Then report(r->b, level + " |")
End Sub
 
Function sum(r1 As Resistor Ptr, r2 As Resistor Ptr) As Resistor Ptr
Dim r As Resistor Ptr = Callocate(1, Sizeof(Resistor))
r->symbol = "+"
r->a = r1
r->b = r2
Return r
End Function
 
Function mul(r1 As Resistor Ptr, r2 As Resistor Ptr) As Resistor Ptr
Dim r As Resistor Ptr = Callocate(1, Sizeof(Resistor))
r->symbol = "*"
r->a = r1
r->b = r2
Return r
End Function
 
Dim As Resistor Ptr r(9)
Dim As Double resistances(9) = {6, 8, 4, 8, 4, 6, 8, 10, 6, 2}
For i As Integer = 0 To 9
r(i) = Callocate(1, Sizeof(Resistor))
r(i)->symbol = "r"
r(i)->resistance = resistances(i)
Next
Dim As Resistor Ptr node
node = sum(r(7), r(9))
node = mul(node, r(8))
node = sum(node, r(6))
node = mul(node, r(5))
node = sum(node, r(4))
node = mul(node, r(3))
node = sum(node, r(2))
node = mul(node, r(1))
node = sum(node, r(0))
setVoltage(node, 18)
Print " Ohm Volt Ampere Watt Network tree"
report(node, "")
 
Sleep</syntaxhighlight>
{{out}}
<pre> Ohm Volt Ampere Watt Network tree
10.000 18.000 1.800 32.400 +
4.000 7.200 1.800 12.960 | *
8.000 7.200 0.900 6.480 | | +
4.000 3.600 0.900 3.240 | | | *
8.000 3.600 0.450 1.620 | | | | +
4.000 1.800 0.450 0.810 | | | | | *
12.000 1.800 0.150 0.270 | | | | | | +
4.000 0.600 0.150 0.090 | | | | | | | *
12.000 0.600 0.050 0.030 | | | | | | | | +
10.000 0.500 0.050 0.025 | | | | | | | | | r
2.000 0.100 0.050 0.005 | | | | | | | | | r
6.000 0.600 0.100 0.060 | | | | | | | | r
8.000 1.200 0.150 0.180 | | | | | | | r
6.000 1.800 0.300 0.540 | | | | | | r
4.000 1.800 0.450 0.810 | | | | | r
8.000 3.600 0.450 1.620 | | | | r
4.000 3.600 0.900 3.240 | | | r
8.000 7.200 0.900 6.480 | | r
6.000 10.800 1.800 19.440 | r
</pre>
 
===RPN===
{{trans|Go}}
<syntaxhighlight lang="vbnet">Const NULL As Any Ptr = 0
 
Type Resistor
symbol As String
resistance As Double
voltage As Double
a As Resistor Ptr
b As Resistor Ptr
End Type
 
Sub push(s() As Resistor Ptr, r As Resistor Ptr)
Redim Preserve s(Ubound(s) + 1)
s(Ubound(s)) = r
End Sub
 
Sub pop(s() As Resistor Ptr, Byref r As Resistor Ptr)
r = s(Ubound(s))
Redim Preserve s(Ubound(s) - 1)
End Sub
 
Function res(r As Resistor Ptr) As Double
Select Case r->symbol
Case "+"
Return res(r->a) + res(r->b)
Case "*"
Return 1 / (1 / res(r->a) + 1 / res(r->b))
Case Else
Return r->resistance
End Select
End Function
 
Sub setVoltage(r As Resistor Ptr, voltage As Double)
Select Case r->symbol
Case "+"
Dim ra As Double = res(r->a)
Dim rb As Double = res(r->b)
setVoltage(r->a, ra / (ra + rb) * voltage)
setVoltage(r->b, rb / (ra + rb) * voltage)
Case "*"
setVoltage(r->a, voltage)
setVoltage(r->b, voltage)
End Select
r->voltage = voltage
End Sub
 
Function current(r As Resistor Ptr) As Double
Return r->voltage / res(r)
End Function
 
Function effect(r As Resistor Ptr) As Double
Return current(r) * r->voltage
End Function
 
Sub report(r As Resistor Ptr, level As String)
Print Using "###.### ###.### ###.### ###.### & &"; res(r); r->voltage; current(r); effect(r); level; r->symbol
If r->a <> NULL Then report(r->a, level + " |")
If r->b <> NULL Then report(r->b, level + " |")
End Sub
 
Sub splitString(s As String, delim As String, result() As String)
Dim As Integer start = 1, endd
While start <= Len(s)
endd = Instr(start, s, delim)
If endd = 0 Then endd = Len(s) + 1
Redim Preserve result(Ubound(result) + 1)
result(Ubound(result)) = Mid(s, start, endd - start)
start = endd + Len(delim)
Wend
End Sub
 
Sub build(rpn As String, Byref node As Resistor Ptr)
Dim As Resistor Ptr s()
Dim As String tokens()
splitString(rpn, " ", tokens())
Dim As Integer i
For i = 0 To Ubound(tokens)
Dim As Resistor Ptr r = Callocate(1, Sizeof(Resistor))
Select Case tokens(i)
Case "+", "*"
pop(s(), r->b)
pop(s(), r->a)
r->symbol = tokens(i)
Case Else
r->resistance = Val(tokens(i))
r->symbol = "r"
End Select
push(s(), r)
Next
pop(s(), node)
End Sub
 
Dim As Resistor Ptr node
build("10 2 + 6 * 8 + 6 * 4 + 8 * 4 + 8 * 6 +", node)
setVoltage(node, 18)
Print " Ohm Volt Ampere Watt Network tree"
report(node, "")
 
Sleep</syntaxhighlight>
{{out}}
<pre>Same as Infix version</pre>
 
=={{header|Go}}==
===Infix===
{{trans|Nim}}
<syntaxhighlight lang="go">package main
 
import "fmt"
 
type Resistor struct {
symbol rune
resistance, voltage float64
a, b *Resistor
}
 
func (r *Resistor) res() float64 {
switch r.symbol {
case '+':
return r.a.res() + r.b.res()
case '*':
return 1 / (1/r.a.res() + 1/r.b.res())
default:
return r.resistance
}
}
 
func (r *Resistor) setVoltage(voltage float64) {
switch r.symbol {
case '+':
ra := r.a.res()
rb := r.b.res()
r.a.setVoltage(ra / (ra + rb) * voltage)
r.b.setVoltage(rb / (ra + rb) * voltage)
case '*':
r.a.setVoltage(voltage)
r.b.setVoltage(voltage)
}
r.voltage = voltage
}
 
func (r *Resistor) current() float64 {
return r.voltage / r.res()
}
 
func (r *Resistor) effect() float64 {
return r.current() * r.voltage
}
 
func (r *Resistor) report(level string) {
fmt.Printf("%8.3f %8.3f %8.3f %8.3f %s%c\n", r.res(), r.voltage, r.current(), r.effect(), level, r.symbol)
if r.a != nil {
r.a.report(level + "| ")
}
if r.b != nil {
r.b.report(level + "| ")
}
}
 
func (r *Resistor) add(other *Resistor) *Resistor {
return &Resistor{'+', 0, 0, r, other}
}
 
func (r *Resistor) mul(other *Resistor) *Resistor {
return &Resistor{'*', 0, 0, r, other}
}
 
func main() {
var r [10]*Resistor
resistances := []float64{6, 8, 4, 8, 4, 6, 8, 10, 6, 2}
for i := 0; i < 10; i++ {
r[i] = &Resistor{'r', resistances[i], 0, nil, nil}
}
node := r[7].add(r[9]).mul(r[8]).add(r[6]).mul(r[5]).add(r[4]).mul(r[3]).add(r[2]).mul(r[1]).add(r[0])
node.setVoltage(18)
fmt.Println(" Ohm Volt Ampere Watt Network tree")
node.report("")
}</syntaxhighlight>
 
===RPN===
<syntaxhighlight lang="go">package main
 
import (
"fmt"
"strconv"
"strings"
)
 
type Stack []*Resistor
 
func (s *Stack) push(r *Resistor) {
*s = append(*s, r)
}
 
func (s *Stack) pop() *Resistor {
le := len(*s)
if le == 0 {
panic("Attempt to pop from an empty stack")
}
le--
r := (*s)[le]
*s = (*s)[:le]
return r
}
 
type Resistor struct {
symbol rune
resistance, voltage float64
a, b *Resistor
}
 
func (r *Resistor) res() float64 {
switch r.symbol {
case '+':
return r.a.res() + r.b.res()
case '*':
return 1 / (1/r.a.res() + 1/r.b.res())
default:
return r.resistance
}
}
 
func (r *Resistor) setVoltage(voltage float64) {
switch r.symbol {
case '+':
ra := r.a.res()
rb := r.b.res()
r.a.setVoltage(ra / (ra + rb) * voltage)
r.b.setVoltage(rb / (ra + rb) * voltage)
case '*':
r.a.setVoltage(voltage)
r.b.setVoltage(voltage)
}
r.voltage = voltage
}
 
func (r *Resistor) current() float64 {
return r.voltage / r.res()
}
 
func (r *Resistor) effect() float64 {
return r.current() * r.voltage
}
 
func (r *Resistor) report(level string) {
fmt.Printf("%8.3f %8.3f %8.3f %8.3f %s%c\n", r.res(), r.voltage, r.current(), r.effect(), level, r.symbol)
if r.a != nil {
r.a.report(level + "| ")
}
if r.b != nil {
r.b.report(level + "| ")
}
}
 
func build(rpn string) *Resistor {
st := new(Stack)
for _, token := range strings.Fields(rpn) {
switch token {
case "+":
b, a := st.pop(), st.pop()
st.push(&Resistor{'+', 0, 0, a, b})
case "*":
b, a := st.pop(), st.pop()
st.push(&Resistor{'*', 0, 0, a, b})
default:
r, _ := strconv.ParseFloat(token, 64)
st.push(&Resistor{'r', r, 0, nil, nil})
}
}
return st.pop()
}
 
func main() {
node := build("10 2 + 6 * 8 + 6 * 4 + 8 * 4 + 8 * 6 +")
node.setVoltage(18)
fmt.Println(" Ohm Volt Ampere Watt Network tree")
node.report("")
}</syntaxhighlight>
 
=={{header|Julia}}==
{{trans|Raku}}
====Infix====
<syntaxhighlight lang="julia">using Formatting
import Base.+, Base.*
 
mutable struct Resistor
operator::Char
voltage::Float64
resistance::Float64
a::Union{Resistor, Nothing}
b::Union{Resistor, Nothing}
end
 
function res(r::Resistor)
if r != nothing
if r.operator == '+'
return res(r.a) + res(r.b)
elseif r.operator == '*'
return 1 / ((1 / res(r.a)) + (1 / res(r.b)))
end
return r.resistance
end
end
 
function setvoltage(r, voltage)
if r != nothing
if r.operator == '+'
ra = res(r.a)
rb = res(r.b)
setvoltage(r.a, voltage * ra / (ra + rb))
setvoltage(r.b, voltage * rb / (ra + rb))
elseif r.operator == '*'
setvoltage(r.a, voltage)
setvoltage(r.b, voltage)
end
r.voltage = voltage
end
end
current(r) = r.voltage / res(r)
 
effect(r) = r.voltage * current(r)
 
function report(r, level=1)
nfmt(x::Real) = rpad(format(x, precision=3), 12)
afmt(arr::Vector) = join(map(nfmt, arr), "| ")
println(afmt([res(r), r.voltage, current(r), effect(r)]), "| "^level, r.operator)
if r.a != nothing
report(r.a, level + 1)
end
if r.b != nothing
report(r.b, level + 1)
end
end
 
Base.:+(a::Resistor, b::Resistor) = Resistor('+', 0.0, 0.0, a, b)
Base.:*(a::Resistor, b::Resistor) = Resistor('*', 0.0, 0.0, a, b)
(R1, R2, R3, R4, R5, R6, R7, R8, R9, R10) =
map(r -> Resistor('r', 0.0, r, nothing, nothing), [6, 8, 4, 8, 4, 6, 8, 10, 6, 2])
node = ((((R8 + R10) * R9 + R7) * R6 + R5) * R4 + R3) * R2 + R1
setvoltage(node, 18)
 
println(" Ohm Volt Ampere Watt Network tree")
report(node)
</syntaxhighlight>{{out}}
<pre>
Ohm Volt Ampere Watt Network tree
10.000 | 18.000 | 1.800 | 32.400 | +
4.000 | 7.200 | 1.800 | 12.960 | | *
8.000 | 7.200 | 0.900 | 6.480 | | | +
4.000 | 3.600 | 0.900 | 3.240 | | | | *
8.000 | 3.600 | 0.450 | 1.620 | | | | | +
4.000 | 1.800 | 0.450 | 0.810 | | | | | | *
12.000 | 1.800 | 0.150 | 0.270 | | | | | | | +
4.000 | 0.600 | 0.150 | 0.090 | | | | | | | | *
12.000 | 0.600 | 0.050 | 0.030 | | | | | | | | | +
10.000 | 0.500 | 0.050 | 0.025 | | | | | | | | | | r
2.000 | 0.100 | 0.050 | 0.005 | | | | | | | | | | r
6.000 | 0.600 | 0.100 | 0.060 | | | | | | | | | r
8.000 | 1.200 | 0.150 | 0.180 | | | | | | | | r
6.000 | 1.800 | 0.300 | 0.540 | | | | | | | r
4.000 | 1.800 | 0.450 | 0.810 | | | | | | r
8.000 | 3.600 | 0.450 | 1.620 | | | | | r
4.000 | 3.600 | 0.900 | 3.240 | | | | r
8.000 | 7.200 | 0.900 | 6.480 | | | r
6.000 | 10.800 | 1.800 | 19.440 | | r
</pre>
 
====RPN====
<syntaxhighlight lang="julia">function rpn(arr::Vector)
stack = Any[]
for op in arr
if isa(op, Function)
arg2 = pop!(stack)
arg1 = pop!(stack)
push!(stack, op(arg1, arg2))
else
push!(stack, op)
end
end
length(stack) != 1 && error("invalid RPN expression array: $arr")
return stack[1]
end
 
node = rpn([R8, R10, +, R9, *, R7, +, R6, *, R5, +, R4, *, R3, +, R2, *, R1, +])
setvoltage(node, 18)
report(node)
</syntaxhighlight>{{out}}
Same as infix version.
 
=={{header|Nim}}==
<syntaxhighlight lang="python">import strutils, strformat
 
type
Node = ref object
kind: char # + = serial * = parallel r = resistor
resistance: float
voltage: float
a: Node
b: Node
 
proc res(node: Node): float =
if node.kind == '+': return node.a.res + node.b.res
if node.kind == '*': return 1 / (1 / node.a.res + 1 / node.b.res)
node.resistance
 
proc current(node: Node): float = node.voltage / node.res
proc effect (node: Node): float = node.current * node.voltage
 
proc report(node: Node, level: string = "") =
echo fmt"{node.res:8.3f} {node.voltage:8.3f} {node.current:8.3f} {node.effect:8.3f} {level}{node.kind}"
if node.kind in "+*":
node.a.report level & "| "
node.b.report level & "| "
 
proc setVoltage(node: Node, voltage: float) =
node.voltage = voltage
if node.kind == '+':
let ra = node.a.res
let rb = node.b.res
node.a.setVoltage ra / (ra+rb) * voltage
node.b.setVoltage rb / (ra+rb) * voltage
if node.kind == '*':
node.a.setVoltage voltage
node.b.setVoltage voltage
 
proc build(tokens: seq[string]): Node =
var stack: seq[Node]
for token in tokens:
stack.add if token == "+": Node(kind: '+', a: stack.pop, b: stack.pop)
elif token == "*": Node(kind: '*', a: stack.pop, b: stack.pop)
else: Node(kind: 'r', resistance: parseFloat(token))
stack.pop
 
proc calculate(voltage: float, tokens: seq[string]): Node =
echo ""
echo " Ohm Volt Ampere Watt Network tree"
let node = build tokens
node.setVoltage voltage
node.report
node</syntaxhighlight>
 
===RPN===
<syntaxhighlight lang="python">proc rpn(voltage:float, s:string): Node = calculate(voltage, s.split ' ')
var node = rpn(18, "10 2 + 6 * 8 + 6 * 4 + 8 * 4 + 8 * 6 +")
assert 10 == node.res
assert 18 == node.voltage
assert 1.8 == node.current()
assert 32.4 == node.effect()
assert '+' == node.kind</syntaxhighlight>
 
===Infix===
<syntaxhighlight lang="python">proc parse(s: string): seq[string] =
<lang python>import strutils,strformat,sugar,sequtils
var tmp = ""
for ch in s:
case ch
of ' ':
if tmp != "": result.add tmp
tmp = ""
continue
of '+', '*', '(', ')':
if tmp != "": result.add tmp
tmp = ""
result.add $ch
else:
tmp &= ch
if tmp != "": result.add tmp
 
proc shuntRPN(s: string): seq[string] =
type
let ops = "+*"
Resistor = ref object of RootObj
var tokens = parse s
symbol : char
var stack: seq[string]
resistance,voltage : float
var op: string
a,b : Resistor
 
for token in tokens:
proc res(r:Resistor) : float =
case token
if r.symbol == '+': return r.a.res + r.b.res
of "(":
if r.symbol == '*': return 1 / (1 / r.a.res + 1 / r.b.res)
stack.add token
r.resistance
of ")":
proc setVoltage(r:Resistor, voltage:float) =
while stack.len > 0:
if r.symbol == '+':
op = stack.pop()
let ra = r.a.res
if op == "(": break
let rb = r.b.res
result.add op
r.a.setVoltage ra/(ra+rb) * voltage
else:
r.b.setVoltage rb/(ra+rb) * voltage
if r.symboltoken ==in '*'ops:
while stack.len > 0:
r.a.setVoltage voltage
op = stack[^1]
r.b.setVoltage voltage
if op notin ops: break
r.voltage = voltage
if ops.find(token) >= ops.find(op): break
proc current(r:Resistor) : auto = return r.voltage / r.res
discard stack.pop()
proc effect(r:Resistor) : auto = return r.current * r.voltage
result.add op
proc report(r:Resistor,level:string="") =
stack.add token
echo fmt"{r.res:8.3f} {r.voltage:8.3f} {r.current:8.3f} {r.effect:8.3f} {level}{r.symbol}"
else: result.add token
if r.a!=nil: r.a.report level & "| "
if r.b!=nil: r.b.report level & "| "
proc `+`(r:Resistor,other:Resistor) : auto = return Resistor(symbol:'+', a:r, b:other)
proc `*`(r:Resistor,other:Resistor) : auto = return Resistor(symbol:'*', a:r, b:other)
 
while stack.len > 0: result.add stack.pop()
var R1,R2,R3,R4,R5,R6,R7,R8,R9,R10 : Resistor
 
let resistors = [6,8,4,8,4,6,8,10,6,2].map(res => Resistor(symbol:'r',resistance:res.float))
proc infix(voltage:float, s:string): Node = calculate(voltage, shuntRPN s)
(R1,R2,R3,R4,R5,R6,R7,R8,R9,R10) = resistors
let node = infix(18, "(((R8 (10+ R102) * R9 6+ R78) * R6 6+ R54) * R4 8+ R34) * R2 8+ R16")
assert 10 == node.res
node.setVoltage(18)
assert 18 == node.voltage
echo(" Ohm Volt Ampere Watt Network tree")
assert 1.8 == node.current()
node.report()</lang>
assert 32.4 == node.effect()
assert '+' == node.kind</syntaxhighlight>
 
=={{header|Perl}}==
===Infix===
{{trans|Raku}}
<syntaxhighlight lang="perl">use v5.36;
 
package Resistor;
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(set_voltage report);
 
use overload '+' => \&serial, '*' => \&parallel;
 
sub new ($class, $args) {
my $self = {
symbol => $args->{symbol},
voltage => $args->{voltage},
resistance => $args->{resistance},
a => $args->{a},
b => $args->{b},
};
return bless $self, $class;
}
 
sub res ($self) {
if ($self->{symbol} eq '+') { return res($self->{a}) + res($self->{b}) }
elsif ($self->{symbol} eq '*') { return 1 / (1/res($self->{a}) + 1/res($self->{b})) }
else { return $self->{resistance} }
}
 
sub set_voltage ($self,$voltage) {
if ($self->{symbol} eq '+') {
my $ra = res($self->{a});
my $rb = res($self->{b});
set_voltage($self->{a}, $ra / ($ra+$rb) * $voltage );
set_voltage($self->{b}, $rb / ($ra+$rb) * $voltage );
} elsif ($self->{symbol} eq '*') {
set_voltage($self->{a}, $voltage );
set_voltage($self->{b}, $voltage );
}
$self->{voltage} = $voltage;
}
 
sub current ($self) { return $self->{voltage} / res($self) }
sub effect ($self) { return $self->{voltage} * current($self) }
 
sub serial ($a,$b,$) { Resistor->new( {symbol => '+', a => $a, b => $b} ) }
sub parallel ($a,$b,$) { Resistor->new( {symbol => '*', a => $a, b => $b} ) }
 
sub report ($self,$level = 0) {
state @results;
push @results, ' Ohm Volt Ampere Watt Network tree' and $level = 1 unless $level;
my $pad = ('| ') x $level;
my $f = sprintf '%9.3f' x 4, res($self), $self->{voltage}, current($self), effect($self);
say "$f $pad" . $self->{symbol};
report($self->{a}, $level+1) if defined $self->{a};
report($self->{b}, $level+1) if defined $self->{b};
join "\n", @results;
}
 
}
 
package main;
Resistor->import;
 
my ($R1, $R2, $R3, $R4, $R5, $R6, $R7, $R8, $R9, $R10) =
map { Resistor->new( {symbol => 'r', resistance => $_} ) } <6 8 4 8 4 6 8 10 6 2>;
 
my $node = (((($R8 + $R10) * $R9 + $R7) * $R6 + $R5)
* $R4 + $R3) * $R2 + $R1;
 
set_voltage($node,18);
say report($node);</syntaxhighlight>
{{out}}
<pre> Ohm Volt Ampere Watt Network tree
10.000 18.000 1.800 32.400 | +
4.000 7.200 1.800 12.960 | | *
8.000 7.200 0.900 6.480 | | | +
4.000 3.600 0.900 3.240 | | | | *
8.000 3.600 0.450 1.620 | | | | | +
4.000 1.800 0.450 0.810 | | | | | | *
12.000 1.800 0.150 0.270 | | | | | | | +
4.000 0.600 0.150 0.090 | | | | | | | | *
12.000 0.600 0.050 0.030 | | | | | | | | | +
10.000 0.500 0.050 0.025 | | | | | | | | | | r
2.000 0.100 0.050 0.005 | | | | | | | | | | r
6.000 0.600 0.100 0.060 | | | | | | | | | r
8.000 1.200 0.150 0.180 | | | | | | | | r
6.000 1.800 0.300 0.540 | | | | | | | r
4.000 1.800 0.450 0.810 | | | | | | r
8.000 3.600 0.450 1.620 | | | | | r
4.000 3.600 0.900 3.240 | | | | r
8.000 7.200 0.900 6.480 | | | r
6.000 10.800 1.800 19.440 | | r</pre>
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">RPN</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span> <span style="color: #000080;font-style:italic;">// or false for infix (same output)
-- node contents:</span>
<span style="color: #008080;">enum</span> <span style="color: #000000;">KIND</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- '+', '*', or 'r'</span>
<span style="color: #000000;">RESISTANCE</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">VOLTAGE</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">A</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">B</span> <span style="color: #000080;font-style:italic;">-- nested nodes or NULL</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">resistance</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">node</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">switch</span> <span style="color: #000000;">node</span><span style="color: #0000FF;">[</span><span style="color: #000000;">KIND</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'+'</span><span style="color: #0000FF;">:</span> <span style="color: #008080;">return</span> <span style="color: #000000;">resistance</span><span style="color: #0000FF;">(</span><span style="color: #000000;">node</span><span style="color: #0000FF;">[</span><span style="color: #000000;">A</span><span style="color: #0000FF;">])</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">resistance</span><span style="color: #0000FF;">(</span><span style="color: #000000;">node</span><span style="color: #0000FF;">[</span><span style="color: #000000;">B</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'*'</span><span style="color: #0000FF;">:</span> <span style="color: #008080;">return</span> <span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">/</span><span style="color: #000000;">resistance</span><span style="color: #0000FF;">(</span><span style="color: #000000;">node</span><span style="color: #0000FF;">[</span><span style="color: #000000;">A</span><span style="color: #0000FF;">])</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">/</span><span style="color: #000000;">resistance</span><span style="color: #0000FF;">(</span><span style="color: #000000;">node</span><span style="color: #0000FF;">[</span><span style="color: #000000;">B</span><span style="color: #0000FF;">]))</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'r'</span><span style="color: #0000FF;">:</span> <span style="color: #008080;">return</span> <span style="color: #000000;">node</span><span style="color: #0000FF;">[</span><span style="color: #000000;">RESISTANCE</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">default</span><span style="color: #0000FF;">:</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #000080;font-style:italic;">-- unknown node kind</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">switch</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">setVoltage</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">node</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">voltage</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">kind</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">node</span><span style="color: #0000FF;">[</span><span style="color: #000000;">KIND</span><span style="color: #0000FF;">]</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">node</span><span style="color: #0000FF;">[</span><span style="color: #000000;">RESISTANCE</span><span style="color: #0000FF;">]</span>
<span style="color: #000080;font-style:italic;">-- v = node[VOLTAGE] -- not needed!</span>
<span style="color: #004080;">object</span> <span style="color: #000000;">na</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">node</span><span style="color: #0000FF;">[</span><span style="color: #000000;">A</span><span style="color: #0000FF;">],</span>
<span style="color: #000000;">nb</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">node</span><span style="color: #0000FF;">[</span><span style="color: #000000;">B</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">switch</span> <span style="color: #000000;">kind</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'+'</span><span style="color: #0000FF;">:</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">ra</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">resistance</span><span style="color: #0000FF;">(</span><span style="color: #000000;">na</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">rb</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">resistance</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nb</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">na</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">setVoltage</span><span style="color: #0000FF;">(</span><span style="color: #000000;">na</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ra</span> <span style="color: #0000FF;">/</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">ra</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">rb</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">*</span> <span style="color: #000000;">voltage</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">nb</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">setVoltage</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nb</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">rb</span> <span style="color: #0000FF;">/</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">ra</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">rb</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">*</span> <span style="color: #000000;">voltage</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'*'</span><span style="color: #0000FF;">:</span>
<span style="color: #000000;">na</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">setVoltage</span><span style="color: #0000FF;">(</span><span style="color: #000000;">na</span><span style="color: #0000FF;">,</span><span style="color: #000000;">voltage</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">nb</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">setVoltage</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nb</span><span style="color: #0000FF;">,</span><span style="color: #000000;">voltage</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">switch</span>
<span style="color: #000000;">node</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">kind</span><span style="color: #0000FF;">,</span><span style="color: #000000;">r</span><span style="color: #0000FF;">,</span><span style="color: #000000;">voltage</span><span style="color: #0000FF;">,</span><span style="color: #000000;">na</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nb</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">node</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">current</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">node</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">node</span><span style="color: #0000FF;">[</span><span style="color: #000000;">VOLTAGE</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">resistance</span><span style="color: #0000FF;">(</span><span style="color: #000000;">node</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">effect</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">node</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">current</span><span style="color: #0000FF;">(</span><span style="color: #000000;">node</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">*</span> <span style="color: #000000;">node</span><span style="color: #0000FF;">[</span><span style="color: #000000;">VOLTAGE</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">report</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">node</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">level</span><span style="color: #0000FF;">=</span><span style="color: #008000;">""</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%8.3f %8.3f %8.3f %8.3f %s%c\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">resistance</span><span style="color: #0000FF;">(</span><span style="color: #000000;">node</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">node</span><span style="color: #0000FF;">[</span><span style="color: #000000;">VOLTAGE</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">current</span><span style="color: #0000FF;">(</span><span style="color: #000000;">node</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">effect</span><span style="color: #0000FF;">(</span><span style="color: #000000;">node</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">level</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">node</span><span style="color: #0000FF;">[</span><span style="color: #000000;">KIND</span><span style="color: #0000FF;">]})</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">node</span><span style="color: #0000FF;">[</span><span style="color: #000000;">A</span><span style="color: #0000FF;">]!=</span><span style="color: #004600;">NULL</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">report</span><span style="color: #0000FF;">(</span><span style="color: #000000;">node</span><span style="color: #0000FF;">[</span><span style="color: #000000;">A</span><span style="color: #0000FF;">],</span><span style="color: #000000;">level</span> <span style="color: #0000FF;">&</span> <span style="color: #008000;">"| "</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">node</span><span style="color: #0000FF;">[</span><span style="color: #000000;">B</span><span style="color: #0000FF;">]!=</span><span style="color: #004600;">NULL</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">report</span><span style="color: #0000FF;">(</span><span style="color: #000000;">node</span><span style="color: #0000FF;">[</span><span style="color: #000000;">B</span><span style="color: #0000FF;">],</span><span style="color: #000000;">level</span> <span style="color: #0000FF;">&</span> <span style="color: #008000;">"| "</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">push_op</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">tok</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">switch</span> <span style="color: #000000;">tok</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">"+"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"*"</span><span style="color: #0000FF;">:</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">[$],</span>
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">[$-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">stack</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">stack</span><span style="color: #0000FF;">[$]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">tok</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">default</span><span style="color: #0000FF;">:</span> <span style="color: #004080;">integer</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">r</span><span style="color: #0000FF;">}}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">scanf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tok</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">stack</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">stack</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">'r'</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">NULL</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">NULL</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">switch</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">stack</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #000080;font-style:italic;">-- RPN</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">rpn</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">stack</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span>
<span style="color: #000000;">tokens</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tokens</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">stack</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">push_op</span><span style="color: #0000FF;">(</span><span style="color: #000000;">stack</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tokens</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">[$]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #000080;font-style:italic;">-- Infix, slightly trickier:</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">ops</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"+"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"*"</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">infix</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">lastnum</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">tokens</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">>=</span><span style="color: #008000;">'0'</span> <span style="color: #008080;">and</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;"><=</span><span style="color: #008000;">'9'</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">lastnum</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">ch</span>
<span style="color: #008080;">else</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lastnum</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">tokens</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tokens</span><span style="color: #0000FF;">,</span><span style="color: #000000;">lastnum</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">lastnum</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">tokens</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tokens</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">&</span><span style="color: #008000;">""</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lastnum</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">tokens</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tokens</span><span style="color: #0000FF;">,</span><span style="color: #000000;">lastnum</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">stack</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span> <span style="color: #000000;">result</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tokens</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">token</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tokens</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">op</span>
<span style="color: #008080;">switch</span> <span style="color: #000000;">token</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">"("</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">stack</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">stack</span><span style="color: #0000FF;">,</span><span style="color: #000000;">token</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">")"</span><span style="color: #0000FF;">:</span> <span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">op</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">[$]</span>
<span style="color: #000000;">stack</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">op</span> <span style="color: #0000FF;">==</span> <span style="color: #008000;">"("</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">result</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">push_op</span><span style="color: #0000FF;">(</span><span style="color: #000000;">result</span><span style="color: #0000FF;">,</span><span style="color: #000000;">op</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">else</span><span style="color: #0000FF;">:</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">tp</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">token</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ops</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">tp</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">while</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">stack</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">op</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">[$]</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">sp</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">op</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ops</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">sp</span> <span style="color: #008080;">or</span> <span style="color: #000000;">tp</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">sp</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">stack</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">result</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">push_op</span><span style="color: #0000FF;">(</span><span style="color: #000000;">result</span><span style="color: #0000FF;">,</span><span style="color: #000000;">op</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #000000;">stack</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">stack</span><span style="color: #0000FF;">,</span><span style="color: #000000;">token</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">result</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">push_op</span><span style="color: #0000FF;">(</span><span style="color: #000000;">result</span><span style="color: #0000FF;">,</span><span style="color: #000000;">token</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">switch</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">stack</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">result</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">push_op</span><span style="color: #0000FF;">(</span><span style="color: #000000;">result</span><span style="color: #0000FF;">,</span><span style="color: #000000;">stack</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">result</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">node</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">RPN</span><span style="color: #0000FF;">?</span><span style="color: #000000;">rpn</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"10 2 + 6 * 8 + 6 * 4 + 8 * 4 + 8 * 6 +"</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">:</span><span style="color: #000000;">infix</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"((((10+2)*6+8)*6+4)*8+4)*8+6"</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">node</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">setVoltage</span><span style="color: #0000FF;">(</span><span style="color: #000000;">node</span><span style="color: #0000FF;">,</span><span style="color: #000000;">18</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" Ohm Volt Ampere Watt Network tree\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">report</span><span style="color: #0000FF;">(</span><span style="color: #000000;">node</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Ohm Volt Ampere Watt Network tree
10.000 18.000 1.800 32.400 +
4.000 7.200 1.800 12.960 | *
8.000 7.200 0.900 6.480 | | +
4.000 3.600 0.900 3.240 | | | *
8.000 3.600 0.450 1.620 | | | | +
4.000 1.800 0.450 0.810 | | | | | *
12.000 1.800 0.150 0.270 | | | | | | +
4.000 0.600 0.150 0.090 | | | | | | | *
12.000 0.600 0.050 0.030 | | | | | | | | +
10.000 0.500 0.050 0.025 | | | | | | | | | r
2.000 0.100 0.050 0.005 | | | | | | | | | r
6.000 0.600 0.100 0.060 | | | | | | | | r
8.000 1.200 0.150 0.180 | | | | | | | r
6.000 1.800 0.300 0.540 | | | | | | r
4.000 1.800 0.450 0.810 | | | | | r
8.000 3.600 0.450 1.620 | | | | r
4.000 3.600 0.900 3.240 | | | r
8.000 7.200 0.900 6.480 | | r
6.000 10.800 1.800 19.440 | r
</pre>
 
=={{header|Python}}==
===RPN===
<langsyntaxhighlight lang="python">class Resistor :
def __init__(self, resistance, a=None, b=None, symbol='r'):
self.resistance = resistance
Line 176 ⟶ 1,085:
print(" Ohm Volt Ampere Watt Network tree")
node.setVoltage(18.0)
node.report()</langsyntaxhighlight>
 
===Infix===
<langsyntaxhighlight lang="python">class Resistor :
def __init__(self, resistance, a=None, b=None, symbol='r') :
self.resistance = resistance
Line 218 ⟶ 1,127:
node.setVoltage(18)
print(" Ohm Volt Ampere Watt Network tree")
node.report()</langsyntaxhighlight>
 
=={{header|Raku}}==
(formerly Perl 6)
===Infix===
{{trans|Nim}}
<syntaxhighlight lang="raku" line>class Resistor {
has Str $.symbol;
has Numeric ( $.voltage, $.resistance );
has Resistor ( $.a, $.b );
 
method res ( ) {
given $.symbol {
when '+' { return $.a.res + $.b.res }
when '*' { return 1 / (1 / $.a.res + 1 / $.b.res) }
default { return $.resistance }
}
}
 
method set-voltage ( Numeric $voltage ) {
given $.symbol {
when '+' {
my $ra = $.a.res;
my $rb = $.b.res;
$.a.set-voltage( $ra / ($ra+$rb) * $voltage );
$.b.set-voltage( $rb / ($ra+$rb) * $voltage );
}
when '*' {
$.a.set-voltage( $voltage );
$.b.set-voltage( $voltage );
}
}
$!voltage = $voltage;
}
method current ( ) { return $.voltage / self.res }
method effect ( ) { return $.voltage * self.current }
 
method report ( Int $level = 1 ) {
my $pad = '| ' x $level;
my $f = ( self.res, $.voltage, self.current, self.effect ).fmt('%8.3f');
say "$f $pad$.symbol";
$.a.report( $level+1 ) if $.a;
$.b.report( $level+1 ) if $.b;
}
}
multi sub infix:<+> (Resistor $a, Resistor $b) { $a.new( symbol => '+', :$a, :$b ) }
multi sub infix:<*> (Resistor $a, Resistor $b) { $a.new( symbol => '*', :$a, :$b ) }
 
my Resistor ($R1, $R2, $R3, $R4, $R5, $R6, $R7, $R8, $R9, $R10) =
map { Resistor.new: symbol => 'r', resistance => $_ },
6, 8, 4, 8, 4, 6, 8, 10, 6, 2;
 
my $node = (((($R8 + $R10) * $R9 + $R7) * $R6 + $R5)
* $R4 + $R3) * $R2 + $R1;
$node.set-voltage(18);
 
say ' Ohm Volt Ampere Watt Network tree';
$node.report;</syntaxhighlight>
{{out}}
<pre style="height:20ex"> Ohm Volt Ampere Watt Network tree
10.000 18.000 1.800 32.400 | +
4.000 7.200 1.800 12.960 | | *
8.000 7.200 0.900 6.480 | | | +
4.000 3.600 0.900 3.240 | | | | *
8.000 3.600 0.450 1.620 | | | | | +
4.000 1.800 0.450 0.810 | | | | | | *
12.000 1.800 0.150 0.270 | | | | | | | +
4.000 0.600 0.150 0.090 | | | | | | | | *
12.000 0.600 0.050 0.030 | | | | | | | | | +
10.000 0.500 0.050 0.025 | | | | | | | | | | r
2.000 0.100 0.050 0.005 | | | | | | | | | | r
6.000 0.600 0.100 0.060 | | | | | | | | | r
8.000 1.200 0.150 0.180 | | | | | | | | r
6.000 1.800 0.300 0.540 | | | | | | | r
4.000 1.800 0.450 0.810 | | | | | | r
8.000 3.600 0.450 1.620 | | | | | r
4.000 3.600 0.900 3.240 | | | | r
8.000 7.200 0.900 6.480 | | | r
6.000 10.800 1.800 19.440 | | r</pre>
 
=={{header|Wren}}==
===Infix===
{{trans|Go}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "./fmt" for Fmt
 
class Resistor {
construct new(symbol, resistance, voltage, a, b) {
_symbol = symbol
_resistance = resistance
_voltage = voltage
_a = a
_b = b
}
 
symbol { _symbol }
resistance { _resistance }
voltage { _voltage}
 
res {
if (_symbol == "+") return _a.res + _b.res
if (_symbol == "*") return 1 / (1/_a.res + 1/_b.res)
return _resistance
}
 
current { _voltage / res }
effect { current * _voltage }
 
voltage=(v) {
if (_symbol == "+") {
var ra = _a.res
var rb = _b.res
_a.voltage = ra / (ra + rb) * v
_b.voltage = rb / (ra + rb) * v
} else if (_symbol == "*") {
_a.voltage = v
_b.voltage = v
}
_voltage = v
}
 
report(level) {
Fmt.lprint("$8.3f $8.3f $8.3f $8.3f $s$s", [res, _voltage, current, effect, level, symbol])
if (_a != null) _a.report(level + "| ")
if (_b != null) _b.report(level + "| ")
}
 
+(other) { Resistor.new("+", 0, 0, this, other) }
*(other) { Resistor.new("*", 0, 0, this, other) }
}
 
var r = List.filled(10, null)
var resistances = [6, 8, 4, 8, 4, 6, 8, 10, 6, 2]
for (i in 0..9) r[i] = Resistor.new("r", resistances[i], 0, null, null)
var node = ((((r[7]+r[9])*r[8]+r[6])*r[5]+r[4])*r[3]+r[2])*r[1] + r[0]
node.voltage = 18
System.print(" Ohm Volt Ampere Watt Network tree")
node.report("")</syntaxhighlight>
 
{{out}}
<pre>
Ohm Volt Ampere Watt Network tree
10.000 18.000 1.800 32.400 +
4.000 7.200 1.800 12.960 | *
8.000 7.200 0.900 6.480 | | +
4.000 3.600 0.900 3.240 | | | *
8.000 3.600 0.450 1.620 | | | | +
4.000 1.800 0.450 0.810 | | | | | *
12.000 1.800 0.150 0.270 | | | | | | +
4.000 0.600 0.150 0.090 | | | | | | | *
12.000 0.600 0.050 0.030 | | | | | | | | +
10.000 0.500 0.050 0.025 | | | | | | | | | r
2.000 0.100 0.050 0.005 | | | | | | | | | r
6.000 0.600 0.100 0.060 | | | | | | | | r
8.000 1.200 0.150 0.180 | | | | | | | r
6.000 1.800 0.300 0.540 | | | | | | r
4.000 1.800 0.450 0.810 | | | | | r
8.000 3.600 0.450 1.620 | | | | r
4.000 3.600 0.900 3.240 | | | r
8.000 7.200 0.900 6.480 | | r
6.000 10.800 1.800 19.440 | r
 
</pre>
 
===RPN===
Additonally:
{{libheader|Wren-seq}}
<syntaxhighlight lang="wren">import "./fmt" for Fmt
import "./seq" for Stack
 
class Resistor {
construct new(symbol, resistance, voltage, a, b) {
_symbol = symbol
_resistance = resistance
_voltage = voltage
_a = a
_b = b
}
 
symbol { _symbol }
resistance { _resistance }
voltage { _voltage}
 
res {
if (_symbol == "+") return _a.res + _b.res
if (_symbol == "*") return 1 / (1/_a.res + 1/_b.res)
return _resistance
}
 
current { _voltage / res }
effect { current * _voltage }
 
voltage=(v) {
if (_symbol == "+") {
var ra = _a.res
var rb = _b.res
_a.voltage = ra / (ra + rb) * v
_b.voltage = rb / (ra + rb) * v
} else if (_symbol == "*") {
_a.voltage = v
_b.voltage = v
}
_voltage = v
}
 
report(level) {
Fmt.lprint("$8.3f $8.3f $8.3f $8.3f $s$s", [res, _voltage, current, effect, level, symbol])
if (_a != null) _a.report(level + "| ")
if (_b != null) _b.report(level + "| ")
}
 
+(other) { Resistor.new("+", 0, 0, this, other) }
*(other) { Resistor.new("*", 0, 0, this, other) }
}
 
var build = Fn.new { |rpn|
var st = Stack.new()
for (token in rpn.split(" ")) {
if (token == "+") {
var b = st.pop()
var a = st.pop()
st.push(Resistor.new("+", 0, 0, a, b))
} else if (token == "*") {
var b = st.pop()
var a = st.pop()
st.push(Resistor.new("*", 0, 0, a, b))
} else {
var r = Num.fromString(token)
st.push(Resistor.new("r", r, 0, null, null))
}
}
return st.pop()
}
 
var node = build.call("10 2 + 6 * 8 + 6 * 4 + 8 * 4 + 8 * 6 +")
node.voltage = 18
System.print(" Ohm Volt Ampere Watt Network tree")
node.report("")</syntaxhighlight>
 
{{out}}
<pre>
Same as Infix version
</pre>
 
=={{header|Zig}}==
{{trans|Nim}}
{{works with|Zig|0.11dev}}
 
Zig requires more "code" than dynamic languages. The following three items account for a good portion of the "extra code".
<ul>
<li>There are no hidden memory allocations. Manual memory management.</li>
<li>Errors are values, and may not be ignored.</li>
<li>Generic data structures and functions.</li>
</ul>
 
===Postfix (RPN)===
<syntaxhighlight lang="zig">
// postfix.zig
const std = @import("std");
const Allocator = std.mem.Allocator;
const Node = @import("common.zig").Node;
const PostfixToken = @import("common.zig").PostfixToken;
const calculate = @import("common.zig").calculate;
 
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer {
const ok = gpa.deinit();
std.debug.assert(ok == .ok);
}
const allocator = gpa.allocator();
 
const stdout = std.io.getStdOut().writer();
 
const node = try postfix(allocator, stdout, 18, "10 2 + 6 * 8 + 6 * 4 + 8 * 4 + 8 * 6 +");
 
std.debug.assert(10 == node.res());
std.debug.assert(18 == node.voltage);
std.debug.assert(1.8 == node.current());
std.debug.assert(std.math.fabs(32.4 - node.effect()) < 0.05);
std.debug.assert(.serial == node.node_type);
 
node.destroyDescendants(allocator);
allocator.destroy(node);
}
 
/// Also know as RPN (Reverse Polish Notation)
fn postfix(allocator: Allocator, writer: anytype, voltage: f32, s: []const u8) !*Node {
const tokens = try parse(allocator, s);
defer allocator.free(tokens);
 
return try calculate(allocator, writer, voltage, tokens);
}
 
const PostfixParseError = error{
UnexpectedCharacter,
};
 
/// Parse postfix expression 's' to give a slice of PostfixToken.
/// Caller owns slice memory on return.
/// There are no Zig language semantics to indicate ownership or transferal thereof.
fn parse(allocator: Allocator, s: []const u8) ![]PostfixToken {
var tokens = std.ArrayList(PostfixToken).init(allocator);
// defer tokens.deinit(); // not needed, toOwnedSlice() owns memory.
 
var slice_start: ?usize = null;
 
// convert the string to a list of Token
for (s, 0..) |ch, i| {
const token: PostfixToken = switch (ch) {
'+' => PostfixToken.serial,
'*' => PostfixToken.parallel,
'0'...'9' => {
// Add digits to 'resistor' value.
// 'slice_start' determines if any digit(s) have already been parsed.
if (slice_start) |_| _ = tokens.pop() else slice_start = i;
const slice_end = i + 1;
try tokens.append(PostfixToken{ .resistor = s[slice_start.?..slice_end] });
continue;
},
' ', '\t' => {
slice_start = null;
continue;
},
else => return PostfixParseError.UnexpectedCharacter,
};
try tokens.append(token);
// Last token was not a resistor. Reset 'start_slice'.
slice_start = null;
}
return tokens.toOwnedSlice();
}
</syntaxhighlight>
 
===Infix===
<syntaxhighlight lang="zig">
// infix.zig
const std = @import("std");
const Allocator = std.mem.Allocator;
const Stack = @import("common.zig").Stack;
const Node = @import("common.zig").Node;
const PostfixToken = @import("common.zig").PostfixToken;
const calculate = @import("common.zig").calculate;
 
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer {
const ok = gpa.deinit();
std.debug.assert(ok == .ok);
}
const allocator = gpa.allocator();
 
const stdout = std.io.getStdOut().writer();
 
const node = try infix(allocator, stdout, 18, "((((10+2)*6+8)*6+4)*8+4)*8+6");
 
std.debug.assert(10 == node.res());
std.debug.assert(18 == node.voltage);
std.debug.assert(1.8 == node.current());
std.debug.assert(std.math.fabs(32.4 - node.effect()) < 0.05);
std.debug.assert(.serial == node.node_type);
 
node.destroyDescendants(allocator);
allocator.destroy(node);
}
 
// Zig tagged union.
const InfixToken = union(enum) {
lparen,
rparen,
serial, // +
parallel, // *
 
// Slice of digits from parent string.
// Do not let the parent string go out of scope while this is in scope.
resistor: []const u8,
};
 
/// Convert infix expression 's' to postfix and call the postfix calculate()
fn infix(allocator: Allocator, writer: anytype, voltage: f32, s: []const u8) !*Node {
// parse infix expression
const infix_tokens: []InfixToken = try parse(allocator, s);
defer allocator.free(infix_tokens);
 
// convert infix to postfix
const postfix_tokens: []PostfixToken = try shuntPostfix(allocator, infix_tokens);
defer allocator.free(postfix_tokens);
 
// use postfix calculate()
return try calculate(allocator, writer, voltage, postfix_tokens);
}
 
const InfixParseError = error{
UnexpectedCharacter,
};
 
/// Parse infix expression 's' to give a slice of InfixToken.
/// Caller owns slice memory on return.
/// There are no Zig language semantics to indicate ownership or transferal thereof.
fn parse(allocator: Allocator, s: []const u8) ![]InfixToken {
var tokens = std.ArrayList(InfixToken).init(allocator);
// defer tokens.deinit(); // not needed, toOwnedSlice() owns memory.
 
var slice_start: ?usize = null;
 
for (s, 0..) |ch, i| {
const token: InfixToken = switch (ch) {
'(' => InfixToken.lparen,
')' => InfixToken.rparen,
'+' => InfixToken.serial,
'*' => InfixToken.parallel,
'0'...'9' => {
// Add digits to 'resistor' value.
// 'slice_start' determines if any digit(s) have already been parsed.
if (slice_start) |_| _ = tokens.pop() else slice_start = i;
const slice_end = i + 1;
try tokens.append(InfixToken{ .resistor = s[slice_start.?..slice_end] });
continue;
},
' ', '\t' => { // extraneous whitespace
slice_start = null;
continue;
},
else => return InfixParseError.UnexpectedCharacter, // unknown
};
try tokens.append(token);
// Last token was not a resistor. Reset 'start_slice'.
slice_start = null;
}
return tokens.toOwnedSlice();
}
 
const ShuntPostfixError = error{
LParenNotAllowed,
RParenNotAllowed,
};
 
/// Input infix (infix tokens) in infix order.
/// Output postfix (postfix tokens) in postfix order.
///
/// Caller owns resultant slice and is responsible for freeing.
fn shuntPostfix(allocator: Allocator, infix_tokens: []InfixToken) ![]PostfixToken {
var result = PostfixTokenArray.init(allocator); // destination storage
var stack = InfixTokenStack.init(allocator); // working storage
defer result.deinit();
defer stack.deinit();
 
for (infix_tokens) |token| {
switch (token) {
.lparen => try stack.push(token),
.rparen => while (!stack.isEmpty()) {
const op = stack.pop();
if (op == InfixToken.lparen) break;
try result.append(op);
},
.parallel, .serial => {
while (!stack.isEmpty()) {
const op = stack.peek();
if (op != InfixToken.serial and op != InfixToken.parallel) break;
_ = stack.pop();
try result.append(op);
}
try stack.push(token);
},
.resistor => try result.append(token),
}
}
while (!stack.isEmpty())
try result.append(stack.pop());
 
// array now contains operands and operators in postfix order (no parentheses)
return result.toOwnedSlice();
}
 
const InfixTokenStack = Stack(InfixToken);
 
/// Façade to an ArrayList that translates from InfixToken tagged unions to
/// PostfixToken tagged unions in its append() function.
const PostfixTokenArray = struct {
result: std.ArrayList(PostfixToken),
 
fn init(allocator: Allocator) PostfixTokenArray {
return PostfixTokenArray{
.result = std.ArrayList(PostfixToken).init(allocator),
};
}
fn deinit(self: *PostfixTokenArray) void {
self.result.deinit();
}
/// Convert InfixToken to PostfixToken.
fn append(self: *PostfixTokenArray, infix_token: InfixToken) !void {
const postfix_token: PostfixToken = switch (infix_token) {
.serial => PostfixToken.serial,
.parallel => PostfixToken.parallel,
.resistor => |slice| PostfixToken{ .resistor = slice },
 
// Postfix does not have parentheses.
.lparen => return ShuntPostfixError.LParenNotAllowed,
.rparen => return ShuntPostfixError.RParenNotAllowed,
};
try self.result.append(postfix_token);
}
fn toOwnedSlice(self: *PostfixTokenArray) !std.ArrayList(PostfixToken).Slice {
return try self.result.toOwnedSlice();
}
};
</syntaxhighlight>
 
===Shared Infix/Postfix Code===
<syntaxhighlight lang="zig">
// common.zig
const std = @import("std");
const Allocator = std.mem.Allocator;
 
// Zig "enum"
const NodeType = enum {
serial,
parallel,
resistor,
 
fn repr(self: NodeType) u8 {
return switch (self) {
.serial => '+',
.parallel => '*',
.resistor => 'r',
};
}
};
 
// Zig "tagged union"
pub const PostfixToken = union(NodeType) {
serial, // '+'
parallel, // '*'
 
// Slice of digits from parent string.
// Do not let the parent string go out of scope while this is in scope.
resistor: []const u8, // 'r'
};
 
// Zig "struct"
pub const Node = struct {
node_type: NodeType,
resistance: ?f32 = null, // optional float, either value or null
voltage: ?f32 = null,
a: ?*Node = null, // optional pointer to Node, either value or null
b: ?*Node = null,
 
pub fn res(self: *Node) f32 {
return switch (self.node_type) {
.serial => self.a.?.res() + self.b.?.res(),
.parallel => 1 / (1 / self.a.?.res() + 1 / self.b.?.res()),
.resistor => if (self.resistance) |resistance| resistance else unreachable,
};
}
 
pub fn current(self: *Node) f32 {
if (self.voltage) |voltage| return voltage / self.res() else unreachable;
}
 
pub fn effect(self: *Node) f32 {
if (self.voltage) |voltage| return self.current() * voltage else unreachable;
}
 
pub fn setVoltage(self: *Node, voltage: f32) void {
self.voltage = voltage;
switch (self.node_type) {
.serial => {
const ra: f32 = self.a.?.res();
const rb: f32 = self.b.?.res();
self.a.?.setVoltage(ra / (ra + rb) * voltage);
self.b.?.setVoltage(rb / (ra + rb) * voltage);
},
.parallel => {
self.a.?.setVoltage(voltage);
self.b.?.setVoltage(voltage);
},
.resistor => {},
}
}
 
pub fn report(self: *Node, allocator: Allocator, writer: anytype, level: []const u8) !void {
if (self.voltage) |voltage| {
try writer.print("{d:8.3} {d:8.3} {d:8.3} {d:8.3} {s}{c}\n", .{
self.res(), voltage, self.current(),
self.effect(), level, self.node_type.repr(),
});
} else unreachable;
// iterate though 'a' and 'b' optional nodes
for ([2]?*Node{ self.a, self.b }) |optional_node| {
if (optional_node) |node| {
const next_level = try std.fmt.allocPrint(allocator, "{s}| ", .{level});
defer allocator.free(next_level);
try node.report(allocator, writer, next_level);
}
}
}
 
/// Free memory allocated to Node descendants and Node itself.
pub fn destroyDescendants(self: *Node, allocator: Allocator) void {
if (self.a) |a| {
self.a = null;
a.destroyDescendants(allocator);
allocator.destroy(a);
}
if (self.b) |b| {
self.b = null;
b.destroyDescendants(allocator);
allocator.destroy(b);
}
}
};
 
fn build(allocator: Allocator, tokens: []PostfixToken) !*Node {
var stack = Stack(*Node).init(allocator);
defer stack.deinit();
 
for (tokens) |token| {
const node = try allocator.create(Node);
 
// 'token' is a tagged union.
// note the extraction of the '.resistor' variable via |r|
node.* = switch (token) {
.serial => Node{ .node_type = NodeType.serial, .b = stack.pop(), .a = stack.pop() },
.parallel => Node{ .node_type = NodeType.parallel, .b = stack.pop(), .a = stack.pop() },
.resistor => |r| Node{ .node_type = NodeType.resistor, .resistance = try std.fmt.parseFloat(f32, r) },
};
try stack.push(node);
}
std.debug.assert(stack.hasOne()); // stack length should be 1.
 
return stack.pop();
}
 
pub fn calculate(allocator: Allocator, writer: anytype, voltage: f32, tokens: []PostfixToken) !*Node {
try writer.print(" Ohm Volt Ampere Watt Network tree\n", .{});
 
var node = try build(allocator, tokens);
node.setVoltage(voltage);
try node.report(allocator, writer, "");
return node;
}
 
// Zig "Generic Data Structure"
// An ad hoc generic stack implementation.
// 'pub' is the Zig way of giving visibility outside module scope.
pub fn Stack(comptime T: type) type {
return struct {
const Self = @This();
stack: std.ArrayList(T),
 
pub fn init(allocator: Allocator) Self {
return Self{
.stack = std.ArrayList(T).init(allocator),
};
}
pub fn deinit(self: *Self) void {
self.stack.deinit();
}
pub fn push(self: *Self, node: T) !void {
return try self.stack.append(node);
}
pub fn pop(self: *Self) T {
return self.stack.pop();
}
pub fn peek(self: *const Self) T {
return self.stack.items[self.stack.items.len - 1];
}
pub fn isEmpty(self: *const Self) bool {
return self.stack.items.len == 0;
}
// no 'pub' - private to this module
fn hasOne(self: *Self) bool {
return self.stack.items.len == 1;
}
};
}
</syntaxhighlight>
 
=={{header|zkl}}==
<syntaxhighlight lang="zkl">class Resistor{
fcn init(resistance_,symbol_="r", a_=Void, b_=Void){
var resistance,a,b,symbol, voltage=Void;
resistance,symbol,a,b = vm.arglist;
resistance=resistance.toFloat(); // deal with strings/ints
}
fcn res{
if (symbol=="+") a.res() + b.res();
else if(symbol=="*") 1.0/(1.0/a.res() + 1.0/b.res());
else resistance
}
fcn setVoltage(voltage){
if(symbol=="+"){
ra,rb := a.res(), b.res();
a.setVoltage(ra/(ra + rb)*voltage);
b.setVoltage(rb/(ra + rb)*voltage);
}
else if(symbol=="*") T(a,b).apply2("setVoltage",voltage);
self.voltage = voltage.toFloat();
}
fcn current{ voltage/res() }
fcn effect { current()*voltage }
fcn report(level=""){
println("%8.3f %8.3f %8.3f %8.3f %s%s".fmt(res(),voltage,current(),effect(),level,symbol));
T(a,b).apply2("report",level + "| "); // noop if Void
}
fcn __opAdd(other){ Resistor(0,"+",self,other) }
fcn __opMul(other){ Resistor(0,"*",self,other) }
}</syntaxhighlight>
===Infix===
<syntaxhighlight lang="zkl">R1,R2,R3,R4,R5,R6,R7,R8,R9,R10 := T(6,8,4,8,4,6,8,10,6,2].apply(Resistor);
node:=((((R8 + R10)*R9 + R7)*R6 + R5)*R4 + R3)*R2 + R1;
node.setVoltage(18);
println(" Ohm Volt Ampere Watt Network tree");
node.report();</syntaxhighlight>
{{out}}
<pre style="height:15ex">
Ohm Volt Ampere Watt Network tree
10.000 18.000 1.800 32.400 +
4.000 7.200 1.800 12.960 | *
8.000 7.200 0.900 6.480 | | +
4.000 3.600 0.900 3.240 | | | *
8.000 3.600 0.450 1.620 | | | | +
4.000 1.800 0.450 0.810 | | | | | *
12.000 1.800 0.150 0.270 | | | | | | +
4.000 0.600 0.150 0.090 | | | | | | | *
12.000 0.600 0.050 0.030 | | | | | | | | +
10.000 0.500 0.050 0.025 | | | | | | | | | r
2.000 0.100 0.050 0.005 | | | | | | | | | r
6.000 0.600 0.100 0.060 | | | | | | | | r
8.000 1.200 0.150 0.180 | | | | | | | r
6.000 1.800 0.300 0.540 | | | | | | r
4.000 1.800 0.450 0.810 | | | | | r
8.000 3.600 0.450 1.620 | | | | r
4.000 3.600 0.900 3.240 | | | r
8.000 7.200 0.900 6.480 | | r
6.000 10.800 1.800 19.440 | r
</pre>
===RPN===
<syntaxhighlight lang="zkl">fcn build(rpnStr){
stack:=List();
foreach symbol in (rpnStr.split()){
if(symbol=="+"){
a,b:=stack.pop(),stack.pop();
stack.append(Resistor(0,"+",b,a))
}
else if(symbol=="*"){
a,b:=stack.pop(),stack.pop();
stack.append(Resistor(0,"*",b,a))
}
else stack.append(Resistor(symbol,"r"));
}
stack.pop() // unevaluated top of circuit
}
node:=build("10 2 + 6 * 8 + 6 * 4 + 8 * 4 + 8 * 6 +");
node.setVoltage(18);
println(" Ohm Volt Ampere Watt Network tree");
node.report();</syntaxhighlight>
{{out}}
<pre style="height:15ex">
Ohm Volt Ampere Watt Network tree
10.000 18.000 1.800 32.400 +
4.000 7.200 1.800 12.960 | *
8.000 7.200 0.900 6.480 | | +
4.000 3.600 0.900 3.240 | | | *
8.000 3.600 0.450 1.620 | | | | +
4.000 1.800 0.450 0.810 | | | | | *
12.000 1.800 0.150 0.270 | | | | | | +
4.000 0.600 0.150 0.090 | | | | | | | *
12.000 0.600 0.050 0.030 | | | | | | | | +
10.000 0.500 0.050 0.025 | | | | | | | | | r
2.000 0.100 0.050 0.005 | | | | | | | | | r
6.000 0.600 0.100 0.060 | | | | | | | | r
8.000 1.200 0.150 0.180 | | | | | | | r
6.000 1.800 0.300 0.540 | | | | | | r
4.000 1.800 0.450 0.810 | | | | | r
8.000 3.600 0.450 1.620 | | | | r
4.000 3.600 0.900 3.240 | | | r
8.000 7.200 0.900 6.480 | | r
6.000 10.800 1.800 19.440 | r
</pre>

Latest revision as of 08:38, 7 May 2024

Resistance calculator is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
Introduction
  • Calculate the resistance of a network of resistors.
  • The resistors can be connected in series or parallel.
  • Use infix or RPN to state the network.
  • Calculate resistance, voltage, current and power for every resistor and operation.
Background
  • Serial Resistors: the sum of the resistors gives the equivalent resistor
  • Parallel Resistors: the inverse of the sum of the inverse of the resistors
  • The voltage drops over the resistors
  • Current = Resistance / Voltage
  • Power = Current * Voltage
Input

Resistance Calculator

  • Infix: ((((10 + 2) * 6 + 8) * 6 + 4) * 8 + 4) * 8 + 6
  • RPN: 10 2 + 6 * 8 + 6 * 4 + 8 * 4 + 8 * 6 +
  • Voltage = 18.0 V
Output
  • 10.000 ohms in the upper left corner is the equivalent resistance.
  • The first operation is 10 + 2 = 12 which can be found in the three middle rows.
    Ohm     Volt   Ampere     Watt  Network tree
 10.000   18.000    1.800   32.400  +
  4.000    7.200    1.800   12.960  | *
  8.000    7.200    0.900    6.480  | | +
  4.000    3.600    0.900    3.240  | | | *
  8.000    3.600    0.450    1.620  | | | | +
  4.000    1.800    0.450    0.810  | | | | | *
 12.000    1.800    0.150    0.270  | | | | | | +
  4.000    0.600    0.150    0.090  | | | | | | | *
 12.000    0.600    0.050    0.030  | | | | | | | | +
 10.000    0.500    0.050    0.025  | | | | | | | | | r
  2.000    0.100    0.050    0.005  | | | | | | | | | r
  6.000    0.600    0.100    0.060  | | | | | | | | r
  8.000    1.200    0.150    0.180  | | | | | | | r
  6.000    1.800    0.300    0.540  | | | | | | r
  4.000    1.800    0.450    0.810  | | | | | r
  8.000    3.600    0.450    1.620  | | | | r
  4.000    3.600    0.900    3.240  | | | r
  8.000    7.200    0.900    6.480  | | r
  6.000   10.800    1.800   19.440  | r

11l

Translation of: Python

RPN

T Resistor
   Float resistance
   voltage = 0.0
   Resistor? a, b
   Char symbol

   F (resistance = 0.0, Resistor? a = N, b = N; symbol = Char(‘r’))
      .resistance = resistance
      .a = a
      .b = b
      .symbol = symbol

   F.virtual.new res() -> Float
      R .resistance
   F.virtual.new setVoltage(Float voltage) -> Void
      .voltage = voltage
   F current()
      R .voltage / .res()
   F effect()
      R .current() * .voltage
   F report(level = ‘’) -> Void
      print(‘#4.3 #4.3 #4.3 #4.3  #.#.’.format(.res(), .voltage, .current(), .effect(), level, .symbol))
      I .a != N {.a.report(level‘| ’)}
      I .b != N {.b.report(level‘| ’)}

T Serial(Resistor)
   F (Resistor a, b)
      .a = move(b)
      .b = a
      .symbol = Char(‘+’)

   F.virtual.override res() -> Float
      R .a.res() + .b.res()

   F.virtual.override setVoltage(Float voltage) -> Void
      V ra = .a.res()
      V rb = .b.res()
      .a.setVoltage(ra / (ra + rb) * voltage)
      .b.setVoltage(rb / (ra + rb) * voltage)
      .voltage = voltage

T Parallel(Resistor)
   F (Resistor a, b)
      .a = move(b)
      .b = a
      .symbol = Char(‘*’)

   F.virtual.override res() -> Float
      R 1 / (1 / .a.res() + 1 / .b.res())

   F.virtual.override setVoltage(Float voltage) -> Void
      .a.setVoltage(voltage)
      .b.setVoltage(voltage)
      .voltage = voltage

F build(s)
   [Resistor] stack
   L(word) s.split(‘ ’)
      I word == ‘+’
         Resistor p = stack.pop()
         stack.append(Serial(p, stack.pop()))
      E I word == ‘*’
         Resistor p = stack.pop()
         stack.append(Parallel(p, stack.pop()))
      E
         stack.append(Resistor(Float(word)))
   R stack.pop()

Resistor node = build(‘10 2 + 6 * 8 + 6 * 4 + 8 * 4 + 8 * 6 +’)
print(‘     Ohm     Volt   Ampere     Watt  Network tree’)
node.setVoltage(18.0)
node.report()

CoffeeScript

RPN

nd = (num) -> num.toFixed(3).padStart 8

class Resistor
	constructor : (@resistance,@a=null,@b=null,@symbol='r') -> 
	res : -> @resistance
	setVoltage : (@voltage) ->
	current : -> @voltage / @res()
	effect : -> @current() * @voltage
	report : (level) ->
		print "#{nd @res()} #{nd @voltage} #{nd @current()} #{nd @effect()}  #{level}#{@symbol}"
		if @a then @a.report level + "| "
		if @b then @b.report level + "| "

class Serial extends Resistor
	constructor : (a,b) -> super 0,a,b,'+'
	res : -> @a.res() + @b.res()
	setVoltage : (@voltage) ->
		ra = @a.res()
		rb = @b.res()
		@a.setVoltage ra/(ra+rb) * @voltage
		@b.setVoltage rb/(ra+rb) * @voltage

class Parallel extends Resistor
	constructor : (a,b) -> super 0,a,b,'*'
	res : -> 1 / (1 / @a.res() + 1 / @b.res())
	setVoltage : (@voltage) ->
		@a.setVoltage @voltage
		@b.setVoltage @voltage

build = (s) ->
	stack = []
	for word in s.split ' '
		if      word == '+' then stack.push new Serial stack.pop(), stack.pop()
		else if word == '*' then stack.push new Parallel stack.pop(), stack.pop()
		else                     stack.push new Resistor parseFloat word
	stack.pop()

node = build "10 2 + 6 * 8 + 6 * 4 + 8 * 4 + 8 * 6 +"
node.setVoltage 18.0
print "     Ohm     Volt   Ampere     Watt  Network tree"
node.report ""

FreeBASIC

Infix

Translation of: Go
Const NULL As Any Ptr = 0

Type Resistor
    symbol As String
    resistance As Double
    voltage As Double
    a As Resistor Ptr
    b As Resistor Ptr
End Type

Function res(r As Resistor Ptr) As Double
    Select Case r->symbol
    Case "+"
        Return res(r->a) + res(r->b)
    Case "*"
        Return 1 / (1 / res(r->a) + 1 / res(r->b))
    Case Else
        Return r->resistance
    End Select
End Function

Sub setVoltage(r As Resistor Ptr, voltage As Double)
    Select Case r->symbol
    Case "+"
        Dim ra As Double = res(r->a)
        Dim rb As Double = res(r->b)
        setVoltage(r->a, ra / (ra + rb) * voltage)
        setVoltage(r->b, rb / (ra + rb) * voltage)
    Case "*"
        setVoltage(r->a, voltage)
        setVoltage(r->b, voltage)
    End Select
    r->voltage = voltage
End Sub

Function current(r As Resistor Ptr) As Double
    Return r->voltage / res(r)
End Function

Function effect(r As Resistor Ptr) As Double
    Return current(r) * r->voltage
End Function

Sub report(r As Resistor Ptr, level As String)
    Print Using "###.### ###.### ###.### ###.### & &"; res(r); r->voltage; current(r); effect(r); level; r->symbol
    If r->a <> NULL Then report(r->a, level + " |")
    If r->b <> NULL Then report(r->b, level + " |")
End Sub

Function sum(r1 As Resistor Ptr, r2 As Resistor Ptr) As Resistor Ptr
    Dim r As Resistor Ptr = Callocate(1, Sizeof(Resistor))
    r->symbol = "+"
    r->a = r1
    r->b = r2
    Return r
End Function

Function mul(r1 As Resistor Ptr, r2 As Resistor Ptr) As Resistor Ptr
    Dim r As Resistor Ptr = Callocate(1, Sizeof(Resistor))
    r->symbol = "*"
    r->a = r1
    r->b = r2
    Return r
End Function

Dim As Resistor Ptr r(9)
Dim As Double resistances(9) = {6, 8, 4, 8, 4, 6, 8, 10, 6, 2}
For i As Integer = 0 To 9
    r(i) = Callocate(1, Sizeof(Resistor))
    r(i)->symbol = "r"
    r(i)->resistance = resistances(i)
Next
Dim As Resistor Ptr node
node = sum(r(7), r(9))
node = mul(node, r(8))
node = sum(node, r(6))
node = mul(node, r(5))
node = sum(node, r(4))
node = mul(node, r(3))
node = sum(node, r(2))
node = mul(node, r(1))
node = sum(node, r(0))
setVoltage(node, 18)
Print "    Ohm   Volt   Ampere    Watt  Network tree"
report(node, "")

Sleep
Output:
    Ohm   Volt   Ampere    Watt  Network tree
 10.000  18.000   1.800  32.400  +
  4.000   7.200   1.800  12.960  | *
  8.000   7.200   0.900   6.480  | | +
  4.000   3.600   0.900   3.240  | | | *
  8.000   3.600   0.450   1.620  | | | | +
  4.000   1.800   0.450   0.810  | | | | | *
 12.000   1.800   0.150   0.270  | | | | | | +
  4.000   0.600   0.150   0.090  | | | | | | | *
 12.000   0.600   0.050   0.030  | | | | | | | | +
 10.000   0.500   0.050   0.025  | | | | | | | | | r
  2.000   0.100   0.050   0.005  | | | | | | | | | r
  6.000   0.600   0.100   0.060  | | | | | | | | r
  8.000   1.200   0.150   0.180  | | | | | | | r
  6.000   1.800   0.300   0.540  | | | | | | r
  4.000   1.800   0.450   0.810  | | | | | r
  8.000   3.600   0.450   1.620  | | | | r
  4.000   3.600   0.900   3.240  | | | r
  8.000   7.200   0.900   6.480  | | r
  6.000  10.800   1.800  19.440  | r

RPN

Translation of: Go
Const NULL As Any Ptr = 0

Type Resistor
    symbol As String
    resistance As Double
    voltage As Double
    a As Resistor Ptr
    b As Resistor Ptr
End Type

Sub push(s() As Resistor Ptr, r As Resistor Ptr)
    Redim Preserve s(Ubound(s) + 1)
    s(Ubound(s)) = r
End Sub

Sub pop(s() As Resistor Ptr, Byref r As Resistor Ptr)
    r = s(Ubound(s))
    Redim Preserve s(Ubound(s) - 1)
End Sub

Function res(r As Resistor Ptr) As Double
    Select Case r->symbol
    Case "+"
        Return res(r->a) + res(r->b)
    Case "*"
        Return 1 / (1 / res(r->a) + 1 / res(r->b))
    Case Else
        Return r->resistance
    End Select
End Function

Sub setVoltage(r As Resistor Ptr, voltage As Double)
    Select Case r->symbol
    Case "+"
        Dim ra As Double = res(r->a)
        Dim rb As Double = res(r->b)
        setVoltage(r->a, ra / (ra + rb) * voltage)
        setVoltage(r->b, rb / (ra + rb) * voltage)
    Case "*"
        setVoltage(r->a, voltage)
        setVoltage(r->b, voltage)
    End Select
    r->voltage = voltage
End Sub

Function current(r As Resistor Ptr) As Double
    Return r->voltage / res(r)
End Function

Function effect(r As Resistor Ptr) As Double
    Return current(r) * r->voltage
End Function

Sub report(r As Resistor Ptr, level As String)
    Print Using "###.### ###.### ###.### ###.### & &"; res(r); r->voltage; current(r); effect(r); level; r->symbol
    If r->a <> NULL Then report(r->a, level + " |")
    If r->b <> NULL Then report(r->b, level + " |")
End Sub

Sub splitString(s As String, delim As String, result() As String)
    Dim As Integer start = 1, endd
    While start <= Len(s)
        endd = Instr(start, s, delim)
        If endd = 0 Then endd = Len(s) + 1
        Redim Preserve result(Ubound(result) + 1)
        result(Ubound(result)) = Mid(s, start, endd - start)
        start = endd + Len(delim)
    Wend
End Sub

Sub build(rpn As String, Byref node As Resistor Ptr)
    Dim As Resistor Ptr s()
    Dim As String tokens()
    splitString(rpn, " ", tokens())
    Dim As Integer i
    For i = 0 To Ubound(tokens)
        Dim As Resistor Ptr r = Callocate(1, Sizeof(Resistor))
        Select Case tokens(i)
        Case "+", "*"
            pop(s(), r->b)
            pop(s(), r->a)
            r->symbol = tokens(i)
        Case Else
            r->resistance = Val(tokens(i))
            r->symbol = "r"
        End Select
        push(s(), r)
    Next
    pop(s(), node)
End Sub

Dim As Resistor Ptr node 
build("10 2 + 6 * 8 + 6 * 4 + 8 * 4 + 8 * 6 +", node)
setVoltage(node, 18)
Print "    Ohm   Volt   Ampere    Watt  Network tree"
report(node, "")

Sleep
Output:
Same as Infix version

Go

Infix

Translation of: Nim
package main

import "fmt"

type Resistor struct {
    symbol              rune
    resistance, voltage float64
    a, b                *Resistor
}

func (r *Resistor) res() float64 {
    switch r.symbol {
    case '+':
        return r.a.res() + r.b.res()
    case '*':
        return 1 / (1/r.a.res() + 1/r.b.res())
    default:
        return r.resistance
    }
}

func (r *Resistor) setVoltage(voltage float64) {
    switch r.symbol {
    case '+':
        ra := r.a.res()
        rb := r.b.res()
        r.a.setVoltage(ra / (ra + rb) * voltage)
        r.b.setVoltage(rb / (ra + rb) * voltage)
    case '*':
        r.a.setVoltage(voltage)
        r.b.setVoltage(voltage)
    }
    r.voltage = voltage
}

func (r *Resistor) current() float64 {
    return r.voltage / r.res()
}

func (r *Resistor) effect() float64 {
    return r.current() * r.voltage
}

func (r *Resistor) report(level string) {
    fmt.Printf("%8.3f %8.3f %8.3f %8.3f  %s%c\n", r.res(), r.voltage, r.current(), r.effect(), level, r.symbol)
    if r.a != nil {
        r.a.report(level + "| ")
    }
    if r.b != nil {
        r.b.report(level + "| ")
    }
}

func (r *Resistor) add(other *Resistor) *Resistor {
    return &Resistor{'+', 0, 0, r, other}
}

func (r *Resistor) mul(other *Resistor) *Resistor {
    return &Resistor{'*', 0, 0, r, other}
}

func main() {
    var r [10]*Resistor
    resistances := []float64{6, 8, 4, 8, 4, 6, 8, 10, 6, 2}
    for i := 0; i < 10; i++ {
        r[i] = &Resistor{'r', resistances[i], 0, nil, nil}
    }
    node := r[7].add(r[9]).mul(r[8]).add(r[6]).mul(r[5]).add(r[4]).mul(r[3]).add(r[2]).mul(r[1]).add(r[0])
    node.setVoltage(18)
    fmt.Println("     Ohm     Volt   Ampere     Watt  Network tree")
    node.report("")
}

RPN

package main

import (
    "fmt"
    "strconv"
    "strings"
)

type Stack []*Resistor

func (s *Stack) push(r *Resistor) {
    *s = append(*s, r)
}

func (s *Stack) pop() *Resistor {
    le := len(*s)
    if le == 0 {
        panic("Attempt to pop from an empty stack")
    }
    le--
    r := (*s)[le]
    *s = (*s)[:le]
    return r
}

type Resistor struct {
    symbol              rune
    resistance, voltage float64
    a, b                *Resistor
}

func (r *Resistor) res() float64 {
    switch r.symbol {
    case '+':
        return r.a.res() + r.b.res()
    case '*':
        return 1 / (1/r.a.res() + 1/r.b.res())
    default:
        return r.resistance
    }
}

func (r *Resistor) setVoltage(voltage float64) {
    switch r.symbol {
    case '+':
        ra := r.a.res()
        rb := r.b.res()
        r.a.setVoltage(ra / (ra + rb) * voltage)
        r.b.setVoltage(rb / (ra + rb) * voltage)
    case '*':
        r.a.setVoltage(voltage)
        r.b.setVoltage(voltage)
    }
    r.voltage = voltage
}

func (r *Resistor) current() float64 {
    return r.voltage / r.res()
}

func (r *Resistor) effect() float64 {
    return r.current() * r.voltage
}

func (r *Resistor) report(level string) {
    fmt.Printf("%8.3f %8.3f %8.3f %8.3f  %s%c\n", r.res(), r.voltage, r.current(), r.effect(), level, r.symbol)
    if r.a != nil {
        r.a.report(level + "| ")
    }
    if r.b != nil {
        r.b.report(level + "| ")
    }
}

func build(rpn string) *Resistor {
    st := new(Stack)
    for _, token := range strings.Fields(rpn) {
        switch token {
        case "+":
            b, a := st.pop(), st.pop()
            st.push(&Resistor{'+', 0, 0, a, b})
        case "*":
            b, a := st.pop(), st.pop()
            st.push(&Resistor{'*', 0, 0, a, b})
        default:
            r, _ := strconv.ParseFloat(token, 64)
            st.push(&Resistor{'r', r, 0, nil, nil})
        }
    }
    return st.pop()
}

func main() {
    node := build("10 2 + 6 * 8 + 6 * 4 + 8 * 4 + 8 * 6 +")
    node.setVoltage(18)
    fmt.Println("     Ohm     Volt   Ampere     Watt  Network tree")
    node.report("")
}

Julia

Translation of: Raku

Infix

using Formatting
import Base.+, Base.*

mutable struct Resistor
    operator::Char
    voltage::Float64
    resistance::Float64
    a::Union{Resistor, Nothing}
    b::Union{Resistor, Nothing}
end

function res(r::Resistor)
    if r != nothing
        if r.operator == '+'
            return res(r.a) + res(r.b)
        elseif r.operator == '*' 
            return 1 / ((1 / res(r.a)) + (1 / res(r.b)))
        end
        return r.resistance
    end
end

function setvoltage(r, voltage)
    if r != nothing
        if r.operator == '+'
            ra = res(r.a)
            rb = res(r.b)
            setvoltage(r.a, voltage * ra / (ra + rb))
            setvoltage(r.b, voltage * rb / (ra + rb))
        elseif r.operator == '*'
            setvoltage(r.a, voltage)
            setvoltage(r.b, voltage)
        end
        r.voltage = voltage
    end
end
    
current(r) = r.voltage / res(r)

effect(r) = r.voltage * current(r)

function report(r, level=1)
    nfmt(x::Real) = rpad(format(x, precision=3), 12)
    afmt(arr::Vector) = join(map(nfmt, arr), "| ")
    println(afmt([res(r), r.voltage, current(r), effect(r)]), "| "^level, r.operator)
    if r.a != nothing
        report(r.a, level + 1)
    end
    if r.b != nothing
        report(r.b, level + 1)
    end
end

Base.:+(a::Resistor, b::Resistor) = Resistor('+',  0.0, 0.0, a, b)
Base.:*(a::Resistor, b::Resistor) = Resistor('*',  0.0, 0.0, a, b)
 
(R1, R2, R3, R4, R5, R6, R7, R8, R9, R10) =
    map(r -> Resistor('r', 0.0, r, nothing, nothing), [6, 8, 4, 8, 4, 6, 8, 10, 6, 2])
 
node = ((((R8 + R10) * R9 + R7) * R6 + R5) * R4 + R3) * R2 + R1
setvoltage(node, 18)

println("   Ohm        Volt          Ampere        Watt        Network tree")
report(node)
Output:
   Ohm        Volt          Ampere        Watt        Network tree
10.000      | 18.000      | 1.800       | 32.400      | +
4.000       | 7.200       | 1.800       | 12.960      | | *
8.000       | 7.200       | 0.900       | 6.480       | | | +
4.000       | 3.600       | 0.900       | 3.240       | | | | *
8.000       | 3.600       | 0.450       | 1.620       | | | | | +
4.000       | 1.800       | 0.450       | 0.810       | | | | | | *
12.000      | 1.800       | 0.150       | 0.270       | | | | | | | +
4.000       | 0.600       | 0.150       | 0.090       | | | | | | | | *
12.000      | 0.600       | 0.050       | 0.030       | | | | | | | | | +
10.000      | 0.500       | 0.050       | 0.025       | | | | | | | | | | r
2.000       | 0.100       | 0.050       | 0.005       | | | | | | | | | | r
6.000       | 0.600       | 0.100       | 0.060       | | | | | | | | | r
8.000       | 1.200       | 0.150       | 0.180       | | | | | | | | r
6.000       | 1.800       | 0.300       | 0.540       | | | | | | | r
4.000       | 1.800       | 0.450       | 0.810       | | | | | | r
8.000       | 3.600       | 0.450       | 1.620       | | | | | r
4.000       | 3.600       | 0.900       | 3.240       | | | | r
8.000       | 7.200       | 0.900       | 6.480       | | | r
6.000       | 10.800      | 1.800       | 19.440      | | r

RPN

function rpn(arr::Vector)
    stack = Any[]
    for op in arr
        if isa(op, Function)
            arg2 = pop!(stack)
            arg1 = pop!(stack)
            push!(stack, op(arg1, arg2))
        else
            push!(stack, op)
        end
    end
    length(stack) != 1 && error("invalid RPN expression array: $arr")
    return stack[1]
end

node = rpn([R8, R10, +, R9, *, R7, +, R6, *, R5, +, R4, *, R3, +, R2, *, R1, +])
setvoltage(node, 18)
report(node)
Output:

Same as infix version.

Nim

import strutils, strformat

type
  Node = ref object
    kind: char  #  + = serial  * = parallel  r = resistor
    resistance: float
    voltage: float
    a: Node
    b: Node

proc res(node: Node): float =
  if node.kind == '+': return node.a.res + node.b.res
  if node.kind == '*': return 1 / (1 / node.a.res + 1 / node.b.res)
  node.resistance

proc current(node: Node): float = node.voltage / node.res
proc effect (node: Node): float = node.current * node.voltage

proc report(node: Node, level: string = "") =
  echo fmt"{node.res:8.3f} {node.voltage:8.3f} {node.current:8.3f} {node.effect:8.3f}  {level}{node.kind}"
  if node.kind in "+*":
    node.a.report level & "| "
    node.b.report level & "| "

proc setVoltage(node: Node, voltage: float) =
  node.voltage = voltage
  if node.kind == '+':
    let ra = node.a.res
    let rb = node.b.res
    node.a.setVoltage ra / (ra+rb) * voltage
    node.b.setVoltage rb / (ra+rb) * voltage
  if node.kind == '*':
    node.a.setVoltage voltage
    node.b.setVoltage voltage

proc build(tokens: seq[string]): Node =
  var stack: seq[Node]
  for token in tokens:
    stack.add if token == "+": Node(kind: '+', a: stack.pop, b: stack.pop)
              elif token == "*": Node(kind: '*', a: stack.pop, b: stack.pop)
              else: Node(kind: 'r', resistance: parseFloat(token))
  stack.pop

proc calculate(voltage: float, tokens: seq[string]): Node =
  echo ""
  echo "     Ohm     Volt   Ampere     Watt  Network tree"
  let node = build tokens
  node.setVoltage voltage
  node.report
  node

RPN

proc rpn(voltage:float, s:string): Node = calculate(voltage, s.split ' ')
var node = rpn(18, "10 2 + 6 * 8 + 6 * 4 + 8 * 4 + 8 * 6 +")
assert 10 == node.res
assert 18 == node.voltage
assert 1.8 == node.current()
assert 32.4 == node.effect()
assert '+' == node.kind

Infix

proc parse(s: string): seq[string] =
  var tmp = ""
  for ch in s:
    case ch
    of ' ':
      if tmp != "": result.add tmp
      tmp = ""
      continue
    of '+', '*', '(', ')':
      if tmp != "": result.add tmp
      tmp = ""
      result.add $ch
    else:
      tmp &= ch
  if tmp != "": result.add tmp

proc shuntRPN(s: string): seq[string] =
  let ops = "+*"
  var tokens = parse s
  var stack: seq[string]
  var op: string

  for token in tokens:
    case token
    of "(":
      stack.add token
    of ")":
      while stack.len > 0:
        op = stack.pop()
        if op == "(": break
        result.add op
    else:
      if token in ops:
        while stack.len > 0:
          op = stack[^1]
          if op notin ops: break
          if ops.find(token) >= ops.find(op): break
          discard stack.pop()
          result.add op
        stack.add token
      else: result.add token

  while stack.len > 0: result.add stack.pop()

proc infix(voltage:float, s:string): Node = calculate(voltage, shuntRPN s)
node = infix(18, "((((10+2)*6+8)*6+4)*8+4)*8+6")
assert 10 == node.res
assert 18 == node.voltage
assert 1.8 == node.current()
assert 32.4 == node.effect()
assert '+' == node.kind

Perl

Infix

Translation of: Raku
use v5.36;

package Resistor;
require Exporter;
our @ISA    = qw(Exporter);
our @EXPORT = qw(set_voltage report);

use overload '+' => \&serial, '*' => \&parallel;

sub new ($class, $args) {
    my $self = {
        symbol     => $args->{symbol},
        voltage    => $args->{voltage},
        resistance => $args->{resistance},
        a          => $args->{a},
        b          => $args->{b},
    };
    return bless $self, $class;
}

sub res ($self) {
    if    ($self->{symbol} eq '+') { return res($self->{a}) + res($self->{b}) }
    elsif ($self->{symbol} eq '*') { return 1 / (1/res($self->{a}) + 1/res($self->{b})) }
    else                           { return $self->{resistance} }
}

sub set_voltage ($self,$voltage) {
    if ($self->{symbol} eq '+') {
        my $ra = res($self->{a});
        my $rb = res($self->{b});
        set_voltage($self->{a}, $ra / ($ra+$rb) * $voltage );
        set_voltage($self->{b}, $rb / ($ra+$rb) * $voltage );
    } elsif ($self->{symbol} eq '*') {
        set_voltage($self->{a}, $voltage );
        set_voltage($self->{b}, $voltage );
    }
    $self->{voltage} = $voltage;
}

sub current ($self) { return $self->{voltage} / res($self)     }
sub effect  ($self) { return $self->{voltage} * current($self) }

sub serial   ($a,$b,$) { Resistor->new( {symbol => '+', a => $a, b => $b} ) }
sub parallel ($a,$b,$) { Resistor->new( {symbol => '*', a => $a, b => $b} ) }

sub report ($self,$level = 0) {
    state @results;
    push @results, '      Ohm     Volt   Ampere     Watt   Network tree' and $level = 1 unless $level;
    my $pad = ('| ') x $level;
    my $f = sprintf '%9.3f' x 4, res($self), $self->{voltage}, current($self), effect($self);
    say "$f $pad" . $self->{symbol};
    report($self->{a}, $level+1) if defined $self->{a};
    report($self->{b}, $level+1) if defined $self->{b};
    join "\n", @results;
}

}

package main;
Resistor->import;

my ($R1, $R2, $R3, $R4, $R5, $R6, $R7, $R8, $R9, $R10) =
    map { Resistor->new( {symbol => 'r', resistance => $_} ) } <6 8 4 8 4 6 8 10 6 2>;

my $node = (((($R8 + $R10) * $R9 + $R7) * $R6 + $R5)
                           * $R4 + $R3) * $R2 + $R1;

set_voltage($node,18);
say report($node);
Output:
      Ohm     Volt   Ampere     Watt   Network tree
   10.000   18.000    1.800   32.400 | +
    4.000    7.200    1.800   12.960 | | *
    8.000    7.200    0.900    6.480 | | | +
    4.000    3.600    0.900    3.240 | | | | *
    8.000    3.600    0.450    1.620 | | | | | +
    4.000    1.800    0.450    0.810 | | | | | | *
   12.000    1.800    0.150    0.270 | | | | | | | +
    4.000    0.600    0.150    0.090 | | | | | | | | *
   12.000    0.600    0.050    0.030 | | | | | | | | | +
   10.000    0.500    0.050    0.025 | | | | | | | | | | r
    2.000    0.100    0.050    0.005 | | | | | | | | | | r
    6.000    0.600    0.100    0.060 | | | | | | | | | r
    8.000    1.200    0.150    0.180 | | | | | | | | r
    6.000    1.800    0.300    0.540 | | | | | | | r
    4.000    1.800    0.450    0.810 | | | | | | r
    8.000    3.600    0.450    1.620 | | | | | r
    4.000    3.600    0.900    3.240 | | | | r
    8.000    7.200    0.900    6.480 | | | r
    6.000   10.800    1.800   19.440 | | r

Phix

with javascript_semantics
constant RPN = true // or false for infix (same output)
-- node contents:
enum KIND, -- '+', '*', or 'r'
     RESISTANCE, VOLTAGE, 
     A, B   -- nested nodes or NULL
 
function resistance(sequence node)
    switch node[KIND] do
        case '+': return resistance(node[A]) + resistance(node[B])
        case '*': return 1 / (1/resistance(node[A]) + 1/resistance(node[B]))
        case 'r': return node[RESISTANCE]
        default: ?9/0 -- unknown node kind
    end switch
end function
 
function setVoltage(sequence node, atom voltage)
    integer kind = node[KIND]
    atom r = node[RESISTANCE]
--       v = node[VOLTAGE] -- not needed!
    object na = node[A],
           nb = node[B]
    switch kind do
        case '+':
            atom ra := resistance(na),
                 rb := resistance(nb)
            na = setVoltage(na, ra / (ra + rb) * voltage)
            nb = setVoltage(nb, rb / (ra + rb) * voltage)
        case '*':
            na = setVoltage(na,voltage)
            nb = setVoltage(nb,voltage)
    end switch
    node = {kind,r,voltage,na,nb}
    return node
end function
 
function current(sequence node)
    return node[VOLTAGE] / resistance(node)
end function
 
function effect(sequence node)
    return current(node) * node[VOLTAGE]
end function
 
procedure report(sequence node, string level="")
    printf(1,"%8.3f %8.3f %8.3f %8.3f  %s%c\n", {resistance(node), node[VOLTAGE], current(node), effect(node), level, node[KIND]})
    if node[A]!=NULL then
        report(node[A],level & "| ")
    end if
    if node[B]!=NULL then
        report(node[B],level & "| ")
    end if
end procedure
 
function push_op(sequence stack, string tok)
    switch tok do
        case "+","*": sequence b = stack[$],
                               a = stack[$-1]
                        stack = stack[1..$-1]
                        stack[$] = {tok[1], 0, 0, a, b}
        default:      integer {{r}} = scanf(tok,"%d")
                        stack = append(stack,{'r', r, 0, NULL, NULL})
    end switch
    return stack
end function

-- RPN
function rpn(string s)
    sequence stack = {},
             tokens = split(s)
    for i=1 to length(tokens) do
        stack = push_op(stack,tokens[i])
    end for
    return stack[$]
end function
 
-- Infix, slightly trickier:
constant ops = {"+","*"}
function infix(string s)
    string lastnum = ""
    sequence tokens = {}
    for i=1 to length(s) do
        integer ch = s[i]
        if ch>='0' and ch<='9' then
            lastnum &= ch
        else
            if length(lastnum) then
                tokens = append(tokens,lastnum)
                lastnum = ""
            end if
            tokens = append(tokens,ch&"")
        end if
    end for
    if length(lastnum) then
        tokens = append(tokens,lastnum)
    end if
    sequence stack = {}, result = {}
    for i=1 to length(tokens) do
        string token = tokens[i], op
        switch token do
            case "(":   stack = append(stack,token)
            case ")":   while true do
                            op = stack[$]
                            stack = stack[1..$-1]
                            if op == "(" then exit end if
                            result = push_op(result,op)
                        end while
            else:
                        integer tp = find(token,ops)
                        if tp then
                            while length(stack) do
                                op = stack[$]
                                integer sp = find(op,ops)
                                if not sp or tp>=sp then exit end if
                                stack = stack[1..$-1]
                                result = push_op(result,op)
                            end while
                            stack = append(stack,token)
                        else
                            result = push_op(result,token)
                        end if 
        end switch
    end for
    for i=length(stack) to 1 by -1 do
        result = push_op(result,stack[i])
    end for
    return result[1]
end function
 
sequence node = iff(RPN?rpn("10 2 + 6 * 8 + 6 * 4 + 8 * 4 + 8 * 6 +")
                       :infix("((((10+2)*6+8)*6+4)*8+4)*8+6"))
node = setVoltage(node,18)
printf(1,"     Ohm     Volt   Ampere     Watt  Network tree\n")
report(node,"")
Output:
     Ohm     Volt   Ampere     Watt  Network tree
  10.000   18.000    1.800   32.400  +
   4.000    7.200    1.800   12.960  | *
   8.000    7.200    0.900    6.480  | | +
   4.000    3.600    0.900    3.240  | | | *
   8.000    3.600    0.450    1.620  | | | | +
   4.000    1.800    0.450    0.810  | | | | | *
  12.000    1.800    0.150    0.270  | | | | | | +
   4.000    0.600    0.150    0.090  | | | | | | | *
  12.000    0.600    0.050    0.030  | | | | | | | | +
  10.000    0.500    0.050    0.025  | | | | | | | | | r
   2.000    0.100    0.050    0.005  | | | | | | | | | r
   6.000    0.600    0.100    0.060  | | | | | | | | r
   8.000    1.200    0.150    0.180  | | | | | | | r
   6.000    1.800    0.300    0.540  | | | | | | r
   4.000    1.800    0.450    0.810  | | | | | r
   8.000    3.600    0.450    1.620  | | | | r
   4.000    3.600    0.900    3.240  | | | r
   8.000    7.200    0.900    6.480  | | r
   6.000   10.800    1.800   19.440  | r

Python

RPN

class Resistor :
	def __init__(self, resistance, a=None, b=None, symbol='r'):
		self.resistance = resistance
		self.a = a
		self.b = b
		self.symbol = symbol
	def res(self) : return self.resistance
	def setVoltage(self, voltage): self.voltage = voltage
	def current(self) : return self.voltage / self.res()
	def effect(self) : return self.current() * self.voltage
	def report(self,level=""):
		print(f"{self.res():8.3f} {self.voltage:8.3f} {self.current():8.3f} {self.effect():8.3f}  {level}{self.symbol}")
		if self.a: self.a.report(level + "| ")
		if self.b: self.b.report(level + "| ")

class Serial(Resistor) :
	def __init__(self, a, b) : super().__init__(0, b, a, '+')
	def res(self) : return self.a.res() + self.b.res()
	def setVoltage(self, voltage) :
		ra = self.a.res()
		rb = self.b.res()
		self.a.setVoltage(ra/(ra+rb) * voltage)
		self.b.setVoltage(rb/(ra+rb) * voltage)
		self.voltage = voltage

class Parallel(Resistor) :
	def __init__(self,a,b) : super().__init__(0, b, a, '*')
	def res(self) : return 1 / (1 / self.a.res() + 1 / self.b.res())
	def setVoltage(self, voltage) :
		self.a.setVoltage(voltage)
		self.b.setVoltage(voltage)
		self.voltage = voltage

def build(s) :
	stack = []
	for word in s.split(' '):
		if   word == "+": stack.append(Serial(stack.pop(), stack.pop()))
		elif word == "*": stack.append(Parallel(stack.pop(), stack.pop()))
		else:             stack.append(Resistor(float(word)))
	return stack.pop()

node = build("10 2 + 6 * 8 + 6 * 4 + 8 * 4 + 8 * 6 +")
print("     Ohm     Volt   Ampere     Watt  Network tree")
node.setVoltage(18.0)
node.report()

Infix

class Resistor :
	def __init__(self, resistance, a=None, b=None, symbol='r') :
		self.resistance = resistance
		self.a = a
		self.b = b
		self.symbol = symbol
	def res(self) : return self.resistance
	def setVoltage(self, voltage) : self.voltage = voltage
	def current(self) : return self.voltage / self.res()
	def effect(self) : return self.current() * self.voltage
	def report(self,level="") :
		print(f"{self.res():8.3f} {self.voltage:8.3f} {self.current():8.3f} {self.effect():8.3f}  {level}{self.symbol}")
		if self.a: self.a.report(level + "| ")
		if self.b: self.b.report(level + "| ")
	def __add__(self,other) : return Serial(self,other)
	def __mul__(self,other) : return Parallel(self,other)

class Serial(Resistor) :
	def __init__(self, a, b) : super().__init__(0, a, b, '+')
	def res(self) : return self.a.res() + self.b.res()
	def setVoltage(self, voltage) :
		ra = self.a.res()
		rb = self.b.res()
		self.a.setVoltage(ra/(ra+rb) * voltage)
		self.b.setVoltage(rb/(ra+rb) * voltage)
		self.voltage = voltage

class Parallel(Resistor) :
	def __init__(self,a,b) : super().__init__(0, a, b, '*')
	def res(self) : return 1 / (1 / self.a.res() + 1 / self.b.res())
	def setVoltage(self, voltage):
		self.a.setVoltage(voltage)
		self.b.setVoltage(voltage)
		self.voltage = voltage

[R1,R2,R3,R4,R5,R6,R7,R8,R9,R10] = [Resistor(res) for res in [6,8,4,8,4,6,8,10,6,2]]
node = ((((R8+R10) * R9 + R7) * R6 + R5) * R4 + R3) * R2 + R1
node.setVoltage(18)
print("     Ohm     Volt   Ampere     Watt  Network tree")
node.report()

Raku

(formerly Perl 6)

Infix

Translation of: Nim
class Resistor {
    has Str        $.symbol;
    has Numeric  ( $.voltage, $.resistance );
    has Resistor ( $.a, $.b );

    method res ( ) {
        given $.symbol {
            when '+' { return $.a.res + $.b.res }
            when '*' { return 1 / (1 / $.a.res  +  1 / $.b.res) }
            default  { return $.resistance }
        }
    }

    method set-voltage ( Numeric $voltage ) {
        given $.symbol {
            when '+' {
                my $ra = $.a.res;
                my $rb = $.b.res;
                $.a.set-voltage( $ra / ($ra+$rb) * $voltage );
                $.b.set-voltage( $rb / ($ra+$rb) * $voltage );
            }
            when '*' {
                $.a.set-voltage( $voltage );
                $.b.set-voltage( $voltage );
            }
        }
        $!voltage = $voltage;
    }
    method current ( ) { return $.voltage / self.res     }
    method effect  ( ) { return $.voltage * self.current }

    method report ( Int $level = 1 ) {
        my $pad = '| ' x $level;
        my $f = ( self.res, $.voltage, self.current, self.effect ).fmt('%8.3f');
        say "$f $pad$.symbol";
        $.a.report( $level+1 ) if $.a;
        $.b.report( $level+1 ) if $.b;
    }
}
multi sub infix:<+> (Resistor $a, Resistor $b) { $a.new( symbol => '+', :$a, :$b ) }
multi sub infix:<*> (Resistor $a, Resistor $b) { $a.new( symbol => '*', :$a, :$b ) }

my Resistor ($R1, $R2, $R3, $R4, $R5, $R6, $R7, $R8, $R9, $R10) =
    map { Resistor.new: symbol => 'r', resistance => $_ },
    6, 8, 4, 8, 4, 6, 8, 10, 6, 2;

my $node = (((($R8 + $R10) * $R9 + $R7) * $R6 + $R5)
                           * $R4 + $R3) * $R2 + $R1;
$node.set-voltage(18);

say '     Ohm     Volt   Ampere     Watt  Network tree';
$node.report;
Output:
     Ohm     Volt   Ampere     Watt  Network tree
  10.000   18.000    1.800   32.400 | +
   4.000    7.200    1.800   12.960 | | *
   8.000    7.200    0.900    6.480 | | | +
   4.000    3.600    0.900    3.240 | | | | *
   8.000    3.600    0.450    1.620 | | | | | +
   4.000    1.800    0.450    0.810 | | | | | | *
  12.000    1.800    0.150    0.270 | | | | | | | +
   4.000    0.600    0.150    0.090 | | | | | | | | *
  12.000    0.600    0.050    0.030 | | | | | | | | | +
  10.000    0.500    0.050    0.025 | | | | | | | | | | r
   2.000    0.100    0.050    0.005 | | | | | | | | | | r
   6.000    0.600    0.100    0.060 | | | | | | | | | r
   8.000    1.200    0.150    0.180 | | | | | | | | r
   6.000    1.800    0.300    0.540 | | | | | | | r
   4.000    1.800    0.450    0.810 | | | | | | r
   8.000    3.600    0.450    1.620 | | | | | r
   4.000    3.600    0.900    3.240 | | | | r
   8.000    7.200    0.900    6.480 | | | r
   6.000   10.800    1.800   19.440 | | r

Wren

Infix

Translation of: Go
Library: Wren-fmt
import "./fmt" for Fmt

class Resistor {
    construct new(symbol, resistance, voltage, a, b) {
        _symbol = symbol
        _resistance = resistance
        _voltage = voltage
        _a = a
        _b = b
    }

    symbol { _symbol }
    resistance { _resistance }
    voltage { _voltage}

    res {
        if (_symbol == "+") return _a.res + _b.res
        if (_symbol == "*") return 1 / (1/_a.res + 1/_b.res)
        return _resistance
    }

    current { _voltage / res }
    
    effect { current * _voltage }

    voltage=(v) {        
        if (_symbol == "+") {
            var ra = _a.res
            var rb = _b.res
            _a.voltage = ra / (ra + rb) * v
            _b.voltage = rb / (ra + rb) * v
        } else if (_symbol == "*") {
            _a.voltage = v
            _b.voltage = v
        }
        _voltage = v 
    }  

    report(level) {
        Fmt.lprint("$8.3f $8.3f $8.3f $8.3f  $s$s", [res, _voltage, current, effect, level, symbol])
        if (_a != null) _a.report(level + "| ")
        if (_b != null) _b.report(level + "| ")
    }

    +(other) { Resistor.new("+", 0, 0, this, other) }
    *(other) { Resistor.new("*", 0, 0, this, other) }
}

var r = List.filled(10, null)
var resistances = [6, 8, 4, 8, 4, 6, 8, 10, 6, 2]
for (i in 0..9) r[i] = Resistor.new("r", resistances[i], 0, null, null)
var node = ((((r[7]+r[9])*r[8]+r[6])*r[5]+r[4])*r[3]+r[2])*r[1] + r[0]
node.voltage = 18
System.print("     Ohm     Volt   Ampere     Watt  Network tree")
node.report("")
Output:
     Ohm     Volt   Ampere     Watt  Network tree
  10.000   18.000    1.800   32.400   +
   4.000    7.200    1.800   12.960  | *
   8.000    7.200    0.900    6.480  | | +
   4.000    3.600    0.900    3.240  | | | *
   8.000    3.600    0.450    1.620  | | | | +
   4.000    1.800    0.450    0.810  | | | | | *
  12.000    1.800    0.150    0.270  | | | | | | +
   4.000    0.600    0.150    0.090  | | | | | | | *
  12.000    0.600    0.050    0.030  | | | | | | | | +
  10.000    0.500    0.050    0.025  | | | | | | | | | r
   2.000    0.100    0.050    0.005  | | | | | | | | | r
   6.000    0.600    0.100    0.060  | | | | | | | | r
   8.000    1.200    0.150    0.180  | | | | | | | r
   6.000    1.800    0.300    0.540  | | | | | | r
   4.000    1.800    0.450    0.810  | | | | | r
   8.000    3.600    0.450    1.620  | | | | r
   4.000    3.600    0.900    3.240  | | | r
   8.000    7.200    0.900    6.480  | | r
   6.000   10.800    1.800   19.440  | r

RPN

Additonally:

Library: Wren-seq
import "./fmt" for Fmt
import "./seq" for Stack

class Resistor {
    construct new(symbol, resistance, voltage, a, b) {
        _symbol = symbol
        _resistance = resistance
        _voltage = voltage
        _a = a
        _b = b
    }

    symbol { _symbol }
    resistance { _resistance }
    voltage { _voltage}

    res {
        if (_symbol == "+") return _a.res + _b.res
        if (_symbol == "*") return 1 / (1/_a.res + 1/_b.res)
        return _resistance
    }

    current { _voltage / res }
    
    effect { current * _voltage }

    voltage=(v) {        
        if (_symbol == "+") {
            var ra = _a.res
            var rb = _b.res
            _a.voltage = ra / (ra + rb) * v
            _b.voltage = rb / (ra + rb) * v
        } else if (_symbol == "*") {
            _a.voltage = v
            _b.voltage = v
        }
        _voltage = v 
    }  

    report(level) {
        Fmt.lprint("$8.3f $8.3f $8.3f $8.3f  $s$s", [res, _voltage, current, effect, level, symbol])
        if (_a != null) _a.report(level + "| ")
        if (_b != null) _b.report(level + "| ")
    }

    +(other) { Resistor.new("+", 0, 0, this, other) }
    *(other) { Resistor.new("*", 0, 0, this, other) }
}

var build = Fn.new { |rpn|
    var st = Stack.new()
    for (token in rpn.split(" ")) {
        if (token == "+") {
            var b = st.pop()
            var a = st.pop()
            st.push(Resistor.new("+", 0, 0, a, b))
        } else if (token == "*") {
            var b = st.pop()
            var a = st.pop()
            st.push(Resistor.new("*", 0, 0, a, b))
        } else {
            var r = Num.fromString(token)
            st.push(Resistor.new("r", r, 0, null, null))
        }
    }
    return st.pop()
}

var node = build.call("10 2 + 6 * 8 + 6 * 4 + 8 * 4 + 8 * 6 +")
node.voltage = 18
System.print("     Ohm     Volt   Ampere     Watt  Network tree")
node.report("")
Output:
Same as Infix version

Zig

Translation of: Nim
Works with: Zig version 0.11dev

Zig requires more "code" than dynamic languages. The following three items account for a good portion of the "extra code".

  • There are no hidden memory allocations. Manual memory management.
  • Errors are values, and may not be ignored.
  • Generic data structures and functions.

Postfix (RPN)

// postfix.zig
const std = @import("std");
const Allocator = std.mem.Allocator;
const Node = @import("common.zig").Node;
const PostfixToken = @import("common.zig").PostfixToken;
const calculate = @import("common.zig").calculate;

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer {
        const ok = gpa.deinit();
        std.debug.assert(ok == .ok);
    }
    const allocator = gpa.allocator();

    const stdout = std.io.getStdOut().writer();

    const node = try postfix(allocator, stdout, 18, "10 2 + 6 * 8 + 6 * 4 + 8 * 4 + 8 * 6 +");

    std.debug.assert(10 == node.res());
    std.debug.assert(18 == node.voltage);
    std.debug.assert(1.8 == node.current());
    std.debug.assert(std.math.fabs(32.4 - node.effect()) < 0.05);
    std.debug.assert(.serial == node.node_type);

    node.destroyDescendants(allocator);
    allocator.destroy(node);
}

/// Also know as RPN (Reverse Polish Notation)
fn postfix(allocator: Allocator, writer: anytype, voltage: f32, s: []const u8) !*Node {
    const tokens = try parse(allocator, s);
    defer allocator.free(tokens);

    return try calculate(allocator, writer, voltage, tokens);
}

const PostfixParseError = error{
    UnexpectedCharacter,
};

/// Parse postfix expression 's' to give a slice of PostfixToken.
/// Caller owns slice memory on return.
/// There are no Zig language semantics to indicate ownership or transferal thereof.
fn parse(allocator: Allocator, s: []const u8) ![]PostfixToken {
    var tokens = std.ArrayList(PostfixToken).init(allocator);
    // defer tokens.deinit(); // not needed, toOwnedSlice() owns memory.

    var slice_start: ?usize = null;

    // convert the string to a list of Token
    for (s, 0..) |ch, i| {
        const token: PostfixToken = switch (ch) {
            '+' => PostfixToken.serial,
            '*' => PostfixToken.parallel,
            '0'...'9' => {
                // Add digits to 'resistor' value.
                // 'slice_start' determines if any digit(s) have already been parsed.
                if (slice_start) |_| _ = tokens.pop() else slice_start = i;
                const slice_end = i + 1;
                try tokens.append(PostfixToken{ .resistor = s[slice_start.?..slice_end] });
                continue;
            },
            ' ', '\t' => {
                slice_start = null;
                continue;
            },
            else => return PostfixParseError.UnexpectedCharacter,
        };
        try tokens.append(token);
        // Last token was not a resistor. Reset 'start_slice'.
        slice_start = null;
    }
    return tokens.toOwnedSlice();
}

Infix

// infix.zig
const std = @import("std");
const Allocator = std.mem.Allocator;
const Stack = @import("common.zig").Stack;
const Node = @import("common.zig").Node;
const PostfixToken = @import("common.zig").PostfixToken;
const calculate = @import("common.zig").calculate;

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer {
        const ok = gpa.deinit();
        std.debug.assert(ok == .ok);
    }
    const allocator = gpa.allocator();

    const stdout = std.io.getStdOut().writer();

    const node = try infix(allocator, stdout, 18, "((((10+2)*6+8)*6+4)*8+4)*8+6");

    std.debug.assert(10 == node.res());
    std.debug.assert(18 == node.voltage);
    std.debug.assert(1.8 == node.current());
    std.debug.assert(std.math.fabs(32.4 - node.effect()) < 0.05);
    std.debug.assert(.serial == node.node_type);

    node.destroyDescendants(allocator);
    allocator.destroy(node);
}

// Zig tagged union.
const InfixToken = union(enum) {
    lparen,
    rparen,
    serial, // +
    parallel, // *

    // Slice of digits from parent string.
    // Do not let the parent string go out of scope while this is in scope.
    resistor: []const u8,
};

/// Convert infix expression 's' to postfix and call the postfix calculate()
fn infix(allocator: Allocator, writer: anytype, voltage: f32, s: []const u8) !*Node {
    // parse infix expression
    const infix_tokens: []InfixToken = try parse(allocator, s);
    defer allocator.free(infix_tokens);

    // convert infix to postfix
    const postfix_tokens: []PostfixToken = try shuntPostfix(allocator, infix_tokens);
    defer allocator.free(postfix_tokens);

    // use postfix calculate()
    return try calculate(allocator, writer, voltage, postfix_tokens);
}

const InfixParseError = error{
    UnexpectedCharacter,
};

/// Parse infix expression 's' to give a slice of InfixToken.
/// Caller owns slice memory on return.
/// There are no Zig language semantics to indicate ownership or transferal thereof.
fn parse(allocator: Allocator, s: []const u8) ![]InfixToken {
    var tokens = std.ArrayList(InfixToken).init(allocator);
    // defer tokens.deinit(); // not needed, toOwnedSlice() owns memory.

    var slice_start: ?usize = null;

    for (s, 0..) |ch, i| {
        const token: InfixToken = switch (ch) {
            '(' => InfixToken.lparen,
            ')' => InfixToken.rparen,
            '+' => InfixToken.serial,
            '*' => InfixToken.parallel,
            '0'...'9' => {
                // Add digits to 'resistor' value.
                // 'slice_start' determines if any digit(s) have already been parsed.
                if (slice_start) |_| _ = tokens.pop() else slice_start = i;
                const slice_end = i + 1;
                try tokens.append(InfixToken{ .resistor = s[slice_start.?..slice_end] });
                continue;
            },
            ' ', '\t' => { // extraneous whitespace
                slice_start = null;
                continue;
            },
            else => return InfixParseError.UnexpectedCharacter, // unknown
        };
        try tokens.append(token);
        // Last token was not a resistor. Reset 'start_slice'.
        slice_start = null;
    }
    return tokens.toOwnedSlice();
}

const ShuntPostfixError = error{
    LParenNotAllowed,
    RParenNotAllowed,
};

/// Input infix (infix tokens) in infix order.
/// Output postfix (postfix tokens) in postfix order.
///
/// Caller owns resultant slice and is responsible for freeing.
fn shuntPostfix(allocator: Allocator, infix_tokens: []InfixToken) ![]PostfixToken {
    var result = PostfixTokenArray.init(allocator); // destination storage
    var stack = InfixTokenStack.init(allocator); // working storage
    defer result.deinit();
    defer stack.deinit();

    for (infix_tokens) |token| {
        switch (token) {
            .lparen => try stack.push(token),
            .rparen => while (!stack.isEmpty()) {
                const op = stack.pop();
                if (op == InfixToken.lparen) break;
                try result.append(op);
            },
            .parallel, .serial => {
                while (!stack.isEmpty()) {
                    const op = stack.peek();
                    if (op != InfixToken.serial and op != InfixToken.parallel) break;
                    _ = stack.pop();
                    try result.append(op);
                }
                try stack.push(token);
            },
            .resistor => try result.append(token),
        }
    }
    while (!stack.isEmpty())
        try result.append(stack.pop());

    // array now contains operands and operators in postfix order (no parentheses)
    return result.toOwnedSlice();
}

const InfixTokenStack = Stack(InfixToken);

/// Façade to an ArrayList that translates from InfixToken tagged unions to
/// PostfixToken tagged unions in its append() function.
const PostfixTokenArray = struct {
    result: std.ArrayList(PostfixToken),

    fn init(allocator: Allocator) PostfixTokenArray {
        return PostfixTokenArray{
            .result = std.ArrayList(PostfixToken).init(allocator),
        };
    }
    fn deinit(self: *PostfixTokenArray) void {
        self.result.deinit();
    }
    /// Convert InfixToken to PostfixToken.
    fn append(self: *PostfixTokenArray, infix_token: InfixToken) !void {
        const postfix_token: PostfixToken = switch (infix_token) {
            .serial => PostfixToken.serial,
            .parallel => PostfixToken.parallel,
            .resistor => |slice| PostfixToken{ .resistor = slice },

            // Postfix does not have parentheses.
            .lparen => return ShuntPostfixError.LParenNotAllowed,
            .rparen => return ShuntPostfixError.RParenNotAllowed,
        };
        try self.result.append(postfix_token);
    }
    fn toOwnedSlice(self: *PostfixTokenArray) !std.ArrayList(PostfixToken).Slice {
        return try self.result.toOwnedSlice();
    }
};

Shared Infix/Postfix Code

// common.zig
const std = @import("std");
const Allocator = std.mem.Allocator;

// Zig "enum"
const NodeType = enum {
    serial,
    parallel,
    resistor,

    fn repr(self: NodeType) u8 {
        return switch (self) {
            .serial => '+',
            .parallel => '*',
            .resistor => 'r',
        };
    }
};

// Zig "tagged union"
pub const PostfixToken = union(NodeType) {
    serial, // '+'
    parallel, // '*'

    // Slice of digits from parent string.
    // Do not let the parent string go out of scope while this is in scope.
    resistor: []const u8, // 'r'
};

// Zig "struct"
pub const Node = struct {
    node_type: NodeType,
    resistance: ?f32 = null, // optional float, either value or null
    voltage: ?f32 = null,
    a: ?*Node = null, // optional pointer to Node, either value or null
    b: ?*Node = null,

    pub fn res(self: *Node) f32 {
        return switch (self.node_type) {
            .serial => self.a.?.res() + self.b.?.res(),
            .parallel => 1 / (1 / self.a.?.res() + 1 / self.b.?.res()),
            .resistor => if (self.resistance) |resistance| resistance else unreachable,
        };
    }

    pub fn current(self: *Node) f32 {
        if (self.voltage) |voltage| return voltage / self.res() else unreachable;
    }

    pub fn effect(self: *Node) f32 {
        if (self.voltage) |voltage| return self.current() * voltage else unreachable;
    }

    pub fn setVoltage(self: *Node, voltage: f32) void {
        self.voltage = voltage;
        switch (self.node_type) {
            .serial => {
                const ra: f32 = self.a.?.res();
                const rb: f32 = self.b.?.res();
                self.a.?.setVoltage(ra / (ra + rb) * voltage);
                self.b.?.setVoltage(rb / (ra + rb) * voltage);
            },
            .parallel => {
                self.a.?.setVoltage(voltage);
                self.b.?.setVoltage(voltage);
            },
            .resistor => {},
        }
    }

    pub fn report(self: *Node, allocator: Allocator, writer: anytype, level: []const u8) !void {
        if (self.voltage) |voltage| {
            try writer.print("{d:8.3} {d:8.3} {d:8.3} {d:8.3}  {s}{c}\n", .{
                self.res(),    voltage, self.current(),
                self.effect(), level,   self.node_type.repr(),
            });
        } else unreachable;
        // iterate though 'a' and 'b' optional nodes
        for ([2]?*Node{ self.a, self.b }) |optional_node| {
            if (optional_node) |node| {
                const next_level = try std.fmt.allocPrint(allocator, "{s}| ", .{level});
                defer allocator.free(next_level);
                try node.report(allocator, writer, next_level);
            }
        }
    }

    /// Free memory allocated to Node descendants and Node itself.
    pub fn destroyDescendants(self: *Node, allocator: Allocator) void {
        if (self.a) |a| {
            self.a = null;
            a.destroyDescendants(allocator);
            allocator.destroy(a);
        }
        if (self.b) |b| {
            self.b = null;
            b.destroyDescendants(allocator);
            allocator.destroy(b);
        }
    }
};

fn build(allocator: Allocator, tokens: []PostfixToken) !*Node {
    var stack = Stack(*Node).init(allocator);
    defer stack.deinit();

    for (tokens) |token| {
        const node = try allocator.create(Node);

        // 'token' is a tagged union.
        // note the extraction of the '.resistor' variable via |r|
        node.* = switch (token) {
            .serial => Node{ .node_type = NodeType.serial, .b = stack.pop(), .a = stack.pop() },
            .parallel => Node{ .node_type = NodeType.parallel, .b = stack.pop(), .a = stack.pop() },
            .resistor => |r| Node{ .node_type = NodeType.resistor, .resistance = try std.fmt.parseFloat(f32, r) },
        };
        try stack.push(node);
    }
    std.debug.assert(stack.hasOne()); // stack length should be 1.

    return stack.pop();
}

pub fn calculate(allocator: Allocator, writer: anytype, voltage: f32, tokens: []PostfixToken) !*Node {
    try writer.print("     Ohm     Volt   Ampere     Watt  Network tree\n", .{});

    var node = try build(allocator, tokens);
    node.setVoltage(voltage);
    try node.report(allocator, writer, "");
    return node;
}

// Zig "Generic Data Structure"
// An ad hoc generic stack implementation.
// 'pub' is the Zig way of giving visibility outside module scope.
pub fn Stack(comptime T: type) type {
    return struct {
        const Self = @This();
        stack: std.ArrayList(T),

        pub fn init(allocator: Allocator) Self {
            return Self{
                .stack = std.ArrayList(T).init(allocator),
            };
        }
        pub fn deinit(self: *Self) void {
            self.stack.deinit();
        }
        pub fn push(self: *Self, node: T) !void {
            return try self.stack.append(node);
        }
        pub fn pop(self: *Self) T {
            return self.stack.pop();
        }
        pub fn peek(self: *const Self) T {
            return self.stack.items[self.stack.items.len - 1];
        }
        pub fn isEmpty(self: *const Self) bool {
            return self.stack.items.len == 0;
        }
        // no 'pub' - private to this module
        fn hasOne(self: *Self) bool {
            return self.stack.items.len == 1;
        }
    };
}

zkl

class Resistor{
   fcn init(resistance_,symbol_="r", a_=Void, b_=Void){
      var resistance,a,b,symbol, voltage=Void;
      resistance,symbol,a,b = vm.arglist;
      resistance=resistance.toFloat();  // deal with strings/ints
   }
   fcn res{ 
      if     (symbol=="+") a.res() + b.res();
      else if(symbol=="*") 1.0/(1.0/a.res() + 1.0/b.res());
      else                 resistance
   }
   fcn setVoltage(voltage){ 
      if(symbol=="+"){
         ra,rb := a.res(), b.res();
	 a.setVoltage(ra/(ra + rb)*voltage);
	 b.setVoltage(rb/(ra + rb)*voltage);
      }
      else if(symbol=="*") T(a,b).apply2("setVoltage",voltage);
      self.voltage = voltage.toFloat();
   }
   fcn current{ voltage/res()     }
   fcn effect { current()*voltage }
   fcn report(level=""){
      println("%8.3f %8.3f %8.3f %8.3f  %s%s".fmt(res(),voltage,current(),effect(),level,symbol));
      T(a,b).apply2("report",level + "| ");  // noop if Void
   }
   fcn __opAdd(other){ Resistor(0,"+",self,other) }
   fcn __opMul(other){ Resistor(0,"*",self,other) }
}

Infix

R1,R2,R3,R4,R5,R6,R7,R8,R9,R10 := T(6,8,4,8,4,6,8,10,6,2].apply(Resistor);
node:=((((R8 + R10)*R9 + R7)*R6 + R5)*R4 + R3)*R2 + R1;
node.setVoltage(18);
println("     Ohm     Volt   Ampere     Watt  Network tree");
node.report();
Output:
     Ohm     Volt   Ampere     Watt  Network tree
  10.000   18.000    1.800   32.400  +
   4.000    7.200    1.800   12.960  | *
   8.000    7.200    0.900    6.480  | | +
   4.000    3.600    0.900    3.240  | | | *
   8.000    3.600    0.450    1.620  | | | | +
   4.000    1.800    0.450    0.810  | | | | | *
  12.000    1.800    0.150    0.270  | | | | | | +
   4.000    0.600    0.150    0.090  | | | | | | | *
  12.000    0.600    0.050    0.030  | | | | | | | | +
  10.000    0.500    0.050    0.025  | | | | | | | | | r
   2.000    0.100    0.050    0.005  | | | | | | | | | r
   6.000    0.600    0.100    0.060  | | | | | | | | r
   8.000    1.200    0.150    0.180  | | | | | | | r
   6.000    1.800    0.300    0.540  | | | | | | r
   4.000    1.800    0.450    0.810  | | | | | r
   8.000    3.600    0.450    1.620  | | | | r
   4.000    3.600    0.900    3.240  | | | r
   8.000    7.200    0.900    6.480  | | r
   6.000   10.800    1.800   19.440  | r

RPN

fcn build(rpnStr){
   stack:=List();
   foreach symbol in (rpnStr.split()){
      if(symbol=="+"){
         a,b:=stack.pop(),stack.pop();
	 stack.append(Resistor(0,"+",b,a))
      }
      else if(symbol=="*"){
         a,b:=stack.pop(),stack.pop();
      	 stack.append(Resistor(0,"*",b,a))
      }
      else stack.append(Resistor(symbol,"r")); 
   }
   stack.pop()	// unevaluated top of circuit
}
 
node:=build("10 2 + 6 * 8 + 6 * 4 + 8 * 4 + 8 * 6 +");
node.setVoltage(18);
println("     Ohm     Volt   Ampere     Watt  Network tree");
node.report();
Output:
     Ohm     Volt   Ampere     Watt  Network tree
  10.000   18.000    1.800   32.400  +
   4.000    7.200    1.800   12.960  | *
   8.000    7.200    0.900    6.480  | | +
   4.000    3.600    0.900    3.240  | | | *
   8.000    3.600    0.450    1.620  | | | | +
   4.000    1.800    0.450    0.810  | | | | | *
  12.000    1.800    0.150    0.270  | | | | | | +
   4.000    0.600    0.150    0.090  | | | | | | | *
  12.000    0.600    0.050    0.030  | | | | | | | | +
  10.000    0.500    0.050    0.025  | | | | | | | | | r
   2.000    0.100    0.050    0.005  | | | | | | | | | r
   6.000    0.600    0.100    0.060  | | | | | | | | r
   8.000    1.200    0.150    0.180  | | | | | | | r
   6.000    1.800    0.300    0.540  | | | | | | r
   4.000    1.800    0.450    0.810  | | | | | r
   8.000    3.600    0.450    1.620  | | | | r
   4.000    3.600    0.900    3.240  | | | r
   8.000    7.200    0.900    6.480  | | r
   6.000   10.800    1.800   19.440  | r