ตัวต้านทานค่าที่ผิดปกติ


23

บทนำ

เมื่อสร้างโครงการอิเล็กทรอนิกส์แผนผังอาจเรียกตัวต้านทานที่มีค่าผิดปกติ (กล่าวคือ 510 โอห์ม) คุณตรวจสอบชิ้นส่วนในถังขยะและพบว่าคุณไม่มีตัวต้านทาน 510 โอห์ม แต่คุณมีค่าทั่วไปมากมายด้านบนและด้านล่างค่านี้ ด้วยการรวมตัวต้านทานแบบขนานและอนุกรมคุณควรจะสามารถประมาณตัวต้านทาน 510 โอห์มได้ดีพอสมควร

งาน

คุณต้องเขียนฟังก์ชั่นหรือโปรแกรมที่รับรายการค่าตัวต้านทาน (ตัวต้านทานที่คุณเก็บไว้) และค่าเป้าหมาย (ซึ่งคุณมุ่งหวังที่จะประมาณ) โปรแกรมจะต้องพิจารณา:

  • ตัวต้านทานส่วนบุคคล
  • ตัวต้านทานสองตัวในอนุกรม
  • ตัวต้านทานสองตัวขนานกัน

โปรแกรมควรคำนวณการรวมกันที่เป็นไปได้ทั้งหมดของตัวต้านทาน 1 และ 2 จากรายการหุ้น (รวมถึงสำเนาสองตัวที่มีค่าตัวต้านทานเดียวกัน) คำนวณอนุกรมและความต้านทานแบบขนานของพวกเขาจากนั้นเรียงลำดับการกำหนดค่าตามความเหมาะสม

รูปแบบเอาต์พุตควรเป็นหนึ่งการกำหนดค่าต่อบรรทัดโดยมี+ชุด|denoting และdenoting ขนานและบางพื้นที่หรือเครื่องหมาย = ก่อนความต้านทานสุทธิ

สูตร

  • ความต้านทานของตัวต้านทานหนึ่งตัวคือ R1
  • ความต้านทานสุทธิของตัวต้านทานสองตัวในอนุกรมคือ R1 + R2
  • ความต้านทานสุทธิของตัวต้านทานสองตัวแบบขนานคือ 1 / (1/R1 + 1/R2)
  • dist = abs(Rapprox / Rtarget - 1)ระยะห่างระหว่างค่าความต้านทานประมาณและค่าเป้าหมายสามารถคำนวณเป็นระยะทางหลอกลอการิทึมระยะทางไม่เป็นเชิงเส้น: ตัวอย่างเช่น 200 ใกล้เคียงกับ 350 มากกว่า 100
  • การวัดระยะทางที่ดีกว่าคือระยะทางลอการิทึมจริง dist = abs(log(Rapprox/Rtarget))แต่เนื่องจากไม่ได้ระบุไว้ในคำถามเดิมคุณมีอิสระที่จะใช้การวัดใดก็ได้

เกณฑ์การให้คะแนน

คะแนนวัดเป็นตัวอักษรของรหัสตามกฎกอล์ฟปกติ คะแนนต่ำสุดชนะ

ตัวอย่าง

เรามีตัวต้านทานต่อไปนี้ในสต็อก[100, 150, 220, 330, 470, 680, 1000, 1500, 2200, 3300, 4700]และต้องการกำหนดเป้าหมาย510โอห์ม โปรแกรมควรแสดงการกำหนดค่า 143 รายการโดยประมาณตามที่แสดง (คุณสามารถเปลี่ยนรูปแบบได้ แต่ต้องแน่ใจว่ากำหนดความหมายได้ง่าย):

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.

ในตัวอย่างนี้การประมาณที่ดีที่สุดคือ 510 โอห์มจะได้รับจากตัวต้านทาน 680- และ 2200-ohm ในแบบคู่ขนาน

ดีที่สุดของแต่ละภาษาจนถึงวันที่ (1 มิถุนายน 2014):

  1. J - 70 ตัวอักษร
  2. APL - 102 อักขระ
  3. Mathematica - 122 ถ่าน
  4. ทับทิม - 154 ถ่าน
  5. Javascript - 156 อักขระ
  6. Julia - 163 ถ่าน
  7. Perl - 185 อักขระ
  8. Python - 270 ถ่าน

