## What's the voltage over each component?

18

1

The picture below shows a RLC circuit. A RLC circuit is an electrical circuit consisting of a resistor (R), an inductor (L), and a capacitor (C), connected in series or in parallel. (1)

In order to simplify computations, it's common to work in the frequency (Laplace) domain instead of the time domain.

Take the values R, L and C as input, and return the voltages VR, VL and VC

The conversion to the Laplace domain is as follows:

R = R
XL = j*w*L      // OK, XL = w*L, and ZL = j*XL, but don't mind this here.
XC = 1/(j*w*C)  // I haven't ruined physics, it's only a minor terminology tweak


where j = sqrt(-1), and w = 2*pi*50 (The frequency is 50 Hz).

The combined impedance, when the components are in series is Z = R + XL + XC. You might remember U = R*I from high school physics lectures. It's almost the same, but a bit more complex now: VS = Z*I. The current is calculated by dividing the voltage VS by the total impedance Z. To find the voltage over a single component, you need to know the current, then multiply it by the impedance. For simplicity, the voltage is assumed to be VS = 1+0*j.

Equations you might need are:

XL = j*w*L
XC = 1/(j*w*C)
Z = R + XL + XC   // The combined impedance of the circuit
I = VS / Z         // The current I (Voltage divided by impedance)
VR = I * R        // Voltage over resistance (Current times resistance)
VL = I * XL       // Voltage over inductor (Current times impedance)
VC = I * XC       // Voltage over capacitor (Current times impedance)


The input is from either STDIN or as function arguments. The output/result must be three complex numbers, in a list, string or whatever is most practical in your language. It's not necessary to include names (ex VR = ...), as long as the results are in the same order as below. The precision has to be at least 3 decimal points for both the real and imaginary part. The input and output/results can be in scientific notation if that's default in your language.

R and L are >= 0, and C > 0. R, L, C <= inf (or the highest possible number in your language).

A simple test case:

R = 1, L = 1, C = 0.00001

VR = 0.0549 + 0.2277i
VL = -71.5372 +17.2353i
VC = 72.4824 -17.4630i


For the results above, this could be one (of many) valid ouput format:

(0.0549 + 0.2277i, -71.5372 +17.2353i, 72.4824 -17.4630i)


Some valid ouput formats for one voltage value are:

1.234+i1.234,   1.23456+1.23456i,   1.2345+i*1.2345,   1.234e001+j*1.234e001.


This list is not exclusive, so other variants can be used, as long as the imaginary part is indicated by an i or a j (common in electrical engineering as i is used for current).

To verify the result for other values of R,L and C, the following must be true for all results: VR + VL + VC = 1.

The shortest code in bytes win!

By the way: Yes, it's voltage over a component, and current through a component. A voltage has never gone through anything. =)

2Actually, reactances are real numbers, so XL = omega*L. The impedance of the inductor is Z = jXL. (This does not affect the problem, it's only a correction) – Voitcus – 2015-09-01T10:09:57.253

@Voitcus, true... I simplified it a bit, to not make the question too confusing. I included the j in the XL/XC terms, when going to the frequency domain. I never said that the reactance was complex though (although I called it X, and not jX) =) But I agree with you! I actually called it impedance too. – Stewie Griffin – 2015-09-01T10:18:01.013

Can I take a list of 3 numbers as a function input, or does it have to be 3 separate arguments? – Martin Ender – 2015-09-01T10:37:58.713

@MartinBüttner, list is OK. – Stewie Griffin – 2015-09-01T10:57:23.133

7

# Pyth, 3029 28 bytes

L*vw*100.l_1)K[Qy0c1y1)cRsKK


Try it online.

9

# Mathematica, 33 bytes

So close to Pyth...

l/Tr[l={#,#2(x=100Pi*I),1/x/#3}]&


This is an unnamed function, which takes R, L and C as its three arguments and returns a list of complex numbers as the result (in the required order VR, VL, VC). Example usage:

l/Tr[l={#,#2(x=100Pi*I),1/x/#3}]&[1, 1, 0.00001]
(* {0.0548617 + 0.22771 I, -71.5372 + 17.2353 I, 72.4824 - 17.463 I} *)


3

# Octave / Matlab, 53 51 bytes

function f(R,L,C)
k=-.01j/pi;Z=[R L/k k/C];Z/sum(Z)


Try it online

Thanks to @StewieGriffin for removing two bytes.

@StewieGriffin 100j?! So many years using Matlab and I didn't know that could be done! :-) (I did know 1j, but I thought it was just that). Thanks! – Luis Mendo – 2015-09-01T16:06:01.697

... aaaand: Apparently I know more about you than you do! Because, you do/did know that it is possible! =)

– Stewie Griffin – 2015-09-01T16:10:05.527

@StewieGriffin Ooooh. It happened to me again. Bad memory!!:-D (I never really use that notation) – Luis Mendo – 2015-09-01T16:11:55.140

You can save another byte if you start with the inverse of k, like this: k=-.01j/pi;Z=[R,L/k,k/C];Z/sum(Z), or k=-.01j/pi;[R L/k k/C]/(R+L/k+k/C). =) – Stewie Griffin – 2015-09-02T09:02:35.510

@StewieGriffin Good idea! Edited – Luis Mendo – 2015-09-02T09:34:17.330

I just stumbled over this: Can't believe I commented and provided a link to a question you posted two years earlier (at the time) in 4 minutes... How did I even remember that you wrote 2i in that post...? Beats me... :P – Stewie Griffin – 2016-11-15T11:13:03.560

@StewieGriffin Specially when I didn't remember about it myself, haha – Luis Mendo – 2016-11-15T11:15:56.763

3

# APL (Dyalog Unicode), 27 24 bytesSBCS

Full program. Prompts for C, L, R in that order.

(⊢÷+/)(⎕,⎕∘÷,÷∘⎕)÷○0J100


Try it online!

0J100 100 i

○ π times that

÷ reciprocal of that

() apply the following tacit function:

÷∘⎕ divide the argument by input (C)

⎕∘÷, prepend input (L) divided by the argument

⎕, prepend input (R)

() apply the following tacit function:

+/ sum the arguments

⊢÷ divide the arguments by that

@StewieGriffin I am note sure what you mean. the "high minus" ¯ is APL's negative number prefix, to distinguish from the function (i.e math operator) negate -. Anyway, it wouldn't be fair to not count APL chars as single bytes, it is just a matter of encoding, and there are many APL systems that use single bytes to store APL code. E.g. Dyalog has both Unicode and Classic (single-byte) versions of their interpreter. – Adám – 2015-09-03T07:18:39.067

1I agree, if you have used encoding where every character is a single byte, then the number of chars should equal the number of bytes. Can you verify that it's the case (i'm not too familiar with apl an different encoding systems). Also, i wasn't familiar with the high minus sign. My bad... – Stewie Griffin – 2015-09-03T08:17:44.087

I just pasted the code into a "count number of bytes" box and got back 31. If it's not correct, then of course you'll have a score of 28 :-) Although, ..,49J¯17.4.. would mean the first part is imaginary and the second is real in any other language (or in mathematical notation in general), so it might violate the rule "as long as the imaginary part is indicated by an i or a j". Have a +1 for teaching me about "high minus", and a nice answer, but I'm not sure I can pick it as the accepted answer, when that day comes. – Stewie Griffin – 2015-09-03T08:28:10.413

