Olağandışı Değer Dirençleri


23

Giriş

Bir elektronik proje inşa ederken, şematik olağandışı bir değere direnç gösterebilir (örneğin, 510 ohm). Parça kutunuzu kontrol edin ve 510 ohm'luk direnç olmadığını görün. Ancak bu değerin üstünde ve altında birçok ortak değeriniz var. Dirençleri paralel ve seri olarak birleştirerek, 510-ohm'luk direnci oldukça iyi bir şekilde değerlendirebilmelisiniz.

Görev

Bir direnç değerleri listesi (stokladığınız dirençler) ve bir hedef değer (yaklaşık olarak hedeflediğiniz) kabul eden bir işlev veya program yazmalısınız. Program şunları göz önünde bulundurmalıdır:

  • Bireysel dirençler
  • Seri halinde iki direnç
  • Paralel olarak iki direnç

Program, stok listesinden 1 ve 2 dirençlerin tüm olası kombinasyonlarını hesaplamalı (aynı direnç değerinin iki kopyası dahil), seri ve paralel direncini hesaplamalı ve sonra konfigürasyonları hedef değerine ne kadar yaklaştığına göre sıralamalıdır.

Çıktı formatı her satırda bir konfigürasyon olmalı, bir +ifade dizisi ve |paralel ifade ile bir miktar boşluk olmalı veya net dirençten önce bir boşluk veya bir = işareti olmalıdır.

Formüller

  • Bir rezistansın direnci R1
  • Serideki iki rezistansın net direnci R1 + R2
  • Paralel olarak iki rezistansın net direnci 1 / (1/R1 + 1/R2)
  • Bir yakınsanan direnç değeri ve hedef değer arasındaki mesafenin mesafe doğrusal, psödo-logaritmik mesafe olarak hesaplanabilir: dist = abs(Rapprox / Rtarget - 1). Örneğin, 200, 350'ye, 100'den daha yakındır.
  • Daha iyi bir uzaklık ölçüsü gerçek logaritmik uzaklıktır dist = abs(log(Rapprox/Rtarget)), ancak orijinal soruda belirtilmediğinden, her iki ölçümü de kullanabilirsiniz.

puanlama

Skor her zamanki golf kurallarına göre kod karakterleriyle ölçülür. En düşük puan kazanır.

Örnek

Aşağıdaki dirençler stoklarımızda mevcuttur [100, 150, 220, 330, 470, 680, 1000, 1500, 2200, 3300, 4700]ve 510ohmları hedef almak istiyoruz . Program yaklaşık gösterildiği gibi 143 yapılandırma çıkarmalıdır (formatı değiştirebilirsiniz, ancak anlamın kolayca belirlendiğinden emin olun):

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.

Bu örnekte, en iyi 510 ohm yaklaşımı paralel olarak 680 ve 2200 ohm dirençlerle verilmiştir.

Şimdiye kadar her dilin en iyisi (1 Haziran 2014):

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

3
@Claudiu 100 + 150 ile 150 + 100 arasında elektriksel olarak bir fark yoktur; her ikisi de 250 ohm'luk direnç verir ve 100 ohm'luk bir direnç ve 150 ohm'luk bir direnç kullanır, bu yüzden iki kat saymamalıyız. Bununla birlikte, 125 + 125'ten ayırt edilmeleri gerekir, çünkü bu 250 ohm da vermesine rağmen, farklı dirençler tüketir (bizim parça sayımıza göre tercih edilebilir).
fosjen

3
510 E24 serisinde, bu yüzden elinizde olması alışılmadık bir durum değil
gnibbler

3
Fosgen, peki ya ROUV'lar?
unclemeat

3
Var olduklarını sanmıyorum.
fosgen

1
Kod golf soruları için genellikle son tarihler koymuyoruz, çünkü bazı kişilerin göndermelerini engelleyebilir. Kabul edilen cevapları her zaman değiştirebilirsiniz.
Nzall

Yanıtlar:


6

J - 86 71 70 karakter

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

