Basit bir sistemin elektrostatik potansiyeli


21

Fizikte, elektrik yükleri gibi itmez ve yüklerin aksine çeker.

İki ünite şarjı arasındaki mesafeyle ayrılan potansiyel enerji d, 1/dbenzer masraflar için ve -1/dmasrafların aksinedir. Bir masraf sisteminin potansiyel enerjisi, tüm masraf çiftleri arasındaki potansiyel enerjilerin toplamıdır.

Meydan okuma

Bir dize tarafından temsil edilen bir birim ücret sisteminin potansiyel enerjisini belirleyin.

Bu , yani bayttaki en kısa çözüm kazanır.


Giriş

Sadece oluşan bir boş olmayan satırlı dize +, -, her hat bir sabit genişlikte olan ve yeni satır. +Ve -+1 ve -1 sırasıyla ücretleri ifade etmektedir. Örneğin, aşağıdaki dize:

    + -
 +     

(üst solun orijin olduğu düşünülürse), (4,0) ve (1, -1) 'de pozitif yüklere (6,0)' da negatif yüke sahip bir sistemi temsil eder.

Alternatif olarak, satırların bir listesi olarak girişi alabilirsiniz.

Çıktı

Ücret sisteminin potansiyel enerjisini temsil eden imzalı bir gerçek sayı. Çıktı , hangisi daha gevşekse, dört önemli sayıya veya 10 -4'e doğru olmalıdır .

Test durumları:

   - 
     

Çıkmalı 0. İtmek veya çekmek için hiçbir ücret çifti yoktur ve beyaz alan hiçbir şeyi değiştirmez.

+  
  -

Sadece iki suçlama var; düşey yönde 1 birim uzakta ve yatay yönde 2 birim uzakta oldukları için mesafeleri sqrt (5) 'dir. Çıktı -1 / sqrt (5) = olmalıdır -0.447213595.

+       -
-       +

Vermelisin -2.001930531.

 - -- -+ - - -+-++-+
 +-- + +-- + ++-++ -
---++-+-+- -+- - +- 
-- - -++-+  --+  +  
-   + --+ ++-+  +-  
--  ++- + +  -+--+  
+ +++-+--+ +--+++ + 
-+- +-+-+-+  -+ +--+
- +-+- +      ---+  
-     - ++ -+- --+--

Vermelisin -22.030557890.

---+--- ++-+++- -+ +
-+ ---+++-+- +- +  +
---+-+ - ----  +-- -
 -   + +--+ -++- - -
--+ - --- - -+---+ -
+---+----++ -   +  +
-+ - ++-- ++-  -+++ 
 +----+-   ++-+-+  -
++- -+ -+---+  -- -+
+-+++ ++-+-+ -+- +- 

Vermelisin 26.231088767.


1
Periyodik sınır koşullarını uygulamak ve Madelung enerjisini hesaplamak için artı puan.
Andras Deak

1
@AndrasDeak Bu ilginç olurdu.
lirtosiast

Yanıtlar:


3

Pyth, 34 bayt

smc*FhMd.atMd.cs.e+RkCUBxL" +"b.z2

gösteri

İlk olarak, her karakteri +1 +, -1 için -ve 0 için dönüştürürüz . Daha sonra, her sayı matris içerisindeki konumuyla açıklanır. Bu noktada, şuna benzeyen bir matrisimiz var:

[[[-1, 0, 0], [-1, 1, 0], [-1, 2, 0], [1, 3, 0], [-1, 4, 0], [-1, 5, 0], [-1, 6, 0]],
 [[1, 0, 1], [1, 1, 1], [-1, 2, 1], [-1, 3, 1], [0, 4, 1], [1, 5, 1], [0, 6, 1]]]

Bu noktaya ulaşan kod .e+RkCUBxL" +"b.z

Sonra, bu matrisi bir düzeye sokar ve olası tüm çiftleri alırız .cs ... 2.

Sonra çifti ile arasındaki mesafeyi .atMdve *FhMdbölme ve toplama potansiyelinin işaretidir .


6

CJam, 51 karakter

Tüm çiftleri sayma, filtreleme Inf/NaNve ikiye bölme:

