Parallel resistance in electric circuits

Introduction:

Two resistors, R1 and R2, in parallel (denoted R1 || R2) have a combined resistance Rp given as:

$$R_{P_2} = \frac{R_1\cdot R_2}{R_1+R_2}$$ or as suggested in comments:

$$R_{P_2} = \frac{1}{\frac{1}{R_1} + \frac{1}{R_2}}$$

Three resistors, R1, R2 and R3 in parallel (R1 || R2 || R3) have a combined resistance (R1 || R2) || R3 = Rp || R3 :

$$R_{P_3} = \frac{\frac{R_1\cdot R_2}{R_1+R_2}\cdot R_3}{\frac{R_1\cdot R_2}{R_1+R_2}+R_3}$$

or, again as suggested in comments:

$$R_{P_3} = \frac{1}{\frac{1}{R_1} + \frac{1}{R_2}+ \frac{1}{R_3}}$$

These formulas can of course be extended to an indefinite number of resistors.

Challenge:

Take a list of positive resistor values as input, and output the combined resistance if they were placed in parallel in an electric circuit. You may not assume a maximum number of resistors (except that your computer can handle it of course).

Test cases:

1, 1
0.5

1, 1, 1
0.3333333

4, 6, 3
1.3333333

20, 14, 18, 8, 2, 12
1.1295

10, 10, 20, 30, 40, 50, 60, 70, 80, 90
2.6117


Shortest code in each language wins. Explanations are highly encouraged.

• There are a few other challenges that refer to the harmonic mean (1 2 3) but I don't think there is a duplicate. In line with what flawr suggested, I think this challenge body should have that phrase listed somewhere so we can close a future dupe more easily. – FryAmTheEggman Sep 11 '19 at 15:17

C#, 16 bytes

1/l.Sum(n=>1f/n)


Try It

• Since the Sum() function can also accept a selector, you can cut 9 bytes by ommiting the .Select() part, like so – pappbence96 Sep 13 '19 at 13:21
• Just realized, one more byte can be saved by writing 1f/n instead of 1.0/n as both methods will avoid integer division. – pappbence96 Sep 13 '19 at 13:29
• nice catch mate! – koviroli Sep 13 '19 at 13:33

SimpleTemplate, 72 bytes

Okay, this was VERY hard!
Specifically with a language that has VERY poor math support.

{@fnx A,S}{@eachA}{@set/_ 1 _}{@set+S S,_}{@/}{@set/S 1 S}{@returnS}{@/}


Creates a function x that must be called by passing an array as the first and only argument.

Ungolfed:

{@fn calc values, sum}
{@each values as value}
{@set/ value 1 value}
{@set+ sum sum, value}
{@/}
{@set/ sum 1 sum}
{@return sum}
{@/}


Explanation:

