Created
July 22, 2019 01:57
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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