q_N#:L;N-" +"f#ee2m*{z~:*\Lfmd2/:.-:mh/}%{zL<},:+2/

Alternatif olarak, ilk önce koordinatları filtrelemek, böylece her çifti bir kez sayarız Inf/NaN;

q_N#:L;N-" +"f#ee2m*{0f=:<},{z~:*\Lfmd2/:.-:mh/}%:+

Açıklama (eski)

q                        Get all input.
 _N#:L;                  Store the line width in L.
       N-                Flatten it into one long line.
         :i              Get all ASCII values.
           :(3f%:(       Map space to 0, + to 1, - to -1.
                  ee     Enumerate: list of [index, sign] pairs.
                    2m*  Get all possible pairs.

{                        }%     For each pair:
 e_~                              i1 s1 i2 s2
    @*                            i1 i2 s        (multiply signs)
      \aa@aa+                     s [[i2] [i1]]  (put indices in nested list)
             Lffmd                s [[x2 y2] [x1 y1]]  (divmod by L)
                  :.-             s [xD yD]      (point diff)
                     :mh          s d            (Euclidean dist.)
                        /         s/d            (divide)

{zL<},                   Filter out infinite results.
      :+2/               Sum all charges, and divide by two.
                           (We counted each pair twice.)

3
Yani açıklama TBA mı? : P
Rɪᴋᴇʀ

2
Bunu kum havuzundayken yazdın mı, yoksa gerçekten hızlı mısın?
lirtosiast

Oldukça hızlıyım :) İlk versiyon "işe yarayan en basit şeydi", yazmam sadece birkaç dakikamı aldı.
Lynn

4

Haskell, 149 144 bayt

z=zip[0..]
g n|f<-[(x,y,c)|(y,r)<-z$lines n,(x,c)<-z r,c>' ']=sum[c%d/sqrt((x-i)^2+(y-j)^2)|a@(x,y,c)<-f,b@(i,j,d)<-f,a/=b]/2
c%d|c==d=1|1<2= -1

Kullanım örneği:

*Main> g " - -- -+ - - -+-++-+\n +-- + +-- + ++-++ -\n---++-+-+- -+- - +- \n-- - -++-+  --+  +  \n-   + --+ ++-+  +-  \n--  ++- + +  -+--+  \n+ +++-+--+ +--+++ + \n-+- +-+-+-+  -+ +--+\n- +-+- +      ---+  \n-     - ++ -+- --+--"
-22.030557889699853

ftüm üçlülerin bir listesidir (x-coord, y-coord, unit charge). gEşit olmayan bu üçlünün tüm kombinasyonları için potansiyel enerjiyi hesaplar, toplar ve sonucu böler 2.


3

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}

Önceki ücretler dizisini tupler şeklinde tutar [charge, location(complex number)]ve her yeni ücreti listeye eklemeden önce bu listeyle karşılaştırır.

Girişteki tüm boşluklar virgül ile değiştirilir. Bu, 44 kodunu kendi ascii kodlarından çıkararak aşağıdaki atamayı sağlar:

symbol  charge (internal representation)
+        -1
,         0
-        +1

Programın +-1 ve -+1 olarak görülmesi nihai sonuçta bir fark yaratmıyor. Programın, boşluklar için 0 ücretinin etkisini hesaplama çabasına girmesi, biraz yavaşlatmanın yanı sıra hiçbir fark yaratmıyor.

Test programında Ungolfed

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[
' - -- -+ - - -+-++-+
 +-- + +-- + ++-++ -
---++-+-+- -+- - +- 
-- - -++-+  --+  +  
-   + --+ ++-+  +-  
--  ++- + +  -+--+  
+ +++-+--+ +--+++ + 
-+- +-+-+-+  -+ +--+
- +-+- +      ---+  
-     - ++ -+- --+--'
]

3

MATL , 39 42 bayt

`jt]N$v'- +'FT#m2-I#fbbhtZPwt!**1w/XRss

Çalışıyor , bu sürümde (5.1.0) . Derleyici Matlab veya Octave üzerinde çalışır.

Her satır ayrı bir giriştir. Boş bir satır girilerek bitiş sinyali verilir.

Örnekler

>> matl
 > `jt]N$v'- +'FT#m2-I#fbbhtZPwt!**1w/XRss
 > 
