Електростатичний потенціал простої системи


21

У фізиці як електричні заряди відштовхуються, і на відміну від зарядів притягують.

Потенційна енергія між двома одиничними зарядами, розділеними на відстань, dстановить1/d для подібних зарядів і -1/dдля несхожих зарядів. Потенційна енергія системи зарядів - це сума потенційних енергій між усіма парами зарядів.

Виклик

Визначте потенційну енергію системи одиничних зарядів, представлених рядком.

Це , тому найкоротше рішення в байтах виграє.


Вхідні дані

Непорожня багаторядкова рядок, що складається тільки +, -, і перекладів рядків, з кожною лінією постійної шириною. +І -є заряди +1 і -1 відповідно. Наприклад, наступний рядок:

    + -
 +     

(враховуючи початок зліва вгорі) являє собою систему з позитивними зарядами при (4,0) та (1, -1) та негативним зарядом при (6,0).

Крім того, ви можете взяти дані як список рядків.

Вихідні дані

Підписане реальне число, що представляє потенційну енергію системи зарядів. Вихід повинен бути правильним для чотирьох значущих цифр або 10 -4 , залежно від того, що є втраченим.

Тестові приклади:

   - 
     

Потрібно вивести 0. Немає пари зарядів для відштовхування або залучення, а пробіл нічого не змінює.

+  
  -

Є лише два звинувачення; вони знаходяться на відстані 1 одиниці у вертикальному напрямку та на 2 одиниці у горизонтальному напрямку, тому їх відстань дорівнює sqrt (5). Вихід повинен бути -1 / sqrt (5) = -0.447213595.

+       -
-       +

Слід давати -2.001930531.

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

Слід давати -22.030557890.

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

Слід давати 26.231088767.


1
Плюс балів за реалізацію періодичних граничних умов та обчислення енергії Маделунга.
Андрас Деак

1
@AndrasDeak Це було б цікаво.
lirtosiast

Відповіді:


3

Pyth, 34 байти

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

Демонстрація

Спочатку ми перетворюємо кожен символ у +1 для +, -1 для -та 0 для . Потім кожне число анотується зі своїм положенням у матриці. На даний момент у нас є матриця, яка виглядає так:

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

Код, який досягає цієї точки, є .e+RkCUBxL" +"b.z

Потім ми вирівнюємо цю матрицю в список і беремо всі можливі пари з .cs ... 2.

Потім він знаходить відстань між парою з .atMdі знаком потенціалу з *FhMd, ділити та суму.


6

CJam, 51 ч

Підрахунок всіх пар, фільтрування Inf/NaNта ділення на два:

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

Крім того, спочатку фільтруємо координати, тому ми підраховуємо кожну пару раз і не натрапляємо на Inf/NaN:

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

Пояснення (стара)

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
Отже, пояснення - TBA? : P
Rɪᴋᴇʀ

2
Ви писали це, поки це було пісочницею, чи ви просто дуже швидкі?
lirtosiast

Я досить швидкий :) Перша версія була "найпростішою справою, що працювала", на що у мене пішло лише пару хвилин, тож я негайно опублікував це, а потім переграв це протягом наступних півгодини.
Лінн

4

Haskell, 149 144 байт

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

Приклад використання:

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

fце список усіх трійки (x-coord, y-coord, unit charge). gобчислює потенційну енергію для всіх комбінацій двох таких трійки, які не є рівними, підсумовує їх і ділить результат на 2.


3

Рубі, 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}

Підтримує масив попередніх стягнень у вигляді кортежів [charge, location(complex number)]і порівнює кожну нову плату з цим списком, перш ніж додавати її до списку.

Усі пробіли на вході замінюються комами. Це дозволяє виконувати наступне завдання, віднімаючи 44 з коду ascii:

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

Той факт, що програма вважає +-1 та -+1, не має значення для кінцевого результату. Те, що програма спрямовується на обчислення впливу зарядів 0 на пробіли, не має ніякої різниці, крім того, щоб трохи уповільнити її :-)

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 байт

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

Працює в поточному випуску (5.1.0) . Компілятор працює на Matlab або Octave.

Кожен рядок є окремим входом. Кінець сигналізується введенням порожнього рядка.

Приклади

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

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

Пояснення

`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

Луа, 293 255 246 228 байт

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)

Ой, 228 байт ... Я, мабуть, можу це значно помітити в гольф, але поки що опублікую його тут. Ймовірно, оновіть його пізніше сьогодні ввечері ще кількома розміщеннями та (сподіваємось) деякими поліпшеннями довжини.

Безумовно

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 байт: Видалено старі два низу для циклів, обробка тепер виконується, оскільки рядки додаються до масиву рядків.

Оновлення 246 байт: Замінено c=="+"or"-"==cз c>" "згідно з пропозицією Ними в. Чудова ідея, дякую!

Оновлення 228 байтів: Якщо оператор можна було повністю видалити, вставивши в таблицю після циклу for, заощадивши досить багато байтів.


2

Математика 223 байти

Ще гольф робити.

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

Останній тестовий випадок:

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

-22.030557890

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.