게으른 물리학자는 이중 슬릿 실험을 수행해야합니다. 그러나 그들은 게으르고 모든 장비를 스스로 설정하기 위해 귀찮게 할 수 없으므로 효과를 시뮬레이트 할 것입니다. 그들은 프로그래밍을 할 수 없지만 도움이 필요할 것입니다. 그들이 게 으르므로 프로그램은 가능한 짧아야합니다.
홀수 양의 정수 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 %의 확률로 떨어질 수 있습니다. 만약 프레임의 끝이 떨어지면 다음 2 개로 넘어 가지 않으면 12.5 %의 확률로 떨어질 것입니다. 떨어지지 않아도 문제가되지 않지만 여전히 프레임의 끝입니다.
확률을 계산하는 방법에 대해 약간의 혼동이 있었으며,이 중 대부분은 확률을 1로 더해야하는 확률로 생각하는 사람들에 의한 것입니다. 마음에서 그 아이디어를 제거하고 약간 정리해야합니다.
- 프레임 당 최대 하나의 파티클이 사라집니다. 이는 파티클이 해당 프레임에 전혀 도달하지 않을 수 있음을 의미합니다.
- 입자는 인쇄 가능한 문자로 나타낼 수 있습니다.
- 파티클은 상자의 임의의 위치에 임의의 확률로 도달합니다.
- 상자의 너비
2n-1
는 캔버스의 크기 여야합니다 . 그러므로n=5
그것들은1/9
캔버스 너비의 일이어야합니다 . - 상자의 높이는 캔버스의 높이 여야합니다.
- 입자가 상자 외부로 떨어지지 않아야합니다.
- 입자가 이미 선택된 지점에 착륙 한 경우 문제가되지 않습니다.
- 위의 ASCII 상자는 명확성을 위해 그려 졌으므로 그려서는 안됩니다.
- 합리적인 경우 자신의 캔버스 크기를 선택할 수 있습니다. 예를 들어 높이가 몇 픽셀에 불과해서는 안됩니다. 또한 모든 상자를 넣을 수 있어야합니다.
- 코드가 프레임 사이에서 휴면 상태 인 경우이를 바이트 수에 추가 할 필요가 없습니다.
각 최대 값, 최소값 사이에 간격이 있어야합니다. 상자와 너비는 같아야하지만 입자가 떨어지지 않습니다. 다음 다이어그램을 참조하십시오.
+---+---+---+---+---+
| | | | | |
|max|min|max|min|max|
| | | | | |
+---+---+---+---+---+
프로그램은 수동으로 중지 될 때까지 실행해야합니다.
규칙
- pRNG (의사 난수 생성기)는 괜찮습니다.
- 표준 허점 은 금지되어 있습니다.
- 적절한 형식으로 입력 할 수 있습니다.
- STDOUT으로 출력해야합니다.
- 이것은 코드 골프 이므로 가장 짧은 대답이 이깁니다.
예
다음 GIF는에 대한 예제입니다 n = 5
. 나는 그것을 빨리 두드려서 기회가 약간 벗어날 수 있습니다.
답변
파이썬 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
답변
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
답변
수학, 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]
산출
답변
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에서는 작동하지 않습니다.
답변
클로저 + 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)))))))
글쎄, 나는 확실히 이기지 못했다. 그러나 이것은 좋은 두뇌 운동이었다! 나는 이것을하는 지나치게 원형 교차로 방법을 선택했을 수도 있지만 작동합니다! 기본적으로 작동 방식은 다음과 같습니다.
-
각 열의 x- 값은를 기준으로 계산됩니다
n
. 그런 다음 점을 포함 할 “활성 열”이 필터링됩니다. 그런 다음 열이 선택 될 가능성으로 압축됩니다. -
애니메이션이 시작되고 각 프레임에 루프가 입력됩니다. 중간부터 시작하여 각 열 쌍이 시도됩니다. 한 쌍의 열이 선택되면 해당 쌍의 한 열이 임의로 선택됩니다.
-
선택한 열 내에서 임의의 위치에 점이 그려지고 내부 루프가 종료되고 새 프레임이 시작됩니다.
본질적으로 Clojure의 처리 래퍼 인 Quil 그래픽 라이브러리를 사용합니다.
골프 코드는 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)))))))
답변
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);
}
}
}