懒惰的物理学家有做双缝实验的工作。然而,他们懒惰,不能费心设置所有的设备本身,所以要模拟的效果。但是他们不会编程,所以需要一些帮助。由于他们懒惰,你的程序应该尽可能短。
给定一个奇数正整数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%。如果它不掉下来,这并不重要,它仍然是框架的结束。
2n-1。因此,对于n=5,它们应该是画布宽度的1/9第四。每个最大值之间都应该有空隙,这是最小值。这应该和盒子一样宽,但是没有粒子会落在那里。见下图:
+---+---+---+---+---+
| | | | | |
|max|min|max|min|max|
| | | | | |
+---+---+---+---+---+程序应该运行,直到手动停止为止。
下面的GIF是n = 5运行的一个示例。我只是很快就把它搞砸了,所以机会可能会略有减少。

发布于 2017-08-02 16:47:09
(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

发布于 2017-08-03 18:10:17
(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)))))))嗯,我当然没有赢,但这是一个很好的大脑锻炼!我可能选择了一种过于迂回的方式来做这件事,但它是有效的!基本上,它的工作原理是:
n计算的.然后,将包含点的“活动列”过滤掉。然后,对列进行拉链,使其具有被选择的可能性。使用Quil图形库,它本质上是Clojure的处理包装器。
注意,金色代码不会产生与GIF中显示的动画相同的动画。在金色的代码中,背景是灰色的,窗口和点更小。它有同样的效果,只是没有那么漂亮。

有关深入解释,请参阅未使用的代码:
(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)))))))发布于 2017-08-04 12:39:56
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);
}
}
}https://codegolf.stackexchange.com/questions/137164
复制相似问题