Resistor dengan Nilai Tidak Biasa


23

pengantar

Ketika membangun sebuah proyek elektronik, sebuah skema mungkin memerlukan resistor dengan nilai yang tidak biasa (katakanlah, 510 ohm). Anda memeriksa nampan bagian Anda dan menemukan bahwa Anda tidak memiliki resistor 510-ohm. Tetapi Anda memiliki banyak nilai umum di atas dan di bawah nilai ini. Dengan menggabungkan resistor secara paralel dan seri, Anda harus dapat memperkirakan resistor 510-ohm dengan cukup baik.

Tugas

Anda harus menulis fungsi atau program yang menerima daftar nilai-nilai resistor (resistor yang Anda stok) dan nilai target (yang Anda perkirakan merupakan perkiraan). Program harus mempertimbangkan:

  • Resistor individu
  • Dua resistor secara seri
  • Dua resistor secara paralel

Program harus menghitung semua kombinasi yang mungkin dari resistor 1 dan 2 dari daftar stok (termasuk dua salinan dari nilai resistor yang sama), menghitung hambatan seri dan paralelnya, kemudian mengurutkan konfigurasi berdasarkan seberapa baik mereka memperkirakan nilai target.

Format output harus berupa satu konfigurasi per baris, dengan +seri yang |menunjukkan dan paralel yang menunjukkan, dan beberapa spasi atau tanda = sebelum resistansi bersih.

Formula

  • Resistansi satu resistor adalah R1
  • Resistansi bersih dari dua resistor secara seri adalah R1 + R2
  • Resistansi bersih dua resistor secara paralel adalah 1 / (1/R1 + 1/R2)
  • Jarak antara nilai resistansi didekati dan nilai target dapat dihitung sebagai jarak pseudo-logaritmik, tidak linear jarak: dist = abs(Rapprox / Rtarget - 1). Misalnya, 200 lebih dekat ke 350 daripada ke 100.
  • Ukuran jarak yang lebih baik adalah jarak logaritmik yang sebenarnya dist = abs(log(Rapprox/Rtarget)), tetapi karena ini tidak ditentukan dalam pertanyaan asli, Anda bebas untuk menggunakan pengukuran mana pun.

Mencetak gol

Skor diukur dalam karakter kode, per aturan golf biasa. Skor terendah menang.

Contoh

Kami memiliki resistor berikut dalam stok [100, 150, 220, 330, 470, 680, 1000, 1500, 2200, 3300, 4700]dan ingin menargetkan 510ohm. Program harus menghasilkan 143 konfigurasi, kira-kira seperti yang ditunjukkan (Anda dapat mengubah format, tetapi pastikan artinya mudah ditentukan):

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.

Dalam contoh ini, perkiraan terbaik 510 ohm diberikan oleh resistor 680- dan 2200-ohm secara paralel.

Terbaik dari setiap bahasa sejauh ini (1 Juni 2014):

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

3
@Claudiu Tidak ada perbedaan elektrik antara 100 + 150 dan 150 + 100; keduanya menghasilkan 250 ohm resistensi dan mengkonsumsi resistor 100-ohm dan resistor 150-ohm, jadi kita tidak boleh menghitung ganda. Namun, mereka harus dibedakan dari 125 + 125, karena meskipun ini juga menghasilkan 250 ohm, ia menggunakan resistor yang berbeda (yang mungkin lebih disukai, mengingat jumlah komponen kami).
phosgene

3
510 adalah di seri E24 sehingga tidak yang biasa untuk memiliki di tangan
gnibbler

3
Phosgene, bagaimana dengan ROUV?
hapus tanda

3
Saya tidak berpikir mereka ada.
phosgene

1
Kami biasanya tidak menetapkan tenggat waktu untuk pertanyaan golf kode, karena mungkin akan membuat beberapa orang enggan untuk memposting. Anda selalu dapat mengubah jawaban yang diterima.
Nzall

Jawaban:


6

J - 86 71 70 char

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