> +       -
> -       +
> 
-2.001930530821583

>> matl
 > `jt]N$v'- +'FT#m2-I#fbbhtZPwt!**1w/XRss
 > 
>  - -- -+ - - -+-++-+
>  +-- + +-- + ++-++ -
> ---++-+-+- -+- - +- 
> -- - -++-+  --+  +  
> -   + --+ ++-+  +-  
> --  ++- + +  -+--+  
> + +++-+--+ +--+++ + 
> -+- +-+-+-+  -+ +--+
> - +-+- +      ---+  
> -     - ++ -+- --+--
> 
-22.03055788969994

açıklama

`jt]           % keep inputting lines until an empty one is found
N$v            % concatenate all inputs vertically. This removes the last empty line
'- +'FT#m      % replace '-', ' ', '+'  by numbers 1, 2, 3
2-             % transform into -1, 0, 1 for '-', ' ', '+'
I#f            % find rows, columnss and values of nonzeros
bbh            % concatenate rows and columns into 2-col matrix or coordinates
tZP            % compute pair-wise distances for those coordinates
wt!*           % generate matrix of signs depending on signs of charges
*              % multiply distances by signs, element-wise
1w/            % invert element-wise
XR             % keep part over the diagonal
ss             % sum along colums, then rows
               % (output is implicitly printed)

3

Lua, 293 255 246 228 Bayt

e=0l={}p={}i=1while l[i-1]~=""do l[i]=io.read()for k=1,#l[i]do c=l[i]:sub(k,k)if(c>" ")then for h,v in ipairs(p)do e=e+(v.s==c and 1 or-1)/math.sqrt((v.y-i)^2+(v.x-k)^2)end table.insert(p,{s=c,x=k,y=i})end end i=i+1 end print(e)

Ah, 228 bayt ... Muhtemelen önemli ölçüde golf bu olabilir, ama şimdilik burada gönderirim. Muhtemelen bu gece daha sonra birkaç müzikle ve (inşallah) uzunluğuyla ilgili bazı gelişmelerle güncelleyin.

Ungolfed

e=0l={}p={}i=1
while l[i-1]~=""do 
    l[i]=io.read()
    for k=1,#l[i]do
        c=l[i]:sub(k,k)
        if(c>" ")then
            for h,v in ipairs(p) do
                e=e+(v.s==c and 1 or-1)/math.sqrt((v.y-i)^2+(v.x-k)^2)
            end
            table.insert(p,{s=c,x=k,y=i})
        end
    end
    i=i+1 
end

print(e)

255 Bayt Güncelleme: Eski alt iki ilmek için kaldırıldı, şimdi dizeler dizeye eklendiğinde işlem yapıldı.

246 Bytes güncelle: Değiştirilen c=="+"or"-"==cile c>" "nimi önerisine göre. Harika fikir, teşekkürler!

Güncelleme 228 Bayt: Eğer for döngüsü sonra tabloya ekleyerek deyimi tamamen kaldırılabilir, oldukça birkaç bayt kaydederek.


2

Mathematica 223 bayt

Hala yapmak için golf.

f[{{c1_,p1_},{c2_,p2_}}]:=N[(c1 c2)/EuclideanDistance[p1,p2],13];
h[charges_]:=Tr[f/@Subsets[DeleteCases[Flatten[Array[{r[[#,#2]],{#,#2}}&,Dimensions[r=Replace[Characters[charges],{"+"-> 1,"-"->-1," "->0},2]]],1],{0,_}],{2}]]

Son test durumu:

h[{" - -- -+ - - -+-++-+", " +-- + +-- + ++-++ -", 
  "---++-+-+- -+- - +- ", "-- - -++-+  --+  +  ", 
  "-   + --+ ++-+  +-  ", "--  ++- + +  -+--+  ", 
  "+ +++-+--+ +--+++ + ", "-+- +-+-+-+  -+ +--+", 
  "- +-+- +      ---+  ", "-     - ++ -+- --+--"}]

-22,030557890

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.