이중 슬릿 실험


16

게으른 물리학자는 이중 슬릿 실험을 수행해야합니다. 그러나 그들은 게으르고 모든 장비를 스스로 설정하기 위해 귀찮게 할 수 없으므로 효과를 시뮬레이트 할 것입니다. 그들은 프로그래밍을 할 수 없지만 도움이 필요할 것입니다. 그들이 게 으르므로 프로그램은 가능한 짧아야합니다.


홀수 양의 정수 n( n >= 1n % 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 %의 확률로 떨어질 수 있습니다. 만약 프레임의 끝이 떨어지면 다음 2 개로 넘어 가지 않으면 12.5 %의 확률로 떨어질 것입니다. 떨어지지 않아도 문제가되지 않지만 여전히 프레임의 끝입니다.

확률을 계산하는 방법에 대해 약간의 혼동이 있었으며,이 중 대부분은 확률을 1로 더해야하는 확률로 생각하는 사람들에 의한 것입니다. 마음에서 그 아이디어를 제거하고 약간 정리해야합니다.

  • 프레임 당 최대 하나의 파티클이 사라집니다. 이는 파티클이 해당 프레임에 전혀 도달하지 않을 수 있음을 의미합니다.
  • 입자는 인쇄 가능한 문자로 나타낼 수 있습니다.
  • 파티클은 상자의 임의의 위치에 임의의 확률로 도달합니다.
  • 상자의 너비 2n-1는 캔버스의 크기 여야합니다 . 그러므로 n=5그것들은 1/9캔버스 너비의 일이어야합니다 .
  • 상자의 높이는 캔버스의 높이 여야합니다.
  • 입자가 상자 외부로 떨어지지 않아야합니다.
  • 입자가 이미 선택된 지점에 착륙 한 경우 문제가되지 않습니다.
  • 위의 ASCII 상자는 명확성을 위해 그려 졌으므로 그려서는 안됩니다.
  • 합리적인 경우 자신의 캔버스 크기를 선택할 수 있습니다. 예를 들어 높이가 몇 픽셀에 불과해서는 안됩니다. 또한 모든 상자를 넣을 수 있어야합니다.
  • 코드가 프레임 사이에서 휴면 상태 인 경우이를 바이트 수에 추가 할 필요가 없습니다.

각 최대 값, 최소값 사이에 간격이 있어야합니다. 상자와 너비는 같아야하지만 입자가 떨어지지 않습니다. 다음 다이어그램을 참조하십시오.

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

프로그램은 수동으로 중지 될 때까지 실행해야합니다.

규칙

  • pRNG (의사 난수 생성기)는 괜찮습니다.
  • 표준 허점 은 금지되어 있습니다.
  • 적절한 형식으로 입력 할 수 있습니다.
  • STDOUT으로 출력해야합니다.
  • 이것은 이므로 가장 짧은 대답이 이깁니다.

다음 GIF는에 대한 예제입니다 n = 5. 나는 그것을 빨리 두드려서 기회가 약간 벗어날 수 있습니다.

이중 슬릿 예


의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
마틴 엔더

답변:


4

파이썬 2, 207200 바이트

이 광기에 대한 방법이 있다고 약속합니다. 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

불행히도 커서를 움직이는 끝없는 루프 및 ANSI 이스케이프 시퀀스 때문에 TryItOnline에서 이것을 입증 할 수는 없지만 터미널에 복사하여 붙여 넣을 수는 있습니다!

축소되지 않은 버전 :

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
bash에서 골프 팁을 확인하십시오 . 예를 들어 $[ ]대신에 수확 할 수있는 쉬운 과일이 몇 개 있습니다 $(( )). 대신에 for i in `seq $((($1+1)/2)) -1 1`;do ...;done시도하십시오 for((i=($1+1)/2;i>0;i--));{ ...;}. 대신에 [ $(($RANDOM%2)) -eq 1 ]시도하십시오 ((RANDOM%2)). sector, SS등은 1 개의 문자 변수 이름으로 바꿔야합니다.
디지털 외상

3

수학, 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

나에게서 좋아, upvote 좋아 보인다
TheLethalCoder

2

C # (. NET 4.5), 319254 바이트

TheLethalCoder 덕분에 65 바이트를 절약했습니다!

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에서는 작동하지 않습니다.


Action<int>바이트를 저장하기 위해 컴파일 while(true)-> ( while(1>0)-> for(;;). using C=Console;또는 using static Console;.
TheLethalCoder

그 신청서도 대리인이 될 수 있습니까? 몰랐어요 잠시 후 업데이트하겠습니다.
Ian H.

프로그램 / 기능은 기본적으로 허용되며 익명 람다는 기능으로 계산됩니다 (호출 할 때 규칙이 조금 더 깊어 지더라도).
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 11

@TheLethalCoder 그 코드는 작동하지 않습니다 : / 많은 Variable is not existing in the current context오류가 발생합니다.
Ian H.

1

클로저 + 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- 값은를 기준으로 계산됩니다 n. 그런 다음 점을 포함 할 "활성 열"이 필터링됩니다. 그런 다음 열이 선택 될 가능성으로 압축됩니다.

  2. 애니메이션이 시작되고 각 프레임에 루프가 입력됩니다. 중간부터 시작하여 각 열 쌍이 시도됩니다. 한 쌍의 열이 선택되면 해당 쌍의 한 열이 임의로 선택됩니다.

  3. 선택한 열 내에서 임의의 위치에 점이 그려지고 내부 루프가 종료되고 새 프레임이 시작됩니다.

본질적으로 Clojure의 처리 래퍼 인 Quil 그래픽 라이브러리를 사용합니다.

골프 코드는 GIF에 표시된 것과 동일한 애니메이션을 생성하지 않습니다. 골프 코드에서 배경은 회색이며 창과 점은 더 작습니다. 같은 효과가 있지만 예쁘지 않습니다.

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.