Điện trở của giá trị bất thường


23

Giới thiệu

Khi xây dựng một dự án điện tử, một sơ đồ có thể gọi một điện trở có giá trị bất thường (giả sử, 510 ohms). Bạn kiểm tra thùng các bộ phận của mình và thấy rằng bạn không có điện trở 510-ohm. Nhưng bạn có nhiều giá trị phổ biến ở trên và dưới giá trị này. Bằng cách kết hợp các điện trở song song và nối tiếp, bạn sẽ có thể xấp xỉ điện trở 510-ohm khá tốt.

Bài tập

Bạn phải viết một hàm hoặc chương trình chấp nhận danh sách các giá trị điện trở (điện trở bạn cung cấp) và giá trị đích (mà bạn nhắm tới gần đúng). Chương trình phải xem xét:

  • Điện trở riêng
  • Hai điện trở nối tiếp
  • Hai điện trở song song

Chương trình sẽ tính toán tất cả các kết hợp có thể có của 1 và 2 điện trở từ danh sách chứng khoán (bao gồm hai bản sao có cùng giá trị điện trở), tính toán chuỗi và điện trở song song của chúng, sau đó sắp xếp các cấu hình theo mức độ chúng xấp xỉ giá trị đích.

Định dạng đầu ra phải là một cấu hình trên mỗi dòng, với một +chuỗi |biểu thị và biểu thị song song và một số dấu cách hoặc dấu = trước điện trở thuần.

Công thức

  • Điện trở của một điện trở là R1
  • Điện trở thuần của hai điện trở mắc nối tiếp là R1 + R2
  • Điện trở thuần của hai điện trở song song là 1 / (1/R1 + 1/R2)
  • Khoảng cách giữa giá trị điện trở gần đúng và giá trị đích có thể được tính là khoảng cách giả logarit, không phải khoảng cách tuyến tính : dist = abs(Rapprox / Rtarget - 1). Ví dụ, 200 gần với 350 hơn 100.
  • Một thước đo khoảng cách tốt hơn là khoảng cách logarit thực sự dist = abs(log(Rapprox/Rtarget)), nhưng vì điều này không được chỉ định trong câu hỏi ban đầu, bạn có thể tự do sử dụng một trong hai phép đo.

Chấm điểm

Điểm được đo bằng các ký tự mã, theo quy tắc golf thông thường. Điểm số thấp nhất chiến thắng.

Thí dụ

Chúng tôi có các điện trở sau trong kho [100, 150, 220, 330, 470, 680, 1000, 1500, 2200, 3300, 4700]và muốn nhắm mục tiêu 510ohms. Chương trình sẽ xuất ra 143 cấu hình, xấp xỉ như được hiển thị (bạn có thể thay đổi định dạng, nhưng đảm bảo rằng ý nghĩa được xác định dễ dàng):

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.

Trong ví dụ này, xấp xỉ 510 ohms tốt nhất được đưa ra bởi các điện trở 680- và 2200 ohm song song.

Tốt nhất của mỗi ngôn ngữ cho đến nay (ngày 1 tháng 6 năm 2014):

  1. J - 70 char
  2. APL - 102 char
  3. Toán học - 122 char
  4. Ruby - 154 char
  5. Javascript - 156 char
  6. Julia - 163 char
  7. Perl - 185 char
  8. Con trăn - 270 char

3
@Claudiu Không có sự khác biệt về điện giữa 100 + 150 và 150 + 100; cả hai đều mang lại điện trở 250 ohms và tiêu thụ điện trở 100 ohm và điện trở 150 ohm, vì vậy chúng ta không được tính hai lần. Tuy nhiên, chúng nên được phân biệt với 125 + 125, bởi vì mặc dù điều này cũng mang lại 250 ohms, nó tiêu thụ các điện trở khác nhau (có thể thích hợp hơn, với số lượng phần của chúng tôi).
phosgene

3
510 nằm trong

3
Phosgene, còn ROUV thì sao?
mở

3
Tôi không nghĩ chúng tồn tại.
phosgene

1
Chúng tôi thường không đặt thời hạn cho các câu hỏi về golf, bởi vì điều đó có thể khiến một số người không khuyến khích đăng bài. Bạn luôn có thể thay đổi câu trả lời được chấp nhận.
Nzall

Câu trả lời:


6

J - 86 71 70 char

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

