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 510
Ohm 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):
- J - 70 Zeichen
- APL - 102 Zeichen
- Mathematica - 122 Zeichen
- Rubin - 154 Zeichen
- Javascript - 156 Zeichen
- Julia - 163 char
- Perl - 185 Zeichen
- Python - 270 Zeichen
quelle
Antworten:
J -
867170 charIch 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:
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 blah
Windows auf STDOUT zwingen - untertoCRLF
Linux löschen -, diesrouv
ist 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 definiertabs(Rapprox/Rtarget-1)
. Um dies in meinem Golf zu korrigieren, können wir den Wert|@<:@%
auf|@^.@%
:<:
ist Dekrement, während der^.
Logarithmus ist ändern .quelle
Mathematica,
151122 ZeichenErwartet, dass der Zielwiderstand in
r
und die Liste der verfügbaren Widerstände in gespeichert werdenl
.Weniger Golf:
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:
Die ersten drei Elemente der Ausgabe werden also gelesen
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 als4675/9
statt zurückgegeben519.444
.quelle
APL (102)
Dies nimmt den Zielwiderstand als linkes Argument und eine Liste verfügbarer Widerstände als rechtes Argument.
Erläuterung:
V←{
...}
:V
ist eine Funktion, die:Z/⍨≤/¨Z←,∘.,⍨⍵
: findet jede eindeutige Kombination von zwei Werten in⍵
,Z←,∘.,⍨⍵
: Verbinde jeden Wert⍵
mit jedem Wert in⍵
, speichere inZ
,Z/⍨≤/¨Z
: Wählen Sie eineZ
Kombination 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 FormatierungsfunktionX [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 dieV
Funktion, um alle seriellen Konfigurationen vorzunehmen (Zeichen ist'+'
und Funktion ist+
).'|'{÷+/÷⍺⍵}V⍵
: Verwenden Sie dieV
Funktion, 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 inK
.0 4↓K
: Lösche die 4 ersten Spalten vonK
und lasse nur die Widerstandswerte übrig.|¯1+⍺÷⍨
: Berechnen Sie den Abstand zwischen⍺
und jeder Konfiguration.K[⍋
...;]
: NachK
Entfernungen sortieren .quelle
510 code_here 100, 150, 220, 330, 470, 680, 1000, 1500, 2200, 3300, 4700
⍎
), I / O (⎕
) oder alle Systemvariablen (auch⎕UCS
und⎕A
nicht 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.Python 3 -
250247270 BytesLaufen Sie wie folgt:
(dh eine durch Leerzeichen getrennte Liste von Widerständen mit dem Zielwert am Ende)
Ausgabe:
Ich würde sagen, dass das Ausgeben, sagen wir,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.680|2200
und2200|680
getrennt, immer noch ziemlich klar ist. Wenn dies nicht akzeptabel ist, kann ich es ändern, aber es kostet mich Bytes.quelle
import sys;r=sys.args[1:]
Anwendung,r=input().split()
und sagen , dass Sie die Werte auf stdin geben. Endlich: Sie verwenden1/sum(1/int(n)for n in b)
statt1/sum(map(lambda n:1/int(n),b)
. Alles in allem sollten das 274 Zeichen seinRuby 2.1,
156154 BytesUngolfed:
Was es macht:
e
ina
;a
, Berechnen von Einzel-, Serien- und Parallelwerten als Schlüssel zu gedruckten Werten in Hashc
;z
für jede Tastatureingabec
. und,e[1]
für jeden Schlüssele[0]
inc
druckene[1]=e[0]
.Beispielnutzung:
s[[100, 150, 220, 330, 470, 680, 1000, 1500, 2200, 3300, 4700], 510]
Beispielausgabe:
quelle
JavaScript (ECMAScript 6) - 186 Zeichen
Eingang:
R
von Widerstandsstärken; undT
, der Zielwiderstand.Ausgabe:
Ein Array von Arrays (sortiert nach Entfernung von
T
), die Folgendes enthalten:p
,s
Oder 0 , wenn die Widerstände parallel sind, seriell oder einzeln; undErläuterung:
quelle
Julia -
179163 BytesDies 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:
In der Funktion wird Folgendes ausgeführt:
Beispielausgabe:
quelle
Javascript (E6) 156
162 164 186Last Edit Unter der Annahme, dass alle Widerstandswerte> 0 sind, können Sie sie für die Schleifenbedingung verwenden
Verwendung :
F(510, [100, 150, 220, 330, 470, 680, 1000, 1500, 2200, 3300, 4700])
Ungolfed
quelle
Javascript, 248 Bytes
Verwendung :
r(510, [100, 150, 220, 330, 470, 680, 1000, 1500, 2200, 3300, 4700]);
Ausgabe
quelle
Perl,
213199185 Bytes213 Bytes:
199 Bytes:
185 Bytes:
Übergeben Sie alle verfügbaren Widerstände als Argumente. Der Zielwiderstand sollte der letzte sein:
Wie es funktioniert (alter Code)
Unterprogramme definieren
S
undP
berechnen Sie die Summe und die Parallelität zweier Widerstände.Auf
$"
"," setzen, um@ARGV
innerhalb desglob
Operators 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///ee
mitgrep
, um die äquivalenten Widerstände zu bewerten und unerwünschte Wiederholungen (durchgeführt von(??{$2<$3})
und) herauszufiltern/\d$/
sort
von Fitness im Unterprogramm berechnett
Änderungen im neuen Code
Vermeiden Sie die Verwendung von
s///ee
, verwenden Sie kürzere reguläre Ausdrücke mit bedingter Prüfung und imeval
Innerengrep
Wiederholungen von
"{@i}" with
$ i` ersetzenEinführen
$x
,$y
statt$2
,$3
Ersetzen
split/=/,pop
durch$_[0]=~s!!!r
Kein Nachziehen nötig
;
eval;
ist äquivalent zueval $_;
Fügen Sie
=
zusammen miteval
-ed Antwort hinzu, anstatt es vorher zu deklarierenAusgabe:
P
repräsentiert Widerstände parallel,S
repräsentiert Widerstände in Reihe.quelle
S(100)=100
undS(1000)=1000
.