Резисторы необычной ценности

23

Введение

При создании проекта электроники схема может потребовать резистор необычного значения (скажем, 510 Ом). Вы проверяете свою корзину для запчастей и обнаруживаете, что у вас нет резисторов на 510 Ом. Но у вас есть много общих значений выше и ниже этого значения. Комбинируя резисторы параллельно и последовательно, вы должны быть в состоянии достаточно хорошо аппроксимировать резистор 510 Ом.

задача

Вы должны написать функцию или программу, которая принимает список значений резисторов (резисторы, которые вы используете) и целевое значение (которое вы стремитесь приблизить). Программа должна учитывать:

  • Индивидуальные резисторы
  • Два резистора в серии
  • Два резистора параллельно

Программа должна вычислить все возможные комбинации 1 и 2 резисторов из списка запасов (включая две копии одного и того же значения резистора), вычислить их серии и параллельное сопротивление, а затем отсортировать конфигурации в соответствии с тем, насколько они приближаются к целевому значению.

Выходным форматом должна быть одна конфигурация на строку с +обозначением серии и |параллелью, а также некоторого пробела или знака = перед чистым сопротивлением.

Формулы

  • Сопротивление одного резистора 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 Ом.

Лучшее на каждом языке (1 июня 2014 г.):

  1. J - 70 символов
  2. APL - 102 символа
  3. Mathematica - 122 символа
  4. Рубин - 154 символа
  5. Javascript - 156 символов
  6. Юлия - 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?
unclemeat
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 строк. Вы можете заставить все это перейти в STDOUT с помощью чего-то похожего tmoutput toCRLF , LF ,.~ ": blah rouv blahна Windows - сбросить toCRLFна Linux - но rouvэто функция, и внутри все строки существуют.

Заметка:

Вопрос, похоже, был изменен прямо у нас под носом, и теперь логарифмическое расстояние определяется как abs(log(Rapprox/Rtarget))вместо abs(Rapprox/Rtarget-1). Чтобы исправить это в моем гольфе, мы можем изменить |@<:@%к |@^.@%: <:это Decrement в то время как ^.это логарифм.

algorithmshark
источник
Хотя ваш код кажется непостижимым, мы все равно можем оценить тайну. Лучший результат после одного дня - это будет стоять?
Фосген
1
Нет, я не хочу отправлять почту по
A
12

Mathematica, 151 122 символов

Ожидается сохранение целевого сопротивления rи список доступных резисторов l.

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/9вместо 519.444.

Мартин Эндер
источник
Хорошо сделано. Вы победили меня в этом (и с более коротким кодом).
DavidC
15
Разве # твое логово # не # w @ rn you @ g @ ins # e @ # ing # h @ # много син # @ c # ic sug @ r?
фосген
2
@ N @ l Кортежи? Это какая-то болезнь программистов?
Клабаккио
@clabacchio удивительно, я даже этого не видел. Фосген, он, должно быть, забыл упомянуть об этом ... или, может быть, он просто любит играть в гольф тоже ...
Мартин Эндер
10

APL (102)

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

Это принимает целевое сопротивление в качестве левого аргумента и список доступных резисторов в качестве правого аргумента.

Объяснение:

  • V←{... }: Vэто функция, которая:
    • Z/⍨≤/¨Z←,∘.,⍨⍵: находит каждую уникальную комбинацию двух значений в ,
      • Z←,∘.,⍨⍵: объединить каждое значение с каждым значением в , сохранить в Z,
      • Z/⍨≤/¨Z: выберите из Zтех комбинаций, где первое значение меньше или равно второму значению
    • ⍺{... }⍺⍺/¨: и затем применяет следующую функцию, связанную с левой функцией ( ⍺⍺) справа и левым аргументом ( ) слева, к каждой паре:
      • ⍺,⍺⍺,⍵,'=',⍺⍵⍵⍵, левый аргумент, за которым следует левый связанный аргумент, за которым следует правый аргумент, за которым =следует правая функция ( ⍵⍵), примененная к обоим аргументам. (Это функция форматирования X [configuration] Y [equals] (X [fn] Y).)
    • ⊃¨: и затем распакуйте каждый элемент.
  • {⍵,' =',⍵}¨⍵: для каждого входного элемента настройте отдельные резисторы. ( , ничего, ничего =, ).
  • ('+'+V⍵): используйте Vфункцию для создания всех последовательных конфигураций (символ есть '+'и функция есть +).
  • '|'{÷+/÷⍺⍵}V⍵: использовать Vфункцию для создания всех параллельных конфигураций (символ is '|'и function is {÷+/÷⍺⍵}, обратный сумме обратных аргументов).
  • K←↑: превратить это в матрицу и сохранить в K.
  • 0 4↓K: удалить 4 первых столбца K, оставив только значения сопротивления.
  • |¯1+⍺÷⍨: вычислить расстояние между каждой конфигурацией.
  • K[⍋... ;]: сортировка Kпо расстоянию.