Tôi sẽ không bận tâm để giải thích từng chi tiết nhỏ vì rất nhiều mã được dành để đồng bộ hóa kết quả của các chức năng khác nhau, nhưng đây là ý chính của golf:

  • ;@((<@,.{:)\) làm cho mọi cặp điện trở có thể, được kết nối song song hoặc nối tiếp.

  • [:,/(<,.+`|,.+/;+&.%/)"1@ sau đó kết nối chúng, song song và nối tiếp, tạo ra một danh sách lớn các kết nối có thể.

  • (;a:,<)"0, thêm vào khả năng chỉ sử dụng một điện trở để ước tính.

  • (]/:[|@<:@%~2{::"1])sắp xếp danh sách kết hợp các điện trở theo khoảng cách giả ( |@<:@%) giữa mục tiêu và điện trở kết quả từ mỗi kết hợp.

Và đây là cách sử dụng nó:

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

Bạn không phải chỉ xem 10 cái đầu tiên như tôi đã làm ở trên, nhưng đây là một hàm và J REPL cắt bớt các giá trị trả về rất lớn và đầu ra đầy đủ cho ví dụ này có 287 dòng. Bạn có thể buộc tất cả vào STDOUT với một cái gì đó nhưtmoutput toCRLF , LF ,.~ ": blah rouv blah trên Windows, bỏ toCRLFLinux Linux nhưng rouvlà một chức năng và bên trong, tất cả các hàng tồn tại.

Chú thích:

Câu hỏi dường như đã được thay đổi ngay dưới mũi của chúng tôi và bây giờ khoảng cách nhật ký được xác định abs(log(Rapprox/Rtarget))thay vì abs(Rapprox/Rtarget-1). Để sửa lỗi này trong golf của tôi, chúng ta có thể thay đổi |@<:@%thành |@^.@%: <:là Decrement trong khi ^.là Logarit.


Mặc dù mã của bạn dường như không thể hiểu được, chúng tôi vẫn có thể đánh giá cao sự bí ẩn. Điểm số tốt nhất sau một ngày - nó sẽ đứng?
phosgene

1
Không, tôi không muốn gửi thư đến -. & A: @, @: {@ (({.;
Kilazur

12

Toán học, 151 122 ký tự

Dự kiến ​​điện trở mục tiêu sẽ được lưu trữ trong rdanh sách các điện trở có sẵn trong l.

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

Ít golf hơn:

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

Định dạng đầu ra khác với định dạng được đề xuất nhưng cấu hình có thể dễ dàng xác định. Đầu ra là một danh sách các cấu hình. Mỗi cấu hình là một trong các hình thức sau:

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

Vì vậy, ba yếu tố đầu tiên của đầu ra đọc

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

Nếu bạn ổn với số hữu tỷ, tôi có thể lưu hai ký tự khỏi bỏ sót N@. Đó là, phần tử đầu tiên (ví dụ) sẽ được trả về 4675/9thay vì 519.444.


Công việc tốt đẹp. Bạn đánh bại tôi với nó (và với mã ngắn hơn).
DavidC

15
Bạn không # # den # của bạn là # w @ rn bạn @ g @ in # e @ # ing # h @ # much syn # @ c # ic sug @ r?
phosgene

2
@ N @ l Tuples? Đó có phải là một số loại bệnh lập trình viên?
clabacchio

@clabacchio tuyệt vời, tôi thậm chí không nhìn thấy điều đó. phosgene, chắc hẳn anh ta đã quên đề cập đến nó ... hoặc có lẽ anh ta cũng chỉ thích chơi gôn ...
Martin Ender

10

APL (102)

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

Điều này lấy điện trở mục tiêu làm đối số bên trái và danh sách các điện trở có sẵn làm đối số bên phải.

Giải trình:

  • V←{... }: Vlà một chức năng:
    • Z/⍨≤/¨Z←,∘.,⍨⍵: tìm mọi kết hợp duy nhất của hai giá trị trong ,
      • Z←,∘.,⍨⍵: tham gia mỗi giá trị với mỗi giá trị trong , lưu trữ trong Z,
      • Z/⍨≤/¨Z: chọn từ Zcác kết hợp trong đó giá trị thứ nhất nhỏ hơn hoặc bằng giá trị thứ hai
    • ⍺{... }⍺⍺/¨: và sau đó áp dụng hàm sau, ràng buộc với hàm trái ( ⍺⍺) ở bên phải và đối số bên trái ( ) ở bên trái, cho mỗi cặp:
      • ⍺,⍺⍺,⍵,'=',⍺⍵⍵⍵, đối số bên trái, theo sau là đối số ràng buộc bên trái, theo sau là đối số bên phải, theo sau là =hàm bên phải ( ⍵⍵) được áp dụng cho cả hai đối số. (Đây là chức năng định dạng , X [configuration] Y [equals] (X [fn] Y).)
    • ⊃¨: và sau đó bỏ hộp từng phần tử.
  • {⍵,' =',⍵}¨⍵: cho mỗi phần tử trong , tạo cấu hình cho các điện trở riêng lẻ. ( , không có gì, không có gì =,, ).
  • ('+'+V⍵): sử dụng Vhàm để tạo tất cả các cấu hình nối tiếp (ký tự '+'và hàm là +).
  • '|'{÷+/÷⍺⍵}V⍵: sử dụng Vhàm để tạo tất cả các cấu hình song song (ký tự '|'và hàm là {÷+/÷⍺⍵}, nghịch đảo của tổng nghịch đảo của các đối số).
  • K←↑: làm cho nó thành một ma trận và lưu trữ nó trong K.
  • 0 4↓K: thả 4 cột đầu tiên từ K, chỉ để lại các giá trị kháng.
  • |¯1+⍺÷⍨: tính khoảng cách giữa và từng cấu hình.
  • K[⍋... ;]: Sắp xếp Ktheo khoảng cách.

3
Tôi sẽ nói với bạn rằng nó hoạt động. Bàn phím của tôi bị thiếu khá nhiều các ký tự sau: D
phosgene

@phosgene: Nếu bạn muốn thử nghiệm nó, bạn có thể tải xuống phiên bản dùng thử của Dyalog APL tại dyalog.com. Sau đó chỉ cần dán toàn bộ vào, nó sẽ hoạt động. Các đối số đi về hai phía, vì vậy, ví dụ:510 code_here 100, 150, 220, 330, 470, 680, 1000, 1500, 2200, 3300, 4700
bến du thuyền

@phosgene Bạn có thể thử trình thông dịch trực tuyến này , mặc dù nó không cung cấp đầu ra hoàn chỉnh, bạn có thể xác minh rằng một vài dòng bắt đầu và vài dòng cuối cùng giống nhau.
dùng12205

Đã xác minh! APL là một số thứ bí truyền.
phosgene

1
@ace TryAPL rất hạn chế và thường thì nó không hoạt động. Rằng nó xảy ra để làm việc trên cái này chỉ là một sự trùng hợp ngẫu nhiên. Nó không hỗ trợ eval ( ), I / O ( ) hoặc bất kỳ biến hệ thống nào (thậm chí ⎕UCS⎕Akhông hoạt động) nên hầu hết các chương trình APL sẽ không chạy. Nó thực sự sẽ cung cấp một LỚP SYNTAX nếu một trong các chức năng bị vô hiệu hóa được sử dụng. Thực tế là điều này xảy ra không sử dụng một trong nhiều chức năng mà TryAPL không hỗ trợ, là một sự trùng hợp ngẫu nhiên.
bến

4

Con trăn 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)

Chạy như thế này:

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

(nghĩa là, một danh sách các điện trở được phân tách bằng không gian, với giá trị đích ở cuối)

Đầu ra:

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

Tôi sẽ nói rằng xuất ra, nói 680|22002200|680 riêng biệt vẫn còn khá rõ ràng. Nếu điều này không được chấp nhận, tôi có thể thay đổi nó, nhưng nó sẽ khiến tôi mất nhiều byte.Không thể chấp nhận được. Chi phí cho tôi byte. Bây giờ tôi sắp xếp các bộ dữ liệu trước khi nhét chúng vào bộ, nếu không thì giải pháp là giống hệt nhau.


Chắc chắn, đầu ra có vẻ rất rõ ràng với tôi!
phosgene

Tuy nhiên, bạn đang tính hai lần. 150 + 330 giống hệt với 330 + 150, do đó, chỉ một trong số chúng sẽ xuất hiện trong kết quả (ví dụ 143 tổng cấu hình).
phosgene

@pho Được rồi, đã sửa. Một vài byte bổ sung nhưng giải pháp nên có hiệu lực ngay bây giờ.
ngầmmonorail

Ngoài ra tôi nghĩ rằng chương trình của bạn không tìm kiếm một điện trở duy nhất, tất cả (a + = [(a, a) cho a trong r]). Bạn có thể bỏ qua a = ... khi bạn sử dụng chính xác một lần. Về điều này import sys;r=sys.args[1:], sử dụng r=input().split()và nói rằng bạn phải đưa ra các giá trị trên stdin. Cuối cùng: bạn sử dụng 1/sum(1/int(n)for n in b)thay vì 1/sum(map(lambda n:1/int(n),b).
Nói chung

Tôi vừa đánh gôn thêm 1 char: Sử dụng print (* sort (...), sep = '\ n')
WorldSEnder

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

Ung dung:

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

Những gì nó làm:

  • Đối với mỗi giá trị etrong a;
    • Lặp lại a, tính toán các giá trị đơn, sê-ri và song song làm khóa cho các giá trị được in theo hàm băm c;
  • Xác định khoảng cách từ zcho mỗi phím trong c; và,
  • Đối với mỗi giá trị e[1]cho mỗi khóa e[0]trong c, in e[1]=e[0].

Sử dụng mẫu:

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

Đầu ra mẫu:

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 ký tự

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

Đầu vào:

  • Một mảng Rcường độ điện trở; và
  • T, kháng chiến mục tiêu.

Đầu ra:

Một mảng các mảng (được sắp xếp theo khoảng cách từ T) mỗi mảng chứa:

  • giá trị của điện trở nhỏ hơn;
  • giá trị của điện trở cao hơn (hoặc 0 nếu điện trở đơn);
  • p, sHoặc 0 nếu điện trở là song song, nối tiếp hoặc đơn độc; và
  • điện trở thuần.

Giải trình:

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

Thiếu điện trở đơn (đầu ra len ví dụ đầu vào là 132 thay vì 143). Tôi muốn mượn thủ thuật Hiểu toàn diện, nếu tôi có thể hiểu nó ...
edc65

À, quên điện trở đơn độc
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)),:]))

Điều này hoạt động giống như phiên bản cũ, nhưng đối số trong câu lệnh in đã được tổ chức hơi khác nhau để giảm số lượng dấu ngoặc vuông cần thiết. Tiết kiệm 4 byte. Việc hấp thụ việc tạo vectơ không gian vào đối số in sẽ tiết kiệm thêm 2 byte. Nó cũng đã chuyển từ sử dụng "tìm" để có được các chỉ số liên quan sang sử dụng hình thức logic. Lưu 6 byte. Việc hấp thụ tính toán của vectơ chỉ mục vào việc điều chỉnh A đã lưu thêm 2 byte. Cuối cùng, thay thế endof (v) bằng sum (v) đã lưu thêm 2 byte. Tổng tiết kiệm: 16 byte.

Phiên bản cũ:

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

Trong chức năng, đây là những gì nó đang làm:

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

Đầu ra mẫu:

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

Tốt đẹp! Đừng thấy nhiều bài nộp của Julia - nó có đang ngày càng phổ biến không?
phosgene

@phosgene - Tôi hy vọng nó là; Tôi chủ yếu gửi những thứ này vì chúng cho tôi thêm kinh nghiệm với ngôn ngữ.
Glen O

2

Javascript (E6) 156 162 164 186

Chỉnh sửa lần cuối Giả sử tất cả các giá trị điện trở> 0, bạn có thể sử dụng chúng cho điều kiện vòng lặp

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

Sử dụng : F(510, [100, 150, 220, 330, 470, 680, 1000, 1500, 2200, 3300, 4700])

Bị đánh cắp

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
Phải đẩy (điểm, thấp hơn)!
phosgene

Lần cuối tôi kiểm tra, tất cả các điện trở của tôi đều có giá trị dương. Tôi nghĩ đó là một giả định an toàn.
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)}

Sử dụng : r(510, [100, 150, 220, 330, 470, 680, 1000, 1500, 2200, 3300, 4700]);

Đầu ra

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

Vượt qua tất cả các điện trở có sẵn như là đối số. Kháng cự mục tiêu nên là cuối cùng:

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

Cách thức hoạt động (mã cũ)

  • Xác định chương trình con SP để tính tổng và giá trị song song của hai điện trở.

  • Đặt $"thành "," để nội suy @ARGVbên trong globtoán tử

  • <{S,P}({@i},{@i})= S({@i})=> tạo ra một cartesian của tất cả các khả năng:

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

  • Kết hợp s///eevới grepđể đánh giá các điện trở tương đương và lọc ra các lần lặp lại không mong muốn (được thực hiện bởi (??{$2<$3})/\d$/

  • sort bởi thể dục được tính trong chương trình con t

Thay đổi mã mới

  • Tránh sử dụng s///ee, sử dụng regex ngắn hơn với kiểm tra có điều kiện và evalbên tronggrep

  • Thay thế lặp lại của "{@i}" with$ i`

  • Giới thiệu $x, $ythay vì $2,$3

  • Thay thế split/=/,popbằng$_[0]=~s!!!r

  • Không cần theo dõi ;

  • eval; tương đương với eval $_;

  • Thêm =cùng với evalcâu trả lời -ed thay vì khai báo trước

Đầu ra:

Pđại diện cho điện trở song song, Sđại diện cho điện trở trong loạt.

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

Hai dòng còn thiếu là S(100)=100S(1000)=1000.
thuật toán

@alerskymshark: Yup, hiểu rồi. Regex đã vô tình tiêu thụ chúng
Zaid

Sẽ rất thú vị để xem liệu có ai có thể đưa ra giải pháp Perl ngắn hơn không.
Zaid
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.