#Ruby, 133#
Ruby, 133
#Ruby, 133#
Ruby, 133
#Ruby, 133#
->n{t=i=j=0.0
c=[]
n.tr(' ',?,).bytes{|e|e-=44
z="#{j}+#{i}i".to_c
i+=1
e<-1?i=0*j+=1:(c.map{|d|t+=d[0]*e/(d[1]-z).abs};c<<[e,z])}
t}
Maintains an array of previous charges in the form of tuples [charge, location(complex number)] and compares each new charge with this list, before appending it to the list.
All spaces in the input are replaced with commas. This enables the following assignment by subtracting 44 from their ascii code:
symbol charge (internal representation)
+ -1
, 0
- +1
The fact that the program considers + to be -1 and - to be +1 makes no difference to the final result. The fact that the program goes to the effort of calculating the influence of the charges of 0 for the spaces makes no difference, apart from slowing it down a bit :-)
Ungolfed in test program
g=->n{
t=i=j=0.0 #t=total potential; i and j are coordinates of charge.
c=[] #array to store tuples: charge + location (complex number).
n.tr(' ',?,).bytes{|e| #replace all spaces with commas, then iterate through characters.
e-=44 #subtract 44 from ascii code: + -> -1; comma -> 0; - -> 1
z="#{j}+#{i}i".to_c #position of current character as complex number
i+=1 #advance x coordinate to next character.
e<-1?i=0*j+=1: #if current character is newline, set i to zero and advance j instead,
(c.map{|d|t+=d[0]*e/(d[1]-z).abs};#else add up the contribution for interaction of the current charge with all previous charges,
c<<[e,z])} #and append the current charge to the list of previous charges.
t} #return t
p g[
'+ -
- +'
]
p g[
' - -- -+ - - -+-++-+
+-- + +-- + ++-++ -
---++-+-+- -+- - +-
-- - -++-+ --+ +
- + --+ ++-+ +-
-- ++- + + -+--+
+ +++-+--+ +--+++ +
-+- +-+-+-+ -+ +--+
- +-+- + ---+
- - ++ -+- --+--'
]