Résistances de valeur inhabituelle

23

introduction

Lors de la construction d'un projet électronique, un schéma peut nécessiter une résistance d'une valeur inhabituelle (disons, 510 ohms). Vous vérifiez votre bac de pièces et constatez que vous n'avez pas de résistances de 510 ohms. Mais vous avez de nombreuses valeurs communes au-dessus et en dessous de cette valeur. En combinant des résistances en parallèle et en série, vous devriez être en mesure d'approximer assez bien la résistance de 510 ohms.

Tâche

Vous devez écrire une fonction ou un programme qui accepte une liste de valeurs de résistance (résistances que vous stockez) et une valeur cible (que vous souhaitez approximer). Le programme doit considérer:

  • Résistances individuelles
  • Deux résistances en série
  • Deux résistances en parallèle

Le programme doit calculer toutes les combinaisons possibles de 1 et 2 résistances à partir de la liste de stock (y compris deux copies de la même valeur de résistance), calculer leur série et leur résistance parallèle, puis trier les configurations en fonction de leur approximation de la valeur cible.

Le format de sortie doit être une configuration par ligne, avec une +série |dénotant et dénotant parallèle, et un peu d'espace ou un signe = avant la résistance nette.

Formules

  • La résistance d'une résistance est R1
  • La résistance nette de deux résistances en série est R1 + R2
  • La résistance nette de deux résistances en parallèle est 1 / (1/R1 + 1/R2)
  • La distance entre une valeur approchée de la résistance et de la valeur cible peut être calculée comme distance de pseudo-logarithmique, non linéaire distance: dist = abs(Rapprox / Rtarget - 1). Par exemple, 200 est plus proche de 350 que de 100.
  • Une meilleure mesure de distance est la vraie distance logarithmique dist = abs(log(Rapprox/Rtarget)), mais comme cela n'était pas spécifié dans la question d'origine, vous êtes libre d'utiliser l'une ou l'autre mesure.

Notation

Le score est mesuré en caractères de code, selon les règles de golf habituelles. Le score le plus bas l'emporte.

Exemple

Nous avons les résistances suivantes en stock [100, 150, 220, 330, 470, 680, 1000, 1500, 2200, 3300, 4700]et souhaitons cibler les 510ohms. Le programme devrait produire 143 configurations, approximativement comme indiqué (vous pouvez changer le format, mais assurez-vous que la signification est facilement déterminée):

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.

Dans cet exemple, la meilleure approximation de 510 ohms est donnée par des résistances de 680 et 2200 ohms en parallèle.

Le meilleur de chaque langue jusqu'à présent (1er juin 2014):

  1. J - 70 car
  2. APL - 102 car.
  3. Mathematica - 122 caractères
  4. Rubis - 154 car.
  5. Javascript - 156 caractères
  6. Julia - 163 caractères
  7. Perl - 185 caractères
  8. Python - 270 caractères
phosgène
la source
3
@Claudiu Il n'y a pas de différence électrique entre 100 + 150 et 150 + 100; les deux produisent 250 ohms de résistance et consomment une résistance de 100 ohms et une résistance de 150 ohms, il ne faut donc pas compter deux fois. Cependant, ils doivent être distingués de 125 + 125, car bien que cela donne également 250 ohms, il consomme différentes résistances (ce qui peut être préférable, compte tenu de notre nombre de pièces).
phosgene
3
510 est dans la série E24 il est donc pas que rare d'avoir à portée de main
gnibbler
3
Phosgene, qu'en est-il des ROUV?
unclemeat
3
Je ne pense pas qu'ils existent.
phosgene
1
Nous ne fixons généralement pas de délais pour les questions de code de golf, car cela pourrait décourager certaines personnes de publier. Vous pouvez toujours modifier les réponses acceptées.
Nzall

Réponses:

6

J - 86 71 70 char

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