Мэринус
источник
3
Я верю вашему слову, что это работает. В моей клавиатуре отсутствует довольно много этих символов: D
фосген
@phosgene: Если вы хотите протестировать его, вы можете загрузить пробную версию Dyalog APL на dyalog.com. Затем просто вставьте все это, оно должно работать. Аргументы идут по сторонам, например, так:510 code_here 100, 150, 220, 330, 470, 680, 1000, 1500, 2200, 3300, 4700
marinus
@phosgene Вы можете попробовать этот онлайн-переводчик, хотя он не обеспечивает полного вывода, вы можете убедиться, что первые несколько строк и последние несколько строк совпадают.
user12205
Проверено! APL - это эзотерика.
Фосген
1
@ace TryAPL очень ограничен, и обычно он не работает. То, что это работает с этим, является просто совпадением. Он не поддерживает eval ( ), I / O ( ) или любые системные переменные (даже ⎕UCSи ⎕Aне работают), поэтому большинство программ APL не будут работать. На самом деле он выдаст ОШИБКУ СИНТАКСА, если будет использована одна из отключенных функций. Тот факт, что эта функция не использует одну из многих функций, которые не поддерживает TryAPL, является совпадением.
Мэринус
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отдельно, все еще довольно ясен. Если это неприемлемо, я могу изменить это, но это будет стоить мне байтов.Не было приемлемо Стоит мне байтов. Теперь я сортирую кортежи перед тем, как поместить их в набор, в противном случае решение идентично.

undergroundmonorail
источник
Конечно, вывод выглядит достаточно ясно для меня!
Фосген
Тем не менее, вы двойной счет вещей. 150 + 330 электрически идентичны 330 + 150, поэтому в результате должна появиться только одна из них (всего 143 конфигурации).
Фосген
@pho Хорошо, исправлено. Несколько дополнительных байтов, но решение должно быть в силе сейчас.
подземный
Также я думаю, что ваша программа вообще не ищет ни одного резистора (a + = [(a, a) для a в r]). Вы можете пропустить = ... так как вы используете ровно один раз. По этому поводу 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
символа
Я только что сыграл в гольф еще 1 символ: Использовать print (* sorted (...), sep = '\ n')
WorldSEnder
3

Ruby 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]в cраспечатайте e[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.
)
mt0
источник
Отсутствует одиночный резистор (например, на входе len вместо 132 указано входное значение 132). Я бы хотел позаимствовать трюк с пониманием массива, если бы я только мог его понять ...
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)),:]))

Это работает так же, как и в старой версии, но аргумент в выражении print был организован несколько иначе, чтобы уменьшить количество необходимых квадратных скобок. Сохраняет 4 байта. Поглощение создания вектора пробелов в аргументе печати экономит лишние 2 байта. Он также перешел от использования «find» для получения соответствующих индексов к использованию логической формы. Сохраняет 6 байтов. Поглощение вычисления вектора индекса в корректировке A сэкономило еще 2 байта. Наконец, замена endof (v) на sum (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
Глен О
источник
Ницца! Не вижу много представлений Джулии - растет ли популярность?
Фосген
@ phhosgene - надеюсь, это так; Я в основном представляю их, потому что они дают мне дополнительный опыт работы с языком.
Глен О,
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))
}
edc65
источник
1
Надо толкать (оценка, ниже)!
Фосген
Последнее, что я проверил, все мои резисторы были положительно оценены. Я думаю, что это безопасное предположение.
Фосген
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, используйте более короткое регулярное выражение с условной проверкой и 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: Да, понял. Регулярное выражение непреднамеренно потребляло их
Заид
Будет интересно посмотреть, сможет ли кто-нибудь придумать более короткое решение Perl.
Заид