Resistance network calculator: Difference between revisions
Content added Content deleted
SqrtNegInf (talk | contribs) (Added Perl example) |
m (→{{header|Wren}}: Minor tidy) |
||
(11 intermediate revisions by 7 users not shown) | |||
Line 58: | Line 58: | ||
assert 180 == network(4,0,3,"0 1 150|0 2 50|1 3 300|2 3 250") |
assert 180 == network(4,0,3,"0 1 150|0 2 50|1 3 300|2 3 250") |
||
=={{header|11l}}== |
|||
{{trans|Python}} |
|||
<syntaxhighlight lang="11l">F gauss(&m) |
|||
V (n, p) = (m.len, m[0].len) |
|||
L(i) 0 .< n |
|||
V k = max(i .< n, key' x -> abs(@m[x][@i])) |
|||
swap(&m[i], &m[k]) |
|||
V t = 1 / m[i][i] |
|||
L(j) i + 1 .< p |
|||
m[i][j] *= t |
|||
L(j) i + 1 .< n |
|||
t = m[j][i] |
|||
L(k) i + 1 .< p |
|||
m[j][k] -= t * m[i][k] |
|||
L(i) (n - 1 .< -1).step(-1) |
|||
L(j) 0 .< i |
|||
m[j].last -= m[j][i] * m[i].last |
|||
R m.map(row -> row.last) |
|||
F network(n, k0, k1, s) |
|||
V m = [[0.0] * (n+1)] * n |
|||
V resistors = s.split(‘|’) |
|||
L(resistor) resistors |
|||
V (aa, bb, rr) = resistor.split(‘ ’) |
|||
V (a, b, r) = (Int(aa), Int(bb), (1 / Int(rr))) |
|||
m[a][a] += r |
|||
m[b][b] += r |
|||
I a > 0 |
|||
m[a][b] -= r |
|||
I b > 0 |
|||
m[b][a] -= r |
|||
m[k0][k0] = 1 |
|||
m[k1].last = 1 |
|||
R gauss(&m)[k1] |
|||
F is_equal(a, b) |
|||
R abs(a - b) < 1e-6 |
|||
assert(is_equal(10 , network(7, 0, 1, ‘0 2 6|2 3 4|3 4 10|4 5 2|5 6 8|6 1 4|3 5 6|3 6 6|3 1 8|2 1 8’))) |
|||
assert(is_equal(3/2 , network(3*3, 0, 3*3-1, ‘0 1 1|1 2 1|3 4 1|4 5 1|6 7 1|7 8 1|0 3 1|3 6 1|1 4 1|4 7 1|2 5 1|5 8 1’))) |
|||
assert(is_equal(13/7, network(4*4, 0, 4*4-1, ‘0 1 1|1 2 1|2 3 1|4 5 1|5 6 1|6 7 1|8 9 1|9 10 1|10 11 1|12 13 1|13 14 1|14 15 1|0 4 1|4 8 1|8 12 1|1 5 1|5 9 1|9 13 1|2 6 1|6 10 1|10 14 1|3 7 1|7 11 1|11 15 1’))) |
|||
assert(is_equal(180 , network(4, 0, 3, ‘0 1 150|0 2 50|1 3 300|2 3 250’))) |
|||
print(‘OK’)</syntaxhighlight> |
|||
=={{header|Go}}== |
=={{header|Go}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 145: | Line 190: | ||
fmt.Printf("%.6g\n", f) |
fmt.Printf("%.6g\n", f) |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 154: | Line 199: | ||
180 |
180 |
||
</pre> |
</pre> |
||
=={{header|Julia}}== |
|||
{{trans|Python}} |
|||
<syntaxhighlight lang="julia">function gauss(m) |
|||
n, p = length(m), length(m[1]) |
|||
for i in 1:n |
|||
_, k = findmax(map(x -> abs(m[x][i]), i:n)) .+ (i - 1) |
|||
m[i], m[k] = m[k], m[i] |
|||
t = 1 // m[i][i] |
|||
for j in i+1:p |
|||
m[i][j] *= t |
|||
end |
|||
for j in i+1:n |
|||
t = m[j][i] |
|||
for k in i+1:p |
|||
m[j][k] -= t * m[i][k] |
|||
end |
|||
end |
|||
end |
|||
for i in n:-1:1, j in 1:i-1; m[j][end] -= m[j][i] * m[i][end]; end |
|||
return [row[end] for row in m] |
|||
end |
|||
function network(n, k0, k1, s) |
|||
m = [[0//1 for i in 1:n + 1] for j in 1:n] |
|||
resistors = split(s, "|") |
|||
for resistor in resistors |
|||
astr, bstr, rstr = split(resistor, " ") |
|||
a, b, r = parse(Int, astr), parse(Int, bstr), 1 // parse(Int, rstr) |
|||
m[a + 1][a + 1] += r |
|||
m[b + 1][b + 1] += r |
|||
if a > 0; m[a + 1][b + 1] -= r end |
|||
if b > 0; m[b + 1][a + 1] -= r end |
|||
end |
|||
m[k0+1][k0+1] = m[k1+1][end] = 1 // 1 |
|||
return gauss(m)[k1+1] |
|||
end |
|||
@assert(10 == network(7,0,1,"0 2 6|2 3 4|3 4 10|4 5 2|5 6 8|6 1 4|3 5 6|3 6 6|3 1 8|2 1 8")) |
|||
@assert(3//2 == network(3*3,0,3*3-1,"0 1 1|1 2 1|3 4 1|4 5 1|6 7 1|7 8 1|0 3 1|3 6 1|1 4 1|4 7 1|2 5 1|5 8 1")) |
|||
@assert(13//7 == network(4*4,0,4*4-1,"0 1 1|1 2 1|2 3 1|4 5 1|5 6 1|6 7 1|8 9 1|9 10 1|10 11 1|12 13 1|13 14 1|14 15 1|0 4 1|4 8 1|8 12 1|1 5 1|5 9 1|9 13 1|2 6 1|6 10 1|10 14 1|3 7 1|7 11 1|11 15 1")) |
|||
@assert(180 == network(4,0,3,"0 1 150|0 2 50|1 3 300|2 3 250")) |
|||
</syntaxhighlight> |
|||
No assertion errors. |
|||
=={{header|Nim}}== |
|||
{{trans|Python}} |
|||
<syntaxhighlight lang="nim">import rationals, sequtils, strscans, strutils, sugar |
|||
type Fraction = Rational[int] |
|||
func argmax(m: seq[seq[Fraction]]; i: int): int = |
|||
var max = -1 // 1 |
|||
for x in i..m.high: |
|||
let val = abs(m[x][i]) |
|||
if val > max: |
|||
max = val |
|||
result = x |
|||
func gauss(m: var seq[seq[Fraction]]): seq[Fraction] = |
|||
let n = m.len |
|||
let p = m[0].len |
|||
for i in 0..<n: |
|||
let k = m.argmax(i) |
|||
swap m[i], m[k] |
|||
let t = 1 / m[i][i] |
|||
for j in (i + 1)..<p: |
|||
m[i][j] *= t |
|||
for j in (i + 1)..<n: |
|||
let t = m[j][i] |
|||
for k in (i + 1)..<p: |
|||
m[j][k] -= t * m[i][k] |
|||
for i in countdown(n - 1, 0): |
|||
for j in 0..<i: |
|||
m[j][^1] -= m[j][i] * m[i][^1] |
|||
result = collect(newSeq, for row in m: row[^1]) |
|||
func network(n, k0, k1: int; s: string): Fraction = |
|||
var m = newSeqWith(n, repeat(0 // 1, n + 1)) |
|||
let resistors = s.split('|') |
|||
for resistor in resistors: |
|||
var a, b, c: int |
|||
if not resistor.scanf("$i $i $i", a, b, c): |
|||
raise newException(ValueError, "Wrong resistor: " & resistor) |
|||
let r: Fraction = 1 // c |
|||
m[a][a] += r |
|||
m[b][b] += r |
|||
if a > 0: m[a][b] -= r |
|||
if b > 0: m[b][a] -= r |
|||
m[k0][k0] = 1 // 1 |
|||
m[k1][^1] = 1 // 1 |
|||
result = gauss(m)[k1] |
|||
assert 10 // 1 == network(7, 0, 1, "0 2 6|2 3 4|3 4 10|4 5 2|5 6 8|6 1 4|3 5 6|3 6 6|3 1 8|2 1 8") |
|||
assert 3 // 2 == network(3*3, 0, 3*3-1, "0 1 1|1 2 1|3 4 1|4 5 1|6 7 1|7 8 1|0 3 1|3 6 1|1 4 1|4 7 1|2 5 1|5 8 1") |
|||
assert 13 // 7 == network(4*4, 0, 4*4-1, "0 1 1|1 2 1|2 3 1|4 5 1|5 6 1|6 7 1|8 9 1|9 10 1|10 11 1|12 13 1|13 14 1|14 15 1|0 4 1|4 8 1|8 12 1|1 5 1|5 9 1|9 13 1|2 6 1|6 10 1|10 14 1|3 7 1|7 11 1|11 15 1") |
|||
assert 180 // 1 == network(4, 0, 3, "0 1 150|0 2 50|1 3 300|2 3 250")</syntaxhighlight> |
|||
{{out}} |
|||
No assertion failed. |
|||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
< |
<syntaxhighlight lang="perl">use strict; |
||
use warnings; |
use warnings; |
||
Line 203: | Line 355: | ||
[ 3*3, 0, 3*3-1, '0 1 1|1 2 1|3 4 1|4 5 1|6 7 1|7 8 1|0 3 1|3 6 1|1 4 1|4 7 1|2 5 1|5 8 1' ], |
[ 3*3, 0, 3*3-1, '0 1 1|1 2 1|3 4 1|4 5 1|6 7 1|7 8 1|0 3 1|3 6 1|1 4 1|4 7 1|2 5 1|5 8 1' ], |
||
[ 4*4, 0, 4*4-1, '0 1 1|1 2 1|2 3 1|4 5 1|5 6 1|6 7 1|8 9 1|9 10 1|10 11 1|12 13 1|13 14 1|14 15 1|0 4 1|4 8 1|8 12 1|1 5 1|5 9 1|9 13 |
[ 4*4, 0, 4*4-1, '0 1 1|1 2 1|2 3 1|4 5 1|5 6 1|6 7 1|8 9 1|9 10 1|10 11 1|12 13 1|13 14 1|14 15 1|0 4 1|4 8 1|8 12 1|1 5 1|5 9 1|9 13 |
||
1|2 6 1|6 10 1|10 14 1|3 7 1|7 11 1|11 15 1' ], |
|||
[ 4, 0, 3, '0 1 150|0 2 50|1 3 300|2 3 250' ], |
[ 4, 0, 3, '0 1 150|0 2 50|1 3 300|2 3 250' ], |
||
) { |
) { |
||
printf "%10.3f\n", network(@$_); |
printf "%10.3f\n", network(@$_); |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> 10.000 |
<pre> 10.000 |
||
Line 214: | Line 367: | ||
180.000</pre> |
180.000</pre> |
||
=={{header| |
=={{header|Phix}}== |
||
{{trans|Go}} |
|||
<!--<syntaxhighlight lang="phix">(phixonline)--> |
|||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">argmax</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">col</span> <span style="color: #0000FF;">:=</span> <span style="color: #7060A8;">sq_abs</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">vslice</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">))</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #7060A8;">largest</span><span style="color: #0000FF;">(</span><span style="color: #000000;">col</span><span style="color: #0000FF;">,</span><span style="color: #000000;">return_index</span><span style="color: #0000FF;">:=</span><span style="color: #004600;">true</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;">gauss</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">),</span> |
|||
<span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</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: #000000;">n</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">i</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">argmax</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">..</span><span style="color: #000000;">n</span><span style="color: #0000FF;">],</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span> |
|||
<span style="color: #0000FF;">{</span><span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]}</span> |
|||
<span style="color: #004080;">atom</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">/</span><span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</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: #000000;">p</span> <span style="color: #008080;">do</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">*=</span> <span style="color: #000000;">t</span> <span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</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: #000000;">n</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">l</span><span style="color: #0000FF;">=</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: #000000;">p</span> <span style="color: #008080;">do</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">l</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">*</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">l</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</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: #000000;">n</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: #004080;">atom</span> <span style="color: #000000;">mip</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">p</span><span style="color: #0000FF;">]</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">p</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">*</span> <span style="color: #000000;">mip</span> <span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #7060A8;">vslice</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">,</span><span style="color: #000000;">p</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;">network</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">k0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">k1</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">m</span> <span style="color: #0000FF;">:=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">s</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: #008000;">'|'</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: #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: #000000;">ri</span><span style="color: #0000FF;">}}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sq_add</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">scanf</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: #008000;">"%d %d %d"</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;">0</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;">1</span><span style="color: #0000FF;">/</span><span style="color: #000000;">ri</span> |
|||
<span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">a</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;">r</span> |
|||
<span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">b</span><span style="color: #0000FF;">][</span><span style="color: #000000;">b</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">r</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">a</span> <span style="color: #0000FF;">></span> <span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #000000;">m</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: #0000FF;">-=</span> <span style="color: #000000;">r</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">b</span> <span style="color: #0000FF;">></span> <span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">b</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;">r</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: #000000;">k0</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">;</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k0</span><span style="color: #0000FF;">][</span><span style="color: #000000;">k0</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span> |
|||
<span style="color: #000000;">k1</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">;</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k1</span><span style="color: #0000FF;">][</span><span style="color: #000000;">n</span><span style="color: #0000FF;">+</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: #008080;">return</span> <span style="color: #000000;">gauss</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">)[</span><span style="color: #000000;">k1</span><span style="color: #0000FF;">]</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</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;">"%.6g\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">network</span><span style="color: #0000FF;">(</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"0 2 6|2 3 4|3 4 10|4 5 2|5 6 8|6 1 4|3 5 6|3 6 6|3 1 8|2 1 8"</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;">"%.6g\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">network</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: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"0 1 1|1 2 1|3 4 1|4 5 1|6 7 1|7 8 1|0 3 1|3 6 1|1 4 1|4 7 1|2 5 1|5 8 1"</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;">"%.6g\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">network</span><span style="color: #0000FF;">(</span><span style="color: #000000;">16</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">15</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"0 1 1|1 2 1|2 3 1|4 5 1|5 6 1|6 7 1|8 9 1|9 10 1|10 11 1|12 13 1|13 14 1|14 15 1|"</span><span style="color: #0000FF;">&</span> |
|||
<span style="color: #008000;">"0 4 1|4 8 1|8 12 1|1 5 1|5 9 1|9 13 1|2 6 1|6 10 1|10 14 1|3 7 1|7 11 1|11 15 1"</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;">"%.6g\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">network</span><span style="color: #0000FF;">(</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"0 1 150|0 2 50|1 3 300|2 3 250"</span><span style="color: #0000FF;">))</span> |
|||
<!--</syntaxhighlight>--> |
|||
{{out}} |
|||
<pre> |
|||
10 |
|||
1.5 |
|||
1.85714 |
|||
180 |
|||
</pre> |
|||
=={{header|Python}}== |
|||
<syntaxhighlight lang="python">from fractions import Fraction |
|||
def gauss(m): |
|||
n, p = len(m), len(m[0]) |
|||
for i in range(n): |
|||
k = max(range(i, n), key = lambda x: abs(m[x][i])) |
|||
m[i], m[k] = m[k], m[i] |
|||
t = 1 / m[i][i] |
|||
for j in range(i + 1, p): m[i][j] *= t |
|||
for j in range(i + 1, n): |
|||
t = m[j][i] |
|||
for k in range(i + 1, p): m[j][k] -= t * m[i][k] |
|||
for i in range(n - 1, -1, -1): |
|||
for j in range(i): m[j][-1] -= m[j][i] * m[i][-1] |
|||
return [row[-1] for row in m] |
|||
def network(n,k0,k1,s): |
|||
m = [[0] * (n+1) for i in range(n)] |
|||
resistors = s.split('|') |
|||
for resistor in resistors: |
|||
a,b,r = resistor.split(' ') |
|||
a,b,r = int(a), int(b), Fraction(1,int(r)) |
|||
m[a][a] += r |
|||
m[b][b] += r |
|||
if a > 0: m[a][b] -= r |
|||
if b > 0: m[b][a] -= r |
|||
m[k0][k0] = Fraction(1, 1) |
|||
m[k1][-1] = Fraction(1, 1) |
|||
return gauss(m)[k1] |
|||
assert 10 == network(7,0,1,"0 2 6|2 3 4|3 4 10|4 5 2|5 6 8|6 1 4|3 5 6|3 6 6|3 1 8|2 1 8") |
|||
assert 3/2 == network(3*3,0,3*3-1,"0 1 1|1 2 1|3 4 1|4 5 1|6 7 1|7 8 1|0 3 1|3 6 1|1 4 1|4 7 1|2 5 1|5 8 1") |
|||
assert Fraction(13,7) == network(4*4,0,4*4-1,"0 1 1|1 2 1|2 3 1|4 5 1|5 6 1|6 7 1|8 9 1|9 10 1|10 11 1|12 13 1|13 14 1|14 15 1|0 4 1|4 8 1|8 12 1|1 5 1|5 9 1|9 13 1|2 6 1|6 10 1|10 14 1|3 7 1|7 11 1|11 15 1") |
|||
assert 180 == network(4,0,3,"0 1 150|0 2 50|1 3 300|2 3 250")</syntaxhighlight> |
|||
=={{header|Raku}}== |
|||
(formerly Perl 6) |
|||
{{trans|Python}} |
{{trans|Python}} |
||
<lang |
<syntaxhighlight lang="raku" line>sub gauss ( @m is copy ) { |
||
for @m.keys -> \i { |
for @m.keys -> \i { |
||
my \k = max |(i .. @m.end), :by({ @m[$_][i].abs }); |
my \k = max |(i .. @m.end), :by({ @m[$_][i].abs }); |
||
Line 258: | Line 508: | ||
; |
; |
||
plan +@tests; |
plan +@tests; |
||
is .[0], network( |.[1..4] ), .[4].substr(0,10)~'…' for @tests;</ |
is .[0], network( |.[1..4] ), .[4].substr(0,10)~'…' for @tests;</syntaxhighlight> |
||
=={{header| |
=={{header|Wren}}== |
||
{{trans|Go}} |
|||
<lang python>from fractions import Fraction |
|||
{{libheader|Wren-fmt}} |
|||
<syntaxhighlight lang="wren">import "./fmt" for Fmt |
|||
var argmax = Fn.new { |m, i| |
|||
def gauss(m): |
|||
var lm = m.count |
|||
n, p = len(m), len(m[0]) |
|||
var col = List.filled(lm, 0) |
|||
for i in range(n): |
|||
var max = -1 |
|||
k = max(range(i, n), key = lambda x: abs(m[x][i])) |
|||
var maxx = -1 |
|||
m[i], m[k] = m[k], m[i] |
|||
for (x in 0...lm) { |
|||
t = 1 / m[i][i] |
|||
col[x] = m[x][i].abs |
|||
if (col[x] > max ) { |
|||
max = col[x] |
|||
t = m[j][i] |
|||
maxx = x |
|||
} |
|||
} |
|||
for j in range(i): m[j][-1] -= m[j][i] * m[i][-1] |
|||
return maxx |
|||
return [row[-1] for row in m] |
|||
} |
|||
var gauss = Fn.new { |m| |
|||
def network(n,k0,k1,s): |
|||
var n = m.count |
|||
m = [[0] * (n+1) for i in range(n)] |
|||
var p = m[0].count |
|||
resistors = s.split('|') |
|||
for (i in 0...n) { |
|||
var k = i + argmax.call(m[i...n], i) |
|||
a,b,r = resistor.split(' ') |
|||
var t = m[i] |
|||
a,b,r = int(a), int(b), Fraction(1,int(r)) |
|||
m[i] = m[k] |
|||
m[k] = t |
|||
t = 1 / m[i][i] |
|||
var j = i + 1 |
|||
if b > 0: m[b][a] -= r |
|||
while (j < p) { |
|||
m[k0][k0] = Fraction(1, 1) |
|||
m[i][j] = m[i][j] * t |
|||
j = j + 1 |
|||
return gauss(m)[k1] |
|||
} |
|||
j = i + 1 |
|||
while (j < n) { |
|||
t = m[j][i] |
|||
var l = i + 1 |
|||
while (l < p) { |
|||
m[j][l] = m[j][l] - t*m[i][l] |
|||
l = l + 1 |
|||
} |
|||
j = j + 1 |
|||
} |
|||
} |
|||
for (i in n-1..0) { |
|||
for (j in 0...i) { |
|||
m[j][p-1] = m[j][p-1] - m[j][i]*m[i][p-1] |
|||
} |
|||
} |
|||
var col = List.filled(n, 0) |
|||
for (x in 0...n) col[x] = m[x][p-1] |
|||
return col |
|||
} |
|||
var network = Fn.new { |n, k0, k1, s| |
|||
assert 10 == network(7,0,1,"0 2 6|2 3 4|3 4 10|4 5 2|5 6 8|6 1 4|3 5 6|3 6 6|3 1 8|2 1 8") |
|||
var m = List.filled(n, null) |
|||
assert 3/2 == network(3*3,0,3*3-1,"0 1 1|1 2 1|3 4 1|4 5 1|6 7 1|7 8 1|0 3 1|3 6 1|1 4 1|4 7 1|2 5 1|5 8 1") |
|||
for (i in 0...n) m[i] = List.filled(n+1, 0) |
|||
assert Fraction(13,7) == network(4*4,0,4*4-1,"0 1 1|1 2 1|2 3 1|4 5 1|5 6 1|6 7 1|8 9 1|9 10 1|10 11 1|12 13 1|13 14 1|14 15 1|0 4 1|4 8 1|8 12 1|1 5 1|5 9 1|9 13 1|2 6 1|6 10 1|10 14 1|3 7 1|7 11 1|11 15 1") |
|||
for (resistor in s.split("|")) { |
|||
assert 180 == network(4,0,3,"0 1 150|0 2 50|1 3 300|2 3 250")</lang> |
|||
var rarr = resistor.split(" ") |
|||
var a = Num.fromString(rarr[0]) |
|||
var b = Num.fromString(rarr[1]) |
|||
var ri = Num.fromString(rarr[2]) |
|||
var r = 1/ri |
|||
m[a][a] = m[a][a] + r |
|||
m[b][b] = m[b][b] + r |
|||
if (a > 0) m[a][b] = m[a][b] - r |
|||
if (b > 0) m[b][a] = m[b][a] - r |
|||
} |
|||
m[k0][k0] = 1 |
|||
m[k1][n] = 1 |
|||
return gauss.call(m)[k1] |
|||
} |
|||
var fa = [ |
|||
network.call(7, 0, 1, "0 2 6|2 3 4|3 4 10|4 5 2|5 6 8|6 1 4|3 5 6|3 6 6|3 1 8|2 1 8"), |
|||
network.call(9, 0, 8, "0 1 1|1 2 1|3 4 1|4 5 1|6 7 1|7 8 1|0 3 1|3 6 1|1 4 1|4 7 1|2 5 1|5 8 1"), |
|||
network.call(16, 0, 15, "0 1 1|1 2 1|2 3 1|4 5 1|5 6 1|6 7 1|8 9 1|9 10 1|10 11 1|12 13 1|13 14 1|14 15 1|0 4 1|4 8 1|8 12 1|1 5 1|5 9 1|9 13 1|2 6 1|6 10 1|10 14 1|3 7 1|7 11 1|11 15 1"), |
|||
network.call(4, 0, 3, "0 1 150|0 2 50|1 3 300|2 3 250") |
|||
] |
|||
for (f in fa) Fmt.print("$.5g", f)</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
10.0 |
|||
1.5 |
|||
1.85714 |
|||
180.0 |
|||
</pre> |
|||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
{{libheader|GSL}} GNU Scientific Library |
{{libheader|GSL}} GNU Scientific Library |
||
This a tweak of [[Resistor_mesh#zkl]] |
This a tweak of [[Resistor_mesh#zkl]] |
||
< |
<syntaxhighlight lang="zkl">var [const] GSL=Import.lib("zklGSL"); // libGSL (GNU Scientific Library) |
||
fcn network(n,k0,k1,mesh){ |
fcn network(n,k0,k1,mesh){ |
||
Line 315: | Line 619: | ||
b[k1]=1; |
b[k1]=1; |
||
A.AxEQb(b)[k1]; |
A.AxEQb(b)[k1]; |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang="zkl">network(7,0,1,"0 2 6|2 3 4|3 4 10|4 5 2|5 6 8|6 1 4|3 5 6|3 6 6|3 1 8|2 1 8") |
||
.println(); |
.println(); |
||
Line 326: | Line 630: | ||
network(4,0,3,"0 1 150|0 2 50|1 3 300|2 3 250") |
network(4,0,3,"0 1 150|0 2 50|1 3 300|2 3 250") |
||
.println();</ |
.println();</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
Latest revision as of 12:04, 2 February 2024
Resistance network 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 any resistor network.
- The network is stated with a string.
- The resistors are separated by a vertical dash.
- Each resistor has
- a starting node
- an ending node
- a resistance
- Background
- Regular 3x3 mesh, using twelve one ohm resistors
0 - 1 - 2 | | | 3 - 4 - 5 | | | 6 - 7 - 8
Battery connection nodes: 0 and 8
assert 3/2 == network(9,0,8,"0 1 1|1 2 1|3 4 1|4 5 1|6 7 1|7 8 1|0 3 1|3 6 1|1 4 1|4 7 1|2 5 1|5 8 1")
- Regular 4x4 mesh, using 24 one ohm resistors
0 - 1 - 2 - 3 | | | | 4 - 5 - 6 - 7 | | | | 8 - 9 -10 -11 | | | | 12 -13 -14 -15
Battery connection nodes: 0 and 15
assert 13/7 == network(16,0,15,"0 1 1|1 2 1|2 3 1|4 5 1|5 6 1|6 7 1|8 9 1|9 10 1|10 11 1|12 13 1|13 14 1|14 15 1|0 4 1|4 8 1|8 12 1|1 5 1|5 9 1|9 13 1|2 6 1|6 10 1|10 14 1|3 7 1|7 11 1|11 15 1")
- Ten resistor network
Battery connection nodes: 0 and 1
assert 10 == network(7,0,1,"0 2 6|2 3 4|3 4 10|4 5 2|5 6 8|6 1 4|3 5 6|3 6 6|3 1 8|2 1 8")
- Wheatstone network
This network is not possible to solve using the previous Resistance Calculator as there is no natural starting point.
assert 180 == network(4,0,3,"0 1 150|0 2 50|1 3 300|2 3 250")
11l
F gauss(&m)
V (n, p) = (m.len, m[0].len)
L(i) 0 .< n
V k = max(i .< n, key' x -> abs(@m[x][@i]))
swap(&m[i], &m[k])
V t = 1 / m[i][i]
L(j) i + 1 .< p
m[i][j] *= t
L(j) i + 1 .< n
t = m[j][i]
L(k) i + 1 .< p
m[j][k] -= t * m[i][k]
L(i) (n - 1 .< -1).step(-1)
L(j) 0 .< i
m[j].last -= m[j][i] * m[i].last
R m.map(row -> row.last)
F network(n, k0, k1, s)
V m = [[0.0] * (n+1)] * n
V resistors = s.split(‘|’)
L(resistor) resistors
V (aa, bb, rr) = resistor.split(‘ ’)
V (a, b, r) = (Int(aa), Int(bb), (1 / Int(rr)))
m[a][a] += r
m[b][b] += r
I a > 0
m[a][b] -= r
I b > 0
m[b][a] -= r
m[k0][k0] = 1
m[k1].last = 1
R gauss(&m)[k1]
F is_equal(a, b)
R abs(a - b) < 1e-6
assert(is_equal(10 , network(7, 0, 1, ‘0 2 6|2 3 4|3 4 10|4 5 2|5 6 8|6 1 4|3 5 6|3 6 6|3 1 8|2 1 8’)))
assert(is_equal(3/2 , network(3*3, 0, 3*3-1, ‘0 1 1|1 2 1|3 4 1|4 5 1|6 7 1|7 8 1|0 3 1|3 6 1|1 4 1|4 7 1|2 5 1|5 8 1’)))
assert(is_equal(13/7, network(4*4, 0, 4*4-1, ‘0 1 1|1 2 1|2 3 1|4 5 1|5 6 1|6 7 1|8 9 1|9 10 1|10 11 1|12 13 1|13 14 1|14 15 1|0 4 1|4 8 1|8 12 1|1 5 1|5 9 1|9 13 1|2 6 1|6 10 1|10 14 1|3 7 1|7 11 1|11 15 1’)))
assert(is_equal(180 , network(4, 0, 3, ‘0 1 150|0 2 50|1 3 300|2 3 250’)))
print(‘OK’)
Go
package main
import (
"fmt"
"math"
"strconv"
"strings"
)
func argmax(m [][]float64, i int) int {
col := make([]float64, len(m))
max, maxx := -1.0, -1
for x := 0; x < len(m); x++ {
col[x] = math.Abs(m[x][i])
if col[x] > max {
max = col[x]
maxx = x
}
}
return maxx
}
func gauss(m [][]float64) []float64 {
n, p := len(m), len(m[0])
for i := 0; i < n; i++ {
k := i + argmax(m[i:n], i)
m[i], m[k] = m[k], m[i]
t := 1 / m[i][i]
for j := i + 1; j < p; j++ {
m[i][j] *= t
}
for j := i + 1; j < n; j++ {
t = m[j][i]
for l := i + 1; l < p; l++ {
m[j][l] -= t * m[i][l]
}
}
}
for i := n - 1; i >= 0; i-- {
for j := 0; j < i; j++ {
m[j][p-1] -= m[j][i] * m[i][p-1]
}
}
col := make([]float64, len(m))
for x := 0; x < len(m); x++ {
col[x] = m[x][p-1]
}
return col
}
func network(n, k0, k1 int, s string) float64 {
m := make([][]float64, n)
for i := 0; i < n; i++ {
m[i] = make([]float64, n+1)
}
for _, resistor := range strings.Split(s, "|") {
rarr := strings.Fields(resistor)
a, _ := strconv.Atoi(rarr[0])
b, _ := strconv.Atoi(rarr[1])
ri, _ := strconv.Atoi(rarr[2])
r := 1.0 / float64(ri)
m[a][a] += r
m[b][b] += r
if a > 0 {
m[a][b] -= r
}
if b > 0 {
m[b][a] -= r
}
}
m[k0][k0] = 1
m[k1][n] = 1
return gauss(m)[k1]
}
func main() {
var fa [4]float64
fa[0] = network(7, 0, 1, "0 2 6|2 3 4|3 4 10|4 5 2|5 6 8|6 1 4|3 5 6|3 6 6|3 1 8|2 1 8")
fa[1] = network(9, 0, 8, "0 1 1|1 2 1|3 4 1|4 5 1|6 7 1|7 8 1|0 3 1|3 6 1|1 4 1|4 7 1|2 5 1|5 8 1")
fa[2] = network(16, 0, 15, "0 1 1|1 2 1|2 3 1|4 5 1|5 6 1|6 7 1|8 9 1|9 10 1|10 11 1|12 13 1|13 14 1|14 15 1|0 4 1|4 8 1|8 12 1|1 5 1|5 9 1|9 13 1|2 6 1|6 10 1|10 14 1|3 7 1|7 11 1|11 15 1")
fa[3] = network(4, 0, 3, "0 1 150|0 2 50|1 3 300|2 3 250")
for _, f := range fa {
fmt.Printf("%.6g\n", f)
}
}
- Output:
10 1.5 1.85714 180
Julia
function gauss(m)
n, p = length(m), length(m[1])
for i in 1:n
_, k = findmax(map(x -> abs(m[x][i]), i:n)) .+ (i - 1)
m[i], m[k] = m[k], m[i]
t = 1 // m[i][i]
for j in i+1:p
m[i][j] *= t
end
for j in i+1:n
t = m[j][i]
for k in i+1:p
m[j][k] -= t * m[i][k]
end
end
end
for i in n:-1:1, j in 1:i-1; m[j][end] -= m[j][i] * m[i][end]; end
return [row[end] for row in m]
end
function network(n, k0, k1, s)
m = [[0//1 for i in 1:n + 1] for j in 1:n]
resistors = split(s, "|")
for resistor in resistors
astr, bstr, rstr = split(resistor, " ")
a, b, r = parse(Int, astr), parse(Int, bstr), 1 // parse(Int, rstr)
m[a + 1][a + 1] += r
m[b + 1][b + 1] += r
if a > 0; m[a + 1][b + 1] -= r end
if b > 0; m[b + 1][a + 1] -= r end
end
m[k0+1][k0+1] = m[k1+1][end] = 1 // 1
return gauss(m)[k1+1]
end
@assert(10 == network(7,0,1,"0 2 6|2 3 4|3 4 10|4 5 2|5 6 8|6 1 4|3 5 6|3 6 6|3 1 8|2 1 8"))
@assert(3//2 == network(3*3,0,3*3-1,"0 1 1|1 2 1|3 4 1|4 5 1|6 7 1|7 8 1|0 3 1|3 6 1|1 4 1|4 7 1|2 5 1|5 8 1"))
@assert(13//7 == network(4*4,0,4*4-1,"0 1 1|1 2 1|2 3 1|4 5 1|5 6 1|6 7 1|8 9 1|9 10 1|10 11 1|12 13 1|13 14 1|14 15 1|0 4 1|4 8 1|8 12 1|1 5 1|5 9 1|9 13 1|2 6 1|6 10 1|10 14 1|3 7 1|7 11 1|11 15 1"))
@assert(180 == network(4,0,3,"0 1 150|0 2 50|1 3 300|2 3 250"))
No assertion errors.
Nim
import rationals, sequtils, strscans, strutils, sugar
type Fraction = Rational[int]
func argmax(m: seq[seq[Fraction]]; i: int): int =
var max = -1 // 1
for x in i..m.high:
let val = abs(m[x][i])
if val > max:
max = val
result = x
func gauss(m: var seq[seq[Fraction]]): seq[Fraction] =
let n = m.len
let p = m[0].len
for i in 0..<n:
let k = m.argmax(i)
swap m[i], m[k]
let t = 1 / m[i][i]
for j in (i + 1)..<p:
m[i][j] *= t
for j in (i + 1)..<n:
let t = m[j][i]
for k in (i + 1)..<p:
m[j][k] -= t * m[i][k]
for i in countdown(n - 1, 0):
for j in 0..<i:
m[j][^1] -= m[j][i] * m[i][^1]
result = collect(newSeq, for row in m: row[^1])
func network(n, k0, k1: int; s: string): Fraction =
var m = newSeqWith(n, repeat(0 // 1, n + 1))
let resistors = s.split('|')
for resistor in resistors:
var a, b, c: int
if not resistor.scanf("$i $i $i", a, b, c):
raise newException(ValueError, "Wrong resistor: " & resistor)
let r: Fraction = 1 // c
m[a][a] += r
m[b][b] += r
if a > 0: m[a][b] -= r
if b > 0: m[b][a] -= r
m[k0][k0] = 1 // 1
m[k1][^1] = 1 // 1
result = gauss(m)[k1]
assert 10 // 1 == network(7, 0, 1, "0 2 6|2 3 4|3 4 10|4 5 2|5 6 8|6 1 4|3 5 6|3 6 6|3 1 8|2 1 8")
assert 3 // 2 == network(3*3, 0, 3*3-1, "0 1 1|1 2 1|3 4 1|4 5 1|6 7 1|7 8 1|0 3 1|3 6 1|1 4 1|4 7 1|2 5 1|5 8 1")
assert 13 // 7 == network(4*4, 0, 4*4-1, "0 1 1|1 2 1|2 3 1|4 5 1|5 6 1|6 7 1|8 9 1|9 10 1|10 11 1|12 13 1|13 14 1|14 15 1|0 4 1|4 8 1|8 12 1|1 5 1|5 9 1|9 13 1|2 6 1|6 10 1|10 14 1|3 7 1|7 11 1|11 15 1")
assert 180 // 1 == network(4, 0, 3, "0 1 150|0 2 50|1 3 300|2 3 250")
- Output:
No assertion failed.
Perl
use strict;
use warnings;
sub gauss {
our @m; local *m = shift;
my ($lead, $rows, $cols) = (0, scalar(@m), scalar(@{$m[0]}));
foreach my $r (0 .. $rows - 1) {
$lead < $cols or return;
my $i = $r;
until ($m[$i][$lead])
{++$i == $rows or next;
$i = $r;
++$lead == $cols and return;}
@m[$i, $r] = @m[$r, $i];
my $lv = $m[$r][$lead];
$_ /= $lv foreach @{ $m[$r] };
my @mr = @{ $m[$r] };
foreach my $i (0 .. $rows - 1)
{$i == $r and next;
($lv, my $n) = ($m[$i][$lead], -1);
$_ -= $lv * $mr[++$n] foreach @{ $m[$i] };}
++$lead;}
}
sub network {
my($n,$k0,$k1,$grid) = @_;
my @m;
push @m, [(0)x($n+1)] for 1..$n;
for my $resistor (split '\|', $grid) {
my ($a,$b,$r_inv) = split /\s+/, $resistor;
my $r = 1 / $r_inv;
$m[$a][$a] += $r;
$m[$b][$b] += $r;
$m[$a][$b] -= $r if $a > 0;
$m[$b][$a] -= $r if $b > 0;
}
$m[$k0][$k0] = 1;
$m[$k1][ -1] = 1;
gauss(\@m);
return $m[$k1][-1];
}
for (
[ 7, 0, 1, '0 2 6|2 3 4|3 4 10|4 5 2|5 6 8|6 1 4|3 5 6|3 6 6|3 1 8|2 1 8' ],
[ 3*3, 0, 3*3-1, '0 1 1|1 2 1|3 4 1|4 5 1|6 7 1|7 8 1|0 3 1|3 6 1|1 4 1|4 7 1|2 5 1|5 8 1' ],
[ 4*4, 0, 4*4-1, '0 1 1|1 2 1|2 3 1|4 5 1|5 6 1|6 7 1|8 9 1|9 10 1|10 11 1|12 13 1|13 14 1|14 15 1|0 4 1|4 8 1|8 12 1|1 5 1|5 9 1|9 13
1|2 6 1|6 10 1|10 14 1|3 7 1|7 11 1|11 15 1' ],
[ 4, 0, 3, '0 1 150|0 2 50|1 3 300|2 3 250' ],
) {
printf "%10.3f\n", network(@$_);
}
- Output:
10.000 1.500 1.857 180.000
Phix
with javascript_semantics function argmax(sequence m, integer i) sequence col := sq_abs(vslice(m,i)) return largest(col,return_index:=true) end function function gauss(sequence m) m = deep_copy(m) integer n = length(m), p = length(m[1]) for i=1 to n do integer k := i + argmax(m[i..n],i)-1 {m[i], m[k]} = {m[k], m[i]} atom t := 1/m[i][i] for j=i+1 to p do m[i][j] *= t end for for j=i+1 to n do t = m[j][i] for l=i+1 to p do m[j][l] -= t * m[i][l] end for end for end for for i=n to 1 by -1 do atom mip = m[i][p] for j=1 to i-1 do m[j][p] -= m[j][i] * mip end for end for return vslice(m,p) end function function network(integer n, k0, k1, sequence s) sequence m := repeat(repeat(0,n+1), n) s = split(s,'|') for i=1 to length(s) do integer {{a,b,ri}} = sq_add(scanf(s[i],"%d %d %d"),{{1,1,0}}) atom r = 1/ri m[a][a] += r m[b][b] += r if a > 1 then m[a][b] -= r end if if b > 1 then m[b][a] -= r end if end for k0 += 1; m[k0][k0] = 1 k1 += 1; m[k1][n+1] = 1 return gauss(m)[k1] end function printf(1,"%.6g\n",network(7, 0, 1, "0 2 6|2 3 4|3 4 10|4 5 2|5 6 8|6 1 4|3 5 6|3 6 6|3 1 8|2 1 8")) printf(1,"%.6g\n",network(9, 0, 8, "0 1 1|1 2 1|3 4 1|4 5 1|6 7 1|7 8 1|0 3 1|3 6 1|1 4 1|4 7 1|2 5 1|5 8 1")) printf(1,"%.6g\n",network(16, 0, 15, "0 1 1|1 2 1|2 3 1|4 5 1|5 6 1|6 7 1|8 9 1|9 10 1|10 11 1|12 13 1|13 14 1|14 15 1|"& "0 4 1|4 8 1|8 12 1|1 5 1|5 9 1|9 13 1|2 6 1|6 10 1|10 14 1|3 7 1|7 11 1|11 15 1")) printf(1,"%.6g\n",network(4, 0, 3, "0 1 150|0 2 50|1 3 300|2 3 250"))
- Output:
10 1.5 1.85714 180
Python
from fractions import Fraction
def gauss(m):
n, p = len(m), len(m[0])
for i in range(n):
k = max(range(i, n), key = lambda x: abs(m[x][i]))
m[i], m[k] = m[k], m[i]
t = 1 / m[i][i]
for j in range(i + 1, p): m[i][j] *= t
for j in range(i + 1, n):
t = m[j][i]
for k in range(i + 1, p): m[j][k] -= t * m[i][k]
for i in range(n - 1, -1, -1):
for j in range(i): m[j][-1] -= m[j][i] * m[i][-1]
return [row[-1] for row in m]
def network(n,k0,k1,s):
m = [[0] * (n+1) for i in range(n)]
resistors = s.split('|')
for resistor in resistors:
a,b,r = resistor.split(' ')
a,b,r = int(a), int(b), Fraction(1,int(r))
m[a][a] += r
m[b][b] += r
if a > 0: m[a][b] -= r
if b > 0: m[b][a] -= r
m[k0][k0] = Fraction(1, 1)
m[k1][-1] = Fraction(1, 1)
return gauss(m)[k1]
assert 10 == network(7,0,1,"0 2 6|2 3 4|3 4 10|4 5 2|5 6 8|6 1 4|3 5 6|3 6 6|3 1 8|2 1 8")
assert 3/2 == network(3*3,0,3*3-1,"0 1 1|1 2 1|3 4 1|4 5 1|6 7 1|7 8 1|0 3 1|3 6 1|1 4 1|4 7 1|2 5 1|5 8 1")
assert Fraction(13,7) == network(4*4,0,4*4-1,"0 1 1|1 2 1|2 3 1|4 5 1|5 6 1|6 7 1|8 9 1|9 10 1|10 11 1|12 13 1|13 14 1|14 15 1|0 4 1|4 8 1|8 12 1|1 5 1|5 9 1|9 13 1|2 6 1|6 10 1|10 14 1|3 7 1|7 11 1|11 15 1")
assert 180 == network(4,0,3,"0 1 150|0 2 50|1 3 300|2 3 250")
Raku
(formerly Perl 6)
sub gauss ( @m is copy ) {
for @m.keys -> \i {
my \k = max |(i .. @m.end), :by({ @m[$_][i].abs });
@m[i, k] .= reverse if \k != i;
.[i ^.. *] »/=» .[i] given @m[i];
for i ^.. @m.end -> \j {
@m[j][i ^.. *] »-=« ( @m[j][i] «*« @m[i][i ^.. *] );
}
}
for @m.keys.reverse -> \i {
@m[^i]».[*-1] »-=« ( @m[^i]».[i] »*» @m[i][*-1] );
}
return @m».[*-1];
}
sub network ( Int \n, Int \k0, Int \k1, Str \grid ) {
my @m = [0 xx n+1] xx n;
for grid.split('|') -> \resistor {
my ( \a, \b, \r_inv ) = resistor.split(/\s+/, :skip-empty);
my \r = 1 / r_inv;
@m[a][a] += r;
@m[b][b] += r;
@m[a][b] -= r if a > 0;
@m[b][a] -= r if b > 0;
}
@m[k0][k0] = 1;
@m[k1][*-1] = 1;
return gauss(@m)[k1];
}
use Test;
my @tests =
( 10, 7, 0, 1, '0 2 6|2 3 4|3 4 10|4 5 2|5 6 8|6 1 4|3 5 6|3 6 6|3 1 8|2 1 8' ),
( 3/2, 3*3, 0, 3*3-1, '0 1 1|1 2 1|3 4 1|4 5 1|6 7 1|7 8 1|0 3 1|3 6 1|1 4 1|4 7 1|2 5 1|5 8 1' ),
( 13/7, 4*4, 0, 4*4-1, '0 1 1|1 2 1|2 3 1|4 5 1|5 6 1|6 7 1|8 9 1|9 10 1|10 11 1|12 13 1|13 14 1|14 15 1|0 4 1|4 8 1|8 12 1|1 5 1|5 9 1|9 13 1|2 6 1|6 10 1|10 14 1|3 7 1|7 11 1|11 15 1' ),
( 180, 4, 0, 3, '0 1 150|0 2 50|1 3 300|2 3 250' ),
;
plan +@tests;
is .[0], network( |.[1..4] ), .[4].substr(0,10)~'…' for @tests;
Wren
import "./fmt" for Fmt
var argmax = Fn.new { |m, i|
var lm = m.count
var col = List.filled(lm, 0)
var max = -1
var maxx = -1
for (x in 0...lm) {
col[x] = m[x][i].abs
if (col[x] > max ) {
max = col[x]
maxx = x
}
}
return maxx
}
var gauss = Fn.new { |m|
var n = m.count
var p = m[0].count
for (i in 0...n) {
var k = i + argmax.call(m[i...n], i)
var t = m[i]
m[i] = m[k]
m[k] = t
t = 1 / m[i][i]
var j = i + 1
while (j < p) {
m[i][j] = m[i][j] * t
j = j + 1
}
j = i + 1
while (j < n) {
t = m[j][i]
var l = i + 1
while (l < p) {
m[j][l] = m[j][l] - t*m[i][l]
l = l + 1
}
j = j + 1
}
}
for (i in n-1..0) {
for (j in 0...i) {
m[j][p-1] = m[j][p-1] - m[j][i]*m[i][p-1]
}
}
var col = List.filled(n, 0)
for (x in 0...n) col[x] = m[x][p-1]
return col
}
var network = Fn.new { |n, k0, k1, s|
var m = List.filled(n, null)
for (i in 0...n) m[i] = List.filled(n+1, 0)
for (resistor in s.split("|")) {
var rarr = resistor.split(" ")
var a = Num.fromString(rarr[0])
var b = Num.fromString(rarr[1])
var ri = Num.fromString(rarr[2])
var r = 1/ri
m[a][a] = m[a][a] + r
m[b][b] = m[b][b] + r
if (a > 0) m[a][b] = m[a][b] - r
if (b > 0) m[b][a] = m[b][a] - r
}
m[k0][k0] = 1
m[k1][n] = 1
return gauss.call(m)[k1]
}
var fa = [
network.call(7, 0, 1, "0 2 6|2 3 4|3 4 10|4 5 2|5 6 8|6 1 4|3 5 6|3 6 6|3 1 8|2 1 8"),
network.call(9, 0, 8, "0 1 1|1 2 1|3 4 1|4 5 1|6 7 1|7 8 1|0 3 1|3 6 1|1 4 1|4 7 1|2 5 1|5 8 1"),
network.call(16, 0, 15, "0 1 1|1 2 1|2 3 1|4 5 1|5 6 1|6 7 1|8 9 1|9 10 1|10 11 1|12 13 1|13 14 1|14 15 1|0 4 1|4 8 1|8 12 1|1 5 1|5 9 1|9 13 1|2 6 1|6 10 1|10 14 1|3 7 1|7 11 1|11 15 1"),
network.call(4, 0, 3, "0 1 150|0 2 50|1 3 300|2 3 250")
]
for (f in fa) Fmt.print("$.5g", f)
- Output:
10.0 1.5 1.85714 180.0
zkl
GNU Scientific Library
This a tweak of Resistor_mesh#zkl
var [const] GSL=Import.lib("zklGSL"); // libGSL (GNU Scientific Library)
fcn network(n,k0,k1,mesh){
A:=GSL.Matrix(n,n); // zero filled
foreach resistor in (mesh.split("|")){
a,b,r := resistor.split().apply("toInt");
r=1.0/r;
A[a,a]=A[a,a] + r;
A[b,b]=A[b,b] + r;
if(a>0) A[a,b]=A[a,b] - r;
if(b>0) A[b,a]=A[b,a] - r;
}
A[k0,k0]=1;
b:=GSL.Vector(n); // zero filled
b[k1]=1;
A.AxEQb(b)[k1];
}
network(7,0,1,"0 2 6|2 3 4|3 4 10|4 5 2|5 6 8|6 1 4|3 5 6|3 6 6|3 1 8|2 1 8")
.println();
network(3*3,0,3*3-1,"0 1 1|1 2 1|3 4 1|4 5 1|6 7 1|7 8 1|0 3 1|3 6 1|1 4 1|4 7 1|2 5 1|5 8 1")
.println();
network(4*4,0,4*4-1,"0 1 1|1 2 1|2 3 1|4 5 1|5 6 1|6 7 1|8 9 1|9 10 1|10 11 1|12 13 1|13 14 1|14 15 1|0 4 1|4 8 1|8 12 1|1 5 1|5 9 1|9 13 1|2 6 1|6 10 1|10 14 1|3 7 1|7 11 1|11 15 1")
.println();
network(4,0,3,"0 1 150|0 2 50|1 3 300|2 3 250")
.println();
- Output:
10 1.5 1.85714 180