Розрахунок опору (Nerd Sniping)


10

Доброго дня гольфісти,

Сьогодні наше виклик натхненний коміксами 356 та 370 XKCD . Ми збираємось написати програму для обчислення опору групи резисторів. Попередження про те, що це майже досить складно, щоб вимагати кодового виклику, проте я думаю, що є певне мистецтво писати трохи складніші програми у форматі для гольфу. Виграє найменша кількість символів.

Розрахунок опору спирається на дві наступні формули:

  • Якщо резистори є послідовними, опір - це сума опору кожного резистора
  • Якщо резистори знаходяться паралельно, опір є оберненою сумою оберненого опору кожного резистора

Так - наприклад:

Приклад розрахунку опору

Ваше завдання полягає в тому, щоб якомога менше символів обчислити опір групи до 64 резисторів. Мої вибачення за складність, особливо за правила введення. Я намагався їх визначити таким чином, що кожна мова буде корисною.

  • Кожен резистор буде підключений до 2 або більше інших резисторів.

  • Гарантія вводу є дійсною, лише один вхід і одна точка виходу, яка підключиться

  • Мережа буде послідовно паралельною, щоб не вимагати більше математики, ніж представлена

  • Введення даних здійснюється через файл, аргумент або stdin, залежно від того, що підходить для вашої мови.

  • Вхід буде складатися з ряду розділених висловлювань прямої чи прямої лінії, що складається з цілого числа опору резистора та пробілів, що розділяють ідентифікатори резисторів, до яких підключена одна сторона резистора.

  • Ідентифікатор першого резистора становитиме 1, збільшуючи по одному для кожного наступного резистора

  • Ідентифікатор старту завжди матиме 0

  • Кінцевий резистор завжди буде мати опір 0 Ом і матиме лише з'єднання, визначені в його лінії

Наприклад:

Приклад 2

Можна представити як

3 0
6 1
1 0
5 0
0 2 3 4
  • Вихід може бути stdout або файл. Він може бути представлений одним із наступних способів:
    • Число, що містить мінімум 2 десяткових знаки, а потім новий рядок
    • Фракція, що складається з цілого числа (чисельник), косою косою рисою та іншого цілого числа (знаменника), після чого йде новий рядок. Фракція не повинна бути такою, щоб вона була в найнижчому вигляді - 4/4 або 10/8, наприклад, прийнятні. Фракція повинна бути точною в межах 1/100. Немає бонусу за ідеальну точність - це умова, що дозволяє мовам без операцій з фіксованою або плаваючою точкою конкурувати.

Я сподіваюся, що охоплює всі моменти. Удачі!


/не є зворотною косою рисою. Ви мали на увазі `\` або нахил вперед?
Джон Дворак

Чи дозволяється нам давати неправильні результати, якщо вхід не є послідовно-паралельною мережею?
Джон Дворак

1
міст Уитстона непослідовно-паралельно , якщо замінити центральний вольтметр з опором
John Dvorak

1
чи будуть резистори завжди підключатися до тих, хто має менший ідентифікатор, або вони можуть бути введені в будь-якому порядку? Чи 1 2/1 0/0 1дійсно?
Джон Дворак

9
Паралельний приклад - неправильний. Це повинно бути 15/23, а не 15/8.
Пітер Тейлор

Відповіді:


6

190 APL

Походження індексу 1. Перший цикл (и) поєднує всі резистори, з'єднані послідовно, другий (p) ті, що з'єднані паралельно, і повторний - перший цикл, щоб об'єднати будь-які паралельні резистори, які зараз є послідовно. Специфікація кінцевого нульового резистора видається зайвою.

r←¯1↓⍎¨(c≠'/')⊂c        
o←⊃↑¨r                  
r←⊃1↓¨r                 
s:→(0=+/n←1=+/×r)/p     
n←↑n/i←⍳↑⍴r             
o[n-1]←+/o[n-0 1]       
o←(i←n≠i)/o             
r←i⌿r                   
r←r-r≥n                 
→s                      
p:n←1⍪2≠/r[;1]          
r←((⍴r),1)⍴r←¯1++\n~0   
o←∊1÷¨+/¨1÷¨n⎕penclose o
→(1<⍴o)/s               
3⍕o                     
' '  

Перевірений на прикладах у запитанні плюс трохи складніший:

      Input: '5 0/3 1/1 2/0 2'
 9.000

      Input: '3 0/1 0/5 0/0 1 2 3'
 0.652

      Input: '3 0/6 1/1 0/5 0/0 2 3 4'
 0.763

      Input: '2 0/2 1/2 0/2 0/2 4/2 5/2 2 3 6/2 7/2 2 3 6/0 8 9'
 2.424

Завжди вражені відповідями APL - вони виглядають абсолютно шалено. Кінцевий резистор полягав лише в тому, щоб дати щось для інших резисторів, щоб підключитися - фіктивний кінцевий зв'язок. Молодці!
лочок

Я думаю, ви можете зберегти пару персонажів. Перші два рядки замініть на o←⊃↑¨r←¯1↓⍎¨(c≠'/')⊂c. Ця модель застосовна в декількох місцях.
FUZxxl

5

Пітон, 329 символів

import sys
N=[[1]]+[map(int,x.split())for x in sys.stdin]
N[-1][0]=1
n=len(N)
S=[set([i])for i in range(2*n)]
for x in range(n):
 C=S[2*x]
 for y in N[x][1:]:C|=S[2*y+1]
 for x in C:S[x]|=C
V=[0]*(2*n-1)+[1]
for k in range(999):
 for i in range(1,2*n-1):V[i]+=sum((V[j^1]-V[i])/N[j/2][0]for j in S[i])/9./len(S[i])
print 1/V[1]-2

Обчислює опір, виконуючи релаксацію напруги по ланцюгу. Спочатку він торкається резистора 1 Ом до початку і змінює останній резистор з 0 Ом на 1 Ом. Потім він встановлює вхідну напругу 0, а вихідну напругу - 1 вольт. Після моделювання поточного струму через мережу опір мережі обчислюється за допомогою падіння напруги на першому резисторі 1 Ом.

Кожному резистору присвоєно два числа - номер для його лівого клеми та номер для правого його терміналу. Лівий термінал резистора r дорівнює 2 * r, а його правий термінал - 2 * r + 1. Вхід використовується для обчислення Sнаборів терміналів, які з'єднані між собою. Кожному терміналу задається напруга, V[t]а розслаблення здійснюється за рахунок підвищення напруги, якщо струм чистий, що надходить в кінцевий набір, і зниження напруги, якщо струм чистий стікає.


2

(Це коментар, але я не можу зробити реальне мистецтво ascii ...)

Як щось подібне вводиться?

    --1--     --3--
   /     \   /     \
---       ---       --0--
   \     /   \     /
    --2--     --4--

Зокрема, до чого пов’язані 3 та 4? 1 або 2, або і 1, і 2?


І один, і два
лочок
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.