Potencjał elektrostatyczny prostego układu

21

W fizyce, jak ładunki elektryczne odpychają, a w przeciwieństwie do ładunków przyciągają.

Energia potencjalna między dwoma ładunkami jednostkowymi oddzielonymi odległością djest 1/ddla podobnych ładunków i -1/ddla różnych ładunków. Energia potencjalna układu ładunków jest sumą energii potencjalnej między wszystkimi parami ładunków.

Wyzwanie

Określ energię potencjalną układu ładunków jednostkowych reprezentowanych przez ciąg.

To jest , więc wygrywa najkrótsze rozwiązanie w bajtach.


Wkład

To niepusty ciąg wielowierszowego, składający się tylko z +, -, i nowej linii, z każdej linii stałej szerokości. +I -stanowią koszty +1 i -1, odpowiednio. Na przykład następujący ciąg:

    + -
 +     

(biorąc pod uwagę, że lewy górny to początek) reprezentuje układ z dodatnimi ładunkami przy (4,0) i (1, -1) i ujemnym ładunkiem przy (6,0).

Alternatywnie, możesz wziąć dane wejściowe jako listę linii.

Wydajność

Podpisana liczba rzeczywista reprezentująca energię potencjalną układu ładunków. Dane wyjściowe powinny być poprawne do czterech cyfr znaczących lub 10-4 , w zależności od tego, która wartość jest luźniejsza.

Przypadki testowe:

   - 
     

Powinien wyjść 0. Nie ma par ładunków, które mogłyby odpychać lub przyciągać, a białe znaki nic nie zmieniają.

+  
  -

Są tylko dwa obciążenia; są one oddalone o 1 jednostkę w kierunku pionowym i 2 jednostki w kierunku poziomym, więc ich odległość wynosi sqrt (5). Wyjście powinno wynosić -1 / sqrt (5) = -0.447213595.

+       -
-       +

Powinien dać -2.001930531.

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

Powinien dać -22.030557890.

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

Powinien dać 26.231088767.

lirtosiast
źródło
1
Plus punkty za wdrożenie okresowych warunków brzegowych i obliczenie energii Madelunga.
Andras Deak,
1
@AndrasDeak To byłoby interesujące.
lirtosiast

Odpowiedzi:

3

Pyth, 34 bajty

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

Demonstracja

Najpierw konwertujemy każdy znak na +1 dla +, -1 dla -i 0 dla . Następnie każda liczba jest opatrzona adnotacjami z jej pozycją w matrycy. W tym momencie mamy matrycę, która wygląda następująco:

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

Kod, który osiąga ten punkt to .e+RkCUBxL" +"b.z

Następnie spłaszczamy tę macierz do listy i bierzemy wszystkie możliwe pary, z .cs ... 2.

Następnie znajduje odległość między parą .atMdi znakiem potencjału z *FhMd, dziel i sumuj.

isaacg
źródło
6

CJam, 51 znaków

Zliczanie wszystkich par, odfiltrowywanie Inf/NaNi dzielenie przez dwie:

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

Alternatywnie, najpierw filtruj współrzędne, aby policzyć każdą parę raz i nie napotkać Inf/NaN:

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

Objaśnienie (stare)

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.)
Lynn
źródło
3
Więc wyjaśnienie to TBA? : P
Rɪᴋᴇʀ
2
Czy napisałeś to w piaskownicy, czy jesteś naprawdę szybki?
lirtosiast
Jestem dość szybki :) Pierwsza wersja była „najprostszą rzeczą, która działała”, co zajęło mi tylko kilka minut, więc natychmiast ją opublikowałem, a potem grałem w golfa w ciągu następnych pół godziny.
Lynn
4

Haskell, 149 144 bajtów

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

Przykład użycia:

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

fto lista wszystkich potrójnych (x-coord, y-coord, unit charge). goblicza energię potencjalną dla wszystkich kombinacji dwóch takich potrójnych, które nie są równe, sumuje je i dzieli wynik przez 2.

nimi
źródło
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}

Utrzymuje szereg poprzednich opłat w postaci krotek [charge, location(complex number)]i porównuje każdą nową opłatę z tą listą, przed dołączeniem jej do listy.

Wszystkie spacje na wejściu są zastępowane przecinkami. Umożliwia to następujące przypisanie, odejmując 44 od kodu ascii:

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

Fakt, że program uważa +za -1 i -za +1, nie ma znaczenia dla końcowego wyniku. Fakt, że program stara się obliczyć wpływ ładunków 0 na przestrzenie, nie ma różnicy, oprócz spowolnienia go :-)

Niegolfowany w programie testowym

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[
' - -- -+ - - -+-++-+
 +-- + +-- + ++-++ -
---++-+-+- -+- - +- 
-- - -++-+  --+  +  
-   + --+ ++-+  +-  
--  ++- + +  -+--+  
+ +++-+--+ +--+++ + 
-+- +-+-+-+  -+ +--+
- +-+- +      ---+  
-     - ++ -+- --+--'
]
Level River St
źródło
3

MATL , 39 42 bajtów

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

Działa w aktualnej wersji (5.1.0) . Kompilator działa na Matlabie lub Octave.

Każda linia jest osobnym wejściem. Koniec jest sygnalizowany przez wprowadzenie pustej linii.

Przykłady

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

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

Wyjaśnienie

`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)
Luis Mendo
źródło
3

Lua, 293 255 246 228 bajtów

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)

Ojej, 228 bajtów ... Prawdopodobnie mogę znacznie zagrać w golfa, ale na razie opublikuję to tutaj. Prawdopodobnie zaktualizuję go później wieczorem o kilka rozważań i (miejmy nadzieję) pewne poprawki długości.

Nie golfił

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)

Aktualizacja 255 bajtów: Usunięto stare dwie dolne dwie pętle, przetwarzanie jest teraz wykonywane, gdy ciągi są dodawane do tablicy ciągów.

Zaktualizuj 246 bajtów: Zastępuje c=="+"or"-"==csię c>" "zgodnie z sugestią za Nimi. Świetny pomysł, dzięki!

Zaktualizuj 228 bajtów: Jeśli instrukcja mogłaby zostać całkowicie usunięta, wstawiając tabelę po pętli for, oszczędzając sporo bajtów.

Cyv
źródło
2

Mathematica 223 bajty

Wciąż gra w golfa.

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

Ostatni przypadek testowy:

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

-22,030557890

DavidC
źródło