Double Slit Experiment


16

นักฟิสิกส์ขี้เกียจมีหน้าที่ในการทำการทดลองสองช่อง อย่างไรก็ตามพวกเขาขี้เกียจและไม่สามารถใส่ใจในการตั้งค่าอุปกรณ์ทั้งหมดด้วยตัวเองและเพื่อจำลองผลกระทบ พวกเขาไม่สามารถตั้งโปรแกรมได้ดังนั้นจะต้องการความช่วยเหลือบ้าง โปรแกรมของคุณควรสั้นที่สุดเท่าที่จะเป็นไปได้


รับจำนวนเต็มบวกคี่n( n >= 1และn % 2 == 1) ทำการจำลอง

มันทำงานอย่างไร

คุณจะเริ่มต้นด้วยผ้าใบที่ว่างเปล่าและแต่ละเฟรมจะมีแสงอนุภาคเดียวผ่านทะลุและลงบนผืนผ้าใบ อนุภาคจะตกลงมาถึงจุดสูงสุดโดยมีโอกาส:

n = 1:

+-----+
|     |
| 1/2 |
|     |
+-----+

n = 3:

+-----+ +-----+ +-----+
|     | |     | |     |
| 1/4 | | 1/2 | | 1/4 |
|     | |     | |     |
+-----+ +-----+ +-----+

n = 5:

+-----+ +-----+ +-----+ +-----+ +-----+
|     | |     | |     | |     | |     |
| 1/8 | | 1/4 | | 1/2 | | 1/4 | | 1/8 |
|     | |     | |     | |     | |     |
+-----+ +-----+ +-----+ +-----+ +-----+

เป็นต้น

ตัวอย่างเช่นn=5เราตรวจสอบกล่องกลางมีโอกาส 50% ที่จะตกลงไป ถ้ามันอยู่ท้ายเฟรมหากไม่เลื่อนไปยังอีกสองเฟรมถัดไปแสดงว่ามีโอกาส 25% ที่จะตกลงมา ถ้ามันอยู่ท้ายเฟรมหากไม่เลื่อนไปยังอีกสองเฟรมถัดไปแสดงว่ามีโอกาส 12.5% ​​ที่จะตกลงไป หากไม่ตกไม่เป็นไรก็ยังเป็นจุดจบของเฟรม

มีความสับสนเกี่ยวกับวิธีการคำนวณโอกาสส่วนใหญ่เกิดจากคนที่คิดว่าพวกเขาเป็นความน่าจะเป็นที่ควรรวมถึง 1 เอาความคิดนั้นออกจากใจของคุณและควรทำให้ชัดเจนขึ้นเล็กน้อยสำหรับคุณ

  • อย่างน้อยที่สุดหนึ่งอนุภาคจะลดลงต่อหนึ่งเฟรมซึ่งหมายความว่าอนุภาคอาจไม่ตกลงบนเฟรมนั้น
  • อนุภาคสามารถแสดงด้วยอักขระที่พิมพ์ได้
  • อนุภาคจะลงที่ใดก็ได้ในกล่องโดยมีโอกาสสุ่ม
  • ความกว้างของกล่องควรเป็น2n-1ขนาดของผืนผ้าใบ ดังนั้นสำหรับn=5พวกเขาควรเป็น1/9ความกว้างของผืนผ้าใบ
  • ความสูงของกล่องควรเป็นความสูงของผืนผ้าใบ
  • อนุภาคไม่ควรลงจอดด้านนอกของกล่องเลย
  • หากอนุภาคได้ร่อนลง ณ จุดที่เลือกไว้แล้วไม่สำคัญว่าจะสามารถลงจอดได้อีก
  • กล่อง ascii ด้านบนมีไว้เพื่อความชัดเจนไม่ควรดึงกล่อง
  • คุณสามารถเลือกขนาดผ้าใบของคุณเองได้ตราบใดที่เหมาะสม ตัวอย่างเช่นจะต้องไม่สูงเพียงไม่กี่พิกเซล มันควรจะสามารถใส่กล่องทั้งหมดที่อยู่ในกล่องได้
  • หากรหัสของคุณอยู่ระหว่างเฟรมคุณไม่จำเป็นต้องเพิ่มเข้าไปในจำนวนไบต์ของคุณ

ควรมีช่องว่างระหว่างค่าสูงสุดแต่ละค่าต่ำสุด ควรมีความกว้างเท่ากับกล่อง แต่จะไม่มีอนุภาคลงจอด ดูแผนภาพต่อไปนี้:

