Direnç Hesaplama (Nerd Sniping)


10

İyi Günler Golfçüler,

XKCD esinlenerek bugün için Bizim mücadelemiz Comics'in 356 ve 370 . Bir grup direncin direncini hesaplamak için bir program yazacağız. Bu bir kod meydan okuma olduğunu garanti etmek için neredeyse yeterince zor bir önsöz, ancak golf biçiminde biraz daha karmaşık programlar yazmak için belirli bir sanat olduğunu düşünüyorum. En az karakter kazanır.

Direncin hesaplanması aşağıdaki iki formüle dayanır:

  • Dirençler seri ise, direnç her bir direncin direncinin toplamıdır
  • Dirençler paralel ise, direnç her bir direncin direncinin tersinin toplamının tersidir

Yani mesela:

Direnç hesaplama örneği

Zorluğunuz, mümkün olan en az karakterde 64 dirence kadar bir grubun direncini hesaplamaktır. Karmaşıklık için özür dilerim, özellikle de giriş kurallarından. Onları her dilin kullanılabileceği şekilde tanımlamaya çalıştım.

  • Her direnç 2 veya daha fazla diğer dirence bağlanır.

  • Girişin, yalnızca bir giriş ve bir çıkış noktası ile geçerli olacağı garanti edilir.

  • Ağ, sunulanlardan daha fazla matematik gerektirmesini önlemek için seri paralel olacaktır

  • Giriş, dilinize neyin uygun olduğuna bağlı olarak dosya, argüman veya stdin aracılığıyla olacaktır.

  • Giriş, direncin direncinin bir tamsayısından ve direncin bir tarafının bağlı olduğu dirençlerin kimliklerini ayıran boşluklardan oluşan bir dizi satırsonu veya öne eğik çizgili ifadeden oluşur.

  • İlk direncin kimliği, birbirini izleyen her direnç için bir artarak 1 olacaktır.

  • Başlangıç ​​her zaman 0 kimliğine sahip olacaktır

  • Son direnç her zaman 0 ohm'luk bir dirence sahip olacak ve sadece kendi hattında tanımlanan bağlantılara sahip olacak

Örneğin:

ÖRNEK 2

Olarak temsil edilebilir

3 0
6 1
1 0
5 0
0 2 3 4
  • Çıktı stdout veya dosya olabilir. Aşağıdaki yollardan biriyle temsil edilebilir:
    • En az 2 ondalık basamağa ve ardından yeni satıra sahip bir sayı
    • Bir tamsayı (pay), bir eğik çizgi ve başka bir tamsayıdan (payda) oluşan bir kesir ve bunu bir satırsonu izler. Fraksiyonun en düşük formda olması gerekmez - örneğin 4/4 veya 10/8 kabul edilebilir. Kesir 1/100 içinde doğru olmalıdır. Mükemmel doğruluk için bir bonus yoktur - bu, sabit veya kayan nokta işlemleri olmayan dillerin rekabet etmesini sağlamak için bir koltuk değneği sağlar.

Umarım tüm noktaları kapsar. İyi şanslar!


/ters eğik çizgi değildir. Şunu mu demek istediniz: `` ya da eğik çizgi?
John Dvorak

Giriş seri paralel bir ağ değilse yanlış sonuçlar üretmemize izin verilir mi?
John Dvorak

1
Wheatstone köprüsü , bir direnç ile merkez voltmetre değiştirirseniz seri-paralel değildir
John Dvorak

1
dirençler her zaman daha düşük ID'li olanlara bağlanır mı yoksa herhangi bir sırada girilebilir mi? Mı 1 2/1 0/0 1geçerli?
John Dvorak

9
Paralel örnek yanlış. 15/8 değil, 15/23 olmalıdır.
Peter Taylor

Yanıtlar:


6

APL 190

Dizin kaynağı 1. İlk devre (ler) seri olarak bağlanmış tüm dirençleri, ikinci (p) paralel olarak bağlanmış olanları ve şimdi seri halinde olan paralel dirençleri birleştirmek için ilk döngüye tekrarlayın. Nihai sıfır direncinin spesifikasyonu gereksiz görünüyor.

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

Sorudaki örnekler ve biraz daha karmaşık olanı test ettik:

      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

Her zaman APL cevaplarına hayran kaldım - kesinlikle deli görünüyorlar. Son direnç sadece diğer dirençlerin bağlanması için bir şey vermekti - kukla bir son bağlantı. Aferin!
lochok

Sanırım birkaç karakter kaydedebilirsin. İlk iki satırı ile değiştirin o←⊃↑¨r←¯1↓⍎¨(c≠'/')⊂c. Bu desen birkaç yerde uygulanabilir.
FUZxxl

5

Python, 329 karakter

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

Devrede voltaj gevşemesi yaparak direnci hesaplar. İlk önce 1 ohm'luk bir direnci başlangıca bağlar ve son direnci 0 ohm'dan 1 ohm'a değiştirir. Daha sonra giriş voltajını 0 ve çıkış voltajını 1 volta ayarlar. Ağ üzerinden akım akışını simüle ettikten sonra, ağ direnci ilk 1 ohm dirençteki voltaj düşüşü kullanılarak hesaplanır.

Her dirence iki sayı verilir, sol terminal numarası ve sağ terminal numarası. Direnç r'in sol terminali 2 * r ve sağ terminali 2 * r + 1'dir. Giriş, Sbirbirine bağlı terminal setlerini hesaplamak için kullanılır . Her terminale bir voltaj verilir V[t]ve bir terminal setine akım net akıyorsa voltaj yükseltilerek ve akım net akıyorsa voltaj düşürülerek gevşeme yapılır.


2

(Bu bir yorum, ama ascii sanatını gerçek bir yorumda yapamam ...)

Böyle bir şey nasıl girilir?

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

Özellikle, 3 ve 4 neye bağlıdır? 1 veya 2 mi, yoksa 1 ve 2 mi?


Hem bir hem de iki
lochok
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.