Resistance network calculator

From Rosetta Code
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

Arbitrary Resistor Grid


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

Picture

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

Picture

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

Translation of: Python
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’)

EasyLang

Translation of: Julia
func[] gauss m[][] .
   n = len m[][]
   p = len m[1][]
   for i to n
      max = 0
      for j = i to n
         if abs m[j][i] > max
            k = i
            max = m[j][i]
         .
      .
      swap m[i][] m[k][]
      t = 1 / m[i][i]
      for j = i + 1 to p
         m[i][j] *= t
      .
      for j = i + 1 to n
         t = m[j][i]
         for k = i + 1 to p
            m[j][k] -= t * m[i][k]
         .
      .
   .
   for i = n downto 1
      for j to i - 1
         m[j][p] -= m[j][i] * m[i][p]
      .
   .
   for r to n
      r[] &= m[r][p]
   .
   return r[]
.
proc network n k0 k1 s$ . .
   len m[][] n
   for i to n
      len m[i][] n + 1
   .
   for resistor$ in strsplit s$ "|"
      res[] = number strsplit resistor$ " "
      a = res[1] + 1
      b = res[2] + 1
      r = 1 / res[3]
      m[a][a] += r
      m[b][b] += r
      if a > 1
         m[a][b] -= r
      .
      if b > 1
         m[b][a] -= r
      .
   .
   m[k0 + 1][k0 + 1] = 1
   m[k1 + 1][n + 1] = 1
   r[] = gauss m[][]
   print r[k1 + 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"
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"
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"
network 4 0 3 "0 1 150|0 2 50|1 3 300|2 3 250"
Output:
10.00
1.50
1.86
180

FreeBASIC

Translation of: Go
Function ArgMax(m() As Double, i As Integer) As Integer
    Dim As Integer n = Ubound(m, 1) + 1
    Dim As Double max = Abs(m(i, i))
    Dim As Integer maxx = i
    For x As Integer = i To n - 1
        If Abs(m(x, i)) > max Then
            max = Abs(m(x, i))
            maxx = x
        End If
    Next x
    Return maxx
End Function

Sub Gauss(m() As Double, col() As Double)
    Dim As Integer n = Ubound(m, 1) + 1
    Dim As Integer p = Ubound(m, 2) + 1
    Dim As Integer i, j, k, l
    For i = 0 To n - 1
        k = ArgMax(m(), i)
        If k <> i Then
            For j = 0 To p - 1
                Swap m(i, j), m(k, j)
            Next j
        End If
        Dim As Double t = 1 / m(i, i)
        For j = i + 1 To p - 1
            m(i, j) *= t
        Next j
        For j = i + 1 To n - 1
            t = m(j, i)
            For l = i + 1 To p - 1
                m(j, l) -= t * m(i, l)
            Next l
        Next j
    Next i
    For i = n - 1 To 0 Step -1
        For j = 0 To i - 1
            m(j, p - 1) -= m(j, i) * m(i, p - 1)
        Next j
    Next i
    For i = 0 To n - 1
        col(i) = m(i, p - 1)
    Next i
End Sub

Function Network(n As Integer, k0 As Integer, k1 As Integer, s As String) As Double
    Dim As Double m(n - 1, n)
    Dim As Integer i = 1
    Dim As String resistor = Mid(s, i, Instr(i, s, "|") - i)
    While Len(resistor) > 0
        Dim As Integer a = Val(Mid(resistor, 1, Instr(1, resistor, " ") - 1))
        Dim As Integer b = Val(Mid(resistor, Instr(1, resistor, " ") + 1, Instr(Instr(1, resistor, " ") + 1, resistor, " ") - Instr(1, resistor, " ") - 1))
        Dim As Integer ri = Val(Mid(resistor, Instr(Instr(1, resistor, " ") + 1, resistor, " ") + 1))
        Dim As Double r = 1.0 / ri
        m(a, a) += r
        m(b, b) += r
        If a > 0 Then m(a, b) -= r
        If b > 0 Then m(b, a) -= r
        i += Len(resistor) + 1
        resistor = Mid(s, i, Instr(i, s, "|") - i)
    Wend
    m(k0, k0) = 1
    m(k1, n) = 1
    Dim As Double col(n - 1)
    Gauss(m(), col())
    Return col(k1)
End Function

Dim As Double fa(3)
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 i As Integer = 0 To Ubound(fa)
    Print Using "###.#####"; fa(i)
Next i

Sleep
Output:
 10.00000
  1.50000
  1.85714
180.00000

Go

Translation of: Python
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

Translation of: Python
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

Translation of: Python
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

Translation of: Go
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)

Translation of: Python
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;

Rust

Translation of: Python
use itertools::Itertools;
use num_rational::Ratio;
use num_traits::sign::Signed;
use std::str::FromStr;

fn gauss(m: &mut Vec<Vec<Ratio<i64>>>) -> Vec<Ratio<i64>> {
    let (n, p) = (m.len(), m[0].len());
    for i in 0..n {
        let k = (i..n)
            .reduce(|x, y| if m[y][i].abs() > m[x][i].abs() { y } else { x })
            .unwrap_or(0);
        let tmp = m[i].clone();
        m[i] = m[k].clone();
        m[k] = tmp;
        let mut t = Ratio::<i64>::new(*m[i][i].denom(), *m[i][i].numer());
        for j in i + 1..p {
            m[i][j] *= t;
        }
        for j in i + 1..n {
            t = m[j][i];
            for k in i + 1..p {
                let tmp = m[i][k];
                m[j][k] -= t * tmp;
            }
        }
    }
    for i in (0..n).rev() {
        for j in 0..i {
            let end = m[j].len() - 1;
            let y = m[i][end];
            let x = m[j][i];
            m[j][end] -= x * y;
        }
    }
    return m.into_iter().map(|row| row[row.len() - 1]).collect_vec();
}

fn network(n: usize, k0: usize, k1: usize, s: &str) -> Ratio<i64> {
    let mut m = vec![vec![Ratio::<i64>::new(0, 1); n + 1]; n];
    let resistors: Vec<&str> = s.split("|").collect();
    for resistor in resistors {
        let [astr, bstr, rstr] = resistor.split(" ").collect_vec()[0..3] else {
            todo!()
        };
        let (a, b, r) = (
            usize::from_str(astr).unwrap(),
            usize::from_str(bstr).unwrap(),
            Ratio::<i64>::new(1, i64::from_str(rstr).unwrap()),
        ); // parse(Int, rstr)
        m[a][a] += r;
        m[b][b] += r;
        if a > 0 {
            m[a][b] -= r
        }
        if b > 0 {
            m[b][a] -= r
        }
    }
    let end = m[k1].len() - 1;
    (m[k0][k0], m[k1][end]) = (Ratio::<i64>::new(1, 1), Ratio::<i64>::new(1, 1));
    return gauss(&mut m)[k1];
}

fn main() {
    assert!(Ratio::<i64>::new(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!(Ratio::<i64>::new(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!(Ratio::<i64>::new(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!(Ratio::<i64>::new(180, 1) == network(4, 0, 3, "0 1 150|0 2 50|1 3 300|2 3 250"));
}

Wren

Translation of: Go
Library: Wren-fmt
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

Library: GSL

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