3
@Claudiu ไม่มีความแตกต่างทางไฟฟ้าระหว่าง 100 + 150 และ 150 + 100; ทั้งให้ความต้านทาน 250 โอห์มและใช้ตัวต้านทาน 100 โอห์มและตัวต้านทาน 150 โอห์มดังนั้นเราจะต้องไม่นับซ้ำ อย่างไรก็ตามพวกมันควรจะแตกต่างจาก 125 + 125 เพราะแม้ว่ามันจะให้ผลตอบแทน 250 โอห์ม แต่มันก็ใช้ตัวต้านทานที่แตกต่างกัน
ฟอสจีน

3
510 อยู่ในชุด E24จึงไม่ว่าผิดปกติจะมีในมือ
gnibbler

3
ฟอสจีนสิ่งที่เกี่ยวกับ ROUV หรือไม่
ลุง

3
ฉันไม่คิดว่าพวกเขามีอยู่จริง
ฟอสจีน

1
โดยปกติเราไม่ได้กำหนดเวลาสำหรับคำถามเกี่ยวกับรหัสกอล์ฟเพราะอาจทำให้บางคนไม่สามารถโพสต์ได้ คุณสามารถเปลี่ยนคำตอบที่ยอมรับได้เสมอ
Nzall

คำตอบ:


6

J - 86 71 70 ตัวอักษร

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