+---+---+---+---+---+
|   |   |   |   |   |
|max|min|max|min|max|
|   |   |   |   |   |
+---+---+---+---+---+

โปรแกรมควรทำงานจนกว่าจะหยุดด้วยตนเอง

กฎระเบียบ

  • ตัวสร้างตัวเลขสุ่มหลอก (pRNG) นั้นใช้ได้
  • ช่องโหว่มาตรฐานเป็นสิ่งต้องห้าม
  • ข้อมูลอาจถูกนำไปใช้ในรูปแบบที่เหมาะสม
  • คุณควรส่งออกไปยัง STDOUT
  • นี่คือดังนั้นคำตอบที่สั้นที่สุดชนะ

ตัวอย่าง

GIF n = 5ต่อไปนี้เป็นตัวอย่างที่ใช้สำหรับ ฉันเพิ่งกระแทกมันอย่างรวดเร็วเพื่อโอกาสที่จะหลุดออกไปเล็กน้อย

ตัวอย่างช่องแยกคู่


ความคิดเห็นไม่ได้มีไว้สำหรับการอภิปรายเพิ่มเติม การสนทนานี้ได้รับการย้ายไปแชท
Martin Ender

คำตอบ:


4

Python 2, 207 200 ไบต์

มีวิธีหนึ่งสำหรับความบ้าคลั่งนี้ฉันสัญญา ทำตามการตีความความน่าจะเป็นที่ฉันแสดงความคิดเห็นใน OP

แก้ไข: -7 ไบต์ผ่านการประเมินผลที่ขี้เกียจที่ฉลาด (และลบเครื่องหมายบางอย่าง)

import time  # not counted for byte total
import random as R,curses as C
r=R.randint
c=C.initscr()
h,w=c.getmaxyx()
n=input()
w/=2*n-1
while 1:
 all(r(0,1)or c.addch(r(0,h-1),(i*(2-4*r(0,1))+n)*w-r(1,w),42)for i in range(n/2+1))
 c.refresh()
 time.sleep(0.1)  # not counted for byte total

4

BASH, 396 - 11 = 385 ไบต์

E='echo -en';$E "\e[2J\e[99A";while :;do sleep 0.01;for i in `seq $((($1+1)/2)) -1 1`;do p=$(((($1+1)/2 - $i)));[ $p -lt 0 ]&&p=$((-$p));p=$((2**(p+1)));if [ $RANDOM -lt $((32768/$p)) ];then [ $(($RANDOM%2)) -eq 1 ]&&i=$((($1+1)-i));sector=$(((i*2-1)-1));C=`tput cols`;R=`tput lines`;SS=$((C/($1*2-1)));SX=$((SS*sector));X=$((SX+(RANDOM%SS)));Y=$((RANDOM%R));$E "\e[$Y;${X}H*";break;fi;done;done

น่าเสียดายที่ฉันไม่สามารถสาธิตสิ่งนี้บน TryItOnline ได้เนื่องจากลำดับการวนลูป & ANSI ไม่มีที่สิ้นสุดที่เลื่อนเคอร์เซอร์ แต่คุณยังสามารถคัดลอกวางในเทอร์มินัลของคุณได้!

รุ่นที่ไม่ระบุ:

E='echo -en'
$E "\e[2J\e[99A"

while :
do
    sleep 0.01
    for i in `seq $((($1+1)/2)) -1 1`
    do
        p=$(((($1+1)/2 - $i)))
        [ $p -lt 0 ] && p=$((-$p));
        p=$((2**(p+1)))
        if [ $RANDOM -lt $((32768/$p)) ]
        then
            [ $(($RANDOM%2)) -eq 1 ] && i=$((($1+1)-i));
            sector=$(((i*2-1)-1))
            C=`tput cols`
            R=`tput lines`
            SS=$((C/($1*2-1)))
            SX=$((SS*sector))
            X=$((SX+(RANDOM%SS)))
            Y=$((RANDOM%R))
            $E "\e[$Y;${X}H*"
            break
        fi
    done
done

1
ตรวจสอบเคล็ดลับสำหรับการเล่นกอล์ฟในทุบตี เช่น - มีค่อนข้างน้อยง่ายผลไม้แขวนต่ำสำหรับคุณที่จะเก็บเกี่ยวที่นี่แทน$[ ] $(( ))แทนfor i in `seq $((($1+1)/2)) -1 1`;do ...;donefor((i=($1+1)/2;i>0;i--));{ ...;}พยายาม แทนที่จะพยายาม[ $(($RANDOM%2)) -eq 1 ] , ฯลฯ ควรถูกแทนที่ด้วย 1 ชื่อตัวแปรถ่าน ((RANDOM%2))sectorSS
บาดเจ็บทางดิจิตอล

