El experimento de la doble rendija

16

Un físico perezoso tiene el trabajo de realizar el experimento de doble rendija. Sin embargo, son flojos y no pueden molestarse en configurar todo el equipo ellos mismos, por lo que simularán los efectos. Sin embargo, no pueden programar, por lo que necesitarán ayuda. Como son flojos, su programa debe ser lo más corto posible.


Dado un entero positivo impar n( n >= 1y n % 2 == 1), realice la simulación.

Cómo funciona

Comenzará con un lienzo vacío y cada cuadro, una sola partícula de luz pasará por las rendijas y aterrizará en el lienzo. La partícula aterrizará en un máximo con una posibilidad de:

n = 1:

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

n = 3:

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

n = 5:

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

etc.

Por ejemplo, para n=5marcar el cuadro del medio, hay un 50% de posibilidades de caer en él. Si cae al final del cuadro, si no se mueve a los siguientes dos, hay un 25% de posibilidades de caer en esos. Si cae al final del cuadro, si no se mueve a los siguientes dos, hay un 12.5% ​​de posibilidades de caer en esos. Si no cae, no importa, sigue siendo el final del marco.

Ha habido cierta confusión sobre cómo calcular las posibilidades, la mayor parte de esto se debe a que las personas piensan en ellas como probabilidades que deberían sumar 1. Elimina esa idea de tu mente y debería aclararte un poco.

  • Como máximo, una partícula saldrá por cuadro, esto significa que una partícula puede no aterrizar en absoluto en ese cuadro.
  • Una partícula puede ser representada por cualquier carácter imprimible.
  • La partícula aterrizará en cualquier lugar de la caja con una probabilidad aleatoria.
  • El ancho de las cajas debe ser 2n-1del tamaño del lienzo. Entonces n=5, deben ser 1/9del ancho del lienzo.
  • La altura de las cajas debe ser la altura del lienzo.
  • La partícula no debe aterrizar fuera de las cajas en absoluto.
  • Si una partícula ya ha aterrizado en un lugar elegido que no importa, puede aterrizar allí nuevamente.
  • Los cuadros ascii anteriores son para mayor claridad, no se deben dibujar.
  • Puede elegir su propio tamaño de lienzo siempre que sea razonable. Por ejemplo, no debe tener solo unos pocos píxeles de altura. También debería poder encajar todas las cajas en él.
  • Si su código duerme entre cuadros, no necesita agregarlo en su conteo de bytes.

Debe haber espacios entre cada uno de los máximos, un mínimo. Debe tener el mismo ancho que una caja, pero no caerán partículas allí. Ver el siguiente diagrama:

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

El programa debe ejecutarse hasta que se detenga manualmente.

Reglas

  • Un generador de números pseudoaleatorios (pRNG) está bien.
  • Las lagunas estándar están prohibidas.
  • La entrada puede ser tomada por cualquier formato razonable.
  • Debe enviar a STDOUT.
  • Este es el por lo que gana la respuesta más corta.

Ejemplo

El siguiente GIF es un ejemplo de ejecución n = 5. Solo lo hice rápidamente, por lo que las posibilidades pueden ser un poco bajas.

Ejemplo de doble rendija

TheLethalCoder
fuente
Los comentarios no son para discusión extendida; Esta conversación se ha movido al chat .
Martin Ender

Respuestas:

4

Python 2, 207 200 bytes

Hay un método para esta locura, lo prometo. Sigue la interpretación de probabilidad que comenté en el OP.

Editar: -7 bytes a través de una evaluación perezosa inteligente (y eliminar algunos signos)

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
algmyr
fuente
4

GOLPETAZO, 396-11 = 385 bytes

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

Desafortunadamente, no puedo demostrar esto en TryItOnline debido al bucle sin fin y las secuencias de escape ANSI que mueven el cursor, ¡pero aún puede copiarlo y pegarlo en su terminal!

Versión no minificada:

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
Andrew Dunai
fuente
1
Echa un vistazo a los consejos para jugar al golf en bash . Aquí puede cosechar bastantes frutas fáciles de colgar, por ejemplo, en $[ ]lugar de$(( )) . En lugar de for i in `seq $((($1+1)/2)) -1 1`;do ...;doneintentarlo for((i=($1+1)/2;i>0;i--));{ ...;}. En lugar de [ $(($RANDOM%2)) -eq 1 ]intentarlo ((RANDOM%2)). sector, SS, Etc debe ser reemplazado con nombres de variables 1 carbonilla.
Trauma digital
3

Mathematica, 231 bytes

(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->" "]])&


entrada

[5]

salida

ingrese la descripción de la imagen aquí

J42161217
fuente
Esto parece no ser válido, para n = 5 solo debe haber 5 casillas, tiene 9
TheLethalCoder
Me di cuenta de que contaba como {... 3,2,1,2,3 ...}. Puedo arreglarlo si no es aceptado
J42161217
2
@TheLethalCoder Fixed! ¡Mejorado! Golfed!
J42161217
Se ve bien, mi
voto a favor
2

C # (.NET 4.5), 319254 bytes

¡Ahorró 65 bytes gracias a 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;}}}

Uf, eso fue mucho trabajo, pero funciona de alguna manera.

Dado que esto utiliza Consolefunciones específicas y Thread sleeping, lamentablemente no funcionará en TIO.

Ian H.
fuente
Compilar a una Action<int>para salvar bytes, while(true)-> ( while(1>0)-> for(;;). using C=Console;O using static Console;.
TheLethalCoder
¿Esa aplicación también puede ser delegada? No lo sabia. Lo actualizaré en un segundo.
Ian H.
Los programas / funciones están permitidos de manera predeterminada y las lambdas anónimas cuentan como funciones (aunque las reglas sobre ellas se vuelven un poco más profundas cuando necesita llamarlas).
TheLethalCoder
255 bytesnamespace 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 Ese código no funciona: / Solo da muchos Variable is not existing in the current contexterrores.
Ian H.
1

Clojure + Quil, 394 bytes

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

Bueno, ciertamente no gané, ¡pero este fue un buen ejercicio mental! Puede que haya elegido una forma demasiado indirecta de hacer esto, ¡pero funciona! Básicamente, cómo funciona es:

  1. Los valores de x de cada columna se calculan en función de n . Luego, las "columnas activas" que contendrán los puntos se filtran. Las columnas se comprimen con las posibilidades de que se elijan.

  2. La animación comienza, y cada cuadro, se ingresa un bucle. Comenzando desde el medio, se prueba cada par de columnas. Una vez que se elige un par de columnas, se elige al azar una columna del par.

  3. Se dibuja un punto en una posición aleatoria dentro de la columna elegida, el bucle interno sale y comienza un nuevo marco.

Utiliza la biblioteca de gráficos Quil, que es esencialmente un contenedor de procesamiento para Clojure.

Tenga en cuenta que el código de golf no produce la misma animación que se muestra en el GIF. En el código de golf, el fondo es gris y la ventana y los puntos son más pequeños. Tiene el mismo efecto, simplemente no es tan bonito.

GIF

Consulte el código no oculto para obtener una explicación detallada:

(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)))))))
Carcigenicate
fuente
0

C #, 238 bytes

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;}}}

Pruébalo en línea!(No funcionará, pero ya sabes).

Versión completa / formateada:

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);
        }
    }
}
TheLethalCoder
fuente