Skip to content

Instantly share code, notes, and snippets.

@ricbit
Created July 22, 2019 01:57
Show Gist options
  • Save ricbit/3729ba619526e6b5917d1ac6559c1784 to your computer and use it in GitHub Desktop.
Save ricbit/3729ba619526e6b5917d1ac6559c1784 to your computer and use it in GitHub Desktop.
Approximate resistor value "target" by using at most "max_resistors" from a given list of resistor values
import itertools
import sys
from fractions import Fraction
def split_integer(n):
for a in range(1, 1 + n // 2):
yield a, n - a
def resistor_pairs(n, cur_list):
for a, b in split_integer(n):
yield from itertools.product(cur_list[a], cur_list[b])
def series():
return (lambda a, b: a + b, lambda a, b: "(%s + %s)" % (a, b))
def parallel():
return (lambda a, b: a * b / (a + b), lambda a, b: "(%s // %s)" % (a, b))
def min_resistor(target, max_resistor, resistor_list):
cur_list = {1: [(Fraction(r), str(r)) for r in resistor_list]}
values = set(Fraction(r) for r in resistor_list)
cur_diff = 1e18
cur_value = 1e18
cur_str = ""
for n in range(2, 1 + max_resistor):
new_list = []
for r1, r2 in resistor_pairs(n, cur_list):
for val_op, str_op in [series(), parallel()]:
new_value = val_op(r1[0], r2[0])
new_str = str_op(r1[1], r2[1])
if new_value not in values:
new_list.append((new_value, new_str))
values.add(new_value)
diff = abs(new_value - target)
if diff < cur_diff:
cur_diff = diff
cur_str = new_str
cur_value = new_value
cur_list[n] = new_list
print(float(cur_value), cur_str)
def main():
if len(sys.argv) < 3:
print("Usage: python3 resistor.py target max_resistors R1 R2 R3 ...")
return
min_resistor(float(sys.argv[1]), int(sys.argv[2]), map(int, sys.argv[3:]))
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment