간단한 시스템의 정전 전위


21

물리학에서는 전하가 격퇴하고 전하와는 달리 매력이 있습니다.

거리만큼 분리 된 두개의 단위 전하 사이의 에너지는 d이고 1/d비용 등과 -1/d달리 비용에 대한. 전하 시스템의 전위 에너지는 모든 전하 쌍 사이의 전위 에너지의 합입니다.

도전

스트링으로 표시되는 단위 요금 시스템의 잠재적 에너지를 결정합니다.

이것은 이므로 바이트 단위의 최단 솔루션이 이깁니다.


입력

만 이루어진 여러 비어 있지 않은 문자열 +, -, 각 라인에 일정 폭과 바꿈. +와는 -+1과 -1 각각의 요금을 나타냅니다. 예를 들어 다음 문자열은

    + -
 +     

(왼쪽 상단을 원점으로 간주)은 (4,0) 및 (1, -1)에 양전하가 있고 (6,0)에 음전하가있는 시스템을 나타냅니다.

또는 줄 목록으로 입력 할 수 있습니다.

산출

충전 시스템의 잠재적 에너지를 나타내는 부호있는 실수. 출력값은 유효 숫자 4 개 또는 10-4 중 더 느슨한쪽에 맞아야합니다.

테스트 사례 :

   - 
     

출력해야합니다 0. 격퇴하거나 유치 할 청구 쌍이 없으며 공백은 아무 것도 변경하지 않습니다.

+  
  -

두 번만 청구됩니다. 수직 방향으로 1 단위, 수평 방향으로 2 단위 떨어져 있으므로 거리는 sqrt (5)입니다. 출력은 -1 / sqrt (5) =이어야합니다 -0.447213595.

+       -
-       +

줘야한다 -2.001930531.

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

줘야한다 -22.030557890.

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

줘야한다 26.231088767.


1
주기적 경계 조건을 구현하고 Madelung 에너지를 계산하기위한 플러스 포인트.
Andras Deak

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내고 2로 나눕니다.

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

나는 매우 빠르다 :) 첫 번째 버전은 "가장 간단한 것"이었다. 몇 분 밖에 걸리지 않았다. 그래서 나는 즉시 그 내용을 게시 한 후 다음 30 분 동안 골프를 쳤다.
Lynn

4

하스켈, 149144 바이트

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)]새 청구 항목을 목록에 추가하기 전에이 목록과 비교합니다.

입력의 모든 공백은 쉼표로 바뀝니다. 이를 통해 ASCII 코드에서 44를 빼서 다음 할당을 수행 할 수 있습니다.

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

프로그램 +이 -1, -+1로 간주한다는 사실 은 최종 결과와 아무런 차이가 없습니다. 프로그램이 공간에 대해 0의 전하의 영향을 계산하려고 노력한다는 사실은 조금 느리게하는 것 외에 차이가 없습니다 :-)

테스트 프로그램에서 언 골프

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 바이트 업데이트 : 루프의 이전 하단 2 개가 제거되었으며 이제 문자열이 문자열 배열에 추가되면 처리가 완료됩니다.

246 바이트 업데이트 : 니미의 제안에 따라 대체 c=="+"or"-"==c되었습니다 c>" ". 좋은 생각이야, 고마워!

228 바이트 업데이트 : for 루프 다음에 테이블에 삽입하여 if 문을 완전히 제거 할 수있어 상당히 많은 바이트를 절약 할 수 있습니다.


2

Mathematica 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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.