Widerstände von ungewöhnlichem Wert


23

Einführung

Bei der Erstellung eines Elektronikprojekts kann ein Schaltplan einen Widerstand mit einem ungewöhnlichen Wert (z. B. 510 Ohm) erfordern. Sie überprüfen Ihren Teilebehälter und stellen fest, dass Sie keine 510-Ohm-Widerstände haben. Aber Sie haben viele gemeinsame Werte über und unter diesem Wert. Wenn Sie Widerstände parallel und in Reihe schalten, sollten Sie in der Lage sein, den 510-Ohm-Widerstand ziemlich gut anzunähern.

Aufgabe

Sie müssen eine Funktion oder ein Programm schreiben, die bzw. das eine Liste von Widerstandswerten (Widerständen, die Sie auf Lager haben) und einen Zielwert (den Sie approximieren möchten) akzeptiert. Das Programm muss berücksichtigen:

  • Einzelwiderstände
  • Zwei Widerstände in Reihe
  • Zwei Widerstände parallel

Das Programm sollte alle möglichen Kombinationen von 1 und 2 Widerständen aus der Bestandsliste berechnen (einschließlich zweier Kopien desselben Widerstandswerts), deren Reihen- und Parallelwiderstand berechnen und die Konfigurationen danach sortieren, wie gut sie sich dem Zielwert annähern.

Das Ausgabeformat sollte eine Konfiguration pro Zeile sein, wobei eine +Reihe und eine |Parallele sowie ein Leerzeichen oder ein Vorzeichen vor dem Nettowiderstand angegeben werden.

Formeln

  • Der Widerstand eines Widerstands ist R1
  • Der Nettowiderstand zweier in Reihe geschalteter Widerstände beträgt R1 + R2
  • Der Nettowiderstand von zwei Widerständen parallel ist 1 / (1/R1 + 1/R2)
  • Der Abstand zwischen einem angenäherten Widerstandswert und dem Sollwert kann als pseudo-logarithmische Abstand berechnet wird, nicht lineare Entfernung: dist = abs(Rapprox / Rtarget - 1). Zum Beispiel ist 200 näher an 350 als an 100.
  • Ein besseres Entfernungsmaß ist die echte logarithmische Entfernung dist = abs(log(Rapprox/Rtarget)). Da dies jedoch in der ursprünglichen Frage nicht angegeben wurde, können Sie beide Messungen verwenden.

Wertung

Die Punktzahl wird gemäß den üblichen Golfregeln in Code-Zeichen gemessen. Die niedrigste Punktzahl gewinnt.

Beispiel

Wir haben die folgenden Widerstände auf Lager [100, 150, 220, 330, 470, 680, 1000, 1500, 2200, 3300, 4700]und möchten 510Ohm ansteuern. Das Programm sollte ungefähr wie gezeigt 143 Konfigurationen ausgeben (Sie können das Format ändern, aber sicherstellen, dass die Bedeutung leicht zu bestimmen ist):

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.

In diesem Beispiel wird die beste Annäherung von 510 Ohm durch 680- und 2200-Ohm-Widerstände parallel gegeben.

Bisher beste Sprache (1. Juni 2014):

  1. J - 70 Zeichen
  2. APL - 102 Zeichen
  3. Mathematica - 122 Zeichen
  4. Rubin - 154 Zeichen
  5. Javascript - 156 Zeichen
  6. Julia - 163 char
  7. Perl - 185 Zeichen
  8. Python - 270 Zeichen

3
@Claudiu Es gibt keinen elektrischen Unterschied zwischen 100 + 150 und 150 + 100; Beide liefern einen Widerstand von 250 Ohm und verbrauchen einen Widerstand von 100 Ohm und einen Widerstand von 150 Ohm. Wir dürfen also nicht doppelt zählen. Sie sollten jedoch von 125 + 125 unterschieden werden, da dies zwar auch 250 Ohm ergibt, aber unterschiedliche Widerstände verbraucht (was angesichts unserer Teilezahlen vorzuziehen sein kann).
Phosgen

