Расчет сопротивления (снайперский ботаник)

10

Добрый день, гольфисты,

Наша задача на сегодняшний день вдохновлена ​​комиксами XKCD 356 и 370 . Мы собираемся написать программу для расчета сопротивления группы резисторов. Предупреждая, что это почти достаточно сложно, чтобы оправдать проблему кода, однако я думаю, что есть определенный навык в написании немного более сложных программ в формате гольфа. Наименьшее количество символов выигрывает.

Расчет сопротивления основывается на следующих двух формулах:

  • Если резисторы включены последовательно, сопротивление является суммой сопротивления каждого резистора.
  • Если резисторы параллельны, сопротивление является обратной величиной суммы обратных сопротивлений каждого резистора.

Итак - например:

Пример расчета сопротивления

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

  • Каждый резистор будет подключен к 2 или более другим резисторам.

  • Вход гарантированно действителен, только с одним входом и одной точкой выхода, которая соединит

  • Сеть будет параллельной, чтобы не требовалось больше математики, чем указано

  • Ввод будет через файл, аргумент или стандартный ввод, в зависимости от того, что подходит для вашего языка.

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

  • Идентификатор первого резистора будет 1, увеличиваясь на единицу для каждого последующего резистора

  • Старт всегда будет иметь идентификатор 0

  • Конечный резистор всегда будет иметь сопротивление 0 Ом, и в его линии будут только те соединения, которые определены

Например:

Пример 2

Может быть представлен как

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

Я надеюсь, что это охватывает все моменты. Удачи!

lochok
источник
/это не обратный слеш Вы имели в виду `\` или косую черту?
Джон Дворжак
Разрешено ли нам давать неверные результаты, если входные данные не являются последовательно-параллельной сетью?
Джон Дворак
1
мост Уитстона не последовательно-параллельно , если заменить центральный вольтметр с сопротивлением
John Dvorak
1
будут ли резисторы всегда подключаться к резисторам с меньшим идентификатором или их можно вводить в любом порядке? Является 1 2/1 0/0 1действительным?
Джон Дворжак
9
Параллельный пример неверен. Это должно быть 15/23, а не 15/8.
Питер Тейлор

Ответы:

6

APL 190

Начало индекса 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 - они выглядят абсолютно безумными. Последний резистор должен был просто дать что-то, что другие резисторы могли бы подключить, - фиктивная концевая связь. Отлично сработано!
lochok
Я думаю, что вы можете сохранить пару символов. Заменить первые две строки на o←⊃↑¨r←¯1↓⍎¨(c≠'/')⊂c. Эта модель применима в нескольких местах.
FUZxxl
5

Python, 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 art в реальном комментарии ...)

Как вводится что-то подобное?

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

В частности, с чем связаны 3 и 4? 1 или 2, или оба 1 и 2?

Кит Рэндалл
источник
И один, и два
Лочок