Saya tidak akan repot-repot menjelaskan setiap detail kecil karena banyak kode dihabiskan untuk menyinkronkan hasil dari fungsi yang berbeda, tapi inilah inti dari golf:

  • ;@((<@,.{:)\) memungkinkan setiap pasangan resistor, untuk dihubungkan baik secara paralel maupun seri.

  • [:,/(<,.+`|,.+/;+&.%/)"1@ kemudian menghubungkannya, secara paralel dan seri, membuat daftar besar kemungkinan koneksi.

  • (;a:,<)"0, menambahkan kemungkinan menggunakan hanya satu resistor dengan sendirinya untuk perkiraan.

  • (]/:[|@<:@%~2{::"1])mengurutkan daftar kombinasi resistor dengan jarak pseudolog ( |@<:@%) antara target dan resistansi yang dihasilkan dari setiap kombinasi.

Dan inilah cara menggunakannya:

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

Anda tidak hanya harus melihat 10 pertama seperti yang saya lakukan di atas, tetapi ini adalah fungsi dan J REPL memotong nilai pengembalian yang sangat besar, dan output penuh untuk contoh ini memiliki 287 baris. Anda dapat memaksakan semuanya untuk STDOUT dengan sesuatu seperti tmoutput toCRLF , LF ,.~ ": blah rouv blahpada Windows — jatuhkan toCRLFpada Linux — tetapi rouvmerupakan fungsi dan secara internal, semua baris ada.

catatan:

Pertanyaannya sepertinya telah diubah tepat di bawah hidung kita, dan sekarang jarak log didefinisikan sebagai abs(log(Rapprox/Rtarget))bukan abs(Rapprox/Rtarget-1). Untuk memperbaikinya di golf saya, kita dapat mengubah |@<:@%to |@^.@%: <:is Decrement while ^.is Logarithm.


Meskipun kode Anda tampaknya tidak terduga, kami masih dapat menghargai misterinya. Skor terbaik setelah satu hari - apakah akan bertahan?
phosgene

1
Tidak, saya tidak ingin mengirim email ke -. & A: @, @: {@ (({.;
Kilazur

12

Mathematica, 151 122 karakter

Mengharapkan resistansi target untuk disimpan rdan daftar resistor yang tersedia di l.

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

Lebih sedikit golf:

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

Format output berbeda dari yang disarankan tetapi konfigurasi mudah ditentukan. Outputnya adalah daftar konfigurasi. Setiap konfigurasi adalah salah satu dari bentuk berikut:

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

Jadi tiga elemen pertama dari keluaran dibaca

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

Jika Anda baik-baik saja dengan angka rasional, saya dapat menyimpan dua karakter dari menghilangkan N@. Artinya, elemen pertama (misalnya) akan dikembalikan sebagai 4675/9ganti 519.444.


Kerja bagus. Anda mengalahkan saya untuk itu (dan dengan kode yang lebih pendek).
DavidC

15
Tidak # sarangmu adalah # w @ rn kamu @ g @ ins # e @ # ing # h @ # banyak syn # @ c # ic sug @ r?
phosgene

2
@ N @ l Tuples? Apakah itu semacam penyakit pemrogram?
clabacchio

@clabacchio luar biasa, saya bahkan tidak melihat itu. Phosgene, dia pasti lupa menyebutkannya ... atau mungkin dia hanya suka bermain golf juga ...
Martin Ender

10

APL (102)

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

Ini mengambil target perlawanan sebagai argumen kiri dan daftar resistor yang tersedia sebagai argumen yang tepat.

Penjelasan:

  • V←{... }: Vadalah fungsi yang:
    • Z/⍨≤/¨Z←,∘.,⍨⍵: menemukan setiap kombinasi unik dari dua nilai di ,
      • Z←,∘.,⍨⍵: gabungkan setiap nilai dengan setiap nilai dalam , simpan dalam Z,
      • Z/⍨≤/¨Z: pilih dari Zkombinasi di mana nilai pertama kurang dari atau sama dengan nilai kedua
    • ⍺{... }⍺⍺/¨: dan kemudian menerapkan fungsi berikut, diikat dengan fungsi kiri ( ⍺⍺) di sebelah kanan dan argumen kiri ( ) di sebelah kiri, untuk setiap pasangan:
      • ⍺,⍺⍺,⍵,'=',⍺⍵⍵⍵, argumen kiri, diikuti oleh argumen terikat kiri, diikuti oleh argumen kanan, diikuti oleh =, diikuti oleh fungsi kanan ( ⍵⍵) diterapkan pada kedua argumen. (Ini adalah fungsi pemformatan X [configuration] Y [equals] (X [fn] Y),.)
    • ⊃¨: dan kemudian hapus kotak setiap elemen.
  • {⍵,' =',⍵}¨⍵: untuk setiap elemen , buat konfigurasi untuk masing-masing resistor. ( , tidak ada, tidak ada =,, ).
  • ('+'+V⍵): gunakan Vfungsi untuk membuat semua konfigurasi serial (karakter adalah '+'dan fungsi +).
  • '|'{÷+/÷⍺⍵}V⍵: gunakan Vfungsi untuk membuat semua konfigurasi paralel (karakter adalah '|'dan fungsinya adalah {÷+/÷⍺⍵}, kebalikan dari jumlah invers argumen).
  • K←↑: buat ini menjadi matriks dan simpan di K.
  • 0 4↓K: jatuhkan 4 kolom pertama dari K, hanya menyisakan nilai resistansi.
  • |¯1+⍺÷⍨: hitung jarak antara dan setiap konfigurasi.
  • K[⍋... ;]: urutkan Kberdasarkan jarak.

3
Saya akan mengambil kata Anda bahwa itu berhasil. Keyboard saya tidak banyak memiliki karakter berikut: D
phosgene

@ phosgene: Jika Anda ingin mengujinya, Anda dapat mengunduh versi percobaan Dyalog APL di dyalog.com. Maka cukup tempelkan semuanya, itu akan berhasil. Argumen-argumen beriringan, jadi misalnya:510 code_here 100, 150, 220, 330, 470, 680, 1000, 1500, 2200, 3300, 4700
marinus

@ phosgene Anda dapat mencoba juru bahasa online ini , meskipun tidak memberikan hasil lengkap, Anda dapat memverifikasi bahwa beberapa baris awal dan beberapa baris terakhir adalah sama.
user12205

Diverifikasi! APL adalah beberapa hal esoterik.
phosgene

1
@ace TryAPL sangat terbatas, dan biasanya tidak berfungsi. Bahwa kebetulan bekerja pada yang satu ini hanyalah kebetulan. Itu tidak mendukung eval ( ), I / O ( ), atau variabel sistem apa pun (bahkan ⎕UCSdan ⎕Atidak berfungsi) sehingga sebagian besar program APL tidak akan berjalan. Ini benar-benar akan memberikan SYNTAX ERROR jika salah satu fungsi yang dinonaktifkan digunakan. Fakta bahwa ini terjadi tidak menggunakan salah satu dari banyak fungsi yang tidak didukung TryAPL, adalah suatu kebetulan.
marinus

4

Python 3 - 250 247 270 byte

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)

Jalankan seperti ini:

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

(yaitu, daftar resistor yang dibatasi ruang, dengan nilai target di akhir)

Keluaran:

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

Saya akan mengatakan bahwa keluaran, katakan, 680|2200dan 2200|680secara terpisah masih cukup jelas. Jika ini tidak dapat diterima, saya dapat mengubahnya, tetapi akan dikenakan biaya byte.Tidak bisa diterima Biaya saya byte. Sekarang saya mengurutkan tuple sebelum melemparkannya ke set, jika tidak solusinya identik.


Tentu, output terlihat sangat jelas bagi saya!
phosgene

Namun, Anda menghitung dua hal. 150 + 330 identik secara elektrik dengan 330 + 150, jadi hanya satu di antaranya yang akan muncul di hasil (143 total konfigurasi sebagai contoh).
phosgene

@pho Oke, sudah diperbaiki. Beberapa byte tambahan tetapi solusinya harus valid sekarang.
undergroundmonorail

Juga saya pikir program Anda tidak mencari resistor tunggal, sama sekali (a + = [(a, a) untuk in r]). Anda dapat melewatkan = ... saat Anda menggunakan waktu yang tepat. Tentang ini import sys;r=sys.args[1:], gunakan r=input().split()dan katakan bahwa Anda harus memberikan nilai pada stdin. Akhirnya: Anda menggunakan 1/sum(1/int(n)for n in b)bukan 1/sum(map(lambda n:1/int(n),b). Semua dalam semua, itu harusnya 274 karakter
WorldSEnder

Saya baru saja
bermain golf

3

Ruby 2.1, 156 154 byte

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

Tidak Disatukan:

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

Apa fungsinya:

  • Untuk setiap nilai edalam a;
    • Iterate through a, komputasi nilai-nilai tunggal, seri, dan paralel sebagai kunci untuk nilai-nilai cetak dalam hash c;
  • Tentukan jarak dari zuntuk setiap kunci c; dan,
  • Untuk setiap nilai e[1]untuk setiap tombol e[0]di c, mencetak e[1]=e[0].

Penggunaan sampel:

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

Output sampel:

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 Karakter

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

Memasukkan:

  • Berbagai Rkekuatan resistor; dan
  • T, target perlawanan.

Keluaran:

Array array (diurutkan berdasarkan jarak dari T) masing-masing berisi:

  • nilai resistor yang lebih kecil;
  • nilai resistor yang lebih tinggi (atau 0 jika resistor soliter);
  • p, satau 0 jika resistor paralel, seri atau soliter; dan
  • resistansi bersih.

Penjelasan:

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

Resistor tunggal tidak ada (output len ​​misalnya input 132 daripada 143). Saya ingin meminjam trik Array Comprehension, jika saya bisa memahaminya ...
edc65

Ah, lupakan resistor soliter
MT0

3

Julia - 179 163 byte

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

Ini berfungsi sama dengan versi lama, tetapi argumen dalam pernyataan cetak telah diatur sedikit berbeda untuk mengurangi jumlah tanda kurung siku yang diperlukan. Menghemat 4 byte Menyerap penciptaan vektor spasi ke dalam argumen cetak menghemat 2 byte tambahan. Itu juga telah beralih dari menggunakan "menemukan" untuk mendapatkan indeks yang relevan untuk menggunakan bentuk logis. Menghemat 6 byte. Menyerap perhitungan vektor indeks ke dalam penyesuaian A disimpan 2 byte lagi. Akhirnya, mengganti endof (v) dengan jumlah (v) disimpan 2 byte lebih. Total penghematan: 16 byte.

Versi lama:

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

Dalam fungsi, inilah yang dilakukannya:

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

Output sampel:

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

Bagus! Tidak melihat banyak kiriman Julia - apakah ini semakin populer?
phosgene

@ phosgene - Saya harap itu; Saya kebanyakan mengirimkan ini karena mereka memberi saya pengalaman ekstra dengan bahasa.
Glen O

2

Javascript (E6) 156 162 164 186

Edit Terakhir Dengan asumsi semua nilai resistor> 0, Anda dapat menggunakannya untuk kondisi loop

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

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

Tidak disatukan

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
Harus dorong (skor, lebih rendah)!
phosgene

Terakhir saya periksa, semua resistor saya bernilai positif. Saya pikir itu asumsi yang aman.
phosgene

1

Javascript, 248 byte

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

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

Keluaran

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 byte

213 byte:

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

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

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

Lewati semua resistor yang tersedia sebagai argumen. Target perlawanan harus menjadi yang terakhir:

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

Bagaimana cara kerjanya (kode lama)

  • Tentukan subrutin Sdan Puntuk menghitung nilai penjumlahan dan paralel dari dua resistor.

  • Setel $"ke "," untuk menginterpolasi@ARGV di dalam globoperator

  • <{S,P}({@i},{@i})= S({@i})=> menghasilkan cartesian dari semua kemungkinan:

    S (100.100), S (100.150), S (100.220), ... P (100.100), P (100.150) ... S (100), S (150) ...

  • Gabungkan s///eedengan grepuntuk mengevaluasi resistensi yang setara dan menyaring pengulangan yang tidak diinginkan (dilakukan oleh(??{$2<$3}) dan/\d$/

  • sort oleh kebugaran dihitung dalam subrutin t

Perubahan kode baru

  • Hindari penggunaan s///ee, gunakan regex yang lebih pendek dengan pemeriksaan bersyarat daneval di dalamgrep

  • Ganti pengulangan dari "{@i}" with $ i`

  • Perkenalkan $x, $yalih-alih$2 ,$3

  • Menggantikan split/=/,pop dengan$_[0]=~s!!!r

  • Tidak perlu untuk tertinggal ;

  • eval; setara dengan eval $_;

  • Tambahkan =bersamaeval -ed jawaban alih-alih mendeklarasikannya di depan

Keluaran:

Pmewakili resistor secara paralel, Smewakili resistor secara seri.

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

Dua baris yang hilang adalah S(100)=100dan S(1000)=1000.
algoritme

@algorithmshark: Yup, mengerti. Regex secara tidak sengaja mengkonsumsinya
Zaid

Ini akan menarik untuk melihat apakah ada yang bisa datang dengan solusi Perl lebih pendek.
Zaid
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.