3
510 ist in der Serie E24 so ist es nicht , dass ungewöhnlich auf der Hand zu haben
gnibbler

3
Phosgen, was ist mit den ROUV?
Unclemeat

3
Ich glaube nicht, dass sie existieren.
Phosgen

1
Normalerweise setzen wir keine Fristen für Code-Golf-Fragen fest, da dies einige Leute vom Posten abhalten könnte. Sie können akzeptierte Antworten jederzeit ändern.
Nzall

Antworten:


6

J - 86 71 70 char

((]/:[|@<:@%~2{::"1])(;a:,<)"0,[:,/(<,.+`|,.+/;+&.%/)"1@;@((<@,.{:)\))

Ich werde mich nicht die Mühe machen, jedes Detail zu erklären, da ein Großteil des Codes für das Synchronisieren der Ergebnisse verschiedener Funktionen aufgewendet wird, aber hier ist der Kern des Golfs:

  • ;@((<@,.{:)\) macht jedes mögliche Paar von Widerständen, entweder parallel oder in Reihe geschaltet werden.

  • [:,/(<,.+`|,.+/;+&.%/)"1@ verbindet sie dann parallel und in Reihe und erstellt eine große Liste möglicher Verbindungen.

  • (;a:,<)"0, Fügt in der Möglichkeit hinzu, nur einen Widerstand für sich zu verwenden, um sich anzunähern.

  • (]/:[|@<:@%~2{::"1])sortiert die Liste der Widerstandskombinationen nach dem Pseudolog-Abstand ( |@<:@%) zwischen dem Ziel und dem resultierenden Widerstand aus jeder Kombination.

Und so benutzt man es:

   rouv =: ((]/:[|@<:@%~2{::"1])(;a:,<)"0,[:,/(<,.+`|,.+/;+&.%/)"1@;@((<@,.{:)\))
   # 510 rouv 100 150 220 330 470 680 1000 1500 2200 3300 4700      NB. how many?
143
   10 {. 510 rouv 100 150 220 330 470 680 1000 1500 2200 3300 4700  NB. view first 10
+---------+-+-------+
|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    |
+---------+-+-------+

Sie müssen nicht nur die ersten 10 wie oben anzeigen, sondern dies ist eine Funktion. J REPL schneidet sehr große Rückgabewerte ab, und die vollständige Ausgabe für dieses Beispiel hat 287 Zeilen. Sie können alles mit so etwas wie tmoutput toCRLF , LF ,.~ ": blah rouv blahWindows auf STDOUT zwingen - unter toCRLFLinux löschen -, dies rouvist jedoch eine Funktion, und intern sind alle Zeilen vorhanden.

Hinweis:

Die Frage scheint sich direkt vor unserer Nase geändert zu haben, und jetzt wird der Stammabstand als abs(log(Rapprox/Rtarget))statt definiert abs(Rapprox/Rtarget-1). Um dies in meinem Golf zu korrigieren, können wir den Wert |@<:@%auf |@^.@%: <:ist Dekrement, während der ^.Logarithmus ist ändern .


Auch wenn Ihr Code scheinbar unergründlich ist, können wir das Rätsel dennoch verstehen. Bestes Ergebnis nach einem Tag - wird es bestehen?
Phosgen

1
Nein, ich möchte keine Mail an -. & A: @, @: {@ (({.;
Kilazur

12

Mathematica, 151 122 Zeichen

Erwartet, dass der Zielwiderstand in rund die Liste der verfügbaren Widerstände in gespeichert werden l.

SortBy[Join[{#,#}&/@l,Join@@(#@@@Union[Sort/@N@l~Tuples~{2}]&/@{{"+",##,#+#2}&,{"|",##,#*#2/(#+#2)}&})],Abs[#[[-1]]/r-1]&]

Weniger Golf:

SortBy[Join[{#, #} & /@ l,
  Join @@ (# @@@ 
       Union[Sort /@ N@l~Tuples~{2}] & /@ {{"+", ##, # + #2} &, {"|", ##, 
        #*#2/(# + #2)} &})], Abs[#[[-1]]/r - 1] &]

Das Ausgabeformat unterscheidet sich vom vorgeschlagenen, aber die Konfigurationen sind leicht zu bestimmen. Die Ausgabe ist eine Liste von Konfigurationen. Jede Konfiguration hat eine der folgenden Formen:

{R1, Total}
{"+", R1, R2, Total}
{"|", R1, R2, Total}

Die ersten drei Elemente der Ausgabe werden also gelesen

{{"|", 680., 2200., 519.444}, {"|", 1000., 1000., 500.}, {"+", 150., 330., 480.}, ...}

Wenn Sie mit rationalen Zahlen zurechtkommen, könnte ich zwei Zeichen vor dem Weglassen retten N@. Das heißt, das erste Element (zum Beispiel) würde als 4675/9statt zurückgegeben 519.444.


Gute Arbeit. Du hast mich geschlagen (und mit kürzerem Code).
DavidC

15
Haben Sie nicht # Ihre # Höhle ist # w @ rn Sie @ g @ ins # e @ # ing # h @ # viel syn # @ c # ic sug @ r?
Phosgen

2
@ N @ l Tupel? Ist das eine Art Programmiererkrankung?
Clabacchio

@clabacchio erstaunlich, ich habe das nicht einmal gesehen. Phosgen, er muss vergessen haben, es zu erwähnen ... oder vielleicht spielt er auch nur gerne Golf ...
Martin Ender

10

APL (102)

{V←{⊃¨⍺{⍺,⍺⍺,⍵,'=',⍺⍵⍵⍵}⍺⍺/¨Z/⍨≤/¨Z←,∘.,⍨⍵}⋄K[⍋|¯1+⍺÷⍨0 4↓K←↑('|'{÷+/÷⍺⍵}V⍵),('+'+V⍵),{⍵,'  =',⍵}¨⍵;]}

Dies nimmt den Zielwiderstand als linkes Argument und eine Liste verfügbarer Widerstände als rechtes Argument.

Erläuterung:

  • V←{... }: Vist eine Funktion, die:
    • Z/⍨≤/¨Z←,∘.,⍨⍵: findet jede eindeutige Kombination von zwei Werten in ,
      • Z←,∘.,⍨⍵: Verbinde jeden Wert mit jedem Wert in , speichere in Z,
      • Z/⍨≤/¨Z: Wählen Sie eine ZKombination aus, bei der der erste Wert kleiner oder gleich dem zweiten Wert ist
    • ⍺{... }⍺⍺/¨: und wendet dann auf jedes Paar die folgende Funktion an, die mit der linken Funktion ( ⍺⍺) rechts und dem linken Argument ( ) links verbunden ist:
      • ⍺,⍺⍺,⍵,'=',⍺⍵⍵⍵, das linke Argument, gefolgt vom linken Argument, gefolgt vom rechten Argument =, gefolgt von der rechten Funktion ( ⍵⍵), die auf beide Argumente angewendet wird. (Dies ist die Formatierungsfunktion X [configuration] Y [equals] (X [fn] Y).)
    • ⊃¨: und dann jedes Element entpacken.
  • {⍵,' =',⍵}¨⍵: Nehmen Sie für jedes Element in die Konfigurationen für die einzelnen Widerstände vor. ( , nichts, nichts =, ).
  • ('+'+V⍵): Verwenden Sie die VFunktion, um alle seriellen Konfigurationen vorzunehmen (Zeichen ist '+'und Funktion ist +).
  • '|'{÷+/÷⍺⍵}V⍵: Verwenden Sie die VFunktion, um alle parallelen Konfigurationen durchzuführen (Zeichen ist '|'und Funktion ist {÷+/÷⍺⍵}, Kehrwert der Summe der Kehrwerte der Argumente).
  • K←↑: mache daraus eine Matrix und speichere sie in K.
  • 0 4↓K: Lösche die 4 ersten Spalten von Kund lasse nur die Widerstandswerte übrig.
  • |¯1+⍺÷⍨: Berechnen Sie den Abstand zwischen und jeder Konfiguration.
  • K[⍋... ;]: Nach KEntfernungen sortieren .

3
Ich nehme dein Wort, dass es funktioniert. Auf meiner Tastatur fehlen ziemlich viele dieser Zeichen: D
Phosgen

@phosgene: Wenn Sie es testen möchten, können Sie eine Testversion von Dyalog APL auf dyalog.com herunterladen. Dann fügen Sie einfach das Ganze ein, es sollte funktionieren. Die Argumente gehen auf die Seiten, so zum Beispiel:510 code_here 100, 150, 220, 330, 470, 680, 1000, 1500, 2200, 3300, 4700
Marinus

@phosgene Sie können diesen Online-Interpreter ausprobieren , obwohl er nicht die vollständige Ausgabe liefert. Sie können überprüfen, ob die ersten und letzten Zeilen identisch sind.
user12205

Verifiziert! APL ist ein esoterisches Zeug.
Phosgen

1
@ace TryAPL ist sehr begrenzt und funktioniert normalerweise nicht. Dass es passiert, dass daran gearbeitet wird, ist nur ein Zufall. Es unterstützt keine eval ( ), I / O ( ) oder alle Systemvariablen (auch ⎕UCSund ⎕Anicht Arbeit) so dass die meisten APL - Programme werden nicht ausgeführt. Es wird tatsächlich ein SYNTAX-FEHLER ausgegeben, wenn eine der deaktivierten Funktionen verwendet wird. Die Tatsache, dass diese eine der vielen Funktionen, die TryAPL nicht unterstützt, nicht verwendet, ist ein Zufall.
marinus

4

Python 3 - 250 247 270 Bytes

from itertools import*
import sys
r=sys.argv[1:]
t=int(r.pop())
p=set(map(tuple,map(sorted,product(r,r))))
a=[('+'.join(b),sum(map(int,b)))for b in p]+[('|'.join(b),1/sum(map(lambda n:1/int(n),b)))for b in p]
for s in sorted(a,key=lambda b:abs(float(b[1])/t-1)):print(s)

Laufen Sie wie folgt:

python resistors.py 100 150 220 330 470 680 1000 1500 2200 3300 4700 510

(dh eine durch Leerzeichen getrennte Liste von Widerständen mit dem Zielwert am Ende)

Ausgabe:

('2200|680', 519.4444444444445)
('1000|1000', 500.0)
('150+330', 480)
('220+330', 550)
('1500|680', 467.88990825688074)
('3300|680', 563.8190954773869)

[snip]

('2200+4700', 6900)
('3300+4700', 8000)
('4700+4700', 9400)

Ich würde sagen, dass das Ausgeben, sagen wir, 680|2200und 2200|680getrennt, immer noch ziemlich klar ist. Wenn dies nicht akzeptabel ist, kann ich es ändern, aber es kostet mich Bytes.War nicht akzeptabel Hat mich Bytes gekostet. Jetzt sortiere ich die Tupel, bevor ich sie in das Set schmeiße, ansonsten ist die Lösung identisch.


Klar, die Ausgabe erscheint mir klar!
Phosgen

Sie zählen die Dinge jedoch doppelt. 150 + 330 ist elektrisch identisch mit 330 + 150, daher sollte nur eine davon im Ergebnis erscheinen (143 Gesamtkonfigurationen für das Beispiel).
Phosgen

@pho Okay, behoben. Ein paar zusätzliche Bytes, aber die Lösung sollte jetzt gültig sein.
bahnmonorail

Ich denke auch, dass Ihr Programm überhaupt nicht nach einem einzelnen Widerstand sucht (a + = [(a, a) für a in r]). Sie können ein = ... überspringen, wenn Sie ein genaues Mal verwenden. Über diese import sys;r=sys.args[1:]Anwendung, r=input().split()und sagen , dass Sie die Werte auf stdin geben. Endlich: Sie verwenden 1/sum(1/int(n)for n in b)statt 1/sum(map(lambda n:1/int(n),b). Alles in allem sollten das 274 Zeichen sein
WorldSEnder

Ich habe gerade noch 1 Zeichen gespielt: Verwende print (* sortiert (...), sep = '\ n')
WorldSEnder

3

Ruby 2.1, 156 154 Bytes

s=->(a,z){c={};a.map{|e|a.map{|f|c[e]=e;c[e+f]="#{e}+#{f}";c[1/(1.0/f+1.0/e)]="#{e}|#{f}"}};c.sort_by{|k,|(k/z.to_f-1).abs}.map{|e|puts"#{e[1]}=#{e[0]}"}}

Ungolfed:

s =->(a,z) {
  c={}
  a.map{|e|
    a.map{|f|
      c[e]=e
      c[e+f]="#{e}+#{f}"
      c[1/(1.0/f+1.0/e)]="#{e}|#{f}"
    }
  }
  c.sort_by{|k,|
    (k/z.to_f-1).abs
  }.map{|e|
    puts "#{e[1]}=#{e[0]}"
  }
}

Was es macht:

  • Für jeden Wert ein a;
    • Durchlaufen a, Berechnen von Einzel-, Serien- und Parallelwerten als Schlüssel zu gedruckten Werten in Hash c;
  • Bestimmen Sie die Entfernung von zfür jede Tastatureingabe c. und,
  • Für jeden Wert e[1] für jeden Schlüssel e[0]in cdrucken e[1]=e[0].

Beispielnutzung:

s[[100, 150, 220, 330, 470, 680, 1000, 1500, 2200, 3300, 4700], 510]

Beispielausgabe:

2200|680=519.4444444444445
1000|1000=500.0
330+150=480
330+220=550
470=470
1500|680=467.88990825688074
3300|680=563.8190954773869
.
.
.
4700+1500=6200
3300+3300=6600
4700+2200=6900
4700+3300=8000
4700+4700=9400

3

JavaScript (ECMAScript 6) - 186 Zeichen

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)))

Eingang:

  • Eine Anordnung R von Widerstandsstärken; und
  • T, der Zielwiderstand.

Ausgabe:

Ein Array von Arrays (sortiert nach Entfernung von T ), die Folgendes enthalten:

  • der kleinere Widerstandswert;
  • der höhere Widerstandswert (oder 0, wenn es sich um einen Einzelwiderstand handelt);
  • p, s Oder 0 , wenn die Widerstände parallel sind, seriell oder einzeln; und
  • der Nettowiderstand.

Erläuterung:

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.
)

Einzelwiderstand fehlt (Ausgang ist zB 132 statt 143). Ich würde gerne den Array-Verständnis-Trick ausleihen, wenn ich es nur verstehen könnte ...
edc65


3

Julia - 179 163 Bytes

f(t,s)=(\ =repmat;m=endof(s);A=A[v=(A=s\m).>=(B=sort(A))];B=B[v];F=[s,C=A+B,A.*B./C];n=sum(v);print([[s P=[" "]\m P;A [+]\n B;A [|]\n B] F][sortperm(abs(F-t)),:]))

Dies funktioniert genauso wie die alte Version, jedoch wurde das Argument in der print-Anweisung etwas anders organisiert, um die Anzahl der erforderlichen eckigen Klammern zu verringern. Spart 4 Bytes. Durch das Absorbieren der Erstellung des Leerzeichenvektors im print-Argument werden zusätzliche 2 Bytes gespart. Es wurde auch von "find" gewechselt, um die relevanten Indizes zur Verwendung der logischen Form zu bringen. Spart 6 Bytes. Durch das Absorbieren der Berechnung des Indexvektors in die Anpassung von A wurden weitere 2 Bytes eingespart. Das Ersetzen von endof (v) durch sum (v) sparte schließlich 2 weitere Bytes. Gesamteinsparung: 16 Bytes.

Alte Version:

f(t,s)=(\ =repmat;m=endof(s);A=s\m;v=find(A.>=(B=sort(A)));A=A[v];B=B[v];F=[s,C=A+B,A.*B./C];n=endof(v);P=[" "]\m;print([[s,A,A] [P,[+]\n,[|]\n] [P,B,B] F][sortperm(abs(F-t)),:]))

In der Funktion wird Folgendes ausgeführt:

\ =repmat            # Overloads \ operator to save lots of characters
m=endof(s)           # Length of input s ("Stock")
A=s\m                # Equivalent to repmat(s,m) (see first command)
B=sort(A)            # Same as A but sorted - rather than cycling through
                     # the resistors m times, it repeats each one m times
v=find(A.>=B)        # Identify which pairs for A,B have A>=B
A=A[v];B=B[v]        # Remove pairs where A<B (prevents duplicates)
F=[s,C=A+B,A.*B./C]  # Constructs vector containing results for single resistor,
                     # resistors in series, and resistors in parallel
n=endof(v)           # equivalent to n=(m+1)m/2, gets number of relevant pairs
P=[" "]\m            # Construct array of blank entries for use in constructing output
print([[s,A,A] [P,[+]\n,[|]\n] [P,B,B] F][sortperm(abs(F-t)),:]))
# The following are the components of the argument in the print statement:
[s,A,A]              # Set of resistor values for resistor 1
[P,[+]\n,[|]\n]      # Operator column, prints either nothing, +, or |
[P,B,B]              # Set of resistor values for resistor 2 (blank for single resistor)
F                    # Contains resulting equivalent resistance
[sortperm(abs(F-t)),:] # Determines permutation for sorting array by distance from Target t
                     # and applies it to array

Beispielausgabe:

julia> f(170,[100,220,300])
300  |  300  150
100  +  100  200
300  |  220  126.92307692307692
220          220
220  |  220  110
100          100
300  |  100  75
220  |  100  68.75
100  |  100  50
300          300
220  +  100  320
300  +  100  400
220  +  220  440
300  +  220  520
300  +  300  600

Nett! Sehen Sie nicht viele Julia Einreichungen - wird es immer beliebter?
Phosgen

@phosgene - ich hoffe es ist; Ich reiche diese meistens ein, weil sie mir zusätzliche Erfahrung mit der Sprache geben.
Glen O

2

Javascript (E6) 156 162 164 186

Last Edit Unter der Annahme, dass alle Widerstandswerte> 0 sind, können Sie sie für die Schleifenbedingung verwenden

F=(t,s)=>{D=a=>Math.abs(a[1]/t-1);for(i=r=[];a=s[j=i++];r[l]=[a,a])for(;b=s[j--];)l=r.push([a+'+'+b,c=a+b],[a+'|'+b,a*b/c]);return r.sort((a,b)=>D(a)-D(b))}

Verwendung : F(510, [100, 150, 220, 330, 470, 680, 1000, 1500, 2200, 3300, 4700])

Ungolfed

F = (t,s) => 
{
  D = a => Math.abs(a[1]/t-1);
  for (i=r=[]; a=s[j=i++]; r[l]=[a,a])
    for(; b=s[j--];)
      l = r.push([a+'+'+b, c=a+b], [a+'|'+b, a*b/c]);
   return r.sort((a,b) => D(a)-D(b))
}

1
Muss drücken (Punktzahl, niedriger)!
Phosgen

Zuletzt habe ich überprüft, alle meine Widerstände waren positiv bewertet. Ich denke, das ist eine sichere Annahme.
Phosgen

1

Javascript, 248 Bytes

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)}

Verwendung : r(510, [100, 150, 220, 330, 470, 680, 1000, 1500, 2200, 3300, 4700]);

Ausgabe

670|2200=519.4444444444445
1000|1000=500
150+330=480

(...such rows...)

2200+4700=6900
3300+4700=8000
4700+4700=9400

0

Perl, 213 199 185 Bytes

213 Bytes:

$t=pop;sub t{abs 1-(split/=/,pop)[1]/$t}sub S{$_[0]+$_[1]}sub P{$_[0]*$_[1]/&S}$"=',';@i=@ARGV;say for sort{t($a)<=>t($b)}grep s!(..\b(\d+)\b,?\b(\d+)?\b\))=\K(??{$2<$3})!$1!ee&&/\d$/,<{S,P}({@i},{@i})= S({@i})=>;

199 Bytes:

$t=pop;sub t{abs 1-(split/=/,pop)[1]/$t}sub S{$_[0]+$_[1]}sub P{$_[0]*$_[1]/&S}$"=',';@i=@ARGV;say for sort{t($a)<=>t($b)}grep/(..(\d+),?(\d+)?\))/&&$2>=$3&&($_.=eval$1),<{S,P}({@i},{@i})= S({@i})=>;

185 Bytes:

$t=pop;sub t{abs 1-$_[0]=~s!.*=!!r/$t}sub S{$_[0]+$_[1]}sub P{$_[0]*$_[1]/&S}$"=',';$i="{@ARGV}";say for sort{t($a)<=>t$b}grep{my($x,$y)=/\d+/g;$_.='='.eval,$x>=$y}<{S,P}($i,$i) S($i)>

Übergeben Sie alle verfügbaren Widerstände als Argumente. Der Zielwiderstand sollte der letzte sein:

$ perl -E 'code' R1 R2 R3 ... Rn target

Wie es funktioniert (alter Code)

  • Unterprogramme definieren SundP berechnen Sie die Summe und die Parallelität zweier Widerstände.

  • Auf $""," setzen, um @ARGVinnerhalb des globOperators zu interpolieren

  • <{S,P}({@i},{@i})= S({@i})=> erzeugt einen kartesischen aller Möglichkeiten:

    S (100, 100), S (100, 150), S (100, 220), ... P (100, 100), P (100, 150) ... S (100), S (150) ...

  • Kombinieren Sie s///eemit grep, um die äquivalenten Widerstände zu bewerten und unerwünschte Wiederholungen (durchgeführt von (??{$2<$3})und) herauszufiltern/\d$/

  • sort von Fitness im Unterprogramm berechnet t

Änderungen im neuen Code

  • Vermeiden Sie die Verwendung von s///ee, verwenden Sie kürzere reguläre Ausdrücke mit bedingter Prüfung und im evalInnerengrep

  • Wiederholungen von "{@i}" with$ i` ersetzen

  • Einführen $x, $ystatt $2,$3

  • Ersetzen split/=/,popdurch$_[0]=~s!!!r

  • Kein Nachziehen nötig ;

  • eval; ist äquivalent zu eval $_;

  • Fügen Sie =zusammen miteval -ed Antwort hinzu, anstatt es vorher zu deklarieren

Ausgabe:

Prepräsentiert Widerstände parallel, Srepräsentiert Widerstände in Reihe.

P(2200,680)=519.444444444444
P(1000,1000)=500
S(330,150)=480
S(330,220)=550
S(470)=470
P(1500,680)=467.889908256881
P(3300,680)=563.819095477387
S(470,100)=570
S(220,220)=440
S(330,100)=430
P(4700,470)=427.272727272727
P(4700,680)=594.052044609665
P(1500,1000)=600
P(3300,470)=411.405835543767
P(1000,680)=404.761904761905
S(470,150)=620
P(2200,470)=387.265917602996
S(220,150)=370
S(330,330)=660
P(1500,470)=357.868020304569
S(680)=680
P(680,680)=340
P(2200,1000)=687.5
S(330)=330
S(470,220)=690
S(220,100)=320
P(1000,470)=319.727891156463
P(4700,330)=308.349900596421
S(150,150)=300
P(3300,330)=300
P(2200,330)=286.95652173913
P(680,470)=277.913043478261
P(1500,330)=270.491803278689
P(1500,1500)=750
P(3300,1000)=767.441860465116
S(150,100)=250
P(1000,330)=248.12030075188
S(680,100)=780
P(470,470)=235
P(680,330)=222.178217821782
S(470,330)=800
S(220)=220
P(4700,220)=210.162601626016
P(3300,220)=206.25
S(100,100)=200
P(2200,220)=200
P(4700,1000)=824.561403508772
P(470,330)=193.875
P(1500,220)=191.860465116279
S(680,150)=830
P(1000,220)=180.327868852459
P(680,220)=166.222222222222
P(330,330)=165
S(150)=150
P(470,220)=149.855072463768
P(4700,150)=145.360824742268
P(3300,150)=143.478260869565
P(2200,150)=140.425531914894
P(1500,150)=136.363636363636
P(330,220)=132
P(1000,150)=130.434782608696
P(2200,1500)=891.891891891892
P(680,150)=122.89156626506
S(680,220)=900
P(470,150)=113.709677419355
P(220,220)=110
P(330,150)=103.125
S(100)=100
P(4700,100)=97.9166666666667
P(3300,100)=97.0588235294118
P(2200,100)=95.6521739130435
P(1500,100)=93.75
P(1000,100)=90.9090909090909
P(220,150)=89.1891891891892
P(680,100)=87.1794871794872
P(470,100)=82.4561403508772
S(470,470)=940
P(330,100)=76.7441860465116
P(150,150)=75
P(220,100)=68.75
P(150,100)=60
P(100,100)=50
S(1000)=1000
S(680,330)=1010
P(3300,1500)=1031.25
S(1000,100)=1100
P(2200,2200)=1100
P(4700,1500)=1137.09677419355
S(680,470)=1150
S(1000,150)=1150
S(1000,220)=1220
P(3300,2200)=1320
S(1000,330)=1330
S(680,680)=1360
S(1000,470)=1470
P(4700,2200)=1498.55072463768
S(1500)=1500
S(1500,100)=1600
S(1500,150)=1650
P(3300,3300)=1650
S(1000,680)=1680
S(1500,220)=1720
S(1500,330)=1830
P(4700,3300)=1938.75
S(1500,470)=1970
S(1000,1000)=2000
S(1500,680)=2180
S(2200)=2200
S(2200,100)=2300
S(2200,150)=2350
P(4700,4700)=2350
S(2200,220)=2420
S(1500,1000)=2500
S(2200,330)=2530
S(2200,470)=2670
S(2200,680)=2880
S(1500,1500)=3000
S(2200,1000)=3200
S(3300)=3300
S(3300,100)=3400
S(3300,150)=3450
S(3300,220)=3520
S(3300,330)=3630
S(2200,1500)=3700
S(3300,470)=3770
S(3300,680)=3980
S(3300,1000)=4300
S(2200,2200)=4400
S(4700)=4700
S(3300,1500)=4800
S(4700,100)=4800
S(4700,150)=4850
S(4700,220)=4920
S(4700,330)=5030
S(4700,470)=5170
S(4700,680)=5380
S(3300,2200)=5500
S(4700,1000)=5700
S(4700,1500)=6200
S(3300,3300)=6600
S(4700,2200)=6900
S(4700,3300)=8000
S(4700,4700)=9400

Die fehlenden zwei Zeilen sind S(100)=100und S(1000)=1000.
Algorithmushai

@algorithmshark: Ja, verstanden. Die Regex konsumierte sie versehentlich
Zaid

Es wird interessant sein zu sehen, ob jemand eine kürzere Perl-Lösung finden kann.
Zaid
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.