Cálculo de resistencia (Nerd Sniping)

10

Buenas tardes golfistas,

Nuestro desafío para hoy está inspirado en los cómics XKCD 356 y 370 . Vamos a escribir un programa para calcular la resistencia de un grupo de resistencias. Una advertencia de que esto es lo suficientemente difícil como para justificar ser un desafío de código, sin embargo, creo que hay cierto arte en escribir programas ligeramente más complejos en un formato de golf. La menor cantidad de personajes gana.

Calcular la resistencia se basa en las siguientes dos fórmulas:

  • Si las resistencias están en serie, la resistencia es la suma de la resistencia de cada resistencia
  • Si las resistencias están en paralelo, la resistencia es la inversa de la suma de la inversa de la resistencia de cada resistencia

Así por ejemplo:

Ejemplo de cálculo de resistencia

Su desafío es, en la menor cantidad de caracteres posible, calcular la resistencia de un grupo de hasta 64 resistencias. Mis disculpas por la complejidad, particularmente de las reglas de entrada. He intentado definirlos de tal manera que todos los idiomas sean utilizables.

  • Cada resistencia se conectará a 2 o más resistencias más.

  • Se garantiza que la entrada sea válida, con solo una entrada y un punto de salida, que se conectará

  • La red será paralela en serie para evitar que se requieran más matemáticas de las que se presentan.

  • La entrada será vía archivo, argumento o stdin, dependiendo de lo que sea apropiado para su idioma.

  • La entrada consistirá en una serie de declaraciones separadas de línea nueva o cortadas hacia adelante que consisten en un número entero de la resistencia de la resistencia y espacios que separan las ID de las resistencias a las que está conectado un lado de la resistencia.

  • La ID de la primera resistencia será 1, incrementándose en uno para cada resistencia sucesiva

  • El inicio siempre tendrá un ID de 0

  • La resistencia final siempre tendrá una resistencia de 0 ohmios y solo tendrá las conexiones definidas en su línea.

Por ejemplo:

Ejemplo 2

Podría ser representado como

3 0
6 1
1 0
5 0
0 2 3 4
  • La salida puede ser stdout o file. Se puede representar de una de las siguientes maneras:
    • Un número con un mínimo de 2 decimales, seguido de una nueva línea
    • Una fracción que consiste en un número entero (el numerador), una barra diagonal y otro número entero (el denominador), seguido de una nueva línea. No es necesario que la fracción esté en su forma más baja: 4/4 o 10/8 son, por ejemplo, aceptables. La fracción debe ser precisa dentro de 1/100. No hay bonificación por ser perfectamente preciso: se proporciona una muleta para permitir que los idiomas sin operaciones de punto fijo o flotante compitan.

Espero que cubra todos los puntos. ¡Buena suerte!

lochok
fuente
/No es una barra invertida. ¿Quiso decir `\ 'o una barra diagonal?
John Dvorak
¿Se nos permite producir resultados incorrectos si la entrada no es una red paralela en serie?
John Dvorak
1
el puente de Wheatstone no es paralelo en serie si reemplaza el voltímetro central con una resistencia
John Dvorak
1
¿Las resistencias siempre se conectarán a aquellas con una ID más baja o pueden ser ingresadas en cualquier orden? Es 1 2/1 0/0 1valido?
John Dvorak
99
El ejemplo paralelo está mal. Debe ser 15/23, no 15/8.
Peter Taylor

Respuestas:

6

APL 190

Origen del índice 1. El primer bucle (s) combina todas las resistencias conectadas en serie, la segunda (p) las conectadas en paralelo y la repetición al primer bucle para combinar cualquier resistencia paralela ahora en serie. La especificación de la resistencia cero final parece ser redundante.

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

Probado sobre los ejemplos en la pregunta más uno un poco más complicado:

      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
Graham
fuente
Siempre asombrados por las respuestas de APL, se ven absolutamente locos. La resistencia final era solo dar algo para que las otras resistencias se conectaran: un enlace final ficticio. ¡Bien hecho!
Lochok
Creo que puedes salvar un par de personajes. Reemplace las dos primeras líneas con o←⊃↑¨r←¯1↓⍎¨(c≠'/')⊂c. Este patrón es aplicable en un par de lugares.
FUZxxl
5

Python, 329 caracteres

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

Calcula la resistencia haciendo una relajación de voltaje en el circuito. Primero, agrega una resistencia de 1 ohm al comienzo y cambia la última resistencia de 0 ohm a 1 ohm. Luego establece el voltaje de entrada a 0 y el voltaje de salida a 1 voltio. Después de simular el flujo de corriente a través de la red, la resistencia de la red se calcula utilizando la caída de voltaje en la primera resistencia de 1 ohm.

Cada resistencia recibe dos números, el número de su terminal izquierdo y el número de su terminal derecho. El terminal izquierdo de la resistencia r es 2 * r y su terminal derecho es 2 * r + 1. La entrada se usa para calcular Slos conjuntos de terminales que están conectados entre sí. A cada terminal se le asigna un voltaje V[t]y se realiza una relajación aumentando el voltaje si la corriente fluye neta hacia un conjunto de terminales y bajando el voltaje si la corriente fluye neta.

Keith Randall
fuente
2

(Este es un comentario, pero no puedo hacer arte ascii en un comentario real ...)

¿Cómo se introduce algo como esto?

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

En particular, ¿a qué están conectados 3 y 4? 1 o 2, o ambos 1 y 2?

Keith Randall
fuente
Tanto uno como dos
lochok