1@StewieGriffin Ninja'd ;) – Beta Decay – 2015-09-03T08:31:33.610

@StewieGriffin See http://help.dyalog.com/14.1/Content/Language/System%20Functions/avu.htm

@StewieGriffin APL uses a notation similar to the last one mentioned in https://en.wikipedia.org/wiki/Complex_number#Notation, as a natual extension to 123E4 (123 × 10 ^ 4) 123J4 (123+i × 4).

@NBZ, but that doesn't explain why J is in front of the minus sign for the last voltage...? Unless there are parentheses, +/- are last in the hierarchy (PEMDAS). ab^c = a*(b^c), but ab-c = (a*b) - c, not a - (b*c), thus: aJ-b = a*J - b. If you didn't know the answer was written in APL, and/or didn't know how APL prints imaginary numbers, it wouldn't make sense. I think the answer deserves the upvotes, as it is a nice answer, but I'm afraid I can't accept it with that particular output format.

– Stewie Griffin – 2015-09-03T10:07:08.247

@StewieGriffin Oh, but APL always evaluates right-to-left, with no hierachy: 9=3×2+1 and 1J2 is 1 + i × 2 (where the + and × are left out and signaled with a J, just as × and 10^ are in 1E2 and signaled with an E). In fact, "J", a close cousin to APL, has many such notations: http://www.jsoftware.com/help/dictionary/dcons.htm

@NBZ, ok, I realize that this is the correct way to output this in APL. But I'm sorry, I stand my ground. In my eyes, this does not adhere to the rule: "as long as the imaginary part is indicated by an i or a j". I didn't understand it at first, second or third glance. If you had written the values on a piece of paper, it would be incorrect. If the task was just: "Calculate it", I would accept it... – Stewie Griffin – 2015-09-03T10:32:57.897

@StewieGriffin Well, one could define output←('J'⎕R'+i×')⍕¨ and then output (⊢÷+/)R(L÷k),C÷⍨k←0J¯0.01÷○1 would give 0.05486169763+i×0.2277101046 ¯71.53723919+i×17.23531062 72.48237749+i×¯17.46302073. It you then would call output the "standard output" of APL... – Adám – 2015-09-03T11:16:13.933

I have to go, but regarding the byte count, you might be interested in the result of this meta post. I think it's fair to count the score according to what the consensus there will end up as...?

– Stewie Griffin – 2015-09-03T11:27:55.167

APL is usually counted as one byte per character. The code golf tag wiki states "Unless the question is specified to be scored by characters, it is scored by bytes. If it doesn't specify a character encoding to use for scoring, answers which use Unicode code points outside 0 to 255 should state the encoding used." That is, you don't have to score in Unicode, as long as you use an existing encoding. Furthermore, there is a codepage which contains the entire APL character set.

– Martin Ender – 2015-09-03T11:55:41.440

@MartinBüttner But to enable people to actually read the APL code, it would be fair to post translation to Unicode. Implicitly, all APL code has the note "this is of course really supposed to be entirely different bytes in a special APL code page, but here is it posted in Unicode to ease reading." – Adám – 2015-09-03T12:54:53.287

@NBZ, it has gone a week now. I'm sorry for not accepting your answer, but as the OP/judge, I don't think the output complies with the rules. As I stated earlier, the j is in the wrong place (according to general notation (and not APL/J etc.)); aJ-b = a*J - b. But again, nice answer and very well done! – Stewie Griffin – 2015-09-08T06:08:34.133

2

# Octave, 41 bytes

@(R,L,C)(Z=[R L/(k=-.01j/pi) k/C])/sum(Z)


1/(100*j*pi) can be shortened to -.01j/pi which is a lot shorter. By assigning it to the variable k inline, the variable can be used twice. Assigning the entire vector to the variable Z costs 4 bytes, but allows us to divide by sum(Z), which is 5 bytes shorter than (R+L/k+k/C).