Je ne vais pas prendre la peine d'expliquer chaque petit détail car une grande partie du code est consacrée à la synchronisation des résultats de différentes fonctions, mais voici l'essentiel du golf:

  • ;@((<@,.{:)\) fabrique toutes les paires de résistances possibles, à connecter en parallèle ou en série.

  • [:,/(<,.+`|,.+/;+&.%/)"1@ puis les connecte, en parallèle et en série, faisant une grande liste de connexions possibles.

  • (;a:,<)"0, ajoute la possibilité d'utiliser une seule résistance par elle-même pour l'approximation.

  • (]/:[|@<:@%~2{::"1])trie la liste des combinaisons de résistances en fonction de la distance pseudologique ( |@<:@%) entre la cible et la résistance résultante de chaque combinaison.

Et voici comment l'utiliser:

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

Vous n'avez pas seulement à visualiser les 10 premiers comme je l'ai fait ci-dessus, mais c'est une fonction et le J REPL tronque de très grandes valeurs de retour, et la sortie complète de cet exemple a 287 lignes. Vous pouvez forcer le tout à STDOUT avec quelque chose comme tmoutput toCRLF , LF ,.~ ": blah rouv blahsous Windows - supprimez le toCRLFsous Linux - mais rouvc'est une fonction et en interne, toutes les lignes existent.

Remarque:

La question semble avoir été changée juste sous notre nez, et maintenant la distance du journal est définie comme abs(log(Rapprox/Rtarget))au lieu de abs(Rapprox/Rtarget-1). Pour corriger cela dans mon golf, nous pouvons changer le |@<:@%en |@^.@%: <:is Decrement while ^.is Logarithm.

algorithmshark
la source
Bien que votre code soit apparemment insondable, nous pouvons toujours apprécier le mystère. Meilleur score après une journée - ça va tenir?
phosgene
1
Non, je ne souhaite pas envoyer de mail à -. & A: @, @: {@ (({.;
Kilazur
12

Mathematica, 151 122 caractères

Attend que la résistance cible soit stockée ret la liste des résistances disponibles l.

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

Moins de golf:

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

Le format de sortie diffère de celui proposé, mais les configurations sont facilement déterminables. Le résultat est une liste de configurations. Chaque configuration se présente sous l'une des formes suivantes:

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

Ainsi, les trois premiers éléments de la sortie lus

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

Si vous êtes d'accord avec les nombres rationnels, je pourrais éviter l'omission de deux caractères N@. Autrement dit, le premier élément (par exemple) serait renvoyé comme 4675/9au lieu de 519.444.

Martin Ender
la source
Bon travail. Vous m'avez battu (et avec un code plus court).
DavidC
15
N'avez-vous pas # votre den # est # w @ rn vous @ g @ ins # e @ # ing # h @ # beaucoup syn # @ c # ic sug @ r?
phosgene
2
@ N @ l Tuples? Est-ce une sorte de maladie des programmeurs?
clabacchio
@clabacchio incroyable, je n'ai même pas vu ça. phosgene, il doit avoir oublié de le mentionner ... ou peut-être qu'il aime juste jouer au golf aussi ...
Martin Ender
10

APL (102)

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

Cela prend la résistance cible comme argument de gauche et une liste des résistances disponibles comme argument de droite.

Explication:

  • V←{... }: Vest une fonction qui:
    • Z/⍨≤/¨Z←,∘.,⍨⍵: trouve chaque combinaison unique de deux valeurs dans ,
      • Z←,∘.,⍨⍵: joindre chaque valeur à chaque valeur dans , stocker dans Z,
      • Z/⍨≤/¨Z: sélectionner parmi Zles combinaisons où la première valeur est inférieure ou égale à la deuxième valeur
    • ⍺{... }⍺⍺/¨: puis applique la fonction suivante, liée avec la fonction gauche ( ⍺⍺) à droite et l'argument gauche ( ) à gauche, à chaque paire:
      • ⍺,⍺⍺,⍵,'=',⍺⍵⍵⍵, l'argument gauche, suivi de l'argument lié à gauche, suivi de l'argument droit, suivi de =, suivi de la fonction droite ( ⍵⍵) appliquée aux deux arguments. (Il s'agit de la fonction de formatage,. X [configuration] Y [equals] (X [fn] Y))
    • ⊃¨: puis décompressez chaque élément.
  • {⍵,' =',⍵}¨⍵: pour chaque élément dans , faites les configurations pour les résistances individuelles. ( , Rien, rien, =, ).
  • ('+'+V⍵): utilisez la Vfonction pour faire toutes les configurations série (le caractère est '+'et la fonction est +).
  • '|'{÷+/÷⍺⍵}V⍵: utilisez la Vfonction pour faire toutes les configurations parallèles (le caractère est '|'et la fonction est {÷+/÷⍺⍵}, inverse de la somme des inverses des arguments).
  • K←↑: en faire une matrice et la stocker K.
  • 0 4↓K: supprimez les 4 premières colonnes de K, ne laissant que les valeurs de résistance.
  • |¯1+⍺÷⍨: calcule la distance entre chaque configuration.
  • K[⍋... ;]: trier Kpar les distances.
marinus
la source
3
Je vais croire que cela fonctionne. Mon clavier manque un peu de ces caractères: D
phosgene
@phosgene: Si vous voulez le tester, vous pouvez télécharger une version d'essai de Dyalog APL sur dyalog.com. Ensuite, collez le tout, cela devrait fonctionner. Les arguments vont sur les côtés, donc par exemple:510 code_here 100, 150, 220, 330, 470, 680, 1000, 1500, 2200, 3300, 4700
marinus
@phosgene Vous pouvez essayer cet interpréteur en ligne, bien qu'il ne fournisse pas la sortie complète, vous pouvez vérifier que les quelques lignes de départ et les dernières lignes sont identiques.
user12205
Vérifié! APL est un truc ésotérique.
phosgene
1
@ace TryAPL est très limité et ne fonctionne généralement pas. Que cela arrive de travailler sur celui-ci n'est qu'une coïncidence. Il ne prend pas en charge eval ( ), I / O ( ), ni aucune variable système (même ⎕UCSet ⎕Ane fonctionne pas), donc la plupart des programmes APL ne s'exécuteront pas. Il donnera en fait une ERREUR SYNTAXE si l'une des fonctions désactivées est utilisée. Le fait que celle-ci n'utilise pas l'une des nombreuses fonctions que TryAPL ne prend pas en charge est une coïncidence.
marinus
4

Python 3 - 250 247 270 octets

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)

Courez comme ceci:

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

(c'est-à-dire une liste de résistances délimitées par des espaces, avec la valeur cible à la fin)

Sortie:

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

Je dirais que la sortie, disons, 680|2200et2200|680 séparément est encore assez claire. Si cela est inacceptable, je peux le changer, mais cela me coûtera des octets.Ce n'était pas acceptable. Me coûte des octets. Maintenant, je trie les tuples avant de les insérer dans l'ensemble, sinon la solution est identique.

métro monorail
la source
Bien sûr, la sortie me semble très claire!
phosgene
Cependant, vous doublez les choses. 150 + 330 est électriquement identique à 330 + 150, donc une seule d'entre elles devrait apparaître dans le résultat (143 configurations totales pour l'exemple).
phosgene
@pho D'accord, fixe. Quelques octets supplémentaires mais la solution devrait être valide maintenant.
métro
Je pense aussi que votre programme ne recherche pas du tout une seule résistance (a + = [(a, a) pour a in r]). Vous pouvez ignorer a = ... car vous utilisez une seule fois. À ce sujet import sys;r=sys.args[1:], utilisez r=input().split()et dites que vous devez donner les valeurs sur stdin. Enfin: vous utilisez 1/sum(1/int(n)for n in b)au lieu de 1/sum(map(lambda n:1/int(n),b). Somme toute, cela devrait être 274 caractères
Somme WorldSEnder
Je viens de jouer au golf avec 1 autre caractère: utilisez print (* sorted (...), sep = '\ n')
WorldSEnder
3

Ruby 2.1, 156 154 octets

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]}"}}

Non golfé:

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]}"
  }
}

Ce qu'il fait:

  • Pour chaque valeur edans a;
    • Itérer à travers a, calculer des valeurs simples, en série et parallèles comme clés des valeurs imprimées dans le hachage c;
  • Déterminez la distance de zchaque entrée c; et,
  • Pour chaque valeur e[1] pour chaque clé e[0]dans c, imprimer e[1]=e[0].

Exemple d'utilisation:

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

Exemple de sortie:

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
Josh
la source
3

JavaScript (ECMAScript 6) - 186 caractères

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

Contribution:

  • Une gamme Rde résistances; et
  • T, la résistance cible.

Sortie:

Un tableau de tableaux (triés par distance de T) contenant chacun:

  • la valeur de la plus petite résistance;
  • la valeur la plus élevée de la résistance (ou 0 s'il s'agit d'une résistance solitaire);
  • p, sou 0 si les résistances sont en parallèle, en série ou solitaires; et
  • la résistance nette.

Explication:

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.
)
MT0
la source
Résistance unique manquante (la sortie len par exemple l'entrée est 132 au lieu de 143). J'aimerais emprunter l'astuce Array Comprehension, si je pouvais simplement comprendre ...
edc65
Ah, j'ai oublié les résistances solitaires
MT0
3

Julia - 179 163 octets

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)),:]))

Cela fonctionne de la même manière que l'ancienne version, mais l'argument de l'instruction print a été organisé légèrement différemment pour réduire le nombre de crochets nécessaires. Enregistre 4 octets. L'absorption de la création du vecteur d'espaces dans l'argument d'impression permet d'économiser 2 octets supplémentaires. Il est également passé de l'utilisation de "find" pour obtenir les indices pertinents à l'utilisation de la forme logique. Enregistre 6 octets. L'absorption du calcul du vecteur d'index dans l'ajustement de A a permis d'économiser encore 2 octets. Enfin, le remplacement de endof (v) par sum (v) a permis d'économiser 2 octets supplémentaires. Économie totale: 16 octets.

Ancienne 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)),:]))

Dans la fonction, voici ce qu'elle fait:

\ =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

Exemple de sortie:

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
Glen O
la source
Agréable! Je ne vois pas beaucoup de soumissions Julia - est-ce qu'il gagne en popularité?
phosgene
@phosgene - J'espère que oui; Je les soumets principalement parce qu'ils me donnent une expérience supplémentaire avec la langue.
Glen O
2

Javascript (E6) 156 162 164 186

Dernière modification En supposant que toutes les valeurs de résistance> 0, vous pouvez les utiliser pour la condition de boucle

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

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

Non golfé

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))
}
edc65
la source
1
Doit pousser (score, plus bas)!
phosgene
La dernière fois que j'ai vérifié, toutes mes résistances avaient une valeur positive. Je pense que c'est une hypothèse sûre.
phosgene
1

Javascript, 248 octets

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

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

Sortie

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

(...such rows...)

2200+4700=6900
3300+4700=8000
4700+4700=9400
Goûter
la source
0

Perl, 213 199 185 octets

213 octets:

$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 octets:

$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 octets:

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

Passez toutes les résistances disponibles comme arguments. La résistance cible doit être la dernière:

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

Comment ça marche (ancien code)

  • Définissez des sous S- programmes et Pcalculez la somme et les valeurs parallèles de deux résistances.

  • Réglez $"sur "," pour interpoler @ARGVà l'intérieur de l' globopérateur

  • <{S,P}({@i},{@i})= S({@i})=> génère un cartésien de toutes les possibilités:

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

  • Combinez s///eeavec greppour évaluer les résistances équivalentes et filtrer les répétitions indésirables (effectuées par (??{$2<$3})et/\d$/

  • sort par fitness calculé dans le sous-programme t

Changements dans le nouveau code

  • Évitez l'utilisation de s///ee, utilisez des expressions rationnelles plus courtes avec vérification conditionnelle et à l' evalintérieurgrep

  • Remplacer les répétitions de "{@i}" with $ i`

  • Présentez $x, $yau lieu de $2,$3

  • Remplacez split/=/,poppar$_[0]=~s!!!r

  • Pas besoin de suivre ;

  • eval; est équivalent à eval $_;

  • Ajouter =avec la evalréponse -ed au lieu de la déclarer d'avance

Sortie:

Preprésente des résistances en parallèle, Sreprésente des résistances en série.

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
Zaid
la source
Les deux lignes manquantes sont S(100)=100et S(1000)=1000.
algorithmshark
@algorithmshark: Ouaip, j'ai compris. Le regex les consommait par inadvertance
Zaid
Il sera intéressant de voir si quelqu'un peut proposer une solution Perl plus courte.
Zaid