⚠️ Warning: This is a draft ⚠️
This means it might contain formatting issues, incorrect code, conceptual problems, or other severe issues.
If you want to help to improve and eventually enable this page, please fork RosettaGit's repository and open a merge request on GitHub.
{{draft task}}
;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 [https://photos.app.goo.gl/58heQVm8UJYf8Ra29 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
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 ""
Go
Infix
{{trans|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("") }
Nim
import tables,strutils,sequtils,sugar,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 = return node.voltage / node.res proc effect (node : Node) : float = return 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: if token == "+": stack.add Node(kind : '+', a : stack.pop, b : stack.pop) elif token == "*": stack.add Node(kind : '*', a : stack.pop, b : stack.pop) else: stack.add 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.0,"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: if ch == ' ': if tmp!="": result.add tmp tmp = "" continue if ch in "+*()": if tmp!="": result.add tmp tmp="" result.add fmt"{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 not (op in 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.0,"((((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
{{trans|Perl 6}}
use strict; use warnings; use feature <say state>; { package Resistor; sub new { my ($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 { my $self = shift; 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 { my($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 { my $self = shift; return $self->{voltage} / res($self) } sub effect { my $self = shift; return $self->{voltage} * current($self) } use overload '+' => \&serial, '*' => \∥ sub serial { my($a,$b) = @_; Resistor->new( {symbol => '+', a => $a, b => $b} ) } sub parallel { my($a,$b) = @_; Resistor->new( {symbol => '*', a => $a, b => $b} ) } sub report { my($self,$level) = @_; 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; 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; Resistor::set_voltage($node,18); say Resistor::report($node);
{{out}}
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 ``` ## Perl 6 ### Infix {{trans|Nim}} ```perl6 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; ``` {{out}}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 ```Phix -- 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) switch node[KIND] do case '+': atom ra := resistance(node[A]), rb := resistance(node[B]) node[A] = setVoltage(node[A], ra / (ra + rb) * voltage) node[B] = setVoltage(node[B], rb / (ra + rb) * voltage) case '*': node[A] = setVoltage(node[A],voltage) node[B] = setVoltage(node[B],voltage) end switch node[VOLTAGE] = voltage 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(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 ```Phix function rpn(string s) sequence stack = {}, tokens = split(s) for i=1 to length(tokens) do stack = push(stack,tokens[i]) end for return stack[$] end function sequence node = rpn("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,"") ``` {{out}} ```txt 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 ``` ### infix slightly trickier ```Phix 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 break end if result = push(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(result,op) end while stack = append(stack,token) else result = push(result,token) end if end switch end for for i=length(stack) to 1 by -1 do result = push(result,stack[i]) end for return result[1] end function sequence node = infix("((((10+2)*6+8)*6+4)*8+4)*8+6") ``` then as per last 3 lines of RPN, same output. ## Python ### RPN ```python 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 ```python 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() ``` ## zkl ```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 ```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(); ``` {{out}}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 ```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(); ``` {{out}}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 ```