fork download
  1. from collections import namedtuple, defaultdict
  2.  
  3. Resistor = namedtuple('Resistor', ['node1', 'node2', 'value'])
  4.  
  5.  
  6. class Circuit(object):
  7. def __init__(self, start, end, resistors):
  8. self.endpoints = (start, end)
  9. self.network = defaultdict(list)
  10. for r in resistors:
  11. self.network[tuple(sorted({r.node1, r.node2}))].append(int(r.value))
  12.  
  13. def nodes(self):
  14. nodes = set()
  15. for n in self.network.keys():
  16. nodes = nodes.union(set(n))
  17. return nodes
  18.  
  19. def neighbors(self, node):
  20. neighbors = set()
  21. for n in self.network.keys():
  22. if node in n:
  23. neighbors = neighbors.union(set(n))
  24. neighbors.remove(node)
  25. return neighbors
  26.  
  27. def equivalent_resistance(self):
  28. def is_simplified():
  29. if len(network) > 1:
  30. return False
  31. if len(list(network.values())[0]) > 1:
  32. return False
  33. return True
  34.  
  35. network = self.network
  36. while not is_simplified():
  37. # Simplify parallel
  38. for nodes, resistances in network.items():
  39. if len(resistances) == 1:
  40. continue
  41. equivalent = 1 / sum(1 / x for x in resistances)
  42. network[nodes] = [equivalent]
  43. # Simplify serial
  44. for node in self.nodes():
  45. if node in self.endpoints:
  46. continue
  47. neighbors = sorted(self.neighbors(node))
  48. if len(neighbors) == 2:
  49. key1 = tuple(sorted((neighbors[0], node)))
  50. key2 = tuple(sorted((neighbors[1], node)))
  51. r1 = network[key1]
  52. r2 = network[key2]
  53. if len(r1) != 1 or len(r2) != 1:
  54. continue
  55. r1 = r1[0]
  56. r2 = r2[0]
  57. del network[key1]
  58. del network[key2]
  59. network[tuple(neighbors)].append(r1 + r2)
  60. return list(network.values())[0][0]
  61.  
  62.  
  63. sample = '''A B C D E F
  64. A C 5
  65. A B 10
  66. D A 5
  67. D E 10
  68. C E 10
  69. E F 15
  70. B F 20'''
  71.  
  72. nodes = sample.splitlines()[0].split()
  73. resistors = [Resistor(*line.split()) for line in sample.splitlines()[1:]]
  74. c = Circuit(nodes[0], nodes[-1], resistors)
  75. print(c.equivalent_resistance())
Success #stdin #stdout 0.03s 10192KB
stdin
Standard input is empty
stdout
12.857142857142858