• {@fn calc values, sum} - Creates the function calc, which has 2 variables (values and sum) taking the values of the first arguments (defaults to null)
• {@each values as value} - Loops over each value in values
• {@set/ value 1 value} - Divides 1 by value, storing it into value
• {@set+ sum sum, value} - Adds sum to value, storing it into sum
• {@/} - Closes the {@each} (usually optional)
• {@set/ sum 1 sum} - Divides 1 by sum, storing it into sum
• {@return sum} - Returns sum (duh)
• {@/} - Closes the {@fn} (usually optional, even if it shouldn't be for functions)

To use the function, you can use this code:

{@set values 10, 10, 20, 30, 40, 50, 60, 70, 80, 90} {@//array of values}
{@call calc into result values}
{@echo result} {@//2.6116696030677}


If you are curious, the ungolfed example compiles to this PHP code:

// {@fn calc values, sum}
$DATA['calc'] = function()use(&$FN, &$_){$DATA = array(
'argv' => func_get_args(),
'argc' => func_num_args(),
'VERSION' => '0.62',
'EOL' => PHP_EOL,
'PARENT' => &$_ );$_ = &$DATA;$DATA["values"] = &$DATA["argv"][0];$DATA["sum"] = &$DATA["argv"][1]; // {@each values as value} // loop variables$tmp_1_val = isset($DATA['values']) ?$tmp_1_val = &$DATA['values'] : null;$tmp_1_keys = gettype($DATA['values']) == 'array' ? array_keys($DATA['values'])
: array_keys(range(0, strlen($tmp_1_val =$tmp_1_val . '') - 1));
$tmp_1_key_last = end($tmp_1_keys);

// loop
foreach($tmp_1_keys as$tmp_1_index => $tmp_1_key){$DATA['loop'] = array(
'index' => $tmp_1_index, 'i' =>$tmp_1_index,
'key' => $tmp_1_key, 'k' =>$tmp_1_key,
'value' => $tmp_1_val[$tmp_1_key],
'v' => $tmp_1_val[$tmp_1_key],
'first' => $tmp_1_key ===$tmp_1_keys[0],
'last' => $tmp_1_key ===$tmp_1_key_last,
);
$DATA['__'] =$tmp_1_key;
$DATA['value'] =$tmp_1_val[$tmp_1_key]; // {@set/ value 1 value}$DATA['value'] = array_map(function($value)use(&$DATA){return (1 / $value);},$FN['array_flat']((isset($DATA['value'])?$DATA['value']:null)));

// {@set+ sum sum, value}
$DATA['sum'] = array_sum($FN['array_flat'](array((isset($DATA['sum'])?$DATA['sum']:null),(isset($DATA['value'])?$DATA['value']:null))));

// {@/}
};

// {@set/ sum 1 sum}
$DATA['sum'] = array_map(function($value)use(&$DATA){return (1 /$value);}, $FN['array_flat']((isset($DATA['sum'])?$DATA['sum']:null))); // {@return sum} return (isset($DATA['sum'])?$DATA['sum']:null); // {@/} }; // {@set values 10, 10, 20, 30, 40, 50, 60, 70, 80, 90}$DATA['values'] = array(10,10,20,30,40,50,60,70,80,90);

// {@call calc into result values}
$DATA['result'] = call_user_func_array(isset($DATA['calc']) && is_callable($DATA['calc'])?$DATA['calc']: (isset($FN["calc"])?$FN["calc"]: "calc"), array((isset($DATA['values'])?$DATA['values']:null)));

// {@echo result}
echo implode('', $FN['array_flat']((isset($DATA['result'])?$DATA['result']:null)));  Ruby, 26 22 bytes -4 bytes thanks to @ValueInk. ->x{1/x.sum{|i|1.0/i}}  Try it online! Pyth, 6 bytes c1scL1  Try it online! Uses the modified formula $$\\frac{1}{R_P}=\frac{1}{R_1} + \frac{1}{R_2}\$$. c1 # 1/ s # sum( ) cL1 # map(lambda x: 1/x, Q) # Q (=input) is implicit  Japt v2.0a0, 7 bytes 1÷Ux!÷1  Try it OCaml, 50 bytes fun l->1./.(List.fold_left(fun a e->a+.1./.e)0. l)  Try it online! Stax, 5 bytes {u+Fu  Run and debug it at staxlang.xyz! { F For each: u Invert + Add to running total u Invert Implicit print as fraction  Scala, 15 bytes 1/_.map(1/).sum  Try it online! Python, 30 bytes lambda v:1/sum(1/x for x in v)  -2, thanks @JoKing • Welcome to PPCG! Unfortunately, submissions should either be a full program (preface with v=input();print ) or a function (preface with lambda v:) to be valid. A snippet which presumes pre-defined variables isn't allowed. – Value Ink Sep 16 '19 at 18:41 • Welcome to the site! This is a snippet, which means that you don't output or input according to our Input/Output rules. You can correct this by wrapping the statement in print(...) and by taking v as input, either in a lambda or by using input. – caird coinheringaahing Sep 16 '19 at 18:42 • That's unfortunate, thanks for pointing me to the IO conventions. I have updated my answer. :) – pikaynu Sep 17 '19 at 9:54 jq, 16 characters 1/(map(1/.)|add)  Sample run: bash-5.0$ jq '1/(map(1/.)|add)' <<< '[10, 10, 20, 30, 40, 50, 60, 70, 80, 90]'
2.611669603067675


Try it online!

C (gcc), 65 62 bytes

Thanks to ceilingcat for -3 bytes.

float a(b,c)int*b;{float d=0;for(;c--;)d+=1./b[c];return 1/d;}


Try it online!

C++ (clang), 78 bytes

#import<list>
void f(std::list<int>r,double&s){s=0;for(int p:r)s+=1./p;s=1/s;}


Try it online!