3

Mathematica, 231 ไบต์

(R=RandomInteger;p=20(#+1)+10;s=Array[0&,{20,6p-3}];i=(#+1)/2;Monitor[While[1<2,y=RandomChoice[Join[q=Riffle[Array[2^#&,i,0],Table[0,i-1]],Reverse@Most@q]->Array[Range[4#+1]&,i,0][[i]]];s[[R@19+1,10y-R@9]]=1;s],Grid[s//. 0->" "]])&


อินพุต

[5]

เอาท์พุต

ป้อนคำอธิบายรูปภาพที่นี่


สิ่งนี้ดูเหมือนจะไม่ถูกต้องสำหรับ n = 5 ควรมีเพียง 5 กล่องคุณมี 9
TheLethalCoder

ฉันรู้ว่าฉันนับเช่น {... 3,2,1,2,3 ... } ฉันสามารถแก้ไขได้หากไม่ได้รับการยอมรับ
J42161217

2
@TheLethalCoder แก้ไขแล้ว! ปรับปรุง! แข็งแรงเล่นกอล์ฟ!
J42161217

ดูดี
โหวตขึ้น

2

C # (.NET 4.5), 319 254 ไบต์

บันทึกแล้ว 65 ไบต์ขอบคุณ TheLethalCoder!

namespace System{using static Console;n=>{for(var r=new Random();;)for(int w=WindowWidth/(2*n-1),i=(n-1)/2,c=0,m=2,l;i>-1;i--,c+=2)if((l=r.Next(0,(m*=2+1)*2))<2){SetCursorPosition((i+(l<1?c:0))*2*w+r.Next(0,w),r.Next(0,WindowHeight));Write('*');break;}}}

ว้านั่นเป็นงานมาก แต่ก็ใช้งานได้ดี

เนื่องจากสิ่งนี้ใช้Consoleฟังก์ชั่นที่เฉพาะเจาะจงและการนอนหลับของเธรดมันจึงไม่สามารถใช้กับ TIO ได้อย่างน่าเศร้า


คอมไพล์เพื่อ an Action<int>บันทึกไบต์while(true)-> ( while(1>0)-> for(;;). using C=Console;หรือusing static Console;.
TheLethalCoder

แอปพลิเคชั่นนั้นได้รับอนุญาตให้เป็นผู้แทนเช่นกัน? ไม่ทราบว่า ฉันจะอัปเดตในไม่กี่วินาที
เอียนเอช.

โปรแกรม / ฟังก์ชั่นได้รับอนุญาตโดยค่าเริ่มต้นและ lambdas ที่ไม่ระบุชื่อจะนับเป็นฟังก์ชั่น
TheLethalCoder

255 ไบต์namespace System{using static Console;n=>{for(var r=new Random();;)for(int w=WindowWidth/(2*n-1),i=(n-1)/2,c=0,m=2,l;i>-1;i--,c+=2)if((l =r.Next(0,(m*=2+1)*2))<2){SetCursorPosition((i+(l<1?c:0))*2*w+r.Next(0,w),r.Next(0,WindowHeight));Write('*');break;}}}
TheLethalCoder

@TheLethalCoder รหัสนั้นไม่ทำงาน: / เพียงแค่ให้Variable is not existing in the current contextข้อผิดพลาดจำนวนมาก
เอียนเอช.

1

Clojure + Quil ขนาด 394 ไบต์

(use '[quil.core])(defn -main[n](let[w 999 h 100 c(/ w(-(* n 2)1))s(range 0 w c)a(vec(take-nth 2 s))v(fn[x](<(rand)x))q(fn[a b](+ a(rand-int(- b a))))g(for[i(range(int(/ n 2))-1 -1)][i(- n 1 i)])z(for[[j i](map vector(range 1(inc(count g)))g)][(/ 1(Math/pow 2 j))i])](defsketch m :size[w h]:draw #(loop[[[p i]& r]z](when p(if(v p)(let[o(a(rand-nth i))](point(q o(+ o c))(q 0 h)))(recur r)))))))

แน่นอนว่าฉันไม่ชนะ แต่นี่เป็นการออกกำลังกายสมองที่ดี! ฉันอาจเลือกวงเวียนสุดเหวี่ยงในการทำสิ่งนี้ แต่ใช้งานได้! โดยพื้นฐานแล้วมันทำงานอย่างไร:

  1. ค่า x ของแต่ละคอลัมน์คำนวณจาก nX-ค่าของแต่ละคอลัมน์จะคำนวณตามจากนั้น "colums ที่ใช้งาน" ซึ่งจะมีจุดต่าง ๆ ถูกกรองออกไป คอลัมน์จะถูกบีบอัดพร้อมกับความเป็นไปได้ที่จะถูกเลือก

  2. ภาพเคลื่อนไหวเริ่มต้นและแต่ละเฟรมจะมีการป้อนลูป เริ่มจากตรงกลางแต่ละคอลัมน์จะถูกลอง เมื่อเลือกหนึ่งคอลัมน์คู่หนึ่งคอลัมน์จากคู่นั้นจะถูกสุ่มเลือก

  3. จุดถูกวาดที่ตำแหน่งสุ่มภายในคอลัมน์ที่เลือกการวนรอบด้านในออกและเฟรมใหม่จะเริ่มขึ้น

ใช้ไลบรารีกราฟิก Quil ซึ่งเป็นตัวห่อหุ้มการประมวลผลสำหรับ Clojure

หมายเหตุรหัส golfed ไม่ได้สร้างภาพเคลื่อนไหวเหมือนที่แสดงใน GIF ในรหัส golfed พื้นหลังเป็นสีเทาและหน้าต่างและจุดต่าง ๆ มีขนาดเล็กลง มันมีเอฟเฟกต์แบบเดียวกันมันไม่สวยเท่าไหร่

GIF

ดูรหัส ungolfed สำหรับคำอธิบายในเชิงลึก:

(ns bits.golf.interference.interference
  (:require [quil.core :as q]))

; Canvas size
(def width 1800)
(def height 800)

(defn -main [n]
  (let [col-width (/ width (- (* n 2) 1))
        ; The left-most x of each column
        col-starts (range 0 width col-width)

        ; The columns that need to be drawn. Need "vec" so I can index it later.
        active-cols (vec (take-nth 2 col-starts))

        ; Function taking a decimal percentage, and returning whether or not it's satisfied.
        ; (chance? 0.5) would be used to simulate a coin toss.
        chance? (fn [perc] (< (rand) perc))

        ; Function that returns a random int between a and b
        r-int (fn [a b] (+ a (rand-int (- b a))))

        ; Generates index pairs for each complimentary column.
        indices (for [i (range (int (/ n 2)) -1 -1)]
                  [i (- n 1 i)])

        ; Zips each index pair from above with the chance that it will be" chosen"
        zipped-perc (for [[j i] (map vector (range 1 (inc (count indices))) indices)]
                      [(/ 1 (Math/pow 2 j)) i])]

    ; Animation boilerplate
    (q/defsketch Interference
      :size [width height]
      :draw
      ; The animation loop. It contains a loop over each complimentary column. It tries each column pair starting
      ;  from the middle, and works outward. Once it picks a pair of columns, it randomly chooses one of them.
      #(loop [[[p i] & r] zipped-perc]
         (when p
           ; Pick this column?
           (if (chance? p)
             ; Pick one of the column pairs
             (let [col (active-cols (rand-nth i))]
               ; Set the coloring and dot size
               (q/fill 0 0 0)
               (q/stroke-weight 5)
               ; And finally draw the dot
               (q/point (r-int col (+ col col-width))
                        (r-int 0 height)))

             ; If the column wasn't chosen, loop again to try the next one
             (recur r)))))))

0

C #, 238 ไบต์

namespace System{using static Console;n=>{for(var r=new Random();;)for(int i=0,p=1,w=WindowWidth/(2*n-1),x;i<n+1;i+=2)if(r.Next(p*=2)<1){SetCursorPosition(r.Next(x=(n-1+(r.Next(2)<1?i:-i))*w,x+w),r.Next(WindowHeight));Write("*");break;}}}

ลองออนไลน์! (มันจะไม่ทำงาน แต่รู้ว่า)

เวอร์ชันเต็ม / ฟอร์แมต:

namespace System
{
    using static Console;

    class P
    {
        static void Main()
        {
            Action<int> f = n =>
            {
                for (var r = new Random(); ;)
                {
                    for (int i = 0, p = 1, w = WindowWidth / (2 * n - 1), x; i < n + 1; i += 2)
                        if (r.Next(p *= 2) < 1)
                        {
                            SetCursorPosition(r.Next(x = (n - 1 + (r.Next(2) < 1 ? i : -i)) * w, x + w), r.Next(WindowHeight));
                            Write("*");
                            break;
                        }

                    Threading.Thread.Sleep(25);
                }
            };

            f(5);
        }
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.