ศักย์ไฟฟ้าของระบบง่าย


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
จุดบวกสำหรับการใช้เงื่อนไขขอบเขตเป็นระยะและการคำนวณพลังงาน 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ออกและหารด้วยสอง:

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
ดังนั้นคำอธิบายคือส ธ ท. : P
Rɪᴋᴇʀ

2
คุณเคยเขียนสิ่งนี้ในขณะที่มันถูก sandboxed หรือว่าคุณกำลังเร็วจริงๆ?
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)เป็นรายการของอเนกประสงค์ทั้งหมด คำนวณพลังงานที่มีศักยภาพสำหรับการรวมทั้งหมดของทั้งสองอเนกประสงค์ดังกล่าวซึ่งจะไม่เท่ากับผลรวมพวกเขาและแบ่งผลโดยg2


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}

รักษาค่าใช้จ่ายก่อนหน้านี้ในรูปแบบของ tuples [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

Lua, 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)

Ouch, 228 bytes ... ฉันสามารถเล่นกอล์ฟนี้ได้อย่างมีนัยสำคัญ แต่ฉันจะโพสต์ไว้ที่นี่ตอนนี้ อาจอัพเดทในคืนนี้ด้วย musings เพิ่มเติมอีกสองสามและ (หวังว่า) จะปรับปรุงความยาวให้ดีขึ้น

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 ไบต์:ลบสองด้านล่างเก่าสำหรับลูปตอนนี้การประมวลผลเสร็จสิ้นเมื่อมีการเพิ่มสตริงลงในอาร์เรย์สตริง

อัปเดต 246 ไบต์:แทนที่c=="+"or"-"==cด้วยc>" "ตามคำแนะนำของ nimi ความคิดที่ดีขอบคุณ!

อัปเดต 228 ไบต์:หากคำสั่งสามารถลบได้อย่างสมบูรณ์โดยการแทรกในตารางหลังจาก for for loop บันทึกค่อนข้างน้อย


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.