双缝实验


16

懒惰的物理学家有工作要做双狭缝实验。但是,它们很懒惰,不会麻烦自己设置所有设备,因此将模拟效果。他们无法编程,因此需要一些帮助。由于它们很懒,因此您的程序应尽可能短。


给定一个奇数正整数nn >= 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%的机会掉入其中。如果它落到帧末,如果不移到下两个,则有12.5%的机会掉入其中。如果不跌倒也没关系,那仍然是框架的尽头。

关于如何计算机会一直存在一些困惑,这主要是由于人们认为它们是应该加起来为1的概率。

  • 每帧最多只能拉出一个粒子,这意味着粒子可能根本不会落在该帧上。
  • 粒子可以用任何可打印的字符表示。
  • 粒子将随机降落在盒子中的任何位置。
  • 盒子的宽度应该是2n-1画布的大小。因此,n=5它们应该是1/9画布宽度的th。
  • 盒子的高度应该是画布的高度。
  • 粒子完全不应落在盒子外面。
  • 如果一个粒子已经降落在一个选定的位置上,那么它可以再次降落在那里。
  • 上面的ascii框是为了清楚起见,因此不应绘制它们。
  • 您可以选择自己的画布大小,只要合理即可。例如,它不能只是几个像素高。它还应该能够适合其上的所有盒子。
  • 如果您的代码在帧之间休眠,则无需将其添加到字节数中。

每个最大值(最小值)之间应该有间隙。该宽度应与盒子的宽度相同,但没有颗粒会落在该盒子上。请参见下图:

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

该程序应运行,直到手动停止为止。

规则

  • 伪随机数生成器(pRNG)可以。
  • 禁止出现标准漏洞
  • 输入可以采用任何合理的格式。
  • 您应该输出到STDOUT。
  • 这是因此最短的答案为准。

以下GIF是针对的示例n = 5。我只是很快把它敲了一下,所以机会可能会略有减少。

双缝示例


评论不作进一步讨论;此对话已转移至聊天
Martin Ender

Answers:


4

Python 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))sectorSS等应替换为1个char变量名称。
Digital Trauma'8

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 '17

看起来不错,请向我
投票-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

该应用程序也可以成为委托人吗?不知道 我会在几秒钟内更新它。
伊恩H.17年

默认情况下,程序/函数是允许的,匿名lambda作为函数(尽管当您需要调用它们时,它们上的规则会更深一些)。
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值基于计算n。然后,将滤除包含点的“活动列”。然后将这些列压缩为可以选择的可能性。

  2. 动画开始,并在每个帧中输入一个循环。从中间开始,尝试每对列。一旦选择了一对列,就可以随机选择一对。

  3. 在所选列中的任意位置绘制一个点,退出内部循环,并开始新的帧。

使用Quil图形库,该库实际上是Clojure的处理包装器。

请注意,打高尔夫球的代码不会产生与GIF中所示相同的动画。在高尔夫球编码中,背景为灰色,并且窗口和点较小。它具有相同的效果,只是不那么漂亮。

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

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);
        }
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.