Potensi elektrostatik dari sistem sederhana


21

Dalam fisika, muatan listrik seperti mengusir, dan muatan yang tidak seperti menarik.

Energi potensial antara dua satuan muatan yang dipisahkan oleh jarak dadalah 1/duntuk muatan sejenis dan -1/duntuk muatan tidak sama. Energi potensial dari sistem muatan adalah jumlah energi potensial di antara semua pasangan muatan.

Tantangan

Tentukan energi potensial sistem muatan unit yang diwakili oleh string.

Ini adalah , jadi solusi terpendek dalam byte menang.


Memasukkan

Sebuah multiline string yang tak kosong, hanya terdiri dari +, -, dan baris baru, dengan setiap baris lebar konstan. The +dan -mewakili tuduhan +1 dan -1 masing-masing. Misalnya, string berikut:

    + -
 +     

(mempertimbangkan kiri atas sebagai asal) mewakili sistem dengan muatan positif pada (4,0) dan (1, -1) dan muatan negatif pada (6,0).

Atau, Anda dapat mengambil input sebagai daftar baris.

Keluaran

Bilangan real yang ditandatangani mewakili energi potensial dari sistem biaya. Keluaran harus benar untuk empat angka penting atau 10 -4 , mana yang lebih longgar.

Kasus uji:

   - 
     

Haruskah output 0. Tidak ada pasangan biaya untuk mengusir atau menarik, dan ruang putih tidak mengubah apa pun.

+  
  -

Hanya ada dua tuduhan; mereka 1 unit jauhnya dalam arah vertikal dan 2 unit jauhnya dalam arah horizontal, sehingga jarak mereka adalah sqrt (5). Output harus -1 / sqrt (5) = -0.447213595.

+       -
-       +

Harus memberi -2.001930531.

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

Harus memberi -22.030557890.

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

Harus memberi 26.231088767.


1
Poin plus untuk menerapkan kondisi batas periodik dan menghitung energi Madelung.
Andras Deak

1
@AndrasDeak Itu akan menarik.
lirtosiast

Jawaban:


3

Pyth, 34 byte

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

Demonstrasi

Pertama, kami mengonversi setiap karakter menjadi +1 untuk +, -1 untuk -, dan 0 untuk . Kemudian, setiap angka dianotasi dengan posisinya dalam matriks. Pada titik ini, kami memiliki matriks yang terlihat seperti:

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

Kode yang mencapai titik ini adalah .e+RkCUBxL" +"b.z

Kemudian, kami meratakan matriks ini ke dalam daftar dan mengambil semua pasangan yang memungkinkan, dengan .cs ... 2.

Kemudian, ia menemukan jarak antara pasangan dengan .atMd, dan tanda potensi dengan *FhMd, bagi, dan jumlah.


6

CJam, 51 karakter

Menghitung semua pasangan, memfilter Inf/NaNdan membaginya menjadi dua:

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

Atau, filter koordinat terlebih dahulu sehingga kami menghitung setiap pasangan satu kali dan tidak mengalami Inf/NaN:

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

Penjelasan (lama)

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
Jadi penjelasannya adalah TBA? : P
Rɪᴋᴇʀ

2
Apakah Anda menulis ini saat kotak pasir, atau apakah Anda benar-benar cepat?
lirtosiast

Saya cukup cepat :) Versi pertama adalah "hal paling sederhana yang berhasil", yang hanya membutuhkan waktu beberapa menit untuk saya tulis, jadi saya segera mempostingnya, lalu memutarnya selama setengah jam berikutnya.
Lynn

4

Haskell, 149 144 byte

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

Contoh penggunaan:

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

fadalah daftar semua tiga kali lipat (x-coord, y-coord, unit charge). gmenghitung energi potensial untuk semua kombinasi dari dua kali lipat seperti yang tidak sama, menjumlahkannya dan membagi hasilnya dengan 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}

Mempertahankan susunan biaya sebelumnya dalam bentuk tupel [charge, location(complex number)]dan membandingkan setiap tagihan baru dengan daftar ini, sebelum menambahkannya ke daftar.

Semua spasi di input diganti dengan koma. Ini memungkinkan penugasan berikut dengan mengurangi 44 dari kode ascii mereka:

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

Fakta bahwa program dianggap +sebagai -1 dan -menjadi +1 tidak ada bedanya dengan hasil akhir. Fakta bahwa program ini berupaya menghitung pengaruh biaya 0 untuk spasi tidak ada bedanya, selain memperlambatnya sedikit :-)

Tidak digabungkan dalam program uji

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 byte

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

Bekerja dalam rilis saat ini (5.1.0) . Kompiler berjalan di Matlab atau Oktaf.

Setiap baris adalah input terpisah. Akhir ditandai dengan memasukkan garis kosong.

Contohnya

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

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

Penjelasan

`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 Bytes

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)

Aduh, 228 byte ... Saya mungkin bisa bermain golf ini secara signifikan, tapi saya akan mempostingnya di sini untuk saat ini. Mungkin perbarui nanti malam dengan beberapa renungan lagi dan (semoga) beberapa perbaikan panjangnya.

Tidak disatukan

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)

Perbarui 255 Bytes: Dihapus dua bawah lama untuk loop, pemrosesan sekarang dilakukan sebagai string ditambahkan ke array string

Perbarui 246 Bytes: Diganti c=="+"or"-"==cdengan c>" "sesuai saran nimi. Ide bagus, terima kasih!

Perbarui 228 Bytes: Jika pernyataan bisa dihapus sepenuhnya dengan memasukkan dalam tabel setelah untuk loop, menyimpan beberapa byte.


2

Mathematica 223 byte

Masih bermain 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}]]

Kasus uji terakhir:

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

-22.030557890

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.