ฉันไม่อยากอธิบายทุกรายละเอียดเล็ก ๆ น้อย ๆ เพราะมีการใช้รหัสจำนวนมากในการซิงค์ผลลัพธ์ของฟังก์ชั่นต่าง ๆ แต่นี่คือส่วนสำคัญของกอล์ฟ:

  • ;@((<@,.{:)\) ทำให้ตัวต้านทานทุกตัวมีความเป็นไปได้ที่จะเชื่อมต่อแบบขนานหรือแบบอนุกรม

  • [:,/(<,.+`|,.+/;+&.%/)"1@ จากนั้นเชื่อมต่อพวกเขาในแบบคู่ขนานและในลำดับทำให้รายการใหญ่ของการเชื่อมต่อที่เป็นไปได้

  • (;a:,<)"0, เพิ่มความเป็นไปได้ในการใช้ตัวต้านทานเพียงตัวเดียวในการประมาณค่า

  • (]/:[|@<:@%~2{::"1])เรียงลำดับรายการการรวมกันของตัวต้านทานตามระยะทางปลอม ( |@<:@%) ระหว่างเป้าหมายและความต้านทานผลลัพธ์จากการรวมกันแต่ละชุด

และนี่คือวิธีการใช้งาน:

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

คุณไม่จำเป็นต้องดูเฉพาะ 10 อันดับแรกอย่างที่ฉันทำข้างต้น แต่นี่เป็นฟังก์ชั่นและ J REPL จะตัดทอนค่าตอบแทนที่มีขนาดใหญ่มากและเอาต์พุตเต็มสำหรับตัวอย่างนี้มี 287 บรรทัด คุณสามารถบังคับให้ทุกอย่างหยุดทำงานด้วยบางสิ่งบางอย่างtmoutput toCRLF , LF ,.~ ": blah rouv blahบน Windows ปล่อยtoCRLFบน Linux แต่rouvเป็นฟังก์ชั่นและภายในแถวทั้งหมดมีอยู่

บันทึก:

คำถามที่ดูเหมือนว่าจะมีการเปลี่ยนแปลงสิทธิภายใต้จมูกของเราและตอนนี้ระยะล็อกถูกกำหนดให้เป็นแทนabs(log(Rapprox/Rtarget)) abs(Rapprox/Rtarget-1)การแก้ไขปัญหานี้ในสนามกอล์ฟของเราสามารถเปลี่ยน|@<:@%ไป|@^.@%: <:เป็นลดในขณะที่^.เป็นลอการิทึม


แม้ว่ารหัสของคุณดูเหมือนจะไม่อาจหยั่งรู้ได้ แต่เราก็ยังสามารถชื่นชมความลึกลับนี้ได้ คะแนนที่ดีที่สุดหลังจากหนึ่งวัน - มันจะยืนอยู่หรือไม่
phosgene

1
ไม่ฉันไม่ต้องการส่งจดหมายถึง -. & a: @, @: {@ (({.;
Kilazur

12

Mathematica, 151 122 ตัวอักษร

คาดว่าจะต้านทานเป้าหมายที่จะถูกเก็บไว้ในและรายชื่อของตัวต้านทานที่มีอยู่ในrl

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

หักกอล์ฟ:

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

รูปแบบเอาต์พุตแตกต่างจากรูปแบบที่แนะนำ แต่สามารถกำหนดค่าได้อย่างง่ายดาย เอาท์พุทเป็นรายการของการกำหนดค่า แต่ละการกำหนดค่าเป็นหนึ่งในรูปแบบต่อไปนี้:

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

ดังนั้นสามองค์ประกอบแรกของเอาต์พุตจึงอ่านได้

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

N@หากคุณดีกับตัวเลขเหตุผลที่ผมจะสามารถประหยัดทั้งสองตัวละครจากถนัด นั่นคือองค์ประกอบแรก (ตัวอย่างเช่น) จะกลับมาเป็นแทน4675/9519.444


ทำได้ดีมาก คุณเอาชนะฉันมัน (และด้วยรหัสที่สั้นกว่า)
DavidC

15
ไม่ ## den # ของคุณ # w @ rn you @ g @ ins # e @ # ing # h @ # syn มาก # @ c # ic sug @ r?
phosgene

2
@ N @ l สิ่งอันดับ? นั่นเป็นโรคของโปรแกรมเมอร์หรือเปล่า?
clabacchio

@clabacchio น่าทึ่งฉันไม่เห็นด้วยซ้ำ ฟอสจีนเขาต้องลืมที่จะพูดถึงมัน ... หรือบางทีเขาก็แค่ชอบเล่นกอล์ฟด้วย ...
Martin Ender

10

APL (102)

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

สิ่งนี้ใช้ความต้านทานเป้าหมายเป็นอาร์กิวเมนต์ด้านซ้ายและรายการของตัวต้านทานที่มีอยู่เป็นอาร์กิวเมนต์ด้านขวา

คำอธิบาย:

  • V←{... }: Vเป็นฟังก์ชันที่:
    • Z/⍨≤/¨Z←,∘.,⍨⍵: พบทุกชุดที่ไม่ซ้ำกันของทั้งสองค่าใน,
      • Z←,∘.,⍨⍵: เข้าร่วมแต่ละค่าในที่มีค่าในแต่ละร้านค้าในZ,
      • Z/⍨≤/¨Z: เลือกจากZชุดค่าผสมที่ค่าแรกน้อยกว่าหรือเท่ากับค่าที่สอง
    • ⍺{... }⍺⍺/¨: จากนั้นใช้ฟังก์ชั่นต่อไปนี้เชื่อมโยงกับฟังก์ชั่นด้านซ้าย ( ⍺⍺) ทางด้านขวาและอาร์กิวเมนต์ด้านซ้าย ( ) ทางด้านซ้ายกับแต่ละคู่:
      • ⍺,⍺⍺,⍵,'=',⍺⍵⍵⍵อาร์กิวเมนต์ซ้ายตามด้วยอาร์กิวเมนต์ bound left ตามด้วยอาร์กิวเมนต์ขวา=ตามด้วยฟังก์ชัน right ( ⍵⍵) ที่ใช้กับอาร์กิวเมนต์ทั้งสอง (นี่คือฟังก์ชั่นการจัดรูปแบบ, X [configuration] Y [equals] (X [fn] Y).)
    • ⊃¨: แล้วแยกกล่องแต่ละองค์ประกอบ
  • {⍵,' =',⍵}¨⍵สำหรับองค์ประกอบแต่ละตัวให้กำหนดค่าสำหรับตัวต้านทานแต่ละตัว ( ไม่มีอะไรไม่มีอะไร=, )
  • ('+'+V⍵): ใช้Vฟังก์ชั่นที่จะทำให้การกำหนดค่าอนุกรมทั้งหมด (ตัวอักษร'+'และฟังก์ชั่น+)
  • '|'{÷+/÷⍺⍵}V⍵: ใช้Vฟังก์ชั่นเพื่อสร้างการกำหนดค่าแบบขนานทั้งหมด (character is '|'and function คือ{÷+/÷⍺⍵}ค่าผกผันของผลรวมของค่าผกผันของอาร์กิวเมนต์)
  • K←↑: Kให้นี้ลงในเมทริกซ์และเก็บไว้ใน
  • 0 4↓K: ปล่อย 4 คอลัมน์แรกจากKเหลือเฉพาะค่าความต้านทาน
  • |¯1+⍺÷⍨: คำนวณระยะห่างระหว่างและแต่ละการกำหนดค่า
  • K[⍋... ;]: เรียงKตามระยะทาง

3
ฉันจะใช้คำพูดของคุณว่ามันทำงาน แป้นพิมพ์ของฉันหายไปค่อนข้างมากของตัวละครเหล่านี้: D
phosgene

@phosgene: หากคุณต้องการทดสอบคุณสามารถดาวน์โหลด Dyalog APL เวอร์ชั่นทดลองได้ที่ dyalog.com จากนั้นเพียงวางสิ่งทั้งหมดลงในนั้นก็ควรจะได้ผล ข้อโต้แย้งเกิดขึ้นข้างๆตัวอย่างเช่น:510 code_here 100, 150, 220, 330, 470, 680, 1000, 1500, 2200, 3300, 4700
marinus

@phosgene คุณสามารถลองใช้ล่ามออนไลน์นี้แม้ว่ามันจะไม่ได้ให้ผลลัพธ์ที่สมบูรณ์คุณสามารถตรวจสอบได้ว่าการเริ่มต้นสองสามบรรทัดและสองสามบรรทัดสุดท้ายนั้นเหมือนกัน
user12205

ยืนยันแล้ว! APL เป็นสิ่งที่ลึกลับ
phosgene

1
@ace TryAPL มีข้อ จำกัด มากและมักจะไม่สามารถใช้งานได้ สิ่งที่เกิดขึ้นกับการทำงานกับสิ่งนี้เป็นเพียงเรื่องบังเอิญ ไม่รองรับeval ( ), I / O ( ) หรือตัวแปรระบบใด ๆ (แม้⎕UCSและ⎕Aไม่ทำงาน) ดังนั้นโปรแกรม APL ส่วนใหญ่จะไม่ทำงาน จริง ๆ แล้วมันจะให้ข้อผิดพลาด SYNTAXถ้ามีใช้ฟังก์ชันที่ปิดใช้งานอย่างใดอย่างหนึ่ง ความจริงที่ว่าสิ่งนี้เกิดขึ้นไม่ให้ใช้หนึ่งในหลาย ๆ ฟังก์ชั่นที่ TryAPL ไม่รองรับเป็นเรื่องบังเอิญ
marinus

4

Python 3 - 250 247 270 ไบต์

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)

ทำงานแบบนี้:

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

(นั่นคือรายการของตัวต้านทานที่มีการเว้นวรรคพื้นที่โดยมีค่าเป้าหมายในตอนท้าย)

เอาท์พุท:

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

ฉันจะบอกว่าเอาท์พุทพูด 680|2200และ2200|680แยกยังคงค่อนข้างชัดเจน หากไม่สามารถยอมรับได้ฉันสามารถเปลี่ยนได้ แต่จะต้องเสียค่าใช้จ่ายเป็นไบต์ไม่เป็นที่ยอมรับ ราคาฉันไบต์ ตอนนี้ฉันจัดเรียงสิ่งอันดับก่อนที่จะโยนพวกเขาลงในชุดมิฉะนั้นการแก้ปัญหาจะเหมือนกัน


แน่นอนว่าผลลัพธ์นั้นชัดเจนสำหรับฉัน!
phosgene

อย่างไรก็ตามคุณเป็นสิ่งที่นับซ้ำ 150 + 330 เป็นระบบไฟฟ้าเหมือนกับ 330 + 150 ดังนั้นหนึ่งในนั้นควรปรากฏในผลลัพธ์ (143 การกำหนดค่าทั้งหมดสำหรับตัวอย่าง)
phosgene

@pho โอเคแก้ไขแล้ว ไม่กี่ไบต์พิเศษ แต่การแก้ปัญหาควรจะถูกต้องในขณะนี้
undergroundmonorail

นอกจากนี้ฉันคิดว่าโปรแกรมของคุณไม่ได้มองหาตัวต้านทานเพียงตัวเดียวเลย (a + = [(a, a) สำหรับ a in r]) คุณสามารถข้าม a = ... เมื่อคุณใช้เพียงครั้งเดียว เกี่ยวกับสิ่งนี้import sys;r=sys.args[1:]ใช้r=input().split()และบอกว่าคุณต้องให้ค่ากับ stdin ที่ล่าสุด: คุณใช้แทน1/sum(1/int(n)for n in b) 1/sum(map(lambda n:1/int(n),b)ทั้งหมดควรเป็น 274 ตัวอักษร
WorldSEnder

ฉันเพิ่งเล่นกอล์ฟอีก 1 ถ่าน: ใช้ print (* เรียงลำดับ (... ), sep = '\ n')
WorldSEnder

3

ทับทิม 2.1 156 154 ไบต์

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

มันทำอะไร:

  • สำหรับแต่ละค่าeในa;
    • ย้ำผ่านaคำนวณเดี่ยวชุดและค่าขนานเป็นกุญแจไปเป็นค่าพิมพ์ในกัญชาc;
  • กำหนดระยะห่างจากzสำหรับแต่ละคีย์ในc ; และ,
  • สำหรับแต่ละค่าe[1]สำหรับแต่ละคีย์e[0]ในการพิมพ์ce[1]=e[0]

ตัวอย่างการใช้งาน:

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

ตัวอย่างผลลัพธ์:

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 ตัวอักษร

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

การป้อนข้อมูล:

  • อาเรย์Rของจุดแข็งของตัวต้านทาน และ
  • Tความต้านทานเป้าหมาย

เอาท์พุท:

อาร์เรย์ของอาร์เรย์ (เรียงตามระยะทางจากT) แต่ละรายการประกอบด้วย:

  • ค่าตัวต้านทานที่เล็กลง
  • ค่าของตัวต้านทานที่สูงขึ้น (หรือ 0 ถ้าตัวต้านทานแบบแยกเดี่ยว);
  • p, sหรือ 0 ถ้าตัวต้านทานแบบขนานแบบอนุกรมหรือโดดเดี่ยว และ
  • ความต้านทานสุทธิ

คำอธิบาย:

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

ไม่มีตัวต้านทานเดียว (เอาต์พุต len ตัวอย่างเช่นอินพุตคือ 132 แทน 143) ฉันต้องการที่จะยืมเคล็ดลับอาร์เรย์เข้าใจถ้าฉันสามารถเข้าใจมัน ...
edc65

อ่าลืมความต้านทานโดดเดี่ยว
MT0

3

จูเลีย - 179 163 ไบต์

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

การทำงานเช่นเดียวกับรุ่นเก่า แต่อาร์กิวเมนต์ในคำสั่งการพิมพ์ได้รับการจัดระเบียบแตกต่างกันเล็กน้อยเพื่อลดจำนวนของวงเล็บเหลี่ยมที่จำเป็น บันทึก 4 ไบต์ การดูดซับการสร้างเวกเตอร์สเปซลงในอาร์กิวเมนต์การพิมพ์จะช่วยเพิ่ม 2 ไบต์ นอกจากนี้ยังเปลี่ยนจากการใช้ "ค้นหา" เพื่อรับดัชนีที่เกี่ยวข้องเป็นการใช้แบบฟอร์มทางตรรกะ บันทึก 6 ไบต์ ดูดซับการคำนวณของเวกเตอร์ดัชนีลงในการปรับ A ที่บันทึกไว้อีก 2 ไบต์ ในที่สุดการแทนที่ endof (v) ด้วยผลรวม (v) บันทึกอีก 2 ไบต์ การประหยัดทั้งหมด: 16 ไบต์

เวอร์ชั่นเก่า:

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

ภายในฟังก์ชันนี่คือสิ่งที่กำลังทำ:

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

ตัวอย่างผลลัพธ์:

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

ดี! ไม่เห็นการส่ง Julia มากมาย - มันได้รับความนิยมเพิ่มขึ้นหรือไม่?
ฟอสจีน

@phosgene - ฉันหวังว่าจะเป็น; ฉันส่งสิ่งเหล่านี้เป็นส่วนใหญ่เพราะพวกเขาให้ประสบการณ์พิเศษกับฉัน
เกลน O

2

Javascript (E6) 156 162 164 186

แก้ไขล่าสุดสมมติว่าค่าตัวต้านทานทั้งหมด> 0 คุณสามารถใช้พวกเขาสำหรับสภาพวง

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

การใช้งาน: 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
ต้องผลัก (คะแนนต่ำกว่า)!
phosgene

ครั้งล่าสุดที่ฉันตรวจสอบตัวต้านทานทั้งหมดของฉันมีมูลค่าในเชิงบวก ฉันคิดว่ามันเป็นสมมติฐานที่ปลอดภัย
ฟอสจีน

1

Javascript, 248 ไบต์

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

การใช้งาน: r(510, [100, 150, 220, 330, 470, 680, 1000, 1500, 2200, 3300, 4700]);

เอาท์พุต

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 ไบต์

213 ไบต์:

$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 ไบต์:

$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 ไบต์:

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

ผ่านตัวต้านทานที่มีอยู่ทั้งหมดเป็นอาร์กิวเมนต์ ความต้านทานเป้าหมายควรเป็นครั้งสุดท้าย:

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

มันทำงานอย่างไร (รหัสเก่า)

  • กำหนดรูทีนย่อยSและPเพื่อคำนวณผลรวมและค่าขนานของตัวต้านทานสองตัว

  • ตั้งค่า$"เป็น "," เพื่อสอดแทรก@ARGVภายในตัวglobดำเนินการ

  • <{S,P}({@i},{@i})= S({@i})=> สร้างคาร์ทีเซียนของความเป็นไปได้ทั้งหมด:

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

  • ใช้ร่วมs///eeกับgrepเพื่อประเมินความต้านทานที่เท่ากันและกรองการทำซ้ำที่ไม่ต้องการ (ดำเนินการโดย(??{$2<$3})และ/\d$/

  • sort โดยการออกกำลังกายที่คำนวณในรูทีนย่อย t

การเปลี่ยนแปลงรหัสใหม่

  • หลีกเลี่ยงการใช้s///eeให้ใช้ regex ที่สั้นลงด้วยการตรวจสอบเงื่อนไขและevalภายในgrep

  • แทนที่"{@i}" with$ i` ซ้ำ

  • แนะนำ$x, $yแทน$2,$3

  • แทนที่split/=/,popด้วย$_[0]=~s!!!r

  • ไม่จำเป็นต้องต่อท้าย ;

  • eval; เทียบเท่ากับ eval $_;

  • เพิ่ม=พร้อมกับevalคำตอบ -ed แทนที่จะประกาศล่วงหน้า

เอาท์พุท:

Pหมายถึงตัวต้านทานในแบบขนานSหมายถึงตัวต้านทานในซีรีส์

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

หายไปสองเส้นและS(100)=100 S(1000)=1000
algorithmshark

@algorithmshark: ใช่เข้าใจแล้ว Regex กำลังบริโภคพวกเขาโดยไม่ตั้งใจ
Zaid

มันจะน่าสนใจเพื่อดูว่าใครสามารถมาพร้อมกับโซลูชั่น Perl สั้นลง
Zaid
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.