当建立一个电子项目时,一个原理图可能需要一个不寻常值的电阻(例如510欧姆)。你检查你的零件箱,发现你没有510欧姆电阻器。但是,在这个值之上和下面确实有许多共同的值。通过并联和串联电阻器的组合,你应该能够很好地近似510欧姆电阻。
您必须编写一个函数或程序,它接受电阻值列表(库存电阻器)和目标值(您的目标是近似的)。该方案必须考虑:
程序应从库存列表中计算1和2个电阻的所有可能组合(包括两个相同电阻值的副本),计算它们的串联和并行电阻,然后根据它们逼近目标值的程度对配置进行排序。
输出格式应该是每行一个配置,+
表示序列和|
表示并行,在净电阻之前有一些空格或=符号。
R1
。R1 + R2
。1 / (1/R1 + 1/R2)
。dist = abs(Rapprox / Rtarget - 1)
。例如,200比100更接近350。dist = abs(log(Rapprox/Rtarget))
,但是由于这不是在最初的问题中指定的,所以您可以自由使用任何一种度量。分数是用代码的字符来衡量的,这是通常的高尔夫规则。最低分获胜。
我们有以下的电阻库存[100, 150, 220, 330, 470, 680, 1000, 1500, 2200, 3300, 4700]
,并希望目标510
欧姆。程序应该输出143种配置,大致如图所示(您可以更改格式,但要确保含义很容易确定):
680 | 2200 519.444
1000 | 1000 500.
150 + 330 480.
220 + 330 550.
470 470
680 | 1500 467.89
680 | 3300 563.819
100 + 470 570.
220 + 220 440.
100 + 330 430.
470 | 4700 427.273
680 | 4700 594.052
1000 | 1500 600.
470 | 3300 411.406
680 | 1000 404.762
150 + 470 620.
...
many more rows
...
2200 + 4700 6900.
3300 + 4700 8000.
4700 + 4700 9400.
在这个例子中,510欧姆的最佳近似是由680-和2200-欧姆电阻并联的.
发布于 2014-05-26 01:11:13
{V←{⊃¨⍺{⍺,⍺⍺,⍵,'=',⍺⍵⍵⍵}⍺⍺/¨Z/⍨≤/¨Z←,∘.,⍨⍵}⋄K[⍋|¯1+⍺÷⍨0 4↓K←↑('|'{÷+/÷⍺⍵}V⍵),('+'+V⍵),{⍵,' =',⍵}¨⍵;]}
这将目标电阻作为左参数,可用电阻列表作为右参数。
解释:
V←{
.}
:V
是一个函数:Z/⍨≤/¨Z←,∘.,⍨⍵
:在⍵
,中查找两个值的每个唯一组合Z←,∘.,⍨⍵
:将⍵
中的每个值与⍵
中的每个值连接起来,存储在Z
中,Z/⍨≤/¨Z
:从Z
中选择第一个值小于或等于第二个值的组合- `⍺{`...`}⍺⍺/¨`: and then applies following function, bound with the left function (`⍺⍺`) on the right and the left argument (`⍺`) on the left, to each pair:
- `⍺,⍺⍺,⍵,'=',⍺⍵⍵⍵`, the left argument, followed by the left bound argument, followed by the right argument, followed by `=`, followed by the right function (`⍵⍵`) applied to both arguments. (This is the formatting function, `X [configuration] Y [equals] (X [fn] Y)`.)
- `⊃¨`: and then unbox each element.
{⍵,' =',⍵}¨⍵
:对于⍵
中的每个元素,为单个电阻器进行配置。(⍵
,nothing,nothing,=
,⍵
)('+'+V⍵)
:使用V
函数进行所有串行配置(字符为'+'
,函数为+
)。'|'{÷+/÷⍺⍵}V⍵
:使用V
函数进行所有并行配置(字符为'|'
,函数为{÷+/÷⍺⍵}
,参数之和为逆)。K←↑
:把它变成一个矩阵,并存储在K
中。0 4↓K
:从K
中删除4列,只留下电阻值。|¯1+⍺÷⍨
:计算⍺
与每个配置之间的距离。K[⍋
.;]
:按距离对K
排序。发布于 2014-05-26 12:57:34
f=(R,T)=>(D=x=>Math.abs(x[3]/T-1),r={p:(x,y)=>x*y/(x+y),s:(x,y)=>x+y},[...[[x,0,0,x]for(x of R)],...[[x,y,z,r[z](x,y)]for(x of R)for(y of R)for(z in r)if(x<=y)]].sort((a,b)=>D(a)-D(b)))
R
;以及T
,目标电阻。数组数组(按距离T
排序),每个数组包含:
p
、s
或0;f=(R,T)=>( // Create a function f with arguments R & T
D=x=>Math.abs(x[3]/T-1), // A function D to calculate relative
// distance from the target value
r={p:(x,y)=>x*y/(x+y),s:(x,y)=>x+y}, // An object containing the formulae
// to calculate resistance in serial and parallel
solitary = [[x,0,0,x]for(x of R)], // Create an array of solitary resistors
pairs = // Use Array Comprehension to create the array of
[[x,y,z,r[z](x,y)] // arrays
for(x of R) // for each resistor value
for(y of R) // for each resistor value (again)
for(z in r) // for both serial & parallel
if(x<=y)], // where the first resistor value is smaller than the second
[
...solitary, // Use the spread ... operator to combine
...pairs // the two arrays
]
.sort((a,b)=>D(a)-D(b)) // Sort the arrays by minimum distance
// and return.
)
发布于 2014-05-26 06:28:38
function r(T,L){R=[],O="";for(i in L){R.push([a=L[i],a]);for(j=i;j<L.length;)b=L[j++],s=a+b,R.push([a+"+"+b,s],[a+"|"+b,a*b/s])}R.sort(function(a,b){A=Math.abs;return A(a[1]/T-1)-A(b[1]/T-1)});for(i in R)q=R[i],O+=q[0]+"="+q[1]+"\n";console.log(O)}
用法:r(510, [100, 150, 220, 330, 470, 680, 1000, 1500, 2200, 3300, 4700]);
670|2200=519.4444444444445
1000|1000=500
150+330=480
(...such rows...)
2200+4700=6900
3300+4700=8000
4700+4700=9400
https://codegolf.stackexchange.com/questions/28595
复制相似问题