Her küçük ayrıntıyı açıklamak için can atmayacağım çünkü kodun çoğu farklı işlevlerin sonuçlarını senkronize etmek için harcanıyor, ancak işte golfün özü:

  • ;@((<@,.{:)\) mümkün olan her direnç çiftini paralel veya seri olarak bağlanmasını sağlar.

  • [:,/(<,.+`|,.+/;+&.%/)"1@ daha sonra bunları paralel, seri ve olası bağlantıların büyük bir listesini yaparak bağlar.

  • (;a:,<)"0, yaklaşık olarak kendi başına sadece bir direnç kullanma olasılığını ekler.

  • (]/:[|@<:@%~2{::"1])direnç kombinasyonlarının listesini |@<:@%, hedef ve her kombinasyondan elde edilen direnç arasındaki psödolog mesafeye ( ) göre sıralar .

Ve bu nasıl kullanılacağı:

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

Sadece ilk 10'u gördüğüm gibi görüntülemek zorunda değilsin, ama bu bir fonksiyon ve J REPL çok büyük dönüş değerlerini kesiyor ve bu örnek için tam çıktının 287 satırı var. Hepsini tmoutput toCRLF , LF ,.~ ": blah rouv blahWindows'taki gibi bir şeyle STDOUT'a zorlayabilirsiniz - toCRLFLinux'ta bırakın - ancak rouvbir fonksiyondur ve dahili olarak tüm satırlar mevcuttur.

Not:

Soru burunlarımızın tam altında değişmiş gibi görünüyor ve şimdi kütük mesafesi abs(log(Rapprox/Rtarget))bunun yerine olarak tanımlanıyor abs(Rapprox/Rtarget-1). Benim golf Bunu düzeltmek için, biz değiştirebilirsiniz |@<:@%için |@^.@%: <:iken Azaltma olan ^.Logaritma olduğunu.


Kodunuz görünüşte anlaşılmaz gibi görünse de, gizemi hala takdir edebiliriz. Bir günden sonra en iyi skor - duracak mı?
fosjen

1
Hayır, -. & A: @, @: {@ (({.;
Kilazur

12

Mathematica, 151 122 karakter

Hedef direnci rve içinde mevcut dirençlerin listesini bekler l.

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

Daha az golf:

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

Çıkış formatı önerilen formattan farklı, ancak yapılandırmalar kolayca belirlenebilir. Çıktı bir yapılandırma listesidir. Her yapılandırma aşağıdaki formlardan biridir:

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

Böylece çıktının ilk üç elemanı okunur.

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

Eğer rasyonel sayılarla iyiyseniz, iki karakteri ihmal etmekten kurtarabilirim N@. Yani, ilk eleman (örneğin) 4675/9yerine döndürülecekti 519.444.


İyi iş. Beni yenersin (ve daha kısa kodla).
DavidC,

15
# # Den # is # w @ rn you @ g @ ins # e @ # ing # h @ # çok syn # @ c # ic sug @ r?
fosgen

2
@ N @ l Tuples? Bu bir çeşit programcının hastalığı mı?
clabacchio

@clabacchio amazing, bunu görmedim bile. fosgen, bundan bahsetmeyi unutmuş olmalı ... ya da belki sadece golf oynamayı da seviyor ...
Martin Ender

10

APL (102)

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

Bu, hedef direnci sol argüman olarak ve kullanılabilir dirençlerin bir listesini doğru argüman olarak alır.

Açıklama:

  • V←{... }: Bu Vbir fonksiyondur:
    • Z/⍨≤/¨Z←,∘.,⍨⍵: İki değerin her benzersiz bir kombinasyonunu bulur ,
      • Z←,∘.,⍨⍵: her bir değerin her bir değerin içinde , depoda Z,
      • Z/⍨≤/¨Z: Zilk değerin ikinci değerden küçük veya ona eşit olduğu kombinasyonlardan birini seçin
    • ⍺{... }⍺⍺/¨: ve ardından aşağıdaki işlevi uygular ⍺⍺, sağdaki sol işlevle ( ) ve soldaki bağımsız değişkenle ( ) her çift için geçerlidir:
      • ⍺,⍺⍺,⍵,'=',⍺⍵⍵⍵sol argüman, ardından sol sınır argümanı, ardından sağ argüman, ardından iki argümana uygulanan =sağ işlev ( ⍵⍵) takip eder . (Bu biçimlendirme işlevidir X [configuration] Y [equals] (X [fn] Y).)
    • ⊃¨: ve sonra her bir öğenin kutusunun işaretini kaldır
  • {⍵,' =',⍵}¨⍵: içindeki her eleman için ayrı ayrı dirençler için konfigürasyonları yapın. ( , hiçbir şey, hiçbir şey =, ).
  • ('+'+V⍵): VTüm seri konfigürasyonları yapmak için fonksiyonu kullanın (karakter '+'ve fonksiyon +).
  • '|'{÷+/÷⍺⍵}V⍵: Vtüm paralel konfigürasyonları yapmak için fonksiyonu kullanın (karakter '|'ve fonksiyon, {÷+/÷⍺⍵}argümanların tersinin toplamıdır).
  • K←↑: bunu bir matrise dönüştürün ve saklayın K.
  • 0 4↓K: ilk 4 sütunu Kbırakarak yalnızca direnç değerlerini bırakın .
  • |¯1+⍺÷⍨: Her bir konfigürasyon arasındaki mesafeyi hesapla .
  • K[⍋... ;]: Kmesafelere göre sırala .

3
İşe yaradığını söyleyeceğim.
phosgene

@ phosgene: Eğer test etmek istiyorsanız, dyalog.com adresinden Dyalog APL'nin deneme sürümünü indirebilirsiniz. Sonra her şeyi yapıştırın, çalışması gerekir. Argümanlar iki taraftan da devam eder, örneğin:510 code_here 100, 150, 220, 330, 470, 680, 1000, 1500, 2200, 3300, 4700
marinus

@ phosgene Bu çevrimiçi tercümanı deneyebilirsiniz , bunun tam çıktısını sağlamamasına rağmen, başlangıçtaki birkaç satırın ve son birkaç satırın aynı olduğunu doğrulayabilirsiniz.
user12205

Doğrulanmış! APL bazı ezoterik şeylerdir.
fosjen

1
@ace TryAPL çok sınırlı ve genellikle çalışmıyor. Bunun üzerinde çalışmak olur sadece bir tesadüf. O desteklemediği eval ( ), I / O ( ) veya (hatta herhangi bir sistem değişkenleri ⎕UCSve ⎕Ayapamaz iş) bu yüzden çoğu APL programları yayınlanmaz. Devre dışı bırakılmış işlevlerden biri kullanılıyorsa , aslında bir SYNTAX ERROR verecektir . Bunun, TryAPL'in desteklemediği birçok fonksiyondan birini kullanmaması gerçeği bir tesadüf.
marinus '

4

Python 3 - 250 247 270 bayt

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)

Bu şekilde koş:

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

(yani, sonunda ayrılmış hedef değere sahip, boşlukla ayrılmış bir direnç listesi.)

Çıktı:

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

Çıktı, ayrı 680|2200ve 2200|680ayrı olarak hala oldukça açık olduğunu söyleyebilirim . Bu kabul edilemez ise, değiştirebilirim, ancak bana baytlık mal olacak.Kabul edilebilir değildi. Bana mal oldu. Şimdi, kümeleri bağlamadan önce dişleri sıralarım, aksi halde çözüm özdeştir.


Tabii, çıktı bana çok net görünüyor!
fosgen

Ancak, şeyleri çift sayıyorsunuz. 150 + 330 elektriksel olarak 330 + 150 ile aynıdır, bu nedenle sonuçlardan sadece bir tanesi görünmelidir (örneğin toplam 143 yapılandırma).
fosgen

@ pho Tamam, düzeltildi. Birkaç ekstra bayt, ancak çözüm şimdi geçerli olmalıdır.
yeraltımonorail

Ayrıca, programınızın tek bir direnç aramamış olduğunu düşünüyorum, (a] için bir (a + = [(a, a))). Tam olarak bir kez kullandığınızda = = atlayabilirsiniz. Bu konuda import sys;r=sys.args[1:]kullanıp r=input().split()stdin'deki değerleri vermeniz gerektiğini söyleyin. Sonunda: 1/sum(1/int(n)for n in b)yerine kullanın 1/sum(map(lambda n:1/int(n),b). Sonuçta, bu 274 karakter olmalı
WorldSEnder

Sadece 1 karakter daha golf oynadım: Kullanın (* (()), sep = '\ n'
dizisini kullanın

3

Yakut 2.1, 156 154 bayt

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

Bu ne yapar:

  • İçindeki her değer eiçin a;
    • aKarma c, basılan değerlerin anahtarları olarak tek, seri ve paralel değerleri hesaplayarak yineleyin ;
  • İçindeki zher anahtar için mesafeyi belirleyin c; ve,
  • Her değer için e[1] her anahtar için e[0]de c, baskı e[1]=e[0].

Örnek kullanım:

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

Örnek çıktı:

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 Karakterler

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

Giriş:

  • Bir dizi R direnç gücü; ve
  • T, hedef direnç.

Çıktı:

THer birini içeren bir dizi dizisi (mesafelere göre sıralanır ):

  • daha küçük direnç değeri;
  • daha yüksek direnç değeri (veya yalnız bir direnç ise 0);
  • p, s Ya da 0 direnç paralel ise, seri ya da tek başına; ve
  • net direnç.

Açıklama:

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

Tek direnç eksik (örneğin çıkış girişi 143 yerine 132.) Dizi Anlama hilesini ödünç almak isterim, eğer anlayabilirsem ...
edc65

Ah, yalnız dirençler unuttum
MT0

3

Julia - 179 163 bayt

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

Bu, eski sürümle aynı şekilde çalışır, ancak print ifadesindeki argüman, gereken köşeli parantez sayısını azaltmak için biraz farklı şekilde düzenlenmiştir. 4 bayt kaydeder. Boşluklar vektör oluşturma işleminin baskı argümanına alınması, fazladan 2 bayt kazandırır. Aynı zamanda, mantıksal formu kullanmaya ilişkin endeksleri elde etmek için "find" komutunu kullanmaktan da geçmiştir. 6 bayt kaydeder. İndeks vektörünün hesaplanmasının A ayarına alınması, 2 byte daha kaydedilmiştir. Son olarak, (v) uçunun toplamla (v) değiştirilmesi, 2 bayt daha kurtardı. Toplam tasarruf: 16 bayt.

Eski versiyon:

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

İşlev içinde, işte yaptığı şey:

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

Örnek çıktı:

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

Güzel! Birçok Julia gönderimi görmüyor musunuz - popülaritesi artıyor mu?
fosgen

Phosgene - Umarım öyledir; Bunları daha çok gönderiyorum çünkü bana dille ilgili ekstra bir deneyim veriyorlar.
Glen O

2

Javascript (E6) 156 162 164 186

Son Düzenleme Tüm direnç değerleri> 0 olduğunda, bunları döngü koşulu için kullanabilirsiniz.

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

Kullanım: 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
İtmeli (puan, daha düşük)!
fosgen

Son kontrol ettiğimde tüm dirençlerim pozitif olarak değerlendi. Bence güvenli bir varsayım.
fosgen

1

Javascript, 248 bayt

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

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

Çıktı

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 bayt

213 bayt:

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

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

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

Mevcut tüm dirençleri argüman olarak iletin. Hedef direnç son olmalı:

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

Nasıl çalışır (eski kod)

  • Alt yordamları tanımlayın Sve Piki rezistörün toplamını ve paralel değerlerini hesaplayın.

  • Operatörün içine $"enterpolasyon yapmak için "," olarak ayarlayın@ARGVglob

  • <{S,P}({@i},{@i})= S({@i})=> Tüm olasılıkların bir kartezyen üretir:

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

  • Eşdeğer rezistansları değerlendirmek ve istenmeyen tekrarları filtrelemek için s///eeile birleştirin grep( (??{$2<$3})ve/\d$/

  • sort alt programda hesaplanan fitness ile t

Yeni koddaki değişiklikler

  • Kullanımdan kaçının s///ee, şartlı kontrol ve evaliçeride daha kısa regex kullanın.grep

  • "{@i}" with$ İ` tekrarlarını değiştirin

  • Tanıtılması $x, $yyerine $2,$3

  • Değiştir split/=/,popile$_[0]=~s!!!r

  • Takip gerek yok ;

  • eval; eşittir eval $_;

  • Önceden bildirmek yerine -ed =ile birlikte ekleyineval

Çıktı:

Pdirençleri paralel olarak, Sdirençleri seri olarak temsil eder.

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

Eksik iki satır S(100)=100ve S(1000)=1000.
algoritmshark

@algorithmshark: Yup, anladım. Regex istemeden onları tüketiyordu
Zaid

Daha kısa bir Perl çözümü bulabilecek birini görmek ilginç olacak.
Zaid
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.